diff --git a/meta/poky/scripts/lib/argparse_oe.py b/meta/poky/scripts/lib/argparse_oe.py
new file mode 100644
index 0000000..9bdfc1c
--- /dev/null
+++ b/meta/poky/scripts/lib/argparse_oe.py
@@ -0,0 +1,176 @@
+import sys
+import argparse
+from collections import defaultdict, OrderedDict
+
+class ArgumentUsageError(Exception):
+    """Exception class you can raise (and catch) in order to show the help"""
+    def __init__(self, message, subcommand=None):
+        self.message = message
+        self.subcommand = subcommand
+
+class ArgumentParser(argparse.ArgumentParser):
+    """Our own version of argparse's ArgumentParser"""
+    def __init__(self, *args, **kwargs):
+        kwargs.setdefault('formatter_class', OeHelpFormatter)
+        self._subparser_groups = OrderedDict()
+        super(ArgumentParser, self).__init__(*args, **kwargs)
+        self._positionals.title = 'arguments'
+        self._optionals.title = 'options'
+
+    def error(self, message):
+        """error(message: string)
+
+        Prints a help message incorporating the message to stderr and
+        exits.
+        """
+        self._print_message('%s: error: %s\n' % (self.prog, message), sys.stderr)
+        self.print_help(sys.stderr)
+        sys.exit(2)
+
+    def error_subcommand(self, message, subcommand):
+        if subcommand:
+            action = self._get_subparser_action()
+            try:
+                subparser = action._name_parser_map[subcommand]
+            except KeyError:
+                self.error('no subparser for name "%s"' % subcommand)
+            else:
+                subparser.error(message)
+
+        self.error(message)
+
+    def add_subparsers(self, *args, **kwargs):
+        if 'dest' not in kwargs:
+            kwargs['dest'] = '_subparser_name'
+
+        ret = super(ArgumentParser, self).add_subparsers(*args, **kwargs)
+        # Need a way of accessing the parent parser
+        ret._parent_parser = self
+        # Ensure our class gets instantiated
+        ret._parser_class = ArgumentSubParser
+        # Hacky way of adding a method to the subparsers object
+        ret.add_subparser_group = self.add_subparser_group
+        return ret
+
+    def add_subparser_group(self, groupname, groupdesc, order=0):
+        self._subparser_groups[groupname] = (groupdesc, order)
+
+    def parse_args(self, args=None, namespace=None):
+        """Parse arguments, using the correct subparser to show the error."""
+        args, argv = self.parse_known_args(args, namespace)
+        if argv:
+            message = 'unrecognized arguments: %s' % ' '.join(argv)
+            if self._subparsers:
+                subparser = self._get_subparser(args)
+                subparser.error(message)
+            else:
+                self.error(message)
+            sys.exit(2)
+        return args
+
+    def _get_subparser(self, args):
+        action = self._get_subparser_action()
+        if action.dest == argparse.SUPPRESS:
+            self.error('cannot get subparser, the subparser action dest is suppressed')
+
+        name = getattr(args, action.dest)
+        try:
+            return action._name_parser_map[name]
+        except KeyError:
+            self.error('no subparser for name "%s"' % name)
+
+    def _get_subparser_action(self):
+        if not self._subparsers:
+            self.error('cannot return the subparser action, no subparsers added')
+
+        for action in self._subparsers._group_actions:
+            if isinstance(action, argparse._SubParsersAction):
+                return action
+
+
+class ArgumentSubParser(ArgumentParser):
+    def __init__(self, *args, **kwargs):
+        if 'group' in kwargs:
+            self._group = kwargs.pop('group')
+        if 'order' in kwargs:
+            self._order = kwargs.pop('order')
+        super(ArgumentSubParser, self).__init__(*args, **kwargs)
+
+    def parse_known_args(self, args=None, namespace=None):
+        # This works around argparse not handling optional positional arguments being
+        # intermixed with other options. A pretty horrible hack, but we're not left
+        # with much choice given that the bug in argparse exists and it's difficult
+        # to subclass.
+        # Borrowed from http://stackoverflow.com/questions/20165843/argparse-how-to-handle-variable-number-of-arguments-nargs
+        # with an extra workaround (in format_help() below) for the positional
+        # arguments disappearing from the --help output, as well as structural tweaks.
+        # Originally simplified from http://bugs.python.org/file30204/test_intermixed.py
+        positionals = self._get_positional_actions()
+        for action in positionals:
+            # deactivate positionals
+            action.save_nargs = action.nargs
+            action.nargs = 0
+
+        namespace, remaining_args = super(ArgumentSubParser, self).parse_known_args(args, namespace)
+        for action in positionals:
+            # remove the empty positional values from namespace
+            if hasattr(namespace, action.dest):
+                delattr(namespace, action.dest)
+        for action in positionals:
+            action.nargs = action.save_nargs
+        # parse positionals
+        namespace, extras = super(ArgumentSubParser, self).parse_known_args(remaining_args, namespace)
+        return namespace, extras
+
+    def format_help(self):
+        # Quick, restore the positionals!
+        positionals = self._get_positional_actions()
+        for action in positionals:
+            if hasattr(action, 'save_nargs'):
+                action.nargs = action.save_nargs
+        return super(ArgumentParser, self).format_help()
+
+
+class OeHelpFormatter(argparse.HelpFormatter):
+    def _format_action(self, action):
+        if hasattr(action, '_get_subactions'):
+            # subcommands list
+            groupmap = defaultdict(list)
+            ordermap = {}
+            subparser_groups = action._parent_parser._subparser_groups
+            groups = sorted(subparser_groups.keys(), key=lambda item: subparser_groups[item][1], reverse=True)
+            for subaction in self._iter_indented_subactions(action):
+                parser = action._name_parser_map[subaction.dest]
+                group = getattr(parser, '_group', None)
+                groupmap[group].append(subaction)
+                if group not in groups:
+                    groups.append(group)
+                order = getattr(parser, '_order', 0)
+                ordermap[subaction.dest] = order
+
+            lines = []
+            if len(groupmap) > 1:
+                groupindent = '  '
+            else:
+                groupindent = ''
+            for group in groups:
+                subactions = groupmap[group]
+                if not subactions:
+                    continue
+                if groupindent:
+                    if not group:
+                        group = 'other'
+                    groupdesc = subparser_groups.get(group, (group, 0))[0]
+                    lines.append('  %s:' % groupdesc)
+                for subaction in sorted(subactions, key=lambda item: ordermap[item.dest], reverse=True):
+                    lines.append('%s%s' % (groupindent, self._format_action(subaction).rstrip()))
+            return '\n'.join(lines)
+        else:
+            return super(OeHelpFormatter, self)._format_action(action)
+
+def int_positive(value):
+    ivalue = int(value)
+    if ivalue <= 0:
+        raise argparse.ArgumentTypeError(
+                "%s is not a positive int value" % value)
+    return ivalue
diff --git a/meta/poky/scripts/lib/build_perf/__init__.py b/meta/poky/scripts/lib/build_perf/__init__.py
new file mode 100644
index 0000000..1f8b729
--- /dev/null
+++ b/meta/poky/scripts/lib/build_perf/__init__.py
@@ -0,0 +1,31 @@
+#
+# Copyright (c) 2017, Intel Corporation.
+#
+# This program is free software; you can redistribute it and/or modify it
+# under the terms and conditions of the GNU General Public License,
+# version 2, as published by the Free Software Foundation.
+#
+# This program is distributed in the hope 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.
+#
+"""Build performance test library functions"""
+
+def print_table(rows, row_fmt=None):
+    """Print data table"""
+    if not rows:
+        return
+    if not row_fmt:
+        row_fmt = ['{:{wid}} '] * len(rows[0])
+
+    # Go through the data to get maximum cell widths
+    num_cols = len(row_fmt)
+    col_widths = [0] * num_cols
+    for row in rows:
+        for i, val in enumerate(row):
+            col_widths[i] = max(col_widths[i], len(str(val)))
+
+    for row in rows:
+        print(*[row_fmt[i].format(col, wid=col_widths[i]) for i, col in enumerate(row)])
+
diff --git a/meta/poky/scripts/lib/build_perf/html.py b/meta/poky/scripts/lib/build_perf/html.py
new file mode 100644
index 0000000..578bb16
--- /dev/null
+++ b/meta/poky/scripts/lib/build_perf/html.py
@@ -0,0 +1,19 @@
+#
+# Copyright (c) 2017, Intel Corporation.
+#
+# This program is free software; you can redistribute it and/or modify it
+# under the terms and conditions of the GNU General Public License,
+# version 2, as published by the Free Software Foundation.
+#
+# This program is distributed in the hope 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.
+#
+"""Helper module for HTML reporting"""
+from jinja2 import Environment, PackageLoader
+
+
+env = Environment(loader=PackageLoader('build_perf', 'html'))
+
+template = env.get_template('report.html')
diff --git a/meta/poky/scripts/lib/build_perf/html/measurement_chart.html b/meta/poky/scripts/lib/build_perf/html/measurement_chart.html
new file mode 100644
index 0000000..65f1a22
--- /dev/null
+++ b/meta/poky/scripts/lib/build_perf/html/measurement_chart.html
@@ -0,0 +1,50 @@
+<script type="text/javascript">
+  chartsDrawing += 1;
+  google.charts.setOnLoadCallback(drawChart_{{ chart_elem_id }});
+  function drawChart_{{ chart_elem_id }}() {
+    var data = new google.visualization.DataTable();
+
+    // Chart options
+    var options = {
+      theme : 'material',
+      legend: 'none',
+      hAxis: { format: '', title: 'Commit number',
+               minValue: {{ chart_opts.haxis.min }},
+               maxValue: {{ chart_opts.haxis.max }} },
+      {% if measurement.type == 'time' %}
+      vAxis: { format: 'h:mm:ss' },
+      {% else %}
+      vAxis: { format: '' },
+      {% endif %}
+      pointSize: 5,
+      chartArea: { left: 80, right: 15 },
+    };
+
+    // Define data columns
+    data.addColumn('number', 'Commit');
+    data.addColumn('{{ measurement.value_type.gv_data_type }}',
+                   '{{ measurement.value_type.quantity }}');
+    // Add data rows
+    data.addRows([
+      {% for sample in measurement.samples %}
+        [{{ sample.commit_num }}, {{ sample.mean.gv_value() }}],
+      {% endfor %}
+    ]);
+
+    // Finally, draw the chart
+    chart_div = document.getElementById('{{ chart_elem_id }}');
+    var chart = new google.visualization.LineChart(chart_div);
+    google.visualization.events.addListener(chart, 'ready', function () {
+      //chart_div = document.getElementById('{{ chart_elem_id }}');
+      //chart_div.innerHTML = '<img src="' + chart.getImageURI() + '">';
+      png_div = document.getElementById('{{ chart_elem_id }}_png');
+      png_div.outerHTML = '<a id="{{ chart_elem_id }}_png" href="' + chart.getImageURI() + '">PNG</a>';
+      console.log("CHART READY: {{ chart_elem_id }}");
+      chartsDrawing -= 1;
+      if (chartsDrawing == 0)
+        console.log("ALL CHARTS READY");
+    });
+    chart.draw(data, options);
+}
+</script>
+
diff --git a/meta/poky/scripts/lib/build_perf/html/report.html b/meta/poky/scripts/lib/build_perf/html/report.html
new file mode 100644
index 0000000..d1ba6f2
--- /dev/null
+++ b/meta/poky/scripts/lib/build_perf/html/report.html
@@ -0,0 +1,289 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+{# Scripts, for visualization#}
+<!--START-OF-SCRIPTS-->
+<script type="text/javascript" src="https://www.gstatic.com/charts/loader.js"></script>
+<script type="text/javascript">
+google.charts.load('current', {'packages':['corechart']});
+var chartsDrawing = 0;
+</script>
+
+{# Render measurement result charts #}
+{% for test in test_data %}
+  {% if test.status == 'SUCCESS' %}
+    {% for measurement in test.measurements %}
+      {% set chart_elem_id = test.name + '_' + measurement.name + '_chart' %}
+      {% include 'measurement_chart.html' %}
+    {% endfor %}
+  {% endif %}
+{% endfor %}
+
+<!--END-OF-SCRIPTS-->
+
+{# Styles #}
+<style>
+.meta-table {
+  font-size: 14px;
+  text-align: left;
+  border-collapse: collapse;
+}
+.meta-table tr:nth-child(even){background-color: #f2f2f2}
+meta-table th, .meta-table td {
+  padding: 4px;
+}
+.summary {
+  margin: 0;
+  font-size: 14px;
+  text-align: left;
+  border-collapse: collapse;
+}
+summary th, .meta-table td {
+  padding: 4px;
+}
+.measurement {
+  padding: 8px 0px 8px 8px;
+  border: 2px solid #f0f0f0;
+  margin-bottom: 10px;
+}
+.details {
+  margin: 0;
+  font-size: 12px;
+  text-align: left;
+  border-collapse: collapse;
+}
+.details th {
+  padding-right: 8px;
+}
+.details.plain th {
+  font-weight: normal;
+}
+.preformatted {
+  font-family: monospace;
+  white-space: pre-wrap;
+  background-color: #f0f0f0;
+  margin-left: 10px;
+}
+hr {
+  color: #f0f0f0;
+}
+h2 {
+  font-size: 20px;
+  margin-bottom: 0px;
+  color: #707070;
+}
+h3 {
+  font-size: 16px;
+  margin: 0px;
+  color: #707070;
+}
+</style>
+
+<title>{{ title }}</title>
+</head>
+
+{% macro poky_link(commit) -%}
+    <a href="http://git.yoctoproject.org/cgit/cgit.cgi/poky/log/?id={{ commit }}">{{ commit[0:11] }}</a>
+{%- endmacro %}
+
+<body><div style="width: 700px">
+  {# Test metadata #}
+  <h2>General</h2>
+  <hr>
+  <table class="meta-table" style="width: 100%">
+    <tr>
+      <th></th>
+      <th>Current commit</th>
+      <th>Comparing with</th>
+    </tr>
+    {% for key, item in metadata.items() %}
+    <tr>
+      <th>{{ item.title }}</th>
+      {%if key == 'commit' %}
+        <td>{{ poky_link(item.value) }}</td>
+        <td>{{ poky_link(item.value_old) }}</td>
+      {% else %}
+        <td>{{ item.value }}</td>
+        <td>{{ item.value_old }}</td>
+      {% endif %}
+    </tr>
+    {% endfor %}
+  </table>
+
+  {# Test result summary #}
+  <h2>Test result summary</h2>
+  <hr>
+  <table class="summary" style="width: 100%">
+    {% for test in test_data %}
+      {% if loop.index is even %}
+        {% set row_style = 'style="background-color: #f2f2f2"' %}
+      {% else %}
+        {% set row_style = 'style="background-color: #ffffff"' %}
+      {% endif %}
+      {% if test.status == 'SUCCESS' %}
+        {% for measurement in test.measurements %}
+          <tr {{ row_style }}>
+            {% if loop.index == 1 %}
+              <td>{{ test.name }}: {{ test.description }}</td>
+            {% else %}
+              {# add empty cell in place of the test name#}
+              <td></td>
+            {% endif %}
+            {% if measurement.absdiff > 0 %}
+              {% set result_style = "color: red" %}
+            {% elif measurement.absdiff == measurement.absdiff %}
+              {% set result_style = "color: green" %}
+            {% else %}
+              {% set result_style = "color: orange" %}
+            {%endif %}
+            {% if measurement.reldiff|abs > 2 %}
+              {% set result_style = result_style + "; font-weight: bold" %}
+            {% endif %}
+            <td>{{ measurement.description }}</td>
+            <td style="font-weight: bold">{{ measurement.value.mean }}</td>
+            <td style="{{ result_style }}">{{ measurement.absdiff_str }}</td>
+            <td style="{{ result_style }}">{{ measurement.reldiff_str }}</td>
+          </tr>
+        {% endfor %}
+      {% else %}
+        <td style="font-weight: bold; color: red;">{{test.status }}</td>
+        <td></td> <td></td> <td></td> <td></td>
+      {% endif %}
+    {% endfor %}
+  </table>
+
+  {# Detailed test results #}
+  {% for test in test_data %}
+  <h2>{{ test.name }}: {{ test.description }}</h2>
+  <hr>
+    {% if test.status == 'SUCCESS' %}
+      {% for measurement in test.measurements %}
+        <div class="measurement">
+          <h3>{{ measurement.description }}</h3>
+          <div style="font-weight:bold;">
+            <span style="font-size: 23px;">{{ measurement.value.mean }}</span>
+            <span style="font-size: 20px; margin-left: 12px">
+            {% if measurement.absdiff > 0 %}
+            <span style="color: red">
+            {% elif measurement.absdiff == measurement.absdiff %}
+            <span style="color: green">
+            {% else %}
+            <span style="color: orange">
+            {% endif %}
+            {{ measurement.absdiff_str }} ({{measurement.reldiff_str}})
+            </span></span>
+          </div>
+          {# Table for trendchart and the statistics #}
+          <table style="width: 100%">
+            <tr>
+              <td style="width: 75%">
+                {# Linechart #}
+                <div id="{{ test.name }}_{{ measurement.name }}_chart"></div>
+              </td>
+              <td>
+                {# Measurement statistics #}
+                <table class="details plain">
+                  <tr>
+                    <th>Test runs</th><td>{{ measurement.value.sample_cnt }}</td>
+                  </tr><tr>
+                    <th>-/+</th><td>-{{ measurement.value.minus }} / +{{ measurement.value.plus }}</td>
+                  </tr><tr>
+                    <th>Min</th><td>{{ measurement.value.min }}</td>
+                  </tr><tr>
+                    <th>Max</th><td>{{ measurement.value.max }}</td>
+                  </tr><tr>
+                    <th>Stdev</th><td>{{ measurement.value.stdev }}</td>
+                  </tr><tr>
+                    <th><div id="{{ test.name }}_{{ measurement.name }}_chart_png"></div></th>
+                    <td></td>
+                  </tr>
+                </table>
+              </td>
+            </tr>
+          </table>
+
+          {# Task and recipe summary from buildstats #}
+          {% if 'buildstats' in measurement %}
+            Task resource usage
+            <table class="details" style="width:100%">
+              <tr>
+                <th>Number of tasks</th>
+                <th>Top consumers of cputime</th>
+              </tr>
+              <tr>
+                <td style="vertical-align: top">{{ measurement.buildstats.tasks.count }} ({{ measurement.buildstats.tasks.change }})</td>
+                {# Table of most resource-hungry tasks #}
+                <td>
+                  <table class="details plain">
+                    {% for diff in measurement.buildstats.top_consumer|reverse %}
+                    <tr>
+                      <th>{{ diff.pkg }}.{{ diff.task }}</th>
+                      <td>{{ '%0.0f' % diff.value2 }} s</td>
+                    </tr>
+                    {% endfor %}
+                  </table>
+                </td>
+              </tr>
+              <tr>
+                <th>Biggest increase in cputime</th>
+                <th>Biggest decrease in cputime</th>
+              </tr>
+              <tr>
+                {# Table biggest increase in resource usage #}
+                <td>
+                  <table class="details plain">
+                    {% for diff in measurement.buildstats.top_increase|reverse %}
+                    <tr>
+                      <th>{{ diff.pkg }}.{{ diff.task }}</th>
+                      <td>{{ '%+0.0f' % diff.absdiff }} s</td>
+                    </tr>
+                    {% endfor %}
+                  </table>
+                </td>
+                {# Table biggest decrease in resource usage #}
+                <td>
+                  <table class="details plain">
+                    {% for diff in measurement.buildstats.top_decrease %}
+                    <tr>
+                      <th>{{ diff.pkg }}.{{ diff.task }}</th>
+                      <td>{{ '%+0.0f' % diff.absdiff }} s</td>
+                    </tr>
+                    {% endfor %}
+                  </table>
+                </td>
+              </tr>
+            </table>
+
+            {# Recipe version differences #}
+            {% if measurement.buildstats.ver_diff %}
+              <div style="margin-top: 16px">Recipe version changes</div>
+              <table class="details">
+                {% for head, recipes in measurement.buildstats.ver_diff.items() %}
+                  <tr>
+                    <th colspan="2">{{ head }}</th>
+                  </tr>
+                  {% for name, info in recipes|sort %}
+                    <tr>
+                      <td>{{ name }}</td>
+                      <td>{{ info }}</td>
+                    </tr>
+                  {% endfor %}
+                {% endfor %}
+              </table>
+            {% else %}
+              <div style="margin-top: 16px">No recipe version changes detected</div>
+            {% endif %}
+          {% endif %}
+        </div>
+      {% endfor %}
+    {# Unsuccessful test #}
+    {% else %}
+      <span style="font-size: 150%; font-weight: bold; color: red;">{{ test.status }}
+      {% if test.err_type %}<span style="font-size: 75%; font-weight: normal">({{ test.err_type }})</span>{% endif %}
+      </span>
+      <div class="preformatted">{{ test.message }}</div>
+    {% endif %}
+  {% endfor %}
+</div></body>
+</html>
+
diff --git a/meta/poky/scripts/lib/build_perf/report.py b/meta/poky/scripts/lib/build_perf/report.py
new file mode 100644
index 0000000..d99a367
--- /dev/null
+++ b/meta/poky/scripts/lib/build_perf/report.py
@@ -0,0 +1,345 @@
+#
+# Copyright (c) 2017, Intel Corporation.
+#
+# This program is free software; you can redistribute it and/or modify it
+# under the terms and conditions of the GNU General Public License,
+# version 2, as published by the Free Software Foundation.
+#
+# This program is distributed in the hope 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.
+#
+"""Handling of build perf test reports"""
+from collections import OrderedDict, Mapping, namedtuple
+from datetime import datetime, timezone
+from numbers import Number
+from statistics import mean, stdev, variance
+
+
+AggregateTestData = namedtuple('AggregateTestData', ['metadata', 'results'])
+
+
+def isofmt_to_timestamp(string):
+    """Convert timestamp string in ISO 8601 format into unix timestamp"""
+    if '.' in string:
+        dt = datetime.strptime(string, '%Y-%m-%dT%H:%M:%S.%f')
+    else:
+        dt = datetime.strptime(string, '%Y-%m-%dT%H:%M:%S')
+    return dt.replace(tzinfo=timezone.utc).timestamp()
+
+
+def metadata_xml_to_json(elem):
+    """Convert metadata xml into JSON format"""
+    assert elem.tag == 'metadata', "Invalid metadata file format"
+
+    def _xml_to_json(elem):
+        """Convert xml element to JSON object"""
+        out = OrderedDict()
+        for child in elem.getchildren():
+            key = child.attrib.get('name', child.tag)
+            if len(child):
+                out[key] = _xml_to_json(child)
+            else:
+                out[key] = child.text
+        return out
+    return _xml_to_json(elem)
+
+
+def results_xml_to_json(elem):
+    """Convert results xml into JSON format"""
+    rusage_fields = ('ru_utime', 'ru_stime', 'ru_maxrss', 'ru_minflt',
+                     'ru_majflt', 'ru_inblock', 'ru_oublock', 'ru_nvcsw',
+                     'ru_nivcsw')
+    iostat_fields = ('rchar', 'wchar', 'syscr', 'syscw', 'read_bytes',
+                     'write_bytes', 'cancelled_write_bytes')
+
+    def _read_measurement(elem):
+        """Convert measurement to JSON"""
+        data = OrderedDict()
+        data['type'] = elem.tag
+        data['name'] = elem.attrib['name']
+        data['legend'] = elem.attrib['legend']
+        values = OrderedDict()
+
+        # SYSRES measurement
+        if elem.tag == 'sysres':
+            for subel in elem:
+                if subel.tag == 'time':
+                    values['start_time'] = isofmt_to_timestamp(subel.attrib['timestamp'])
+                    values['elapsed_time'] = float(subel.text)
+                elif subel.tag == 'rusage':
+                    rusage = OrderedDict()
+                    for field in rusage_fields:
+                        if 'time' in field:
+                            rusage[field] = float(subel.attrib[field])
+                        else:
+                            rusage[field] = int(subel.attrib[field])
+                    values['rusage'] = rusage
+                elif subel.tag == 'iostat':
+                    values['iostat'] = OrderedDict([(f, int(subel.attrib[f]))
+                        for f in iostat_fields])
+                elif subel.tag == 'buildstats_file':
+                    values['buildstats_file'] = subel.text
+                else:
+                    raise TypeError("Unknown sysres value element '{}'".format(subel.tag))
+        # DISKUSAGE measurement
+        elif elem.tag == 'diskusage':
+            values['size'] = int(elem.find('size').text)
+        else:
+            raise Exception("Unknown measurement tag '{}'".format(elem.tag))
+        data['values'] = values
+        return data
+
+    def _read_testcase(elem):
+        """Convert testcase into JSON"""
+        assert elem.tag == 'testcase', "Expecting 'testcase' element instead of {}".format(elem.tag)
+
+        data = OrderedDict()
+        data['name'] = elem.attrib['name']
+        data['description'] = elem.attrib['description']
+        data['status'] = 'SUCCESS'
+        data['start_time'] = isofmt_to_timestamp(elem.attrib['timestamp'])
+        data['elapsed_time'] = float(elem.attrib['time'])
+        measurements = OrderedDict()
+
+        for subel in elem.getchildren():
+            if subel.tag == 'error' or subel.tag == 'failure':
+                data['status'] = subel.tag.upper()
+                data['message'] = subel.attrib['message']
+                data['err_type'] = subel.attrib['type']
+                data['err_output'] = subel.text
+            elif subel.tag == 'skipped':
+                data['status'] = 'SKIPPED'
+                data['message'] = subel.text
+            else:
+                measurements[subel.attrib['name']] = _read_measurement(subel)
+        data['measurements'] = measurements
+        return data
+
+    def _read_testsuite(elem):
+        """Convert suite to JSON"""
+        assert elem.tag == 'testsuite', \
+                "Expecting 'testsuite' element instead of {}".format(elem.tag)
+
+        data = OrderedDict()
+        if 'hostname' in elem.attrib:
+            data['tester_host'] = elem.attrib['hostname']
+        data['start_time'] = isofmt_to_timestamp(elem.attrib['timestamp'])
+        data['elapsed_time'] = float(elem.attrib['time'])
+        tests = OrderedDict()
+
+        for case in elem.getchildren():
+            tests[case.attrib['name']] = _read_testcase(case)
+        data['tests'] = tests
+        return data
+
+    # Main function
+    assert elem.tag == 'testsuites', "Invalid test report format"
+    assert len(elem) == 1, "Too many testsuites"
+
+    return _read_testsuite(elem.getchildren()[0])
+
+
+def aggregate_metadata(metadata):
+    """Aggregate metadata into one, basically a sanity check"""
+    mutable_keys = ('pretty_name', 'version_id')
+
+    def aggregate_obj(aggregate, obj, assert_str=True):
+        """Aggregate objects together"""
+        assert type(aggregate) is type(obj), \
+                "Type mismatch: {} != {}".format(type(aggregate), type(obj))
+        if isinstance(obj, Mapping):
+            assert set(aggregate.keys()) == set(obj.keys())
+            for key, val in obj.items():
+                aggregate_obj(aggregate[key], val, key not in mutable_keys)
+        elif isinstance(obj, list):
+            assert len(aggregate) == len(obj)
+            for i, val in enumerate(obj):
+                aggregate_obj(aggregate[i], val)
+        elif not isinstance(obj, str) or (isinstance(obj, str) and assert_str):
+            assert aggregate == obj, "Data mismatch {} != {}".format(aggregate, obj)
+
+    if not metadata:
+        return {}
+
+    # Do the aggregation
+    aggregate = metadata[0].copy()
+    for testrun in metadata[1:]:
+        aggregate_obj(aggregate, testrun)
+    aggregate['testrun_count'] = len(metadata)
+    return aggregate
+
+
+def aggregate_data(data):
+    """Aggregate multiple test results JSON structures into one"""
+
+    mutable_keys = ('status', 'message', 'err_type', 'err_output')
+
+    class SampleList(list):
+        """Container for numerical samples"""
+        pass
+
+    def new_aggregate_obj(obj):
+        """Create new object for aggregate"""
+        if isinstance(obj, Number):
+            new_obj = SampleList()
+            new_obj.append(obj)
+        elif isinstance(obj, str):
+            new_obj = obj
+        else:
+            # Lists and and dicts are kept as is
+            new_obj = obj.__class__()
+            aggregate_obj(new_obj, obj)
+        return new_obj
+
+    def aggregate_obj(aggregate, obj, assert_str=True):
+        """Recursive "aggregation" of JSON objects"""
+        if isinstance(obj, Number):
+            assert isinstance(aggregate, SampleList)
+            aggregate.append(obj)
+            return
+
+        assert type(aggregate) == type(obj), \
+                "Type mismatch: {} != {}".format(type(aggregate), type(obj))
+        if isinstance(obj, Mapping):
+            for key, val in obj.items():
+                if not key in aggregate:
+                    aggregate[key] = new_aggregate_obj(val)
+                else:
+                    aggregate_obj(aggregate[key], val, key not in mutable_keys)
+        elif isinstance(obj, list):
+            for i, val in enumerate(obj):
+                if i >= len(aggregate):
+                    aggregate[key] = new_aggregate_obj(val)
+                else:
+                    aggregate_obj(aggregate[i], val)
+        elif isinstance(obj, str):
+            # Sanity check for data
+            if assert_str:
+                assert aggregate == obj, "Data mismatch {} != {}".format(aggregate, obj)
+        else:
+            raise Exception("BUG: unable to aggregate '{}' ({})".format(type(obj), str(obj)))
+
+    if not data:
+        return {}
+
+    # Do the aggregation
+    aggregate = data[0].__class__()
+    for testrun in data:
+        aggregate_obj(aggregate, testrun)
+    return aggregate
+
+
+class MeasurementVal(float):
+    """Base class representing measurement values"""
+    gv_data_type = 'number'
+
+    def gv_value(self):
+        """Value formatting for visualization"""
+        if self != self:
+            return "null"
+        else:
+            return self
+
+
+class TimeVal(MeasurementVal):
+    """Class representing time values"""
+    quantity = 'time'
+    gv_title = 'elapsed time'
+    gv_data_type = 'timeofday'
+
+    def hms(self):
+        """Split time into hours, minutes and seconeds"""
+        hhh = int(abs(self) / 3600)
+        mmm = int((abs(self) % 3600) / 60)
+        sss = abs(self) % 60
+        return hhh, mmm, sss
+
+    def __str__(self):
+        if self != self:
+            return "nan"
+        hh, mm, ss = self.hms()
+        sign = '-' if self < 0 else ''
+        if hh > 0:
+            return '{}{:d}:{:02d}:{:02.0f}'.format(sign, hh, mm, ss)
+        elif mm > 0:
+            return '{}{:d}:{:04.1f}'.format(sign, mm, ss)
+        elif ss > 1:
+            return '{}{:.1f} s'.format(sign, ss)
+        else:
+            return '{}{:.2f} s'.format(sign, ss)
+
+    def gv_value(self):
+        """Value formatting for visualization"""
+        if self != self:
+            return "null"
+        hh, mm, ss = self.hms()
+        return [hh, mm, int(ss), int(ss*1000) % 1000]
+
+
+class SizeVal(MeasurementVal):
+    """Class representing time values"""
+    quantity = 'size'
+    gv_title = 'size in MiB'
+    gv_data_type = 'number'
+
+    def __str__(self):
+        if self != self:
+            return "nan"
+        if abs(self) < 1024:
+            return '{:.1f} kiB'.format(self)
+        elif abs(self) < 1048576:
+            return '{:.2f} MiB'.format(self / 1024)
+        else:
+            return '{:.2f} GiB'.format(self / 1048576)
+
+    def gv_value(self):
+        """Value formatting for visualization"""
+        if self != self:
+            return "null"
+        return self / 1024
+
+def measurement_stats(meas, prefix=''):
+    """Get statistics of a measurement"""
+    if not meas:
+        return {prefix + 'sample_cnt': 0,
+                prefix + 'mean': MeasurementVal('nan'),
+                prefix + 'stdev': MeasurementVal('nan'),
+                prefix + 'variance': MeasurementVal('nan'),
+                prefix + 'min': MeasurementVal('nan'),
+                prefix + 'max': MeasurementVal('nan'),
+                prefix + 'minus': MeasurementVal('nan'),
+                prefix + 'plus': MeasurementVal('nan')}
+
+    stats = {'name': meas['name']}
+    if meas['type'] == 'sysres':
+        val_cls = TimeVal
+        values = meas['values']['elapsed_time']
+    elif meas['type'] == 'diskusage':
+        val_cls = SizeVal
+        values = meas['values']['size']
+    else:
+        raise Exception("Unknown measurement type '{}'".format(meas['type']))
+    stats['val_cls'] = val_cls
+    stats['quantity'] = val_cls.quantity
+    stats[prefix + 'sample_cnt'] = len(values)
+
+    mean_val = val_cls(mean(values))
+    min_val = val_cls(min(values))
+    max_val = val_cls(max(values))
+
+    stats[prefix + 'mean'] = mean_val
+    if len(values) > 1:
+        stats[prefix + 'stdev'] = val_cls(stdev(values))
+        stats[prefix + 'variance'] = val_cls(variance(values))
+    else:
+        stats[prefix + 'stdev'] = float('nan')
+        stats[prefix + 'variance'] = float('nan')
+    stats[prefix + 'min'] = min_val
+    stats[prefix + 'max'] = max_val
+    stats[prefix + 'minus'] = val_cls(mean_val - min_val)
+    stats[prefix + 'plus'] = val_cls(max_val - mean_val)
+
+    return stats
+
diff --git a/meta/poky/scripts/lib/build_perf/scrape-html-report.js b/meta/poky/scripts/lib/build_perf/scrape-html-report.js
new file mode 100644
index 0000000..05a1f57
--- /dev/null
+++ b/meta/poky/scripts/lib/build_perf/scrape-html-report.js
@@ -0,0 +1,56 @@
+var fs = require('fs');
+var system = require('system');
+var page = require('webpage').create();
+
+// Examine console log for message from chart drawing
+page.onConsoleMessage = function(msg) {
+    console.log(msg);
+    if (msg === "ALL CHARTS READY") {
+        window.charts_ready = true;
+    }
+    else if (msg.slice(0, 11) === "CHART READY") {
+        var chart_id = msg.split(" ")[2];
+        console.log('grabbing ' + chart_id);
+        var png_data = page.evaluate(function (chart_id) {
+            var chart_div = document.getElementById(chart_id + '_png');
+            return chart_div.outerHTML;
+        }, chart_id);
+        fs.write(args[2] + '/' + chart_id + '.png', png_data, 'w');
+    }
+};
+
+// Check command line arguments
+var args = system.args;
+if (args.length != 3) {
+    console.log("USAGE: " + args[0] + " REPORT_HTML OUT_DIR\n");
+    phantom.exit(1);
+}
+
+// Open the web page
+page.open(args[1], function(status) {
+    if (status == 'fail') {
+        console.log("Failed to open file '" + args[1] + "'");
+        phantom.exit(1);
+    }
+});
+
+// Check status every 100 ms
+interval = window.setInterval(function () {
+    //console.log('waiting');
+    if (window.charts_ready) {
+        clearTimeout(timer);
+        clearInterval(interval);
+
+        var fname = args[1].replace(/\/+$/, "").split("/").pop()
+        console.log("saving " + fname);
+        fs.write(args[2] + '/' + fname, page.content, 'w');
+        phantom.exit(0);
+    }
+}, 100);
+
+// Time-out after 10 seconds
+timer = window.setTimeout(function () {
+    clearInterval(interval);
+    console.log("ERROR: timeout");
+    phantom.exit(1);
+}, 10000);
diff --git a/meta/poky/scripts/lib/buildstats.py b/meta/poky/scripts/lib/buildstats.py
new file mode 100644
index 0000000..f7db3ea
--- /dev/null
+++ b/meta/poky/scripts/lib/buildstats.py
@@ -0,0 +1,349 @@
+#
+# Copyright (c) 2017, Intel Corporation.
+#
+# This program is free software; you can redistribute it and/or modify it
+# under the terms and conditions of the GNU General Public License,
+# version 2, as published by the Free Software Foundation.
+#
+# This program is distributed in the hope 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.
+#
+"""Functionality for analyzing buildstats"""
+import json
+import logging
+import os
+import re
+from collections import namedtuple,OrderedDict
+from statistics import mean
+
+
+log = logging.getLogger()
+
+
+taskdiff_fields = ('pkg', 'pkg_op', 'task', 'task_op', 'value1', 'value2',
+                   'absdiff', 'reldiff')
+TaskDiff = namedtuple('TaskDiff', ' '.join(taskdiff_fields))
+
+
+class BSError(Exception):
+    """Error handling of buildstats"""
+    pass
+
+
+class BSTask(dict):
+    def __init__(self, *args, **kwargs):
+        self['start_time'] = None
+        self['elapsed_time'] = None
+        self['status'] = None
+        self['iostat'] = {}
+        self['rusage'] = {}
+        self['child_rusage'] = {}
+        super(BSTask, self).__init__(*args, **kwargs)
+
+    @property
+    def cputime(self):
+        """Sum of user and system time taken by the task"""
+        rusage = self['rusage']['ru_stime'] + self['rusage']['ru_utime']
+        if self['child_rusage']:
+            # Child rusage may have been optimized out
+            return rusage + self['child_rusage']['ru_stime'] + self['child_rusage']['ru_utime']
+        else:
+            return rusage
+
+    @property
+    def walltime(self):
+        """Elapsed wall clock time"""
+        return self['elapsed_time']
+
+    @property
+    def read_bytes(self):
+        """Bytes read from the block layer"""
+        return self['iostat']['read_bytes']
+
+    @property
+    def write_bytes(self):
+        """Bytes written to the block layer"""
+        return self['iostat']['write_bytes']
+
+    @property
+    def read_ops(self):
+        """Number of read operations on the block layer"""
+        if self['child_rusage']:
+            # Child rusage may have been optimized out
+            return self['rusage']['ru_inblock'] + self['child_rusage']['ru_inblock']
+        else:
+            return self['rusage']['ru_inblock']
+
+    @property
+    def write_ops(self):
+        """Number of write operations on the block layer"""
+        if self['child_rusage']:
+            # Child rusage may have been optimized out
+            return self['rusage']['ru_oublock'] + self['child_rusage']['ru_oublock']
+        else:
+            return self['rusage']['ru_oublock']
+
+    @classmethod
+    def from_file(cls, buildstat_file):
+        """Read buildstat text file"""
+        bs_task = cls()
+        log.debug("Reading task buildstats from %s", buildstat_file)
+        end_time = None
+        with open(buildstat_file) as fobj:
+            for line in fobj.readlines():
+                key, val = line.split(':', 1)
+                val = val.strip()
+                if key == 'Started':
+                    start_time = float(val)
+                    bs_task['start_time'] = start_time
+                elif key == 'Ended':
+                    end_time = float(val)
+                elif key.startswith('IO '):
+                    split = key.split()
+                    bs_task['iostat'][split[1]] = int(val)
+                elif key.find('rusage') >= 0:
+                    split = key.split()
+                    ru_key = split[-1]
+                    if ru_key in ('ru_stime', 'ru_utime'):
+                        val = float(val)
+                    else:
+                        val = int(val)
+                    ru_type = 'rusage' if split[0] == 'rusage' else \
+                                                      'child_rusage'
+                    bs_task[ru_type][ru_key] = val
+                elif key == 'Status':
+                    bs_task['status'] = val
+        if end_time is not None and start_time is not None:
+            bs_task['elapsed_time'] = end_time - start_time
+        else:
+            raise BSError("{} looks like a invalid buildstats file".format(buildstat_file))
+        return bs_task
+
+
+class BSTaskAggregate(object):
+    """Class representing multiple runs of the same task"""
+    properties = ('cputime', 'walltime', 'read_bytes', 'write_bytes',
+                  'read_ops', 'write_ops')
+
+    def __init__(self, tasks=None):
+        self._tasks = tasks or []
+        self._properties = {}
+
+    def __getattr__(self, name):
+        if name in self.properties:
+            if name not in self._properties:
+                # Calculate properties on demand only. We only provide mean
+                # value, so far
+                self._properties[name] = mean([getattr(t, name) for t in self._tasks])
+            return self._properties[name]
+        else:
+            raise AttributeError("'BSTaskAggregate' has no attribute '{}'".format(name))
+
+    def append(self, task):
+        """Append new task"""
+        # Reset pre-calculated properties
+        assert isinstance(task, BSTask), "Type is '{}' instead of 'BSTask'".format(type(task))
+        self._properties = {}
+        self._tasks.append(task)
+
+
+class BSRecipe(object):
+    """Class representing buildstats of one recipe"""
+    def __init__(self, name, epoch, version, revision):
+        self.name = name
+        self.epoch = epoch
+        self.version = version
+        self.revision = revision
+        if epoch is None:
+            self.evr = "{}-{}".format(version, revision)
+        else:
+            self.evr = "{}_{}-{}".format(epoch, version, revision)
+        self.tasks = {}
+
+    def aggregate(self, bsrecipe):
+        """Aggregate data of another recipe buildstats"""
+        if self.nevr != bsrecipe.nevr:
+            raise ValueError("Refusing to aggregate buildstats, recipe version "
+                             "differs: {} vs. {}".format(self.nevr, bsrecipe.nevr))
+        if set(self.tasks.keys()) != set(bsrecipe.tasks.keys()):
+            raise ValueError("Refusing to aggregate buildstats, set of tasks "
+                             "in {} differ".format(self.name))
+
+        for taskname, taskdata in bsrecipe.tasks.items():
+            if not isinstance(self.tasks[taskname], BSTaskAggregate):
+                self.tasks[taskname] = BSTaskAggregate([self.tasks[taskname]])
+            self.tasks[taskname].append(taskdata)
+
+    @property
+    def nevr(self):
+        return self.name + '-' + self.evr
+
+
+class BuildStats(dict):
+    """Class representing buildstats of one build"""
+
+    @property
+    def num_tasks(self):
+        """Get number of tasks"""
+        num = 0
+        for recipe in self.values():
+            num += len(recipe.tasks)
+        return num
+
+    @classmethod
+    def from_json(cls, bs_json):
+        """Create new BuildStats object from JSON object"""
+        buildstats = cls()
+        for recipe in bs_json:
+            if recipe['name'] in buildstats:
+                raise BSError("Cannot handle multiple versions of the same "
+                              "package ({})".format(recipe['name']))
+            bsrecipe = BSRecipe(recipe['name'], recipe['epoch'],
+                                recipe['version'], recipe['revision'])
+            for task, data in recipe['tasks'].items():
+                bsrecipe.tasks[task] = BSTask(data)
+
+            buildstats[recipe['name']] = bsrecipe
+
+        return buildstats
+
+    @staticmethod
+    def from_file_json(path):
+        """Load buildstats from a JSON file"""
+        with open(path) as fobj:
+            bs_json = json.load(fobj)
+        return BuildStats.from_json(bs_json)
+
+
+    @staticmethod
+    def split_nevr(nevr):
+        """Split name and version information from recipe "nevr" string"""
+        n_e_v, revision = nevr.rsplit('-', 1)
+        match = re.match(r'^(?P<name>\S+)-((?P<epoch>[0-9]{1,5})_)?(?P<version>[0-9]\S*)$',
+                         n_e_v)
+        if not match:
+            # If we're not able to parse a version starting with a number, just
+            # take the part after last dash
+            match = re.match(r'^(?P<name>\S+)-((?P<epoch>[0-9]{1,5})_)?(?P<version>[^-]+)$',
+                             n_e_v)
+        name = match.group('name')
+        version = match.group('version')
+        epoch = match.group('epoch')
+        return name, epoch, version, revision
+
+    @classmethod
+    def from_dir(cls, path):
+        """Load buildstats from a buildstats directory"""
+        if not os.path.isfile(os.path.join(path, 'build_stats')):
+            raise BSError("{} does not look like a buildstats directory".format(path))
+
+        log.debug("Reading buildstats directory %s", path)
+
+        buildstats = cls()
+        subdirs = os.listdir(path)
+        for dirname in subdirs:
+            recipe_dir = os.path.join(path, dirname)
+            if not os.path.isdir(recipe_dir):
+                continue
+            name, epoch, version, revision = cls.split_nevr(dirname)
+            bsrecipe = BSRecipe(name, epoch, version, revision)
+            for task in os.listdir(recipe_dir):
+                bsrecipe.tasks[task] = BSTask.from_file(
+                    os.path.join(recipe_dir, task))
+            if name in buildstats:
+                raise BSError("Cannot handle multiple versions of the same "
+                              "package ({})".format(name))
+            buildstats[name] = bsrecipe
+
+        return buildstats
+
+    def aggregate(self, buildstats):
+        """Aggregate other buildstats into this"""
+        if set(self.keys()) != set(buildstats.keys()):
+            raise ValueError("Refusing to aggregate buildstats, set of "
+                             "recipes is different: %s" % (set(self.keys()) ^ set(buildstats.keys())))
+        for pkg, data in buildstats.items():
+            self[pkg].aggregate(data)
+
+
+def diff_buildstats(bs1, bs2, stat_attr, min_val=None, min_absdiff=None):
+    """Compare the tasks of two buildstats"""
+    tasks_diff = []
+    pkgs = set(bs1.keys()).union(set(bs2.keys()))
+    for pkg in pkgs:
+        tasks1 = bs1[pkg].tasks if pkg in bs1 else {}
+        tasks2 = bs2[pkg].tasks if pkg in bs2 else {}
+        if not tasks1:
+            pkg_op = '+'
+        elif not tasks2:
+            pkg_op = '-'
+        else:
+            pkg_op = ' '
+
+        for task in set(tasks1.keys()).union(set(tasks2.keys())):
+            task_op = ' '
+            if task in tasks1:
+                val1 = getattr(bs1[pkg].tasks[task], stat_attr)
+            else:
+                task_op = '+'
+                val1 = 0
+            if task in tasks2:
+                val2 = getattr(bs2[pkg].tasks[task], stat_attr)
+            else:
+                val2 = 0
+                task_op = '-'
+
+            if val1 == 0:
+                reldiff = float('inf')
+            else:
+                reldiff = 100 * (val2 - val1) / val1
+
+            if min_val and max(val1, val2) < min_val:
+                log.debug("Filtering out %s:%s (%s)", pkg, task,
+                          max(val1, val2))
+                continue
+            if min_absdiff and abs(val2 - val1) < min_absdiff:
+                log.debug("Filtering out %s:%s (difference of %s)", pkg, task,
+                          val2-val1)
+                continue
+            tasks_diff.append(TaskDiff(pkg, pkg_op, task, task_op, val1, val2,
+                                       val2-val1, reldiff))
+    return tasks_diff
+
+
+class BSVerDiff(object):
+    """Class representing recipe version differences between two buildstats"""
+    def __init__(self, bs1, bs2):
+        RecipeVerDiff = namedtuple('RecipeVerDiff', 'left right')
+
+        recipes1 = set(bs1.keys())
+        recipes2 = set(bs2.keys())
+
+        self.new = dict([(r, bs2[r]) for r in sorted(recipes2 - recipes1)])
+        self.dropped = dict([(r, bs1[r]) for r in sorted(recipes1 - recipes2)])
+        self.echanged = {}
+        self.vchanged = {}
+        self.rchanged = {}
+        self.unchanged = {}
+        self.empty_diff = False
+
+        common = recipes2.intersection(recipes1)
+        if common:
+            for recipe in common:
+                rdiff = RecipeVerDiff(bs1[recipe], bs2[recipe])
+                if bs1[recipe].epoch != bs2[recipe].epoch:
+                    self.echanged[recipe] = rdiff
+                elif bs1[recipe].version != bs2[recipe].version:
+                    self.vchanged[recipe] = rdiff
+                elif bs1[recipe].revision != bs2[recipe].revision:
+                    self.rchanged[recipe] = rdiff
+                else:
+                    self.unchanged[recipe] = rdiff
+
+        if len(recipes1) == len(recipes2) == len(self.unchanged):
+            self.empty_diff = True
+
+    def __bool__(self):
+        return not self.empty_diff
diff --git a/meta/poky/scripts/lib/checklayer/__init__.py b/meta/poky/scripts/lib/checklayer/__init__.py
new file mode 100644
index 0000000..670f0ee
--- /dev/null
+++ b/meta/poky/scripts/lib/checklayer/__init__.py
@@ -0,0 +1,396 @@
+# Yocto Project layer check tool
+#
+# Copyright (C) 2017 Intel Corporation
+# Released under the MIT license (see COPYING.MIT)
+
+import os
+import re
+import subprocess
+from enum import Enum
+
+import bb.tinfoil
+
+class LayerType(Enum):
+    BSP = 0
+    DISTRO = 1
+    SOFTWARE = 2
+    ERROR_NO_LAYER_CONF = 98
+    ERROR_BSP_DISTRO = 99
+
+def _get_configurations(path):
+    configs = []
+
+    for f in os.listdir(path):
+        file_path = os.path.join(path, f)
+        if os.path.isfile(file_path) and f.endswith('.conf'):
+            configs.append(f[:-5]) # strip .conf
+    return configs
+
+def _get_layer_collections(layer_path, lconf=None, data=None):
+    import bb.parse
+    import bb.data
+
+    if lconf is None:
+        lconf = os.path.join(layer_path, 'conf', 'layer.conf')
+
+    if data is None:
+        ldata = bb.data.init()
+        bb.parse.init_parser(ldata)
+    else:
+        ldata = data.createCopy()
+
+    ldata.setVar('LAYERDIR', layer_path)
+    try:
+        ldata = bb.parse.handle(lconf, ldata, include=True)
+    except:
+        raise RuntimeError("Parsing of layer.conf from layer: %s failed" % layer_path)
+    ldata.expandVarref('LAYERDIR')
+
+    collections = (ldata.getVar('BBFILE_COLLECTIONS') or '').split()
+    if not collections:
+        name = os.path.basename(layer_path)
+        collections = [name]
+
+    collections = {c: {} for c in collections}
+    for name in collections:
+        priority = ldata.getVar('BBFILE_PRIORITY_%s' % name)
+        pattern = ldata.getVar('BBFILE_PATTERN_%s' % name)
+        depends = ldata.getVar('LAYERDEPENDS_%s' % name)
+        compat = ldata.getVar('LAYERSERIES_COMPAT_%s' % name)
+        collections[name]['priority'] = priority
+        collections[name]['pattern'] = pattern
+        collections[name]['depends'] = depends
+        collections[name]['compat'] = compat
+
+    return collections
+
+def _detect_layer(layer_path):
+    """
+        Scans layer directory to detect what type of layer
+        is BSP, Distro or Software.
+
+        Returns a dictionary with layer name, type and path.
+    """
+
+    layer = {}
+    layer_name = os.path.basename(layer_path)
+
+    layer['name'] = layer_name
+    layer['path'] = layer_path
+    layer['conf'] = {}
+
+    if not os.path.isfile(os.path.join(layer_path, 'conf', 'layer.conf')):
+        layer['type'] = LayerType.ERROR_NO_LAYER_CONF
+        return layer
+
+    machine_conf = os.path.join(layer_path, 'conf', 'machine')
+    distro_conf = os.path.join(layer_path, 'conf', 'distro')
+
+    is_bsp = False
+    is_distro = False
+
+    if os.path.isdir(machine_conf):
+        machines = _get_configurations(machine_conf)
+        if machines:
+            is_bsp = True
+
+    if os.path.isdir(distro_conf):
+        distros = _get_configurations(distro_conf)
+        if distros:
+            is_distro = True
+
+    if is_bsp and is_distro:
+        layer['type'] = LayerType.ERROR_BSP_DISTRO
+    elif is_bsp:
+        layer['type'] = LayerType.BSP
+        layer['conf']['machines'] = machines
+    elif is_distro:
+        layer['type'] = LayerType.DISTRO
+        layer['conf']['distros'] = distros
+    else:
+        layer['type'] = LayerType.SOFTWARE
+
+    layer['collections'] = _get_layer_collections(layer['path'])
+
+    return layer
+
+def detect_layers(layer_directories, no_auto):
+    layers = []
+
+    for directory in layer_directories:
+        directory = os.path.realpath(directory)
+        if directory[-1] == '/':
+            directory = directory[0:-1]
+
+        if no_auto:
+            conf_dir = os.path.join(directory, 'conf')
+            if os.path.isdir(conf_dir):
+                layer = _detect_layer(directory)
+                if layer:
+                    layers.append(layer)
+        else:
+            for root, dirs, files in os.walk(directory):
+                dir_name = os.path.basename(root)
+                conf_dir = os.path.join(root, 'conf')
+                if os.path.isdir(conf_dir):
+                    layer = _detect_layer(root)
+                    if layer:
+                        layers.append(layer)
+
+    return layers
+
+def _find_layer_depends(depend, layers):
+    for layer in layers:
+        for collection in layer['collections']:
+            if depend == collection:
+                return layer
+    return None
+
+def add_layer_dependencies(bblayersconf, layer, layers, logger):
+    def recurse_dependencies(depends, layer, layers, logger, ret = []):
+        logger.debug('Processing dependencies %s for layer %s.' % \
+                    (depends, layer['name']))
+
+        for depend in depends.split():
+            # core (oe-core) is suppose to be provided
+            if depend == 'core':
+                continue
+
+            layer_depend = _find_layer_depends(depend, layers)
+            if not layer_depend:
+                logger.error('Layer %s depends on %s and isn\'t found.' % \
+                        (layer['name'], depend))
+                ret = None
+                continue
+
+            # We keep processing, even if ret is None, this allows us to report
+            # multiple errors at once
+            if ret is not None and layer_depend not in ret:
+                ret.append(layer_depend)
+            else:
+                # we might have processed this dependency already, in which case
+                # we should not do it again (avoid recursive loop)
+                continue
+
+            # Recursively process...
+            if 'collections' not in layer_depend:
+                continue
+
+            for collection in layer_depend['collections']:
+                collect_deps = layer_depend['collections'][collection]['depends']
+                if not collect_deps:
+                    continue
+                ret = recurse_dependencies(collect_deps, layer_depend, layers, logger, ret)
+
+        return ret
+
+    layer_depends = []
+    for collection in layer['collections']:
+        depends = layer['collections'][collection]['depends']
+        if not depends:
+            continue
+
+        layer_depends = recurse_dependencies(depends, layer, layers, logger, layer_depends)
+
+    # Note: [] (empty) is allowed, None is not!
+    if layer_depends is None:
+        return False
+    else:
+        add_layers(bblayersconf, layer_depends, logger)
+
+    return True
+
+def add_layers(bblayersconf, layers, logger):
+    # Don't add a layer that is already present.
+    added = set()
+    output = check_command('Getting existing layers failed.', 'bitbake-layers show-layers').decode('utf-8')
+    for layer, path, pri in re.findall(r'^(\S+) +([^\n]*?) +(\d+)$', output, re.MULTILINE):
+        added.add(path)
+
+    with open(bblayersconf, 'a+') as f:
+        for layer in layers:
+            logger.info('Adding layer %s' % layer['name'])
+            name = layer['name']
+            path = layer['path']
+            if path in added:
+                logger.info('%s is already in %s' % (name, bblayersconf))
+            else:
+                added.add(path)
+                f.write("\nBBLAYERS += \"%s\"\n" % path)
+    return True
+
+def check_command(error_msg, cmd, cwd=None):
+    '''
+    Run a command under a shell, capture stdout and stderr in a single stream,
+    throw an error when command returns non-zero exit code. Returns the output.
+    '''
+
+    p = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, cwd=cwd)
+    output, _ = p.communicate()
+    if p.returncode:
+        msg = "%s\nCommand: %s\nOutput:\n%s" % (error_msg, cmd, output.decode('utf-8'))
+        raise RuntimeError(msg)
+    return output
+
+def get_signatures(builddir, failsafe=False, machine=None):
+    import re
+
+    # some recipes needs to be excluded like meta-world-pkgdata
+    # because a layer can add recipes to a world build so signature
+    # will be change
+    exclude_recipes = ('meta-world-pkgdata',)
+
+    sigs = {}
+    tune2tasks = {}
+
+    cmd = ''
+    if machine:
+        cmd += 'MACHINE=%s ' % machine
+    cmd += 'bitbake '
+    if failsafe:
+        cmd += '-k '
+    cmd += '-S none world'
+    sigs_file = os.path.join(builddir, 'locked-sigs.inc')
+    if os.path.exists(sigs_file):
+        os.unlink(sigs_file)
+    try:
+        check_command('Generating signatures failed. This might be due to some parse error and/or general layer incompatibilities.',
+                      cmd, builddir)
+    except RuntimeError as ex:
+        if failsafe and os.path.exists(sigs_file):
+            # Ignore the error here. Most likely some recipes active
+            # in a world build lack some dependencies. There is a
+            # separate test_machine_world_build which exposes the
+            # failure.
+            pass
+        else:
+            raise
+
+    sig_regex = re.compile("^(?P<task>.*:.*):(?P<hash>.*) .$")
+    tune_regex = re.compile("(^|\s)SIGGEN_LOCKEDSIGS_t-(?P<tune>\S*)\s*=\s*")
+    current_tune = None
+    with open(sigs_file, 'r') as f:
+        for line in f.readlines():
+            line = line.strip()
+            t = tune_regex.search(line)
+            if t:
+                current_tune = t.group('tune')
+            s = sig_regex.match(line)
+            if s:
+                exclude = False
+                for er in exclude_recipes:
+                    (recipe, task) = s.group('task').split(':')
+                    if er == recipe:
+                        exclude = True
+                        break
+                if exclude:
+                    continue
+
+                sigs[s.group('task')] = s.group('hash')
+                tune2tasks.setdefault(current_tune, []).append(s.group('task'))
+
+    if not sigs:
+        raise RuntimeError('Can\'t load signatures from %s' % sigs_file)
+
+    return (sigs, tune2tasks)
+
+def get_depgraph(targets=['world'], failsafe=False):
+    '''
+    Returns the dependency graph for the given target(s).
+    The dependency graph is taken directly from DepTreeEvent.
+    '''
+    depgraph = None
+    with bb.tinfoil.Tinfoil() as tinfoil:
+        tinfoil.prepare(config_only=False)
+        tinfoil.set_event_mask(['bb.event.NoProvider', 'bb.event.DepTreeGenerated', 'bb.command.CommandCompleted'])
+        if not tinfoil.run_command('generateDepTreeEvent', targets, 'do_build'):
+            raise RuntimeError('starting generateDepTreeEvent failed')
+        while True:
+            event = tinfoil.wait_event(timeout=1000)
+            if event:
+                if isinstance(event, bb.command.CommandFailed):
+                    raise RuntimeError('Generating dependency information failed: %s' % event.error)
+                elif isinstance(event, bb.command.CommandCompleted):
+                    break
+                elif isinstance(event, bb.event.NoProvider):
+                    if failsafe:
+                        # The event is informational, we will get information about the
+                        # remaining dependencies eventually and thus can ignore this
+                        # here like we do in get_signatures(), if desired.
+                        continue
+                    if event._reasons:
+                        raise RuntimeError('Nothing provides %s: %s' % (event._item, event._reasons))
+                    else:
+                        raise RuntimeError('Nothing provides %s.' % (event._item))
+                elif isinstance(event, bb.event.DepTreeGenerated):
+                    depgraph = event._depgraph
+
+    if depgraph is None:
+        raise RuntimeError('Could not retrieve the depgraph.')
+    return depgraph
+
+def compare_signatures(old_sigs, curr_sigs):
+    '''
+    Compares the result of two get_signatures() calls. Returns None if no
+    problems found, otherwise a string that can be used as additional
+    explanation in self.fail().
+    '''
+    # task -> (old signature, new signature)
+    sig_diff = {}
+    for task in old_sigs:
+        if task in curr_sigs and \
+           old_sigs[task] != curr_sigs[task]:
+            sig_diff[task] = (old_sigs[task], curr_sigs[task])
+
+    if not sig_diff:
+        return None
+
+    # Beware, depgraph uses task=<pn>.<taskname> whereas get_signatures()
+    # uses <pn>:<taskname>. Need to convert sometimes. The output follows
+    # the convention from get_signatures() because that seems closer to
+    # normal bitbake output.
+    def sig2graph(task):
+        pn, taskname = task.rsplit(':', 1)
+        return pn + '.' + taskname
+    def graph2sig(task):
+        pn, taskname = task.rsplit('.', 1)
+        return pn + ':' + taskname
+    depgraph = get_depgraph(failsafe=True)
+    depends = depgraph['tdepends']
+
+    # If a task A has a changed signature, but none of its
+    # dependencies, then we need to report it because it is
+    # the one which introduces a change. Any task depending on
+    # A (directly or indirectly) will also have a changed
+    # signature, but we don't need to report it. It might have
+    # its own changes, which will become apparent once the
+    # issues that we do report are fixed and the test gets run
+    # again.
+    sig_diff_filtered = []
+    for task, (old_sig, new_sig) in sig_diff.items():
+        deps_tainted = False
+        for dep in depends.get(sig2graph(task), ()):
+            if graph2sig(dep) in sig_diff:
+                deps_tainted = True
+                break
+        if not deps_tainted:
+            sig_diff_filtered.append((task, old_sig, new_sig))
+
+    msg = []
+    msg.append('%d signatures changed, initial differences (first hash before, second after):' %
+               len(sig_diff))
+    for diff in sorted(sig_diff_filtered):
+        recipe, taskname = diff[0].rsplit(':', 1)
+        cmd = 'bitbake-diffsigs --task %s %s --signature %s %s' % \
+              (recipe, taskname, diff[1], diff[2])
+        msg.append('   %s: %s -> %s' % diff)
+        msg.append('      %s' % cmd)
+        try:
+            output = check_command('Determining signature difference failed.',
+                                   cmd).decode('utf-8')
+        except RuntimeError as error:
+            output = str(error)
+        if output:
+            msg.extend(['      ' + line for line in output.splitlines()])
+            msg.append('')
+    return '\n'.join(msg)
diff --git a/meta/poky/scripts/lib/checklayer/case.py b/meta/poky/scripts/lib/checklayer/case.py
new file mode 100644
index 0000000..9dd0041
--- /dev/null
+++ b/meta/poky/scripts/lib/checklayer/case.py
@@ -0,0 +1,7 @@
+# Copyright (C) 2017 Intel Corporation
+# Released under the MIT license (see COPYING.MIT)
+
+from oeqa.core.case import OETestCase
+
+class OECheckLayerTestCase(OETestCase):
+    pass
diff --git a/meta/poky/scripts/lib/checklayer/cases/__init__.py b/meta/poky/scripts/lib/checklayer/cases/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/meta/poky/scripts/lib/checklayer/cases/__init__.py
diff --git a/meta/poky/scripts/lib/checklayer/cases/bsp.py b/meta/poky/scripts/lib/checklayer/cases/bsp.py
new file mode 100644
index 0000000..b6b611b
--- /dev/null
+++ b/meta/poky/scripts/lib/checklayer/cases/bsp.py
@@ -0,0 +1,204 @@
+# Copyright (C) 2017 Intel Corporation
+# Released under the MIT license (see COPYING.MIT)
+
+import unittest
+
+from checklayer import LayerType, get_signatures, check_command, get_depgraph
+from checklayer.case import OECheckLayerTestCase
+
+class BSPCheckLayer(OECheckLayerTestCase):
+    @classmethod
+    def setUpClass(self):
+        if self.tc.layer['type'] != LayerType.BSP:
+            raise unittest.SkipTest("BSPCheckLayer: Layer %s isn't BSP one." %\
+                self.tc.layer['name'])
+
+    def test_bsp_defines_machines(self):
+        self.assertTrue(self.tc.layer['conf']['machines'], 
+                "Layer is BSP but doesn't defines machines.")
+
+    def test_bsp_no_set_machine(self):
+        from oeqa.utils.commands import get_bb_var
+
+        machine = get_bb_var('MACHINE')
+        self.assertEqual(self.td['bbvars']['MACHINE'], machine,
+                msg="Layer %s modified machine %s -> %s" % \
+                    (self.tc.layer['name'], self.td['bbvars']['MACHINE'], machine))
+
+
+    def test_machine_world(self):
+        '''
+        "bitbake world" is expected to work regardless which machine is selected.
+        BSP layers sometimes break that by enabling a recipe for a certain machine
+        without checking whether that recipe actually can be built in the current
+        distro configuration (for example, OpenGL might not enabled).
+
+        This test iterates over all machines. It would be nicer to instantiate
+        it once per machine. It merely checks for errors during parse
+        time. It does not actually attempt to build anything.
+        '''
+
+        if not self.td['machines']:
+            self.skipTest('No machines set with --machines.')
+        msg = []
+        for machine in self.td['machines']:
+            # In contrast to test_machine_signatures() below, errors are fatal here.
+            try:
+                get_signatures(self.td['builddir'], failsafe=False, machine=machine)
+            except RuntimeError as ex:
+                msg.append(str(ex))
+        if msg:
+            msg.insert(0, 'The following machines broke a world build:')
+            self.fail('\n'.join(msg))
+
+    def test_machine_signatures(self):
+        '''
+        Selecting a machine may only affect the signature of tasks that are specific
+        to that machine. In other words, when MACHINE=A and MACHINE=B share a recipe
+        foo and the output of foo, then both machine configurations must build foo
+        in exactly the same way. Otherwise it is not possible to use both machines
+        in the same distribution.
+
+        This criteria can only be tested by testing different machines in combination,
+        i.e. one main layer, potentially several additional BSP layers and an explicit
+        choice of machines:
+        yocto-check-layer --additional-layers .../meta-intel --machines intel-corei7-64 imx6slevk -- .../meta-freescale
+        '''
+
+        if not self.td['machines']:
+            self.skipTest('No machines set with --machines.')
+
+        # Collect signatures for all machines that we are testing
+        # and merge that into a hash:
+        # tune -> task -> signature -> list of machines with that combination
+        #
+        # It is an error if any tune/task pair has more than one signature,
+        # because that implies that the machines that caused those different
+        # signatures do not agree on how to execute the task.
+        tunes = {}
+        # Preserve ordering of machines as chosen by the user.
+        for machine in self.td['machines']:
+            curr_sigs, tune2tasks = get_signatures(self.td['builddir'], failsafe=True, machine=machine)
+            # Invert the tune -> [tasks] mapping.
+            tasks2tune = {}
+            for tune, tasks in tune2tasks.items():
+                for task in tasks:
+                    tasks2tune[task] = tune
+            for task, sighash in curr_sigs.items():
+                tunes.setdefault(tasks2tune[task], {}).setdefault(task, {}).setdefault(sighash, []).append(machine)
+
+        msg = []
+        pruned = 0
+        last_line_key = None
+        # do_fetch, do_unpack, ..., do_build
+        taskname_list = []
+        if tunes:
+            # The output below is most useful when we start with tasks that are at
+            # the bottom of the dependency chain, i.e. those that run first. If
+            # those tasks differ, the rest also does.
+            #
+            # To get an ordering of tasks, we do a topological sort of the entire
+            # depgraph for the base configuration, then on-the-fly flatten that list by stripping
+            # out the recipe names and removing duplicates. The base configuration
+            # is not necessarily representative, but should be close enough. Tasks
+            # that were not encountered get a default priority.
+            depgraph = get_depgraph()
+            depends = depgraph['tdepends']
+            WHITE = 1
+            GRAY = 2
+            BLACK = 3
+            color = {}
+            found = set()
+            def visit(task):
+                color[task] = GRAY
+                for dep in depends.get(task, ()):
+                    if color.setdefault(dep, WHITE) == WHITE:
+                        visit(dep)
+                color[task] = BLACK
+                pn, taskname = task.rsplit('.', 1)
+                if taskname not in found:
+                    taskname_list.append(taskname)
+                    found.add(taskname)
+            for task in depends.keys():
+                if color.setdefault(task, WHITE) == WHITE:
+                    visit(task)
+
+        taskname_order = dict([(task, index) for index, task in enumerate(taskname_list) ])
+        def task_key(task):
+            pn, taskname = task.rsplit(':', 1)
+            return (pn, taskname_order.get(taskname, len(taskname_list)), taskname)
+
+        for tune in sorted(tunes.keys()):
+            tasks = tunes[tune]
+            # As for test_signatures it would be nicer to sort tasks
+            # by dependencies here, but that is harder because we have
+            # to report on tasks from different machines, which might
+            # have different dependencies. We resort to pruning the
+            # output by reporting only one task per recipe if the set
+            # of machines matches.
+            #
+            # "bitbake-diffsigs -t -s" is intelligent enough to print
+            # diffs recursively, so often it does not matter that much
+            # if we don't pick the underlying difference
+            # here. However, sometimes recursion fails
+            # (https://bugzilla.yoctoproject.org/show_bug.cgi?id=6428).
+            #
+            # To mitigate that a bit, we use a hard-coded ordering of
+            # tasks that represents how they normally run and prefer
+            # to print the ones that run first.
+            for task in sorted(tasks.keys(), key=task_key):
+                signatures = tasks[task]
+                # do_build can be ignored: it is know to have
+                # different signatures in some cases, for example in
+                # the allarch ca-certificates due to RDEPENDS=openssl.
+                # That particular dependency is whitelisted via
+                # SIGGEN_EXCLUDE_SAFE_RECIPE_DEPS, but still shows up
+                # in the sstate signature hash because filtering it
+                # out would be hard and running do_build multiple
+                # times doesn't really matter.
+                if len(signatures.keys()) > 1 and \
+                   not task.endswith(':do_build'):
+                    # Error!
+                    #
+                    # Sort signatures by machines, because the hex values don't mean anything.
+                    # => all-arch adwaita-icon-theme:do_build: 1234... (beaglebone, qemux86) != abcdf... (qemux86-64)
+                    #
+                    # Skip the line if it is covered already by the predecessor (same pn, same sets of machines).
+                    pn, taskname = task.rsplit(':', 1)
+                    next_line_key = (pn, sorted(signatures.values()))
+                    if next_line_key != last_line_key:
+                        line = '   %s %s: ' % (tune, task)
+                        line += ' != '.join(['%s (%s)' % (signature, ', '.join([m for m in signatures[signature]])) for
+                                             signature in sorted(signatures.keys(), key=lambda s: signatures[s])])
+                        last_line_key = next_line_key
+                        msg.append(line)
+                        # Randomly pick two mismatched signatures and remember how to invoke
+                        # bitbake-diffsigs for them.
+                        iterator = iter(signatures.items())
+                        a = next(iterator)
+                        b = next(iterator)
+                        diffsig_machines = '(%s) != (%s)' % (', '.join(a[1]), ', '.join(b[1]))
+                        diffsig_params = '-t %s %s -s %s %s' % (pn, taskname, a[0], b[0])
+                    else:
+                        pruned += 1
+
+        if msg:
+            msg.insert(0, 'The machines have conflicting signatures for some shared tasks:')
+            if pruned > 0:
+                msg.append('')
+                msg.append('%d tasks where not listed because some other task of the recipe already differed.' % pruned)
+                msg.append('It is likely that differences from different recipes also have the same root cause.')
+            msg.append('')
+            # Explain how to investigate...
+            msg.append('To investigate, run bitbake-diffsigs -t recipename taskname -s fromsig tosig.')
+            cmd = 'bitbake-diffsigs %s' % diffsig_params
+            msg.append('Example: %s in the last line' % diffsig_machines)
+            msg.append('Command: %s' % cmd)
+            # ... and actually do it automatically for that example, but without aborting
+            # when that fails.
+            try:
+                output = check_command('Comparing signatures failed.', cmd).decode('utf-8')
+            except RuntimeError as ex:
+                output = str(ex)
+            msg.extend(['   ' + line for line in output.splitlines()])
+            self.fail('\n'.join(msg))
diff --git a/meta/poky/scripts/lib/checklayer/cases/common.py b/meta/poky/scripts/lib/checklayer/cases/common.py
new file mode 100644
index 0000000..1bef61b
--- /dev/null
+++ b/meta/poky/scripts/lib/checklayer/cases/common.py
@@ -0,0 +1,58 @@
+# Copyright (C) 2017 Intel Corporation
+# Released under the MIT license (see COPYING.MIT)
+
+import glob
+import os
+import unittest
+from checklayer import get_signatures, LayerType, check_command, get_depgraph, compare_signatures
+from checklayer.case import OECheckLayerTestCase
+
+class CommonCheckLayer(OECheckLayerTestCase):
+    def test_readme(self):
+        # The top-level README file may have a suffix (like README.rst or README.txt).
+        readme_files = glob.glob(os.path.join(self.tc.layer['path'], 'README*'))
+        self.assertTrue(len(readme_files) > 0,
+                        msg="Layer doesn't contains README file.")
+
+        # There might be more than one file matching the file pattern above
+        # (for example, README.rst and README-COPYING.rst). The one with the shortest
+        # name is considered the "main" one.
+        readme_file = sorted(readme_files)[0]
+        data = ''
+        with open(readme_file, 'r') as f:
+            data = f.read()
+        self.assertTrue(data,
+                msg="Layer contains a README file but it is empty.")
+
+    def test_parse(self):
+        check_command('Layer %s failed to parse.' % self.tc.layer['name'],
+                      'bitbake -p')
+
+    def test_show_environment(self):
+        check_command('Layer %s failed to show environment.' % self.tc.layer['name'],
+                      'bitbake -e')
+
+    def test_world(self):
+        '''
+        "bitbake world" is expected to work. test_signatures does not cover that
+        because it is more lenient and ignores recipes in a world build that
+        are not actually buildable, so here we fail when "bitbake -S none world"
+        fails.
+        '''
+        get_signatures(self.td['builddir'], failsafe=False)
+
+    def test_signatures(self):
+        if self.tc.layer['type'] == LayerType.SOFTWARE and \
+           not self.tc.test_software_layer_signatures:
+            raise unittest.SkipTest("Not testing for signature changes in a software layer %s." \
+                     % self.tc.layer['name'])
+
+        curr_sigs, _ = get_signatures(self.td['builddir'], failsafe=True)
+        msg = compare_signatures(self.td['sigs'], curr_sigs)
+        if msg is not None:
+            self.fail('Adding layer %s changed signatures.\n%s' % (self.tc.layer['name'], msg))
+
+    def test_layerseries_compat(self):
+        for collection_name, collection_data in self.tc.layer['collections'].items():
+            self.assertTrue(collection_data['compat'], "Collection %s from layer %s does not set compatible oe-core versions via LAYERSERIES_COMPAT_collection." \
+                 % (collection_name, self.tc.layer['name']))
diff --git a/meta/poky/scripts/lib/checklayer/cases/distro.py b/meta/poky/scripts/lib/checklayer/cases/distro.py
new file mode 100644
index 0000000..df1b303
--- /dev/null
+++ b/meta/poky/scripts/lib/checklayer/cases/distro.py
@@ -0,0 +1,26 @@
+# Copyright (C) 2017 Intel Corporation
+# Released under the MIT license (see COPYING.MIT)
+
+import unittest
+
+from checklayer import LayerType
+from checklayer.case import OECheckLayerTestCase
+
+class DistroCheckLayer(OECheckLayerTestCase):
+    @classmethod
+    def setUpClass(self):
+        if self.tc.layer['type'] != LayerType.DISTRO:
+            raise unittest.SkipTest("DistroCheckLayer: Layer %s isn't Distro one." %\
+                self.tc.layer['name'])
+
+    def test_distro_defines_distros(self):
+        self.assertTrue(self.tc.layer['conf']['distros'], 
+                "Layer is BSP but doesn't defines machines.")
+
+    def test_distro_no_set_distros(self):
+        from oeqa.utils.commands import get_bb_var
+
+        distro = get_bb_var('DISTRO')
+        self.assertEqual(self.td['bbvars']['DISTRO'], distro,
+                msg="Layer %s modified distro %s -> %s" % \
+                    (self.tc.layer['name'], self.td['bbvars']['DISTRO'], distro))
diff --git a/meta/poky/scripts/lib/checklayer/context.py b/meta/poky/scripts/lib/checklayer/context.py
new file mode 100644
index 0000000..1bec2c4
--- /dev/null
+++ b/meta/poky/scripts/lib/checklayer/context.py
@@ -0,0 +1,15 @@
+# Copyright (C) 2017 Intel Corporation
+# Released under the MIT license (see COPYING.MIT)
+
+import os
+import sys
+import glob
+import re
+
+from oeqa.core.context import OETestContext
+
+class CheckLayerTestContext(OETestContext):
+    def __init__(self, td=None, logger=None, layer=None, test_software_layer_signatures=True):
+        super(CheckLayerTestContext, self).__init__(td, logger)
+        self.layer = layer
+        self.test_software_layer_signatures = test_software_layer_signatures
diff --git a/meta/poky/scripts/lib/devtool/__init__.py b/meta/poky/scripts/lib/devtool/__init__.py
new file mode 100644
index 0000000..8fc7fff
--- /dev/null
+++ b/meta/poky/scripts/lib/devtool/__init__.py
@@ -0,0 +1,384 @@
+#!/usr/bin/env python3
+
+# Development tool - utility functions for plugins
+#
+# Copyright (C) 2014 Intel Corporation
+#
+# 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.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+"""Devtool plugins module"""
+
+import os
+import sys
+import subprocess
+import logging
+import re
+import codecs
+
+logger = logging.getLogger('devtool')
+
+class DevtoolError(Exception):
+    """Exception for handling devtool errors"""
+    def __init__(self, message, exitcode=1):
+        super(DevtoolError, self).__init__(message)
+        self.exitcode = exitcode
+
+
+def exec_build_env_command(init_path, builddir, cmd, watch=False, **options):
+    """Run a program in bitbake build context"""
+    import bb
+    if not 'cwd' in options:
+        options["cwd"] = builddir
+    if init_path:
+        # As the OE init script makes use of BASH_SOURCE to determine OEROOT,
+        # and can't determine it when running under dash, we need to set
+        # the executable to bash to correctly set things up
+        if not 'executable' in options:
+            options['executable'] = 'bash'
+        logger.debug('Executing command: "%s" using init path %s' % (cmd, init_path))
+        init_prefix = '. %s %s > /dev/null && ' % (init_path, builddir)
+    else:
+        logger.debug('Executing command "%s"' % cmd)
+        init_prefix = ''
+    if watch:
+        if sys.stdout.isatty():
+            # Fool bitbake into thinking it's outputting to a terminal (because it is, indirectly)
+            cmd = 'script -e -q -c "%s" /dev/null' % cmd
+        return exec_watch('%s%s' % (init_prefix, cmd), **options)
+    else:
+        return bb.process.run('%s%s' % (init_prefix, cmd), **options)
+
+def exec_watch(cmd, **options):
+    """Run program with stdout shown on sys.stdout"""
+    import bb
+    if isinstance(cmd, str) and not "shell" in options:
+        options["shell"] = True
+
+    process = subprocess.Popen(
+        cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, **options
+    )
+
+    reader = codecs.getreader('utf-8')(process.stdout)
+    buf = ''
+    while True:
+        out = reader.read(1, 1)
+        if out:
+            sys.stdout.write(out)
+            sys.stdout.flush()
+            buf += out
+        elif out == '' and process.poll() != None:
+            break
+
+    if process.returncode != 0:
+        raise bb.process.ExecutionError(cmd, process.returncode, buf, None)
+
+    return buf, None
+
+def exec_fakeroot(d, cmd, **kwargs):
+    """Run a command under fakeroot (pseudo, in fact) so that it picks up the appropriate file permissions"""
+    # Grab the command and check it actually exists
+    fakerootcmd = d.getVar('FAKEROOTCMD')
+    if not os.path.exists(fakerootcmd):
+        logger.error('pseudo executable %s could not be found - have you run a build yet? pseudo-native should install this and if you have run any build then that should have been built')
+        return 2
+    # Set up the appropriate environment
+    newenv = dict(os.environ)
+    fakerootenv = d.getVar('FAKEROOTENV')
+    for varvalue in fakerootenv.split():
+        if '=' in varvalue:
+            splitval = varvalue.split('=', 1)
+            newenv[splitval[0]] = splitval[1]
+    return subprocess.call("%s %s" % (fakerootcmd, cmd), env=newenv, **kwargs)
+
+def setup_tinfoil(config_only=False, basepath=None, tracking=False):
+    """Initialize tinfoil api from bitbake"""
+    import scriptpath
+    orig_cwd = os.path.abspath(os.curdir)
+    try:
+        if basepath:
+            os.chdir(basepath)
+        bitbakepath = scriptpath.add_bitbake_lib_path()
+        if not bitbakepath:
+            logger.error("Unable to find bitbake by searching parent directory of this script or PATH")
+            sys.exit(1)
+
+        import bb.tinfoil
+        tinfoil = bb.tinfoil.Tinfoil(tracking=tracking)
+        try:
+            tinfoil.logger.setLevel(logger.getEffectiveLevel())
+            tinfoil.prepare(config_only)
+        except bb.tinfoil.TinfoilUIException:
+            tinfoil.shutdown()
+            raise DevtoolError('Failed to start bitbake environment')
+        except:
+            tinfoil.shutdown()
+            raise
+    finally:
+        os.chdir(orig_cwd)
+    return tinfoil
+
+def parse_recipe(config, tinfoil, pn, appends, filter_workspace=True):
+    """Parse the specified recipe"""
+    try:
+        recipefile = tinfoil.get_recipe_file(pn)
+    except bb.providers.NoProvider as e:
+        logger.error(str(e))
+        return None
+    if appends:
+        append_files = tinfoil.get_file_appends(recipefile)
+        if filter_workspace:
+            # Filter out appends from the workspace
+            append_files = [path for path in append_files if
+                            not path.startswith(config.workspace_path)]
+    else:
+        append_files = None
+    try:
+        rd = tinfoil.parse_recipe_file(recipefile, appends, append_files)
+    except Exception as e:
+        logger.error(str(e))
+        return None
+    return rd
+
+def check_workspace_recipe(workspace, pn, checksrc=True, bbclassextend=False):
+    """
+    Check that a recipe is in the workspace and (optionally) that source
+    is present.
+    """
+
+    workspacepn = pn
+
+    for recipe, value in workspace.items():
+        if recipe == pn:
+            break
+        if bbclassextend:
+            recipefile = value['recipefile']
+            if recipefile:
+                targets = get_bbclassextend_targets(recipefile, recipe)
+                if pn in targets:
+                    workspacepn = recipe
+                    break
+    else:
+        raise DevtoolError("No recipe named '%s' in your workspace" % pn)
+
+    if checksrc:
+        srctree = workspace[workspacepn]['srctree']
+        if not os.path.exists(srctree):
+            raise DevtoolError("Source tree %s for recipe %s does not exist" % (srctree, workspacepn))
+        if not os.listdir(srctree):
+            raise DevtoolError("Source tree %s for recipe %s is empty" % (srctree, workspacepn))
+
+    return workspacepn
+
+def use_external_build(same_dir, no_same_dir, d):
+    """
+    Determine if we should use B!=S (separate build and source directories) or not
+    """
+    b_is_s = True
+    if no_same_dir:
+        logger.info('Using separate build directory since --no-same-dir specified')
+        b_is_s = False
+    elif same_dir:
+        logger.info('Using source tree as build directory since --same-dir specified')
+    elif bb.data.inherits_class('autotools-brokensep', d):
+        logger.info('Using source tree as build directory since recipe inherits autotools-brokensep')
+    elif os.path.abspath(d.getVar('B')) == os.path.abspath(d.getVar('S')):
+        logger.info('Using source tree as build directory since that would be the default for this recipe')
+    else:
+        b_is_s = False
+    return b_is_s
+
+def setup_git_repo(repodir, version, devbranch, basetag='devtool-base', d=None):
+    """
+    Set up the git repository for the source tree
+    """
+    import bb.process
+    import oe.patch
+    if not os.path.exists(os.path.join(repodir, '.git')):
+        bb.process.run('git init', cwd=repodir)
+        bb.process.run('git config --local gc.autodetach 0', cwd=repodir)
+        bb.process.run('git add .', cwd=repodir)
+        commit_cmd = ['git']
+        oe.patch.GitApplyTree.gitCommandUserOptions(commit_cmd, d=d)
+        commit_cmd += ['commit', '-q']
+        stdout, _ = bb.process.run('git status --porcelain', cwd=repodir)
+        if not stdout:
+            commit_cmd.append('--allow-empty')
+            commitmsg = "Initial empty commit with no upstream sources"
+        elif version:
+            commitmsg = "Initial commit from upstream at version %s" % version
+        else:
+            commitmsg = "Initial commit from upstream"
+        commit_cmd += ['-m', commitmsg]
+        bb.process.run(commit_cmd, cwd=repodir)
+
+    # Ensure singletask.lock (as used by externalsrc.bbclass) is ignored by git
+    excludes = []
+    excludefile = os.path.join(repodir, '.git', 'info', 'exclude')
+    try:
+        with open(excludefile, 'r') as f:
+            excludes = f.readlines()
+    except FileNotFoundError:
+        pass
+    if 'singletask.lock\n' not in excludes:
+        excludes.append('singletask.lock\n')
+    with open(excludefile, 'w') as f:
+        for line in excludes:
+            f.write(line)
+
+    bb.process.run('git checkout -b %s' % devbranch, cwd=repodir)
+    bb.process.run('git tag -f %s' % basetag, cwd=repodir)
+
+def recipe_to_append(recipefile, config, wildcard=False):
+    """
+    Convert a recipe file to a bbappend file path within the workspace.
+    NOTE: if the bbappend already exists, you should be using
+    workspace[args.recipename]['bbappend'] instead of calling this
+    function.
+    """
+    appendname = os.path.splitext(os.path.basename(recipefile))[0]
+    if wildcard:
+        appendname = re.sub(r'_.*', '_%', appendname)
+    appendpath = os.path.join(config.workspace_path, 'appends')
+    appendfile = os.path.join(appendpath, appendname + '.bbappend')
+    return appendfile
+
+def get_bbclassextend_targets(recipefile, pn):
+    """
+    Cheap function to get BBCLASSEXTEND and then convert that to the
+    list of targets that would result.
+    """
+    import bb.utils
+
+    values = {}
+    def get_bbclassextend_varfunc(varname, origvalue, op, newlines):
+        values[varname] = origvalue
+        return origvalue, None, 0, True
+    with open(recipefile, 'r') as f:
+        bb.utils.edit_metadata(f, ['BBCLASSEXTEND'], get_bbclassextend_varfunc)
+
+    targets = []
+    bbclassextend = values.get('BBCLASSEXTEND', '').split()
+    if bbclassextend:
+        for variant in bbclassextend:
+            if variant == 'nativesdk':
+                targets.append('%s-%s' % (variant, pn))
+            elif variant in ['native', 'cross', 'crosssdk']:
+                targets.append('%s-%s' % (pn, variant))
+    return targets
+
+def replace_from_file(path, old, new):
+    """Replace strings on a file"""
+
+    def read_file(path):
+        data = None
+        with open(path) as f:
+            data = f.read()
+        return data
+
+    def write_file(path, data):
+        if data is None:
+            return
+        wdata = data.rstrip() + "\n"
+        with open(path, "w") as f:
+            f.write(wdata)
+
+    # In case old is None, return immediately
+    if old is None:
+        return
+    try:
+        rdata = read_file(path)
+    except IOError as e:
+        # if file does not exit, just quit, otherwise raise an exception
+        if e.errno == errno.ENOENT:
+            return
+        else:
+            raise
+
+    old_contents = rdata.splitlines()
+    new_contents = []
+    for old_content in old_contents:
+        try:
+            new_contents.append(old_content.replace(old, new))
+        except ValueError:
+            pass
+    write_file(path, "\n".join(new_contents))
+
+
+def update_unlockedsigs(basepath, workspace, fixed_setup, extra=None):
+    """ This function will make unlocked-sigs.inc match the recipes in the
+    workspace plus any extras we want unlocked. """
+
+    if not fixed_setup:
+        # Only need to write this out within the eSDK
+        return
+
+    if not extra:
+        extra = []
+
+    confdir = os.path.join(basepath, 'conf')
+    unlockedsigs = os.path.join(confdir, 'unlocked-sigs.inc')
+
+    # Get current unlocked list if any
+    values = {}
+    def get_unlockedsigs_varfunc(varname, origvalue, op, newlines):
+        values[varname] = origvalue
+        return origvalue, None, 0, True
+    if os.path.exists(unlockedsigs):
+        with open(unlockedsigs, 'r') as f:
+            bb.utils.edit_metadata(f, ['SIGGEN_UNLOCKED_RECIPES'], get_unlockedsigs_varfunc)
+    unlocked = sorted(values.get('SIGGEN_UNLOCKED_RECIPES', []))
+
+    # If the new list is different to the current list, write it out
+    newunlocked = sorted(list(workspace.keys()) + extra)
+    if unlocked != newunlocked:
+        bb.utils.mkdirhier(confdir)
+        with open(unlockedsigs, 'w') as f:
+            f.write("# DO NOT MODIFY! YOUR CHANGES WILL BE LOST.\n" +
+                    "# This layer was created by the OpenEmbedded devtool" +
+                    " utility in order to\n" +
+                    "# contain recipes that are unlocked.\n")
+
+            f.write('SIGGEN_UNLOCKED_RECIPES += "\\\n')
+            for pn in newunlocked:
+                f.write('    ' + pn)
+            f.write('"')
+
+def check_prerelease_version(ver, operation):
+    if 'pre' in ver or 'rc' in ver:
+        logger.warning('Version "%s" looks like a pre-release version. '
+                       'If that is the case, in order to ensure that the '
+                       'version doesn\'t appear to go backwards when you '
+                       'later upgrade to the final release version, it is '
+                       'recommmended that instead you use '
+                       '<current version>+<pre-release version> e.g. if '
+                       'upgrading from 1.9 to 2.0-rc2 use "1.9+2.0-rc2". '
+                       'If you prefer not to reset and re-try, you can change '
+                       'the version after %s succeeds using "devtool rename" '
+                       'with -V/--version.' % (ver, operation))
+
+def check_git_repo_dirty(repodir):
+    """Check if a git repository is clean or not"""
+    stdout, _ = bb.process.run('git status --porcelain', cwd=repodir)
+    return stdout
+
+def check_git_repo_op(srctree, ignoredirs=None):
+    """Check if a git repository is in the middle of a rebase"""
+    stdout, _ = bb.process.run('git rev-parse --show-toplevel', cwd=srctree)
+    topleveldir = stdout.strip()
+    if ignoredirs and topleveldir in ignoredirs:
+        return
+    gitdir = os.path.join(topleveldir, '.git')
+    if os.path.exists(os.path.join(gitdir, 'rebase-merge')):
+        raise DevtoolError("Source tree %s appears to be in the middle of a rebase - please resolve this first" % srctree)
+    if os.path.exists(os.path.join(gitdir, 'rebase-apply')):
+        raise DevtoolError("Source tree %s appears to be in the middle of 'git am' or 'git apply' - please resolve this first" % srctree)
diff --git a/meta/poky/scripts/lib/devtool/build.py b/meta/poky/scripts/lib/devtool/build.py
new file mode 100644
index 0000000..ba9593f
--- /dev/null
+++ b/meta/poky/scripts/lib/devtool/build.py
@@ -0,0 +1,91 @@
+# Development tool - build command plugin
+#
+# Copyright (C) 2014-2015 Intel Corporation
+#
+# 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.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+"""Devtool build plugin"""
+
+import os
+import bb
+import logging
+import argparse
+import tempfile
+from devtool import exec_build_env_command, check_workspace_recipe, DevtoolError
+
+logger = logging.getLogger('devtool')
+
+
+def _set_file_values(fn, values):
+    remaining = list(values.keys())
+
+    def varfunc(varname, origvalue, op, newlines):
+        newvalue = values.get(varname, origvalue)
+        remaining.remove(varname)
+        return (newvalue, '=', 0, True)
+
+    with open(fn, 'r') as f:
+        (updated, newlines) = bb.utils.edit_metadata(f, values, varfunc)
+
+    for item in remaining:
+        updated = True
+        newlines.append('%s = "%s"' % (item, values[item]))
+
+    if updated:
+        with open(fn, 'w') as f:
+            f.writelines(newlines)
+    return updated
+
+def _get_build_tasks(config):
+    tasks = config.get('Build', 'build_task', 'populate_sysroot,packagedata').split(',')
+    return ['do_%s' % task.strip() for task in tasks]
+
+def build(args, config, basepath, workspace):
+    """Entry point for the devtool 'build' subcommand"""
+    workspacepn = check_workspace_recipe(workspace, args.recipename, bbclassextend=True)
+
+    if args.clean:
+        # use clean instead of cleansstate to avoid messing things up in eSDK
+        build_tasks = ['do_clean']
+    else:
+        build_tasks = _get_build_tasks(config)
+
+    bbappend = workspace[workspacepn]['bbappend']
+    if args.disable_parallel_make:
+        logger.info("Disabling 'make' parallelism")
+        _set_file_values(bbappend, {'PARALLEL_MAKE': ''})
+    try:
+        bbargs = []
+        for task in build_tasks:
+            if args.recipename.endswith('-native') and 'package' in task:
+                continue
+            bbargs.append('%s:%s' % (args.recipename, task))
+        exec_build_env_command(config.init_path, basepath, 'bitbake %s' % ' '.join(bbargs), watch=True)
+    except bb.process.ExecutionError as e:
+        # We've already seen the output since watch=True, so just ensure we return something to the user
+        return e.exitcode
+    finally:
+        if args.disable_parallel_make:
+            _set_file_values(bbappend, {'PARALLEL_MAKE': None})
+
+    return 0
+
+def register_commands(subparsers, context):
+    """Register devtool subcommands from this plugin"""
+    parser_build = subparsers.add_parser('build', help='Build a recipe',
+                                         description='Builds the specified recipe using bitbake (up to and including %s)' % ', '.join(_get_build_tasks(context.config)),
+                                         group='working', order=50)
+    parser_build.add_argument('recipename', help='Recipe to build')
+    parser_build.add_argument('-s', '--disable-parallel-make', action="store_true", help='Disable make parallelism')
+    parser_build.add_argument('-c', '--clean', action='store_true', help='clean up recipe building results')
+    parser_build.set_defaults(func=build)
diff --git a/meta/poky/scripts/lib/devtool/build_image.py b/meta/poky/scripts/lib/devtool/build_image.py
new file mode 100644
index 0000000..e581038
--- /dev/null
+++ b/meta/poky/scripts/lib/devtool/build_image.py
@@ -0,0 +1,174 @@
+# Development tool - build-image plugin
+#
+# Copyright (C) 2015 Intel Corporation
+#
+# 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.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+"""Devtool plugin containing the build-image subcommand."""
+
+import os
+import errno
+import logging
+
+from bb.process import ExecutionError
+from devtool import exec_build_env_command, setup_tinfoil, parse_recipe, DevtoolError
+
+logger = logging.getLogger('devtool')
+
+class TargetNotImageError(Exception):
+    pass
+
+def _get_packages(tinfoil, workspace, config):
+    """Get list of packages from recipes in the workspace."""
+    result = []
+    for recipe in workspace:
+        data = parse_recipe(config, tinfoil, recipe, True)
+        if 'class-target' in data.getVar('OVERRIDES').split(':'):
+            if recipe in data.getVar('PACKAGES').split():
+                result.append(recipe)
+            else:
+                logger.warning("Skipping recipe %s as it doesn't produce a "
+                               "package with the same name", recipe)
+    return result
+
+def build_image(args, config, basepath, workspace):
+    """Entry point for the devtool 'build-image' subcommand."""
+
+    image = args.imagename
+    auto_image = False
+    if not image:
+        sdk_targets = config.get('SDK', 'sdk_targets', '').split()
+        if sdk_targets:
+            image = sdk_targets[0]
+            auto_image = True
+    if not image:
+        raise DevtoolError('Unable to determine image to build, please specify one')
+
+    try:
+        if args.add_packages:
+            add_packages = args.add_packages.split(',')
+        else:
+            add_packages = None
+        result, outputdir = build_image_task(config, basepath, workspace, image, add_packages)
+    except TargetNotImageError:
+        if auto_image:
+            raise DevtoolError('Unable to determine image to build, please specify one')
+        else:
+            raise DevtoolError('Specified recipe %s is not an image recipe' % image)
+
+    if result == 0:
+        logger.info('Successfully built %s. You can find output files in %s'
+                    % (image, outputdir))
+    return result
+
+def build_image_task(config, basepath, workspace, image, add_packages=None, task=None, extra_append=None):
+    # remove <image>.bbappend to make sure setup_tinfoil doesn't
+    # break because of it
+    target_basename = config.get('SDK', 'target_basename', '')
+    if target_basename:
+        appendfile = os.path.join(config.workspace_path, 'appends',
+                                  '%s.bbappend' % target_basename)
+        try:
+            os.unlink(appendfile)
+        except OSError as exc:
+            if exc.errno != errno.ENOENT:
+                raise
+
+    tinfoil = setup_tinfoil(basepath=basepath)
+    try:
+        rd = parse_recipe(config, tinfoil, image, True)
+        if not rd:
+            # Error already shown
+            return (1, None)
+        if not bb.data.inherits_class('image', rd):
+            raise TargetNotImageError()
+
+        # Get the actual filename used and strip the .bb and full path
+        target_basename = rd.getVar('FILE')
+        target_basename = os.path.splitext(os.path.basename(target_basename))[0]
+        config.set('SDK', 'target_basename', target_basename)
+        config.write()
+
+        appendfile = os.path.join(config.workspace_path, 'appends',
+                                '%s.bbappend' % target_basename)
+
+        outputdir = None
+        try:
+            if workspace or add_packages:
+                if add_packages:
+                    packages = add_packages
+                else:
+                    packages = _get_packages(tinfoil, workspace, config)
+            else:
+                packages = None
+            if not task:
+                if not packages and not add_packages and workspace:
+                    logger.warning('No recipes in workspace, building image %s unmodified', image)
+                elif not packages:
+                    logger.warning('No packages to add, building image %s unmodified', image)
+
+            if packages or extra_append:
+                bb.utils.mkdirhier(os.path.dirname(appendfile))
+                with open(appendfile, 'w') as afile:
+                    if packages:
+                        # include packages from workspace recipes into the image
+                        afile.write('IMAGE_INSTALL_append = " %s"\n' % ' '.join(packages))
+                        if not task:
+                            logger.info('Building image %s with the following '
+                                        'additional packages: %s', image, ' '.join(packages))
+                    if extra_append:
+                        for line in extra_append:
+                            afile.write('%s\n' % line)
+
+            if task in ['populate_sdk', 'populate_sdk_ext']:
+                outputdir = rd.getVar('SDK_DEPLOY')
+            else:
+                outputdir = rd.getVar('DEPLOY_DIR_IMAGE')
+
+            tmp_tinfoil = tinfoil
+            tinfoil = None
+            tmp_tinfoil.shutdown()
+
+            options = ''
+            if task:
+                options += '-c %s' % task
+
+            # run bitbake to build image (or specified task)
+            try:
+                exec_build_env_command(config.init_path, basepath,
+                                    'bitbake %s %s' % (options, image), watch=True)
+            except ExecutionError as err:
+                return (err.exitcode, None)
+        finally:
+            if os.path.isfile(appendfile):
+                os.unlink(appendfile)
+    finally:
+        if tinfoil:
+            tinfoil.shutdown()
+    return (0, outputdir)
+
+
+def register_commands(subparsers, context):
+    """Register devtool subcommands from the build-image plugin"""
+    parser = subparsers.add_parser('build-image',
+                                   help='Build image including workspace recipe packages',
+                                   description='Builds an image, extending it to include '
+                                   'packages from recipes in the workspace',
+                                   group='testbuild', order=-10)
+    parser.add_argument('imagename', help='Image recipe to build', nargs='?')
+    parser.add_argument('-p', '--add-packages', help='Instead of adding packages for the '
+                        'entire workspace, specify packages to be added to the image '
+                        '(separate multiple packages by commas)',
+                        metavar='PACKAGES')
+    parser.set_defaults(func=build_image)
diff --git a/meta/poky/scripts/lib/devtool/build_sdk.py b/meta/poky/scripts/lib/devtool/build_sdk.py
new file mode 100644
index 0000000..b89d65b
--- /dev/null
+++ b/meta/poky/scripts/lib/devtool/build_sdk.py
@@ -0,0 +1,65 @@
+# Development tool - build-sdk command plugin
+#
+# Copyright (C) 2015-2016 Intel Corporation
+#
+# 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.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+import os
+import subprocess
+import logging
+import glob
+import shutil
+import errno
+import sys
+import tempfile
+from devtool import exec_build_env_command, setup_tinfoil, parse_recipe, DevtoolError
+from devtool import build_image
+
+logger = logging.getLogger('devtool')
+
+
+def build_sdk(args, config, basepath, workspace):
+    """Entry point for the devtool build-sdk command"""
+
+    sdk_targets = config.get('SDK', 'sdk_targets', '').split()
+    if sdk_targets:
+        image = sdk_targets[0]
+    else:
+        raise DevtoolError('Unable to determine image to build SDK for')
+
+    extra_append = ['SDK_DERIVATIVE = "1"']
+    try:
+        result, outputdir = build_image.build_image_task(config,
+                                                         basepath,
+                                                         workspace,
+                                                         image,
+                                                         task='populate_sdk_ext',
+                                                         extra_append=extra_append)
+    except build_image.TargetNotImageError:
+        raise DevtoolError('Unable to determine image to build SDK for')
+
+    if result == 0:
+        logger.info('Successfully built SDK. You can find output files in %s'
+                    % outputdir)
+    return result
+
+
+def register_commands(subparsers, context):
+    """Register devtool subcommands"""
+    if context.fixed_setup:
+        parser_build_sdk = subparsers.add_parser('build-sdk',
+                                                 help='Build a derivative SDK of this one',
+                                                 description='Builds an extensible SDK based upon this one and the items in your workspace',
+                                                 group='advanced')
+        parser_build_sdk.set_defaults(func=build_sdk)
diff --git a/meta/poky/scripts/lib/devtool/deploy.py b/meta/poky/scripts/lib/devtool/deploy.py
new file mode 100644
index 0000000..886004b
--- /dev/null
+++ b/meta/poky/scripts/lib/devtool/deploy.py
@@ -0,0 +1,350 @@
+# Development tool - deploy/undeploy command plugin
+#
+# Copyright (C) 2014-2016 Intel Corporation
+#
+# 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.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+"""Devtool plugin containing the deploy subcommands"""
+
+import logging
+import os
+import shutil
+import subprocess
+import tempfile
+
+import bb.utils
+import argparse_oe
+import oe.types
+
+from devtool import exec_fakeroot, setup_tinfoil, check_workspace_recipe, DevtoolError
+
+logger = logging.getLogger('devtool')
+
+deploylist_path = '/.devtool'
+
+def _prepare_remote_script(deploy, verbose=False, dryrun=False, undeployall=False, nopreserve=False, nocheckspace=False):
+    """
+    Prepare a shell script for running on the target to
+    deploy/undeploy files. We have to be careful what we put in this
+    script - only commands that are likely to be available on the
+    target are suitable (the target might be constrained, e.g. using
+    busybox rather than bash with coreutils).
+    """
+    lines = []
+    lines.append('#!/bin/sh')
+    lines.append('set -e')
+    if undeployall:
+        # Yes, I know this is crude - but it does work
+        lines.append('for entry in %s/*.list; do' % deploylist_path)
+        lines.append('[ ! -f $entry ] && exit')
+        lines.append('set `basename $entry | sed "s/.list//"`')
+    if dryrun:
+        if not deploy:
+            lines.append('echo "Previously deployed files for $1:"')
+    lines.append('manifest="%s/$1.list"' % deploylist_path)
+    lines.append('preservedir="%s/$1.preserve"' % deploylist_path)
+    lines.append('if [ -f $manifest ] ; then')
+    # Read manifest in reverse and delete files / remove empty dirs
+    lines.append('    sed \'1!G;h;$!d\' $manifest | while read file')
+    lines.append('    do')
+    if dryrun:
+        lines.append('        if [ ! -d $file ] ; then')
+        lines.append('            echo $file')
+        lines.append('        fi')
+    else:
+        lines.append('        if [ -d $file ] ; then')
+        # Avoid deleting a preserved directory in case it has special perms
+        lines.append('            if [ ! -d $preservedir/$file ] ; then')
+        lines.append('                rmdir $file > /dev/null 2>&1 || true')
+        lines.append('            fi')
+        lines.append('        else')
+        lines.append('            rm -f $file')
+        lines.append('        fi')
+    lines.append('    done')
+    if not dryrun:
+        lines.append('    rm $manifest')
+    if not deploy and not dryrun:
+        # May as well remove all traces
+        lines.append('    rmdir `dirname $manifest` > /dev/null 2>&1 || true')
+    lines.append('fi')
+
+    if deploy:
+        if not nocheckspace:
+            # Check for available space
+            # FIXME This doesn't take into account files spread across multiple
+            # partitions, but doing that is non-trivial
+            # Find the part of the destination path that exists
+            lines.append('checkpath="$2"')
+            lines.append('while [ "$checkpath" != "/" ] && [ ! -e $checkpath ]')
+            lines.append('do')
+            lines.append('    checkpath=`dirname "$checkpath"`')
+            lines.append('done')
+            lines.append(r'freespace=$(df -P $checkpath | sed -nre "s/^(\S+\s+){3}([0-9]+).*/\2/p")')
+            # First line of the file is the total space
+            lines.append('total=`head -n1 $3`')
+            lines.append('if [ $total -gt $freespace ] ; then')
+            lines.append('    echo "ERROR: insufficient space on target (available ${freespace}, needed ${total})"')
+            lines.append('    exit 1')
+            lines.append('fi')
+        if not nopreserve:
+            # Preserve any files that exist. Note that this will add to the
+            # preserved list with successive deployments if the list of files
+            # deployed changes, but because we've deleted any previously
+            # deployed files at this point it will never preserve anything
+            # that was deployed, only files that existed prior to any deploying
+            # (which makes the most sense)
+            lines.append('cat $3 | sed "1d" | while read file fsize')
+            lines.append('do')
+            lines.append('    if [ -e $file ] ; then')
+            lines.append('    dest="$preservedir/$file"')
+            lines.append('    mkdir -p `dirname $dest`')
+            lines.append('    mv $file $dest')
+            lines.append('    fi')
+            lines.append('done')
+            lines.append('rm $3')
+        lines.append('mkdir -p `dirname $manifest`')
+        lines.append('mkdir -p $2')
+        if verbose:
+            lines.append('    tar xv -C $2 -f - | tee $manifest')
+        else:
+            lines.append('    tar xv -C $2 -f - > $manifest')
+        lines.append('sed -i "s!^./!$2!" $manifest')
+    elif not dryrun:
+        # Put any preserved files back
+        lines.append('if [ -d $preservedir ] ; then')
+        lines.append('    cd $preservedir')
+        # find from busybox might not have -exec, so we don't use that
+        lines.append('    find . -type f | while read file')
+        lines.append('    do')
+        lines.append('        mv $file /$file')
+        lines.append('    done')
+        lines.append('    cd /')
+        lines.append('    rm -rf $preservedir')
+        lines.append('fi')
+
+    if undeployall:
+        if not dryrun:
+            lines.append('echo "NOTE: Successfully undeployed $1"')
+        lines.append('done')
+
+    # Delete the script itself
+    lines.append('rm $0')
+    lines.append('')
+
+    return '\n'.join(lines)
+
+
+
+def deploy(args, config, basepath, workspace):
+    """Entry point for the devtool 'deploy' subcommand"""
+    import math
+    import oe.recipeutils
+    import oe.package
+
+    check_workspace_recipe(workspace, args.recipename, checksrc=False)
+
+    try:
+        host, destdir = args.target.split(':')
+    except ValueError:
+        destdir = '/'
+    else:
+        args.target = host
+    if not destdir.endswith('/'):
+        destdir += '/'
+
+    tinfoil = setup_tinfoil(basepath=basepath)
+    try:
+        try:
+            rd = tinfoil.parse_recipe(args.recipename)
+        except Exception as e:
+            raise DevtoolError('Exception parsing recipe %s: %s' %
+                            (args.recipename, e))
+        recipe_outdir = rd.getVar('D')
+        if not os.path.exists(recipe_outdir) or not os.listdir(recipe_outdir):
+            raise DevtoolError('No files to deploy - have you built the %s '
+                            'recipe? If so, the install step has not installed '
+                            'any files.' % args.recipename)
+
+        if args.strip and not args.dry_run:
+            # Fakeroot copy to new destination
+            srcdir = recipe_outdir
+            recipe_outdir = os.path.join(rd.getVar('WORKDIR'), 'deploy-target-stripped')
+            if os.path.isdir(recipe_outdir):
+                bb.utils.remove(recipe_outdir, True)
+            exec_fakeroot(rd, "cp -af %s %s" % (os.path.join(srcdir, '.'), recipe_outdir), shell=True)
+            os.environ['PATH'] = ':'.join([os.environ['PATH'], rd.getVar('PATH') or ''])
+            oe.package.strip_execs(args.recipename, recipe_outdir, rd.getVar('STRIP'), rd.getVar('libdir'),
+                        rd.getVar('base_libdir'), rd)
+
+        filelist = []
+        ftotalsize = 0
+        for root, _, files in os.walk(recipe_outdir):
+            for fn in files:
+                # Get the size in kiB (since we'll be comparing it to the output of du -k)
+                # MUST use lstat() here not stat() or getfilesize() since we don't want to
+                # dereference symlinks
+                fsize = int(math.ceil(float(os.lstat(os.path.join(root, fn)).st_size)/1024))
+                ftotalsize += fsize
+                # The path as it would appear on the target
+                fpath = os.path.join(destdir, os.path.relpath(root, recipe_outdir), fn)
+                filelist.append((fpath, fsize))
+
+        if args.dry_run:
+            print('Files to be deployed for %s on target %s:' % (args.recipename, args.target))
+            for item, _ in filelist:
+                print('  %s' % item)
+            return 0
+
+        extraoptions = ''
+        if args.no_host_check:
+            extraoptions += '-o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no'
+        if not args.show_status:
+            extraoptions += ' -q'
+
+        scp_port = ''
+        ssh_port = ''
+        if args.port:
+            scp_port = "-P %s" % args.port
+            ssh_port = "-p %s" % args.port
+
+        # In order to delete previously deployed files and have the manifest file on
+        # the target, we write out a shell script and then copy it to the target
+        # so we can then run it (piping tar output to it).
+        # (We cannot use scp here, because it doesn't preserve symlinks.)
+        tmpdir = tempfile.mkdtemp(prefix='devtool')
+        try:
+            tmpscript = '/tmp/devtool_deploy.sh'
+            tmpfilelist = os.path.join(os.path.dirname(tmpscript), 'devtool_deploy.list')
+            shellscript = _prepare_remote_script(deploy=True,
+                                                verbose=args.show_status,
+                                                nopreserve=args.no_preserve,
+                                                nocheckspace=args.no_check_space)
+            # Write out the script to a file
+            with open(os.path.join(tmpdir, os.path.basename(tmpscript)), 'w') as f:
+                f.write(shellscript)
+            # Write out the file list
+            with open(os.path.join(tmpdir, os.path.basename(tmpfilelist)), 'w') as f:
+                f.write('%d\n' % ftotalsize)
+                for fpath, fsize in filelist:
+                    f.write('%s %d\n' % (fpath, fsize))
+            # Copy them to the target
+            ret = subprocess.call("scp %s %s %s/* %s:%s" % (scp_port, extraoptions, tmpdir, args.target, os.path.dirname(tmpscript)), shell=True)
+            if ret != 0:
+                raise DevtoolError('Failed to copy script to %s - rerun with -s to '
+                                'get a complete error message' % args.target)
+        finally:
+            shutil.rmtree(tmpdir)
+
+        # Now run the script
+        ret = exec_fakeroot(rd, 'tar cf - . | ssh  %s %s %s \'sh %s %s %s %s\'' % (ssh_port, extraoptions, args.target, tmpscript, args.recipename, destdir, tmpfilelist), cwd=recipe_outdir, shell=True)
+        if ret != 0:
+            raise DevtoolError('Deploy failed - rerun with -s to get a complete '
+                            'error message')
+
+        logger.info('Successfully deployed %s' % recipe_outdir)
+
+        files_list = []
+        for root, _, files in os.walk(recipe_outdir):
+            for filename in files:
+                filename = os.path.relpath(os.path.join(root, filename), recipe_outdir)
+                files_list.append(os.path.join(destdir, filename))
+    finally:
+        tinfoil.shutdown()
+
+    return 0
+
+def undeploy(args, config, basepath, workspace):
+    """Entry point for the devtool 'undeploy' subcommand"""
+    if args.all and args.recipename:
+        raise argparse_oe.ArgumentUsageError('Cannot specify -a/--all with a recipe name', 'undeploy-target')
+    elif not args.recipename and not args.all:
+        raise argparse_oe.ArgumentUsageError('If you don\'t specify a recipe, you must specify -a/--all', 'undeploy-target')
+
+    extraoptions = ''
+    if args.no_host_check:
+        extraoptions += '-o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no'
+    if not args.show_status:
+        extraoptions += ' -q'
+
+    scp_port = ''
+    ssh_port = ''
+    if args.port:
+        scp_port = "-P %s" % args.port
+        ssh_port = "-p %s" % args.port
+
+    args.target = args.target.split(':')[0]
+
+    tmpdir = tempfile.mkdtemp(prefix='devtool')
+    try:
+        tmpscript = '/tmp/devtool_undeploy.sh'
+        shellscript = _prepare_remote_script(deploy=False, dryrun=args.dry_run, undeployall=args.all)
+        # Write out the script to a file
+        with open(os.path.join(tmpdir, os.path.basename(tmpscript)), 'w') as f:
+            f.write(shellscript)
+        # Copy it to the target
+        ret = subprocess.call("scp %s %s %s/* %s:%s" % (scp_port, extraoptions, tmpdir, args.target, os.path.dirname(tmpscript)), shell=True)
+        if ret != 0:
+            raise DevtoolError('Failed to copy script to %s - rerun with -s to '
+                                'get a complete error message' % args.target)
+    finally:
+        shutil.rmtree(tmpdir)
+
+    # Now run the script
+    ret = subprocess.call('ssh %s %s %s \'sh %s %s\'' % (ssh_port, extraoptions, args.target, tmpscript, args.recipename), shell=True)
+    if ret != 0:
+        raise DevtoolError('Undeploy failed - rerun with -s to get a complete '
+                           'error message')
+
+    if not args.all and not args.dry_run:
+        logger.info('Successfully undeployed %s' % args.recipename)
+    return 0
+
+
+def register_commands(subparsers, context):
+    """Register devtool subcommands from the deploy plugin"""
+
+    parser_deploy = subparsers.add_parser('deploy-target',
+                                          help='Deploy recipe output files to live target machine',
+                                          description='Deploys a recipe\'s build output (i.e. the output of the do_install task) to a live target machine over ssh. By default, any existing files will be preserved instead of being overwritten and will be restored if you run devtool undeploy-target. Note: this only deploys the recipe itself and not any runtime dependencies, so it is assumed that those have been installed on the target beforehand.',
+                                          group='testbuild')
+    parser_deploy.add_argument('recipename', help='Recipe to deploy')
+    parser_deploy.add_argument('target', help='Live target machine running an ssh server: user@hostname[:destdir]')
+    parser_deploy.add_argument('-c', '--no-host-check', help='Disable ssh host key checking', action='store_true')
+    parser_deploy.add_argument('-s', '--show-status', help='Show progress/status output', action='store_true')
+    parser_deploy.add_argument('-n', '--dry-run', help='List files to be deployed only', action='store_true')
+    parser_deploy.add_argument('-p', '--no-preserve', help='Do not preserve existing files', action='store_true')
+    parser_deploy.add_argument('--no-check-space', help='Do not check for available space before deploying', action='store_true')
+    parser_deploy.add_argument('-P', '--port', help='Specify port to use for connection to the target')
+
+    strip_opts = parser_deploy.add_mutually_exclusive_group(required=False)
+    strip_opts.add_argument('-S', '--strip',
+                               help='Strip executables prior to deploying (default: %(default)s). '
+                                    'The default value of this option can be controlled by setting the strip option in the [Deploy] section to True or False.',
+                               default=oe.types.boolean(context.config.get('Deploy', 'strip', default='0')),
+                               action='store_true')
+    strip_opts.add_argument('--no-strip', help='Do not strip executables prior to deploy', dest='strip', action='store_false')
+
+    parser_deploy.set_defaults(func=deploy)
+
+    parser_undeploy = subparsers.add_parser('undeploy-target',
+                                            help='Undeploy recipe output files in live target machine',
+                                            description='Un-deploys recipe output files previously deployed to a live target machine by devtool deploy-target.',
+                                            group='testbuild')
+    parser_undeploy.add_argument('recipename', help='Recipe to undeploy (if not using -a/--all)', nargs='?')
+    parser_undeploy.add_argument('target', help='Live target machine running an ssh server: user@hostname')
+    parser_undeploy.add_argument('-c', '--no-host-check', help='Disable ssh host key checking', action='store_true')
+    parser_undeploy.add_argument('-s', '--show-status', help='Show progress/status output', action='store_true')
+    parser_undeploy.add_argument('-a', '--all', help='Undeploy all recipes deployed on the target', action='store_true')
+    parser_undeploy.add_argument('-n', '--dry-run', help='List files to be undeployed only', action='store_true')
+    parser_undeploy.add_argument('-P', '--port', help='Specify port to use for connection to the target')
+    parser_undeploy.set_defaults(func=undeploy)
diff --git a/meta/poky/scripts/lib/devtool/export.py b/meta/poky/scripts/lib/devtool/export.py
new file mode 100644
index 0000000..35349e2
--- /dev/null
+++ b/meta/poky/scripts/lib/devtool/export.py
@@ -0,0 +1,119 @@
+# Development tool - export command plugin
+#
+# Copyright (C) 2014-2017 Intel Corporation
+#
+# 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.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+"""Devtool export plugin"""
+
+import os
+import argparse
+import tarfile
+import logging
+import datetime
+import json
+
+logger = logging.getLogger('devtool')
+
+# output files
+default_arcname_prefix = "workspace-export"
+metadata = '.export_metadata'
+
+def export(args, config, basepath, workspace):
+    """Entry point for the devtool 'export' subcommand"""
+
+    def add_metadata(tar):
+        """Archive the workspace object"""
+        # finally store the workspace metadata
+        with open(metadata, 'w') as fd:
+            fd.write(json.dumps((config.workspace_path, workspace)))
+        tar.add(metadata)
+        os.unlink(metadata)
+
+    def add_recipe(tar, recipe, data):
+        """Archive recipe with proper arcname"""
+        # Create a map of name/arcnames
+        arcnames = []
+        for key, name in data.items():
+            if name:
+                if key == 'srctree':
+                    # all sources, no matter where are located, goes into the sources directory
+                    arcname = 'sources/%s' % recipe
+                else:
+                    arcname = name.replace(config.workspace_path, '')
+                arcnames.append((name, arcname))
+
+        for name, arcname in arcnames:
+            tar.add(name, arcname=arcname)
+
+
+    # Make sure workspace is non-empty and possible listed include/excluded recipes are in workspace
+    if not workspace:
+        logger.info('Workspace contains no recipes, nothing to export')
+        return 0
+    else:
+        for param, recipes in {'include':args.include,'exclude':args.exclude}.items():
+            for recipe in recipes:
+                if recipe not in workspace:
+                    logger.error('Recipe (%s) on %s argument not in the current workspace' % (recipe, param))
+                    return 1
+
+    name = args.file
+
+    default_name = "%s-%s.tar.gz" % (default_arcname_prefix, datetime.datetime.now().strftime('%Y%m%d%H%M%S'))
+    if not name:
+        name = default_name
+    else:
+        # if name is a directory, append the default name
+        if os.path.isdir(name):
+            name = os.path.join(name, default_name)
+
+    if os.path.exists(name) and not args.overwrite:
+        logger.error('Tar archive %s exists. Use --overwrite/-o to overwrite it')
+        return 1
+
+    # if all workspace is excluded, quit
+    if not len(set(workspace.keys()).difference(set(args.exclude))):
+        logger.warning('All recipes in workspace excluded, nothing to export')
+        return 0
+
+    exported = []
+    with tarfile.open(name, 'w:gz') as tar:
+        if args.include:
+            for recipe in args.include:
+                add_recipe(tar, recipe, workspace[recipe])
+                exported.append(recipe)
+        else:
+            for recipe, data in workspace.items():
+                if recipe not in args.exclude:
+                    add_recipe(tar, recipe, data)
+                    exported.append(recipe)
+
+        add_metadata(tar)
+
+    logger.info('Tar archive created at %s with the following recipes: %s' % (name, ', '.join(exported)))
+    return 0
+
+def register_commands(subparsers, context):
+    """Register devtool export subcommands"""
+    parser = subparsers.add_parser('export',
+                                   help='Export workspace into a tar archive',
+                                   description='Export one or more recipes from current workspace into a tar archive',
+                                   group='advanced')
+
+    parser.add_argument('--file', '-f', help='Output archive file name')
+    parser.add_argument('--overwrite', '-o', action="store_true", help='Overwrite previous export tar archive')
+    group = parser.add_mutually_exclusive_group()
+    group.add_argument('--include', '-i', nargs='+', default=[], help='Include recipes into the tar archive')
+    group.add_argument('--exclude', '-e', nargs='+', default=[], help='Exclude recipes into the tar archive')
+    parser.set_defaults(func=export)
diff --git a/meta/poky/scripts/lib/devtool/import.py b/meta/poky/scripts/lib/devtool/import.py
new file mode 100644
index 0000000..4264b7d
--- /dev/null
+++ b/meta/poky/scripts/lib/devtool/import.py
@@ -0,0 +1,144 @@
+# Development tool - import command plugin
+#
+# Copyright (C) 2014-2017 Intel Corporation
+#
+# 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.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+"""Devtool import plugin"""
+
+import os
+import tarfile
+import logging
+import collections
+import json
+import fnmatch
+
+from devtool import standard, setup_tinfoil, replace_from_file, DevtoolError
+from devtool import export
+
+logger = logging.getLogger('devtool')
+
+def devimport(args, config, basepath, workspace):
+    """Entry point for the devtool 'import' subcommand"""
+
+    def get_pn(name):
+        """ Returns the filename of a workspace recipe/append"""
+        metadata = name.split('/')[-1]
+        fn, _ = os.path.splitext(metadata)
+        return fn
+
+    if not os.path.exists(args.file):
+        raise DevtoolError('Tar archive %s does not exist. Export your workspace using "devtool export"' % args.file)
+
+    with tarfile.open(args.file) as tar:
+        # Get exported metadata
+        export_workspace_path = export_workspace = None
+        try:
+            metadata = tar.getmember(export.metadata)
+        except KeyError as ke:
+            raise DevtoolError('The export metadata file created by "devtool export" was not found. "devtool import" can only be used to import tar archives created by "devtool export".')
+
+        tar.extract(metadata)
+        with open(metadata.name) as fdm:
+            export_workspace_path, export_workspace = json.load(fdm)
+        os.unlink(metadata.name)
+
+        members = tar.getmembers()
+
+        # Get appends and recipes from the exported archive, these
+        # will be needed to find out those appends without corresponding
+        # recipe pair
+        append_fns, recipe_fns = set(), set()
+        for member in members:
+            if member.name.startswith('appends'):
+                append_fns.add(get_pn(member.name))
+            elif member.name.startswith('recipes'):
+                recipe_fns.add(get_pn(member.name))
+
+        # Setup tinfoil, get required data and shutdown
+        tinfoil = setup_tinfoil(config_only=False, basepath=basepath)
+        try:
+            current_fns = [os.path.basename(recipe[0]) for recipe in tinfoil.cooker.recipecaches[''].pkg_fn.items()]
+        finally:
+            tinfoil.shutdown()
+
+        # Find those appends that do not have recipes in current metadata
+        non_importables = []
+        for fn in append_fns - recipe_fns:
+            # Check on current metadata (covering those layers indicated in bblayers.conf)
+            for current_fn in current_fns:
+                if fnmatch.fnmatch(current_fn, '*' + fn.replace('%', '') + '*'):
+                    break
+            else:
+                non_importables.append(fn)
+                logger.warning('No recipe to append %s.bbapppend, skipping' % fn)
+
+        # Extract
+        imported = []
+        for member in members:
+            if member.name == export.metadata:
+                continue
+
+            for nonimp in non_importables:
+                pn = nonimp.split('_')[0]
+                # do not extract data from non-importable recipes or metadata
+                if member.name.startswith('appends/%s' % nonimp) or \
+                        member.name.startswith('recipes/%s' % nonimp) or \
+                        member.name.startswith('sources/%s' % pn):
+                    break
+            else:
+                path = os.path.join(config.workspace_path, member.name)
+                if os.path.exists(path):
+                    # by default, no file overwrite is done unless -o is given by the user
+                    if args.overwrite:
+                        try:
+                            tar.extract(member, path=config.workspace_path)
+                        except PermissionError as pe:
+                            logger.warning(pe)
+                    else:
+                        logger.warning('File already present. Use --overwrite/-o to overwrite it: %s' % member.name)
+                        continue
+                else:
+                    tar.extract(member, path=config.workspace_path)
+
+                # Update EXTERNALSRC and the devtool md5 file
+                if member.name.startswith('appends'):
+                    if export_workspace_path:
+                        # appends created by 'devtool modify' just need to update the workspace
+                        replace_from_file(path, export_workspace_path, config.workspace_path)
+
+                        # appends created by 'devtool add' need replacement of exported source tree
+                        pn = get_pn(member.name).split('_')[0]
+                        exported_srctree = export_workspace[pn]['srctree']
+                        if exported_srctree:
+                            replace_from_file(path, exported_srctree, os.path.join(config.workspace_path, 'sources', pn))
+
+                    standard._add_md5(config, pn, path)
+                    imported.append(pn)
+
+    if imported:
+        logger.info('Imported recipes into workspace %s: %s' % (config.workspace_path, ', '.join(imported)))
+    else:
+        logger.warning('No recipes imported into the workspace')
+
+    return 0
+
+def register_commands(subparsers, context):
+    """Register devtool import subcommands"""
+    parser = subparsers.add_parser('import',
+                                   help='Import exported tar archive into workspace',
+                                   description='Import tar archive previously created by "devtool export" into workspace',
+                                   group='advanced')
+    parser.add_argument('file', metavar='FILE', help='Name of the tar archive to import')
+    parser.add_argument('--overwrite', '-o', action="store_true", help='Overwrite files when extracting')
+    parser.set_defaults(func=devimport)
diff --git a/meta/poky/scripts/lib/devtool/package.py b/meta/poky/scripts/lib/devtool/package.py
new file mode 100644
index 0000000..af9e8f1
--- /dev/null
+++ b/meta/poky/scripts/lib/devtool/package.py
@@ -0,0 +1,60 @@
+# Development tool - package command plugin
+#
+# Copyright (C) 2014-2015 Intel Corporation
+#
+# 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.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+"""Devtool plugin containing the package subcommands"""
+
+import os
+import subprocess
+import logging
+from bb.process import ExecutionError
+from devtool import exec_build_env_command, setup_tinfoil, check_workspace_recipe, DevtoolError
+
+logger = logging.getLogger('devtool')
+
+def package(args, config, basepath, workspace):
+    """Entry point for the devtool 'package' subcommand"""
+    check_workspace_recipe(workspace, args.recipename)
+
+    tinfoil = setup_tinfoil(basepath=basepath, config_only=True)
+    try:
+        image_pkgtype = config.get('Package', 'image_pkgtype', '')
+        if not image_pkgtype:
+            image_pkgtype = tinfoil.config_data.getVar('IMAGE_PKGTYPE')
+
+        deploy_dir_pkg = tinfoil.config_data.getVar('DEPLOY_DIR_%s' % image_pkgtype.upper())
+    finally:
+        tinfoil.shutdown()
+
+    package_task = config.get('Package', 'package_task', 'package_write_%s' % image_pkgtype)
+    try:
+        exec_build_env_command(config.init_path, basepath, 'bitbake -c %s %s' % (package_task, args.recipename), watch=True)
+    except bb.process.ExecutionError as e:
+        # We've already seen the output since watch=True, so just ensure we return something to the user
+        return e.exitcode
+
+    logger.info('Your packages are in %s' % deploy_dir_pkg)
+
+    return 0
+
+def register_commands(subparsers, context):
+    """Register devtool subcommands from the package plugin"""
+    if context.fixed_setup:
+        parser_package = subparsers.add_parser('package',
+                                               help='Build packages for a recipe',
+                                               description='Builds packages for a recipe\'s output files',
+                                               group='testbuild', order=-5)
+        parser_package.add_argument('recipename', help='Recipe to package')
+        parser_package.set_defaults(func=package)
diff --git a/meta/poky/scripts/lib/devtool/runqemu.py b/meta/poky/scripts/lib/devtool/runqemu.py
new file mode 100644
index 0000000..e26cf28
--- /dev/null
+++ b/meta/poky/scripts/lib/devtool/runqemu.py
@@ -0,0 +1,74 @@
+# Development tool - runqemu command plugin
+#
+# Copyright (C) 2015 Intel Corporation
+#
+# 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.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+"""Devtool runqemu plugin"""
+
+import os
+import bb
+import logging
+import argparse
+import glob
+from devtool import exec_build_env_command, setup_tinfoil, DevtoolError
+
+logger = logging.getLogger('devtool')
+
+def runqemu(args, config, basepath, workspace):
+    """Entry point for the devtool 'runqemu' subcommand"""
+
+    tinfoil = setup_tinfoil(config_only=True, basepath=basepath)
+    try:
+        machine = tinfoil.config_data.getVar('MACHINE')
+        bindir_native = os.path.join(tinfoil.config_data.getVar('STAGING_DIR'),
+                                     tinfoil.config_data.getVar('BUILD_ARCH'),
+                                     tinfoil.config_data.getVar('bindir_native').lstrip(os.path.sep))
+    finally:
+        tinfoil.shutdown()
+
+    if not glob.glob(os.path.join(bindir_native, 'qemu-system-*')):
+        raise DevtoolError('QEMU is not available within this SDK')
+
+    imagename = args.imagename
+    if not imagename:
+        sdk_targets = config.get('SDK', 'sdk_targets', '').split()
+        if sdk_targets:
+            imagename = sdk_targets[0]
+    if not imagename:
+        raise DevtoolError('Unable to determine image name to run, please specify one')
+
+    try:
+        # FIXME runqemu assumes that if OECORE_NATIVE_SYSROOT is set then it shouldn't
+        # run bitbake to find out the values of various environment variables, which
+        # isn't the case for the extensible SDK. Work around it for now.
+        newenv = dict(os.environ)
+        newenv.pop('OECORE_NATIVE_SYSROOT', '')
+        exec_build_env_command(config.init_path, basepath, 'runqemu %s %s %s' % (machine, imagename, " ".join(args.args)), watch=True, env=newenv)
+    except bb.process.ExecutionError as e:
+        # We've already seen the output since watch=True, so just ensure we return something to the user
+        return e.exitcode
+
+    return 0
+
+def register_commands(subparsers, context):
+    """Register devtool subcommands from this plugin"""
+    if context.fixed_setup:
+        parser_runqemu = subparsers.add_parser('runqemu', help='Run QEMU on the specified image',
+                                               description='Runs QEMU to boot the specified image',
+                                               group='testbuild', order=-20)
+        parser_runqemu.add_argument('imagename', help='Name of built image to boot within QEMU', nargs='?')
+        parser_runqemu.add_argument('args', help='Any remaining arguments are passed to the runqemu script (pass --help after imagename to see what these are)',
+                                    nargs=argparse.REMAINDER)
+        parser_runqemu.set_defaults(func=runqemu)
diff --git a/meta/poky/scripts/lib/devtool/sdk.py b/meta/poky/scripts/lib/devtool/sdk.py
new file mode 100644
index 0000000..4616753
--- /dev/null
+++ b/meta/poky/scripts/lib/devtool/sdk.py
@@ -0,0 +1,339 @@
+# Development tool - sdk-update command plugin
+#
+# Copyright (C) 2015-2016 Intel Corporation
+#
+# 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.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+import os
+import subprocess
+import logging
+import glob
+import shutil
+import errno
+import sys
+import tempfile
+import re
+from devtool import exec_build_env_command, setup_tinfoil, parse_recipe, DevtoolError
+
+logger = logging.getLogger('devtool')
+
+def parse_locked_sigs(sigfile_path):
+    """Return <pn:task>:<hash> dictionary"""
+    sig_dict = {}
+    with open(sigfile_path) as f:
+        lines = f.readlines()
+        for line in lines:
+            if ':' in line:
+                taskkey, _, hashval = line.rpartition(':')
+                sig_dict[taskkey.strip()] = hashval.split()[0]
+    return sig_dict
+
+def generate_update_dict(sigfile_new, sigfile_old):
+    """Return a dict containing <pn:task>:<hash> which indicates what need to be updated"""
+    update_dict = {}
+    sigdict_new = parse_locked_sigs(sigfile_new)
+    sigdict_old = parse_locked_sigs(sigfile_old)
+    for k in sigdict_new:
+        if k not in sigdict_old:
+            update_dict[k] = sigdict_new[k]
+            continue
+        if sigdict_new[k] != sigdict_old[k]:
+            update_dict[k] = sigdict_new[k]
+            continue
+    return update_dict
+
+def get_sstate_objects(update_dict, sstate_dir):
+    """Return a list containing sstate objects which are to be installed"""
+    sstate_objects = []
+    for k in update_dict:
+        files = set()
+        hashval = update_dict[k]
+        p = sstate_dir + '/' + hashval[:2] + '/*' + hashval + '*.tgz'
+        files |= set(glob.glob(p))
+        p = sstate_dir + '/*/' + hashval[:2] + '/*' + hashval + '*.tgz'
+        files |= set(glob.glob(p))
+        files = list(files)
+        if len(files) == 1:
+            sstate_objects.extend(files)
+        elif len(files) > 1:
+            logger.error("More than one matching sstate object found for %s" % hashval)
+
+    return sstate_objects
+
+def mkdir(d):
+    try:
+        os.makedirs(d)
+    except OSError as e:
+        if e.errno != errno.EEXIST:
+            raise e
+
+def install_sstate_objects(sstate_objects, src_sdk, dest_sdk):
+    """Install sstate objects into destination SDK"""
+    sstate_dir = os.path.join(dest_sdk, 'sstate-cache')
+    if not os.path.exists(sstate_dir):
+        logger.error("Missing sstate-cache directory in %s, it might not be an extensible SDK." % dest_sdk)
+        raise
+    for sb in sstate_objects:
+        dst = sb.replace(src_sdk, dest_sdk)
+        destdir = os.path.dirname(dst)
+        mkdir(destdir)
+        logger.debug("Copying %s to %s" % (sb, dst))
+        shutil.copy(sb, dst)
+
+def check_manifest(fn, basepath):
+    import bb.utils
+    changedfiles = []
+    with open(fn, 'r') as f:
+        for line in f:
+            splitline = line.split()
+            if len(splitline) > 1:
+                chksum = splitline[0]
+                fpath = splitline[1]
+                curr_chksum = bb.utils.sha256_file(os.path.join(basepath, fpath))
+                if chksum != curr_chksum:
+                    logger.debug('File %s changed: old csum = %s, new = %s' % (os.path.join(basepath, fpath), curr_chksum, chksum))
+                    changedfiles.append(fpath)
+    return changedfiles
+
+def sdk_update(args, config, basepath, workspace):
+    """Entry point for devtool sdk-update command"""
+    updateserver = args.updateserver
+    if not updateserver:
+        updateserver = config.get('SDK', 'updateserver', '')
+    logger.debug("updateserver: %s" % updateserver)
+
+    # Make sure we are using sdk-update from within SDK
+    logger.debug("basepath = %s" % basepath)
+    old_locked_sig_file_path = os.path.join(basepath, 'conf/locked-sigs.inc')
+    if not os.path.exists(old_locked_sig_file_path):
+        logger.error("Not using devtool's sdk-update command from within an extensible SDK. Please specify correct basepath via --basepath option")
+        return -1
+    else:
+        logger.debug("Found conf/locked-sigs.inc in %s" % basepath)
+
+    if not '://' in updateserver:
+        logger.error("Update server must be a URL")
+        return -1
+
+    layers_dir = os.path.join(basepath, 'layers')
+    conf_dir = os.path.join(basepath, 'conf')
+
+    # Grab variable values
+    tinfoil = setup_tinfoil(config_only=True, basepath=basepath)
+    try:
+        stamps_dir = tinfoil.config_data.getVar('STAMPS_DIR')
+        sstate_mirrors = tinfoil.config_data.getVar('SSTATE_MIRRORS')
+        site_conf_version = tinfoil.config_data.getVar('SITE_CONF_VERSION')
+    finally:
+        tinfoil.shutdown()
+
+    tmpsdk_dir = tempfile.mkdtemp()
+    try:
+        os.makedirs(os.path.join(tmpsdk_dir, 'conf'))
+        new_locked_sig_file_path = os.path.join(tmpsdk_dir, 'conf', 'locked-sigs.inc')
+        # Fetch manifest from server
+        tmpmanifest = os.path.join(tmpsdk_dir, 'conf', 'sdk-conf-manifest')
+        ret = subprocess.call("wget -q -O %s %s/conf/sdk-conf-manifest" % (tmpmanifest, updateserver), shell=True)
+        if ret != 0:
+            logger.error("Cannot dowload files from %s" % updateserver)
+            return ret
+        changedfiles = check_manifest(tmpmanifest, basepath)
+        if not changedfiles:
+            logger.info("Already up-to-date")
+            return 0
+        # Update metadata
+        logger.debug("Updating metadata via git ...")
+        #Check for the status before doing a fetch and reset
+        if os.path.exists(os.path.join(basepath, 'layers/.git')):
+            out = subprocess.check_output("git status --porcelain", shell=True, cwd=layers_dir)
+            if not out:
+                ret = subprocess.call("git fetch --all; git reset --hard @{u}", shell=True, cwd=layers_dir)
+            else:
+                logger.error("Failed to update metadata as there have been changes made to it. Aborting.");
+                logger.error("Changed files:\n%s" % out);
+                return -1
+        else:
+            ret = -1
+        if ret != 0:
+            ret = subprocess.call("git clone %s/layers/.git" % updateserver, shell=True, cwd=tmpsdk_dir)
+            if ret != 0:
+                logger.error("Updating metadata via git failed")
+                return ret
+        logger.debug("Updating conf files ...")
+        for changedfile in changedfiles:
+            ret = subprocess.call("wget -q -O %s %s/%s" % (changedfile, updateserver, changedfile), shell=True, cwd=tmpsdk_dir)
+            if ret != 0:
+                logger.error("Updating %s failed" % changedfile)
+                return ret
+
+        # Check if UNINATIVE_CHECKSUM changed
+        uninative = False
+        if 'conf/local.conf' in changedfiles:
+            def read_uninative_checksums(fn):
+                chksumitems = []
+                with open(fn, 'r') as f:
+                    for line in f:
+                        if line.startswith('UNINATIVE_CHECKSUM'):
+                            splitline = re.split(r'[\[\]"\']', line)
+                            if len(splitline) > 3:
+                                chksumitems.append((splitline[1], splitline[3]))
+                return chksumitems
+
+            oldsums = read_uninative_checksums(os.path.join(basepath, 'conf/local.conf'))
+            newsums = read_uninative_checksums(os.path.join(tmpsdk_dir, 'conf/local.conf'))
+            if oldsums != newsums:
+                uninative = True
+                for buildarch, chksum in newsums:
+                    uninative_file = os.path.join('downloads', 'uninative', chksum, '%s-nativesdk-libc.tar.bz2' % buildarch)
+                    mkdir(os.path.join(tmpsdk_dir, os.path.dirname(uninative_file)))
+                    ret = subprocess.call("wget -q -O %s %s/%s" % (uninative_file, updateserver, uninative_file), shell=True, cwd=tmpsdk_dir)
+
+        # Ok, all is well at this point - move everything over
+        tmplayers_dir = os.path.join(tmpsdk_dir, 'layers')
+        if os.path.exists(tmplayers_dir):
+            shutil.rmtree(layers_dir)
+            shutil.move(tmplayers_dir, layers_dir)
+        for changedfile in changedfiles:
+            destfile = os.path.join(basepath, changedfile)
+            os.remove(destfile)
+            shutil.move(os.path.join(tmpsdk_dir, changedfile), destfile)
+        os.remove(os.path.join(conf_dir, 'sdk-conf-manifest'))
+        shutil.move(tmpmanifest, conf_dir)
+        if uninative:
+            shutil.rmtree(os.path.join(basepath, 'downloads', 'uninative'))
+            shutil.move(os.path.join(tmpsdk_dir, 'downloads', 'uninative'), os.path.join(basepath, 'downloads'))
+
+        if not sstate_mirrors:
+            with open(os.path.join(conf_dir, 'site.conf'), 'a') as f:
+                f.write('SCONF_VERSION = "%s"\n' % site_conf_version)
+                f.write('SSTATE_MIRRORS_append = " file://.* %s/sstate-cache/PATH \\n "\n' % updateserver)
+    finally:
+        shutil.rmtree(tmpsdk_dir)
+
+    if not args.skip_prepare:
+        # Find all potentially updateable tasks
+        sdk_update_targets = []
+        tasks = ['do_populate_sysroot', 'do_packagedata']
+        for root, _, files in os.walk(stamps_dir):
+            for fn in files:
+                if not '.sigdata.' in fn:
+                    for task in tasks:
+                        if '.%s.' % task in fn or '.%s_setscene.' % task in fn:
+                            sdk_update_targets.append('%s:%s' % (os.path.basename(root), task))
+        # Run bitbake command for the whole SDK
+        logger.info("Preparing build system... (This may take some time.)")
+        try:
+            exec_build_env_command(config.init_path, basepath, 'bitbake --setscene-only %s' % ' '.join(sdk_update_targets), stderr=subprocess.STDOUT)
+            output, _ = exec_build_env_command(config.init_path, basepath, 'bitbake -n %s' % ' '.join(sdk_update_targets), stderr=subprocess.STDOUT)
+            runlines = []
+            for line in output.splitlines():
+                if 'Running task ' in line:
+                    runlines.append(line)
+            if runlines:
+                logger.error('Unexecuted tasks found in preparation log:\n  %s' % '\n  '.join(runlines))
+                return -1
+        except bb.process.ExecutionError as e:
+            logger.error('Preparation failed:\n%s' % e.stdout)
+            return -1
+    return 0
+
+def sdk_install(args, config, basepath, workspace):
+    """Entry point for the devtool sdk-install command"""
+
+    import oe.recipeutils
+    import bb.process
+
+    for recipe in args.recipename:
+        if recipe in workspace:
+            raise DevtoolError('recipe %s is a recipe in your workspace' % recipe)
+
+    tasks = ['do_populate_sysroot', 'do_packagedata']
+    stampprefixes = {}
+    def checkstamp(recipe):
+        stampprefix = stampprefixes[recipe]
+        stamps = glob.glob(stampprefix + '*')
+        for stamp in stamps:
+            if '.sigdata.' not in stamp and stamp.startswith((stampprefix + '.', stampprefix + '_setscene.')):
+                return True
+        else:
+            return False
+
+    install_recipes = []
+    tinfoil = setup_tinfoil(config_only=False, basepath=basepath)
+    try:
+        for recipe in args.recipename:
+            rd = parse_recipe(config, tinfoil, recipe, True)
+            if not rd:
+                return 1
+            stampprefixes[recipe] = '%s.%s' % (rd.getVar('STAMP'), tasks[0])
+            if checkstamp(recipe):
+                logger.info('%s is already installed' % recipe)
+            else:
+                install_recipes.append(recipe)
+    finally:
+        tinfoil.shutdown()
+
+    if install_recipes:
+        logger.info('Installing %s...' % ', '.join(install_recipes))
+        install_tasks = []
+        for recipe in install_recipes:
+            for task in tasks:
+                if recipe.endswith('-native') and 'package' in task:
+                    continue
+                install_tasks.append('%s:%s' % (recipe, task))
+        options = ''
+        if not args.allow_build:
+            options += ' --setscene-only'
+        try:
+            exec_build_env_command(config.init_path, basepath, 'bitbake %s %s' % (options, ' '.join(install_tasks)), watch=True)
+        except bb.process.ExecutionError as e:
+            raise DevtoolError('Failed to install %s:\n%s' % (recipe, str(e)))
+        failed = False
+        for recipe in install_recipes:
+            if checkstamp(recipe):
+                logger.info('Successfully installed %s' % recipe)
+            else:
+                raise DevtoolError('Failed to install %s - unavailable' % recipe)
+                failed = True
+        if failed:
+            return 2
+
+        try:
+            exec_build_env_command(config.init_path, basepath, 'bitbake build-sysroots', watch=True)
+        except bb.process.ExecutionError as e:
+            raise DevtoolError('Failed to bitbake build-sysroots:\n%s' % (str(e)))
+
+
+def register_commands(subparsers, context):
+    """Register devtool subcommands from the sdk plugin"""
+    if context.fixed_setup:
+        parser_sdk = subparsers.add_parser('sdk-update',
+                                           help='Update SDK components',
+                                           description='Updates installed SDK components from a remote server',
+                                           group='sdk')
+        updateserver = context.config.get('SDK', 'updateserver', '')
+        if updateserver:
+            parser_sdk.add_argument('updateserver', help='The update server to fetch latest SDK components from (default %s)' % updateserver, nargs='?')
+        else:
+            parser_sdk.add_argument('updateserver', help='The update server to fetch latest SDK components from')
+        parser_sdk.add_argument('--skip-prepare', action="store_true", help='Skip re-preparing the build system after updating (for debugging only)')
+        parser_sdk.set_defaults(func=sdk_update)
+
+        parser_sdk_install = subparsers.add_parser('sdk-install',
+                                                   help='Install additional SDK components',
+                                                   description='Installs additional recipe development files into the SDK. (You can use "devtool search" to find available recipes.)',
+                                                   group='sdk')
+        parser_sdk_install.add_argument('recipename', help='Name of the recipe to install the development artifacts for', nargs='+')
+        parser_sdk_install.add_argument('-s', '--allow-build', help='Allow building requested item(s) from source', action='store_true')
+        parser_sdk_install.set_defaults(func=sdk_install)
diff --git a/meta/poky/scripts/lib/devtool/search.py b/meta/poky/scripts/lib/devtool/search.py
new file mode 100644
index 0000000..b4f209b
--- /dev/null
+++ b/meta/poky/scripts/lib/devtool/search.py
@@ -0,0 +1,118 @@
+# Development tool - search command plugin
+#
+# Copyright (C) 2015 Intel Corporation
+#
+# 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.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+"""Devtool search plugin"""
+
+import os
+import bb
+import logging
+import argparse
+import re
+from devtool import setup_tinfoil, parse_recipe, DevtoolError
+
+logger = logging.getLogger('devtool')
+
+def search(args, config, basepath, workspace):
+    """Entry point for the devtool 'search' subcommand"""
+
+    tinfoil = setup_tinfoil(config_only=False, basepath=basepath)
+    try:
+        pkgdata_dir = tinfoil.config_data.getVar('PKGDATA_DIR')
+        defsummary = tinfoil.config_data.getVar('SUMMARY', False) or ''
+
+        keyword_rc = re.compile(args.keyword)
+
+        def print_match(pn):
+            rd = parse_recipe(config, tinfoil, pn, True)
+            if not rd:
+                return
+            summary = rd.getVar('SUMMARY')
+            if summary == rd.expand(defsummary):
+                summary = ''
+            print("%s  %s" % (pn.ljust(20), summary))
+
+
+        matches = []
+        if os.path.exists(pkgdata_dir):
+            for fn in os.listdir(pkgdata_dir):
+                pfn = os.path.join(pkgdata_dir, fn)
+                if not os.path.isfile(pfn):
+                    continue
+
+                packages = []
+                match = False
+                if keyword_rc.search(fn):
+                    match = True
+
+                if not match:
+                    with open(pfn, 'r') as f:
+                        for line in f:
+                            if line.startswith('PACKAGES:'):
+                                packages = line.split(':', 1)[1].strip().split()
+
+                    for pkg in packages:
+                        if keyword_rc.search(pkg):
+                            match = True
+                            break
+                        if os.path.exists(os.path.join(pkgdata_dir, 'runtime', pkg + '.packaged')):
+                            with open(os.path.join(pkgdata_dir, 'runtime', pkg), 'r') as f:
+                                for line in f:
+                                    if ': ' in line:
+                                        splitline = line.split(':', 1)
+                                        key = splitline[0]
+                                        value = splitline[1].strip()
+                                    if key in ['PKG_%s' % pkg, 'DESCRIPTION', 'FILES_INFO'] or key.startswith('FILERPROVIDES_'):
+                                        if keyword_rc.search(value):
+                                            match = True
+                                            break
+                if match:
+                    print_match(fn)
+                    matches.append(fn)
+        else:
+            logger.warning('Package data is not available, results may be limited')
+
+        for recipe in tinfoil.all_recipes():
+            if args.fixed_setup and 'nativesdk' in recipe.inherits():
+                continue
+
+            match = False
+            if keyword_rc.search(recipe.pn):
+                match = True
+            else:
+                for prov in recipe.provides:
+                    if keyword_rc.search(prov):
+                        match = True
+                        break
+                if not match:
+                    for rprov in recipe.rprovides:
+                        if keyword_rc.search(rprov):
+                            match = True
+                            break
+            if match and not recipe.pn in matches:
+                print_match(recipe.pn)
+    finally:
+        tinfoil.shutdown()
+
+    return 0
+
+def register_commands(subparsers, context):
+    """Register devtool subcommands from this plugin"""
+    parser_search = subparsers.add_parser('search', help='Search available recipes',
+                                            description='Searches for available recipes. Matches on recipe name, package name, description and installed files, and prints the recipe name and summary on match.',
+                                            group='info')
+    parser_search.add_argument('keyword', help='Keyword to search for (regular expression syntax allowed, use quotes to avoid shell expansion)')
+    parser_search.set_defaults(func=search, no_workspace=True, fixed_setup=context.fixed_setup)
diff --git a/meta/poky/scripts/lib/devtool/standard.py b/meta/poky/scripts/lib/devtool/standard.py
new file mode 100644
index 0000000..ea09bbf
--- /dev/null
+++ b/meta/poky/scripts/lib/devtool/standard.py
@@ -0,0 +1,2171 @@
+# Development tool - standard commands plugin
+#
+# Copyright (C) 2014-2017 Intel Corporation
+#
+# 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.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+"""Devtool standard plugins"""
+
+import os
+import sys
+import re
+import shutil
+import subprocess
+import tempfile
+import logging
+import argparse
+import argparse_oe
+import scriptutils
+import errno
+import glob
+import filecmp
+from collections import OrderedDict
+from devtool import exec_build_env_command, setup_tinfoil, check_workspace_recipe, use_external_build, setup_git_repo, recipe_to_append, get_bbclassextend_targets, update_unlockedsigs, check_prerelease_version, check_git_repo_dirty, check_git_repo_op, DevtoolError
+from devtool import parse_recipe
+
+logger = logging.getLogger('devtool')
+
+override_branch_prefix = 'devtool-override-'
+
+
+def add(args, config, basepath, workspace):
+    """Entry point for the devtool 'add' subcommand"""
+    import bb
+    import oe.recipeutils
+
+    if not args.recipename and not args.srctree and not args.fetch and not args.fetchuri:
+        raise argparse_oe.ArgumentUsageError('At least one of recipename, srctree, fetchuri or -f/--fetch must be specified', 'add')
+
+    # These are positional arguments, but because we're nice, allow
+    # specifying e.g. source tree without name, or fetch URI without name or
+    # source tree (if we can detect that that is what the user meant)
+    if scriptutils.is_src_url(args.recipename):
+        if not args.fetchuri:
+            if args.fetch:
+                raise DevtoolError('URI specified as positional argument as well as -f/--fetch')
+            args.fetchuri = args.recipename
+            args.recipename = ''
+    elif scriptutils.is_src_url(args.srctree):
+        if not args.fetchuri:
+            if args.fetch:
+                raise DevtoolError('URI specified as positional argument as well as -f/--fetch')
+            args.fetchuri = args.srctree
+            args.srctree = ''
+    elif args.recipename and not args.srctree:
+        if os.sep in args.recipename:
+            args.srctree = args.recipename
+            args.recipename = None
+        elif os.path.isdir(args.recipename):
+            logger.warning('Ambiguous argument "%s" - assuming you mean it to be the recipe name' % args.recipename)
+
+    if not args.fetchuri:
+        if args.srcrev:
+            raise DevtoolError('The -S/--srcrev option is only valid when fetching from an SCM repository')
+        if args.srcbranch:
+            raise DevtoolError('The -B/--srcbranch option is only valid when fetching from an SCM repository')
+
+    if args.srctree and os.path.isfile(args.srctree):
+        args.fetchuri = 'file://' + os.path.abspath(args.srctree)
+        args.srctree = ''
+
+    if args.fetch:
+        if args.fetchuri:
+            raise DevtoolError('URI specified as positional argument as well as -f/--fetch')
+        else:
+            logger.warning('-f/--fetch option is deprecated - you can now simply specify the URL to fetch as a positional argument instead')
+            args.fetchuri = args.fetch
+
+    if args.recipename:
+        if args.recipename in workspace:
+            raise DevtoolError("recipe %s is already in your workspace" %
+                               args.recipename)
+        reason = oe.recipeutils.validate_pn(args.recipename)
+        if reason:
+            raise DevtoolError(reason)
+
+    if args.srctree:
+        srctree = os.path.abspath(args.srctree)
+        srctreeparent = None
+        tmpsrcdir = None
+    else:
+        srctree = None
+        srctreeparent = get_default_srctree(config)
+        bb.utils.mkdirhier(srctreeparent)
+        tmpsrcdir = tempfile.mkdtemp(prefix='devtoolsrc', dir=srctreeparent)
+
+    if srctree and os.path.exists(srctree):
+        if args.fetchuri:
+            if not os.path.isdir(srctree):
+                raise DevtoolError("Cannot fetch into source tree path %s as "
+                                   "it exists and is not a directory" %
+                                   srctree)
+            elif os.listdir(srctree):
+                raise DevtoolError("Cannot fetch into source tree path %s as "
+                                   "it already exists and is non-empty" %
+                                   srctree)
+    elif not args.fetchuri:
+        if args.srctree:
+            raise DevtoolError("Specified source tree %s could not be found" %
+                               args.srctree)
+        elif srctree:
+            raise DevtoolError("No source tree exists at default path %s - "
+                               "either create and populate this directory, "
+                               "or specify a path to a source tree, or a "
+                               "URI to fetch source from" % srctree)
+        else:
+            raise DevtoolError("You must either specify a source tree "
+                               "or a URI to fetch source from")
+
+    if args.version:
+        if '_' in args.version or ' ' in args.version:
+            raise DevtoolError('Invalid version string "%s"' % args.version)
+
+    if args.color == 'auto' and sys.stdout.isatty():
+        color = 'always'
+    else:
+        color = args.color
+    extracmdopts = ''
+    if args.fetchuri:
+        source = args.fetchuri
+        if srctree:
+            extracmdopts += ' -x %s' % srctree
+        else:
+            extracmdopts += ' -x %s' % tmpsrcdir
+    else:
+        source = srctree
+    if args.recipename:
+        extracmdopts += ' -N %s' % args.recipename
+    if args.version:
+        extracmdopts += ' -V %s' % args.version
+    if args.binary:
+        extracmdopts += ' -b'
+    if args.also_native:
+        extracmdopts += ' --also-native'
+    if args.src_subdir:
+        extracmdopts += ' --src-subdir "%s"' % args.src_subdir
+    if args.autorev:
+        extracmdopts += ' -a'
+    if args.fetch_dev:
+        extracmdopts += ' --fetch-dev'
+    if args.mirrors:
+        extracmdopts += ' --mirrors'
+    if args.srcrev:
+        extracmdopts += ' --srcrev %s' % args.srcrev
+    if args.srcbranch:
+        extracmdopts += ' --srcbranch %s' % args.srcbranch
+    if args.provides:
+        extracmdopts += ' --provides %s' % args.provides
+
+    tempdir = tempfile.mkdtemp(prefix='devtool')
+    try:
+        try:
+            stdout, _ = exec_build_env_command(config.init_path, basepath, 'recipetool --color=%s create --devtool -o %s \'%s\' %s' % (color, tempdir, source, extracmdopts), watch=True)
+        except bb.process.ExecutionError as e:
+            if e.exitcode == 15:
+                raise DevtoolError('Could not auto-determine recipe name, please specify it on the command line')
+            else:
+                raise DevtoolError('Command \'%s\' failed' % e.command)
+
+        recipes = glob.glob(os.path.join(tempdir, '*.bb'))
+        if recipes:
+            recipename = os.path.splitext(os.path.basename(recipes[0]))[0].split('_')[0]
+            if recipename in workspace:
+                raise DevtoolError('A recipe with the same name as the one being created (%s) already exists in your workspace' % recipename)
+            recipedir = os.path.join(config.workspace_path, 'recipes', recipename)
+            bb.utils.mkdirhier(recipedir)
+            recipefile = os.path.join(recipedir, os.path.basename(recipes[0]))
+            appendfile = recipe_to_append(recipefile, config)
+            if os.path.exists(appendfile):
+                # This shouldn't be possible, but just in case
+                raise DevtoolError('A recipe with the same name as the one being created already exists in your workspace')
+            if os.path.exists(recipefile):
+                raise DevtoolError('A recipe file %s already exists in your workspace; this shouldn\'t be there - please delete it before continuing' % recipefile)
+            if tmpsrcdir:
+                srctree = os.path.join(srctreeparent, recipename)
+                if os.path.exists(tmpsrcdir):
+                    if os.path.exists(srctree):
+                        if os.path.isdir(srctree):
+                            try:
+                                os.rmdir(srctree)
+                            except OSError as e:
+                                if e.errno == errno.ENOTEMPTY:
+                                    raise DevtoolError('Source tree path %s already exists and is not empty' % srctree)
+                                else:
+                                    raise
+                        else:
+                            raise DevtoolError('Source tree path %s already exists and is not a directory' % srctree)
+                    logger.info('Using default source tree path %s' % srctree)
+                    shutil.move(tmpsrcdir, srctree)
+                else:
+                    raise DevtoolError('Couldn\'t find source tree created by recipetool')
+            bb.utils.mkdirhier(recipedir)
+            shutil.move(recipes[0], recipefile)
+            # Move any additional files created by recipetool
+            for fn in os.listdir(tempdir):
+                shutil.move(os.path.join(tempdir, fn), recipedir)
+        else:
+            raise DevtoolError('Command \'%s\' did not create any recipe file:\n%s' % (e.command, e.stdout))
+        attic_recipe = os.path.join(config.workspace_path, 'attic', recipename, os.path.basename(recipefile))
+        if os.path.exists(attic_recipe):
+            logger.warning('A modified recipe from a previous invocation exists in %s - you may wish to move this over the top of the new recipe if you had changes in it that you want to continue with' % attic_recipe)
+    finally:
+        if tmpsrcdir and os.path.exists(tmpsrcdir):
+            shutil.rmtree(tmpsrcdir)
+        shutil.rmtree(tempdir)
+
+    for fn in os.listdir(recipedir):
+        _add_md5(config, recipename, os.path.join(recipedir, fn))
+
+    tinfoil = setup_tinfoil(config_only=True, basepath=basepath)
+    try:
+        try:
+            rd = tinfoil.parse_recipe_file(recipefile, False)
+        except Exception as e:
+            logger.error(str(e))
+            rd = None
+        if not rd:
+            # Parsing failed. We just created this recipe and we shouldn't
+            # leave it in the workdir or it'll prevent bitbake from starting
+            movefn = '%s.parsefailed' % recipefile
+            logger.error('Parsing newly created recipe failed, moving recipe to %s for reference. If this looks to be caused by the recipe itself, please report this error.' % movefn)
+            shutil.move(recipefile, movefn)
+            return 1
+
+        if args.fetchuri and not args.no_git:
+            setup_git_repo(srctree, args.version, 'devtool', d=tinfoil.config_data)
+
+        initial_rev = None
+        if os.path.exists(os.path.join(srctree, '.git')):
+            (stdout, _) = bb.process.run('git rev-parse HEAD', cwd=srctree)
+            initial_rev = stdout.rstrip()
+
+        if args.src_subdir:
+            srctree = os.path.join(srctree, args.src_subdir)
+
+        bb.utils.mkdirhier(os.path.dirname(appendfile))
+        with open(appendfile, 'w') as f:
+            f.write('inherit externalsrc\n')
+            f.write('EXTERNALSRC = "%s"\n' % srctree)
+
+            b_is_s = use_external_build(args.same_dir, args.no_same_dir, rd)
+            if b_is_s:
+                f.write('EXTERNALSRC_BUILD = "%s"\n' % srctree)
+            if initial_rev:
+                f.write('\n# initial_rev: %s\n' % initial_rev)
+
+            if args.binary:
+                f.write('do_install_append() {\n')
+                f.write('    rm -rf ${D}/.git\n')
+                f.write('    rm -f ${D}/singletask.lock\n')
+                f.write('}\n')
+
+            if bb.data.inherits_class('npm', rd):
+                f.write('do_install_append() {\n')
+                f.write('    # Remove files added to source dir by devtool/externalsrc\n')
+                f.write('    rm -f ${NPM_INSTALLDIR}/singletask.lock\n')
+                f.write('    rm -rf ${NPM_INSTALLDIR}/.git\n')
+                f.write('    rm -rf ${NPM_INSTALLDIR}/oe-local-files\n')
+                f.write('    for symlink in ${EXTERNALSRC_SYMLINKS} ; do\n')
+                f.write('        rm -f ${NPM_INSTALLDIR}/${symlink%%:*}\n')
+                f.write('    done\n')
+                f.write('}\n')
+
+        # Check if the new layer provides recipes whose priorities have been
+        # overriden by PREFERRED_PROVIDER.
+        recipe_name = rd.getVar('PN')
+        provides = rd.getVar('PROVIDES')
+        # Search every item defined in PROVIDES
+        for recipe_provided in provides.split():
+            preferred_provider = 'PREFERRED_PROVIDER_' + recipe_provided
+            current_pprovider = rd.getVar(preferred_provider)
+            if current_pprovider and current_pprovider != recipe_name:
+                if args.fixed_setup:
+                    #if we are inside the eSDK add the new PREFERRED_PROVIDER in the workspace layer.conf
+                    layerconf_file = os.path.join(config.workspace_path, "conf", "layer.conf")
+                    with open(layerconf_file, 'a') as f:
+                        f.write('%s = "%s"\n' % (preferred_provider, recipe_name))
+                else:
+                    logger.warning('Set \'%s\' in order to use the recipe' % preferred_provider)
+                break
+
+        _add_md5(config, recipename, appendfile)
+
+        check_prerelease_version(rd.getVar('PV'), 'devtool add')
+
+        logger.info('Recipe %s has been automatically created; further editing may be required to make it fully functional' % recipefile)
+
+    finally:
+        tinfoil.shutdown()
+
+    return 0
+
+
+def _check_compatible_recipe(pn, d):
+    """Check if the recipe is supported by devtool"""
+    if pn == 'perf':
+        raise DevtoolError("The perf recipe does not actually check out "
+                           "source and thus cannot be supported by this tool",
+                           4)
+
+    if pn in ['kernel-devsrc', 'package-index'] or pn.startswith('gcc-source'):
+        raise DevtoolError("The %s recipe is not supported by this tool" % pn, 4)
+
+    if bb.data.inherits_class('image', d):
+        raise DevtoolError("The %s recipe is an image, and therefore is not "
+                           "supported by this tool" % pn, 4)
+
+    if bb.data.inherits_class('populate_sdk', d):
+        raise DevtoolError("The %s recipe is an SDK, and therefore is not "
+                           "supported by this tool" % pn, 4)
+
+    if bb.data.inherits_class('packagegroup', d):
+        raise DevtoolError("The %s recipe is a packagegroup, and therefore is "
+                           "not supported by this tool" % pn, 4)
+
+    if bb.data.inherits_class('meta', d):
+        raise DevtoolError("The %s recipe is a meta-recipe, and therefore is "
+                           "not supported by this tool" % pn, 4)
+
+    if bb.data.inherits_class('externalsrc', d) and d.getVar('EXTERNALSRC'):
+        # Not an incompatibility error per se, so we don't pass the error code
+        raise DevtoolError("externalsrc is currently enabled for the %s "
+                           "recipe. This prevents the normal do_patch task "
+                           "from working. You will need to disable this "
+                           "first." % pn)
+
+def _dry_run_copy(src, dst, dry_run_outdir, base_outdir):
+    """Common function for copying a file to the dry run output directory"""
+    relpath = os.path.relpath(dst, base_outdir)
+    if relpath.startswith('..'):
+        raise Exception('Incorrect base path %s for path %s' % (base_outdir, dst))
+    dst = os.path.join(dry_run_outdir, relpath)
+    dst_d = os.path.dirname(dst)
+    if dst_d:
+        bb.utils.mkdirhier(dst_d)
+    # Don't overwrite existing files, otherwise in the case of an upgrade
+    # the dry-run written out recipe will be overwritten with an unmodified
+    # version
+    if not os.path.exists(dst):
+        shutil.copy(src, dst)
+
+def _move_file(src, dst, dry_run_outdir=None, base_outdir=None):
+    """Move a file. Creates all the directory components of destination path."""
+    dry_run_suffix = ' (dry-run)' if dry_run_outdir else ''
+    logger.debug('Moving %s to %s%s' % (src, dst, dry_run_suffix))
+    if dry_run_outdir:
+        # We want to copy here, not move
+        _dry_run_copy(src, dst, dry_run_outdir, base_outdir)
+    else:
+        dst_d = os.path.dirname(dst)
+        if dst_d:
+            bb.utils.mkdirhier(dst_d)
+        shutil.move(src, dst)
+
+def _copy_file(src, dst, dry_run_outdir=None):
+    """Copy a file. Creates all the directory components of destination path."""
+    dry_run_suffix = ' (dry-run)' if dry_run_outdir else ''
+    logger.debug('Copying %s to %s%s' % (src, dst, dry_run_suffix))
+    if dry_run_outdir:
+        _dry_run_copy(src, dst, dry_run_outdir, base_outdir)
+    else:
+        dst_d = os.path.dirname(dst)
+        if dst_d:
+            bb.utils.mkdirhier(dst_d)
+        shutil.copy(src, dst)
+
+def _git_ls_tree(repodir, treeish='HEAD', recursive=False):
+    """List contents of a git treeish"""
+    import bb
+    cmd = ['git', 'ls-tree', '-z', treeish]
+    if recursive:
+        cmd.append('-r')
+    out, _ = bb.process.run(cmd, cwd=repodir)
+    ret = {}
+    if out:
+        for line in out.split('\0'):
+            if line:
+                split = line.split(None, 4)
+                ret[split[3]] = split[0:3]
+    return ret
+
+def _git_exclude_path(srctree, path):
+    """Return pathspec (list of paths) that excludes certain path"""
+    # NOTE: "Filtering out" files/paths in this way is not entirely reliable -
+    # we don't catch files that are deleted, for example. A more reliable way
+    # to implement this would be to use "negative pathspecs" which were
+    # introduced in Git v1.9.0. Revisit this when/if the required Git version
+    # becomes greater than that.
+    path = os.path.normpath(path)
+    recurse = True if len(path.split(os.path.sep)) > 1 else False
+    git_files = list(_git_ls_tree(srctree, 'HEAD', recurse).keys())
+    if path in git_files:
+        git_files.remove(path)
+        return git_files
+    else:
+        return ['.']
+
+def _ls_tree(directory):
+    """Recursive listing of files in a directory"""
+    ret = []
+    for root, dirs, files in os.walk(directory):
+        ret.extend([os.path.relpath(os.path.join(root, fname), directory) for
+                    fname in files])
+    return ret
+
+
+def extract(args, config, basepath, workspace):
+    """Entry point for the devtool 'extract' subcommand"""
+    import bb
+
+    tinfoil = setup_tinfoil(basepath=basepath, tracking=True)
+    if not tinfoil:
+        # Error already shown
+        return 1
+    try:
+        rd = parse_recipe(config, tinfoil, args.recipename, True)
+        if not rd:
+            return 1
+
+        srctree = os.path.abspath(args.srctree)
+        initial_rev, _ = _extract_source(srctree, args.keep_temp, args.branch, False, config, basepath, workspace, args.fixed_setup, rd, tinfoil, no_overrides=args.no_overrides)
+        logger.info('Source tree extracted to %s' % srctree)
+
+        if initial_rev:
+            return 0
+        else:
+            return 1
+    finally:
+        tinfoil.shutdown()
+
+def sync(args, config, basepath, workspace):
+    """Entry point for the devtool 'sync' subcommand"""
+    import bb
+
+    tinfoil = setup_tinfoil(basepath=basepath, tracking=True)
+    if not tinfoil:
+        # Error already shown
+        return 1
+    try:
+        rd = parse_recipe(config, tinfoil, args.recipename, True)
+        if not rd:
+            return 1
+
+        srctree = os.path.abspath(args.srctree)
+        initial_rev, _ = _extract_source(srctree, args.keep_temp, args.branch, True, config, basepath, workspace, args.fixed_setup, rd, tinfoil, no_overrides=True)
+        logger.info('Source tree %s synchronized' % srctree)
+
+        if initial_rev:
+            return 0
+        else:
+            return 1
+    finally:
+        tinfoil.shutdown()
+
+
+def _extract_source(srctree, keep_temp, devbranch, sync, config, basepath, workspace, fixed_setup, d, tinfoil, no_overrides=False):
+    """Extract sources of a recipe"""
+    import oe.recipeutils
+    import oe.patch
+
+    pn = d.getVar('PN')
+
+    _check_compatible_recipe(pn, d)
+
+    if sync:
+        if not os.path.exists(srctree):
+                raise DevtoolError("output path %s does not exist" % srctree)
+    else:
+        if os.path.exists(srctree):
+            if not os.path.isdir(srctree):
+                raise DevtoolError("output path %s exists and is not a directory" %
+                                   srctree)
+            elif os.listdir(srctree):
+                raise DevtoolError("output path %s already exists and is "
+                                   "non-empty" % srctree)
+
+        if 'noexec' in (d.getVarFlags('do_unpack', False) or []):
+            raise DevtoolError("The %s recipe has do_unpack disabled, unable to "
+                               "extract source" % pn, 4)
+
+    if not sync:
+        # Prepare for shutil.move later on
+        bb.utils.mkdirhier(srctree)
+        os.rmdir(srctree)
+
+    extra_overrides = []
+    if not no_overrides:
+        history = d.varhistory.variable('SRC_URI')
+        for event in history:
+            if not 'flag' in event:
+                if event['op'].startswith(('_append[', '_prepend[')):
+                    extra_overrides.append(event['op'].split('[')[1].split(']')[0])
+        # We want to remove duplicate overrides. If a recipe had multiple
+        # SRC_URI_override += values it would cause mulitple instances of
+        # overrides. This doesn't play nicely with things like creating a
+        # branch for every instance of DEVTOOL_EXTRA_OVERRIDES.
+        extra_overrides = list(set(extra_overrides))
+        if extra_overrides:
+            logger.info('SRC_URI contains some conditional appends/prepends - will create branches to represent these')
+
+    initial_rev = None
+
+    appendexisted = False
+    recipefile = d.getVar('FILE')
+    appendfile = recipe_to_append(recipefile, config)
+    is_kernel_yocto = bb.data.inherits_class('kernel-yocto', d)
+
+    # We need to redirect WORKDIR, STAMPS_DIR etc. under a temporary
+    # directory so that:
+    # (a) we pick up all files that get unpacked to the WORKDIR, and
+    # (b) we don't disturb the existing build
+    # However, with recipe-specific sysroots the sysroots for the recipe
+    # will be prepared under WORKDIR, and if we used the system temporary
+    # directory (i.e. usually /tmp) as used by mkdtemp by default, then
+    # our attempts to hardlink files into the recipe-specific sysroots
+    # will fail on systems where /tmp is a different filesystem, and it
+    # would have to fall back to copying the files which is a waste of
+    # time. Put the temp directory under the WORKDIR to prevent that from
+    # being a problem.
+    tempbasedir = d.getVar('WORKDIR')
+    bb.utils.mkdirhier(tempbasedir)
+    tempdir = tempfile.mkdtemp(prefix='devtooltmp-', dir=tempbasedir)
+    try:
+        tinfoil.logger.setLevel(logging.WARNING)
+
+        # FIXME this results in a cache reload under control of tinfoil, which is fine
+        # except we don't get the knotty progress bar
+
+        if os.path.exists(appendfile):
+            appendbackup = os.path.join(tempdir, os.path.basename(appendfile) + '.bak')
+            shutil.copyfile(appendfile, appendbackup)
+        else:
+            appendbackup = None
+            bb.utils.mkdirhier(os.path.dirname(appendfile))
+        logger.debug('writing append file %s' % appendfile)
+        with open(appendfile, 'a') as f:
+            f.write('###--- _extract_source\n')
+            f.write('DEVTOOL_TEMPDIR = "%s"\n' % tempdir)
+            f.write('DEVTOOL_DEVBRANCH = "%s"\n' % devbranch)
+            if not is_kernel_yocto:
+                f.write('PATCHTOOL = "git"\n')
+                f.write('PATCH_COMMIT_FUNCTIONS = "1"\n')
+            if extra_overrides:
+                f.write('DEVTOOL_EXTRA_OVERRIDES = "%s"\n' % ':'.join(extra_overrides))
+            f.write('inherit devtool-source\n')
+            f.write('###--- _extract_source\n')
+
+        update_unlockedsigs(basepath, workspace, fixed_setup, [pn])
+
+        sstate_manifests = d.getVar('SSTATE_MANIFESTS')
+        bb.utils.mkdirhier(sstate_manifests)
+        preservestampfile = os.path.join(sstate_manifests, 'preserve-stamps')
+        with open(preservestampfile, 'w') as f:
+            f.write(d.getVar('STAMP'))
+        try:
+            if bb.data.inherits_class('kernel-yocto', d):
+                # We need to generate the kernel config
+                task = 'do_configure'
+            else:
+                task = 'do_patch'
+
+            # Run the fetch + unpack tasks
+            res = tinfoil.build_targets(pn,
+                                        task,
+                                        handle_events=True)
+        finally:
+            if os.path.exists(preservestampfile):
+                os.remove(preservestampfile)
+
+        if not res:
+            raise DevtoolError('Extracting source for %s failed' % pn)
+
+        try:
+            with open(os.path.join(tempdir, 'initial_rev'), 'r') as f:
+                initial_rev = f.read()
+
+            with open(os.path.join(tempdir, 'srcsubdir'), 'r') as f:
+                srcsubdir = f.read()
+        except FileNotFoundError as e:
+            raise DevtoolError('Something went wrong with source extraction - the devtool-source class was not active or did not function correctly:\n%s' % str(e))
+        srcsubdir_rel = os.path.relpath(srcsubdir, os.path.join(tempdir, 'workdir'))
+
+        tempdir_localdir = os.path.join(tempdir, 'oe-local-files')
+        srctree_localdir = os.path.join(srctree, 'oe-local-files')
+
+        if sync:
+            bb.process.run('git fetch file://' + srcsubdir + ' ' + devbranch + ':' + devbranch, cwd=srctree)
+
+            # Move oe-local-files directory to srctree
+            # As the oe-local-files is not part of the constructed git tree,
+            # remove them directly during the synchrounizating might surprise
+            # the users.  Instead, we move it to oe-local-files.bak and remind
+            # user in the log message.
+            if os.path.exists(srctree_localdir + '.bak'):
+                shutil.rmtree(srctree_localdir, srctree_localdir + '.bak')
+
+            if os.path.exists(srctree_localdir):
+                logger.info('Backing up current local file directory %s' % srctree_localdir)
+                shutil.move(srctree_localdir, srctree_localdir + '.bak')
+
+            if os.path.exists(tempdir_localdir):
+                logger.info('Syncing local source files to srctree...')
+                shutil.copytree(tempdir_localdir, srctree_localdir)
+        else:
+            # Move oe-local-files directory to srctree
+            if os.path.exists(tempdir_localdir):
+                logger.info('Adding local source files to srctree...')
+                shutil.move(tempdir_localdir, srcsubdir)
+
+            shutil.move(srcsubdir, srctree)
+
+            if os.path.abspath(d.getVar('S')) == os.path.abspath(d.getVar('WORKDIR')):
+                # If recipe extracts to ${WORKDIR}, symlink the files into the srctree
+                # (otherwise the recipe won't build as expected)
+                local_files_dir = os.path.join(srctree, 'oe-local-files')
+                addfiles = []
+                for root, _, files in os.walk(local_files_dir):
+                    relpth = os.path.relpath(root, local_files_dir)
+                    if relpth != '.':
+                        bb.utils.mkdirhier(os.path.join(srctree, relpth))
+                    for fn in files:
+                        if fn == '.gitignore':
+                            continue
+                        destpth = os.path.join(srctree, relpth, fn)
+                        if os.path.exists(destpth):
+                            os.unlink(destpth)
+                        os.symlink('oe-local-files/%s' % fn, destpth)
+                        addfiles.append(os.path.join(relpth, fn))
+                if addfiles:
+                    bb.process.run('git add %s' % ' '.join(addfiles), cwd=srctree)
+                useroptions = []
+                oe.patch.GitApplyTree.gitCommandUserOptions(useroptions, d=d)
+                bb.process.run('git %s commit -a -m "Committing local file symlinks\n\n%s"' % (' '.join(useroptions), oe.patch.GitApplyTree.ignore_commit_prefix), cwd=srctree)
+
+        if is_kernel_yocto:
+            logger.info('Copying kernel config to srctree')
+            shutil.copy2(os.path.join(tempdir, '.config'), srctree)
+
+    finally:
+        if appendbackup:
+            shutil.copyfile(appendbackup, appendfile)
+        elif os.path.exists(appendfile):
+            os.remove(appendfile)
+        if keep_temp:
+            logger.info('Preserving temporary directory %s' % tempdir)
+        else:
+            shutil.rmtree(tempdir)
+    return initial_rev, srcsubdir_rel
+
+def _add_md5(config, recipename, filename):
+    """Record checksum of a file (or recursively for a directory) to the md5-file of the workspace"""
+    import bb.utils
+
+    def addfile(fn):
+        md5 = bb.utils.md5_file(fn)
+        with open(os.path.join(config.workspace_path, '.devtool_md5'), 'a+') as f:
+            md5_str = '%s|%s|%s\n' % (recipename, os.path.relpath(fn, config.workspace_path), md5)
+            f.seek(0, os.SEEK_SET)
+            if not md5_str in f.read():
+                f.write(md5_str)
+
+    if os.path.isdir(filename):
+        for root, _, files in os.walk(filename):
+            for f in files:
+                addfile(os.path.join(root, f))
+    else:
+        addfile(filename)
+
+def _check_preserve(config, recipename):
+    """Check if a file was manually changed and needs to be saved in 'attic'
+       directory"""
+    import bb.utils
+    origfile = os.path.join(config.workspace_path, '.devtool_md5')
+    newfile = os.path.join(config.workspace_path, '.devtool_md5_new')
+    preservepath = os.path.join(config.workspace_path, 'attic', recipename)
+    with open(origfile, 'r') as f:
+        with open(newfile, 'w') as tf:
+            for line in f.readlines():
+                splitline = line.rstrip().split('|')
+                if splitline[0] == recipename:
+                    removefile = os.path.join(config.workspace_path, splitline[1])
+                    try:
+                        md5 = bb.utils.md5_file(removefile)
+                    except IOError as err:
+                        if err.errno == 2:
+                            # File no longer exists, skip it
+                            continue
+                        else:
+                            raise
+                    if splitline[2] != md5:
+                        bb.utils.mkdirhier(preservepath)
+                        preservefile = os.path.basename(removefile)
+                        logger.warning('File %s modified since it was written, preserving in %s' % (preservefile, preservepath))
+                        shutil.move(removefile, os.path.join(preservepath, preservefile))
+                    else:
+                        os.remove(removefile)
+                else:
+                    tf.write(line)
+    os.rename(newfile, origfile)
+
+def modify(args, config, basepath, workspace):
+    """Entry point for the devtool 'modify' subcommand"""
+    import bb
+    import oe.recipeutils
+    import oe.patch
+
+    if args.recipename in workspace:
+        raise DevtoolError("recipe %s is already in your workspace" %
+                           args.recipename)
+
+    tinfoil = setup_tinfoil(basepath=basepath, tracking=True)
+    try:
+        rd = parse_recipe(config, tinfoil, args.recipename, True)
+        if not rd:
+            return 1
+
+        pn = rd.getVar('PN')
+        if pn != args.recipename:
+            logger.info('Mapping %s to %s' % (args.recipename, pn))
+        if pn in workspace:
+            raise DevtoolError("recipe %s is already in your workspace" %
+                            pn)
+
+        if args.srctree:
+            srctree = os.path.abspath(args.srctree)
+        else:
+            srctree = get_default_srctree(config, pn)
+
+        if args.no_extract and not os.path.isdir(srctree):
+            raise DevtoolError("--no-extract specified and source path %s does "
+                            "not exist or is not a directory" %
+                            srctree)
+
+        recipefile = rd.getVar('FILE')
+        appendfile = recipe_to_append(recipefile, config, args.wildcard)
+        if os.path.exists(appendfile):
+            raise DevtoolError("Another variant of recipe %s is already in your "
+                            "workspace (only one variant of a recipe can "
+                            "currently be worked on at once)"
+                            % pn)
+
+        _check_compatible_recipe(pn, rd)
+
+        initial_rev = None
+        commits = []
+        check_commits = False
+        if not args.no_extract:
+            initial_rev, _ = _extract_source(srctree, args.keep_temp, args.branch, False, config, basepath, workspace, args.fixed_setup, rd, tinfoil, no_overrides=args.no_overrides)
+            if not initial_rev:
+                return 1
+            logger.info('Source tree extracted to %s' % srctree)
+            # Get list of commits since this revision
+            (stdout, _) = bb.process.run('git rev-list --reverse %s..HEAD' % initial_rev, cwd=srctree)
+            commits = stdout.split()
+            check_commits = True
+        else:
+            if os.path.exists(os.path.join(srctree, '.git')):
+                # Check if it's a tree previously extracted by us. This is done
+                # by ensuring that devtool-base and args.branch (devtool) exist.
+                # The check_commits logic will cause an exception if either one
+                # of these doesn't exist
+                try:
+                    (stdout, _) = bb.process.run('git branch --contains devtool-base', cwd=srctree)
+                    bb.process.run('git rev-parse %s' % args.branch, cwd=srctree)
+                except bb.process.ExecutionError:
+                    stdout = ''
+                if stdout:
+                    check_commits = True
+                for line in stdout.splitlines():
+                    if line.startswith('*'):
+                        (stdout, _) = bb.process.run('git rev-parse devtool-base', cwd=srctree)
+                        initial_rev = stdout.rstrip()
+                if not initial_rev:
+                    # Otherwise, just grab the head revision
+                    (stdout, _) = bb.process.run('git rev-parse HEAD', cwd=srctree)
+                    initial_rev = stdout.rstrip()
+
+        branch_patches = {}
+        if check_commits:
+            # Check if there are override branches
+            (stdout, _) = bb.process.run('git branch', cwd=srctree)
+            branches = []
+            for line in stdout.rstrip().splitlines():
+                branchname = line[2:].rstrip()
+                if branchname.startswith(override_branch_prefix):
+                    branches.append(branchname)
+            if branches:
+                logger.warning('SRC_URI is conditionally overridden in this recipe, thus several %s* branches have been created, one for each override that makes changes to SRC_URI. It is recommended that you make changes to the %s branch first, then checkout and rebase each %s* branch and update any unique patches there (duplicates on those branches will be ignored by devtool finish/update-recipe)' % (override_branch_prefix, args.branch, override_branch_prefix))
+            branches.insert(0, args.branch)
+            seen_patches = []
+            for branch in branches:
+                branch_patches[branch] = []
+                (stdout, _) = bb.process.run('git log devtool-base..%s' % branch, cwd=srctree)
+                for line in stdout.splitlines():
+                    line = line.strip()
+                    if line.startswith(oe.patch.GitApplyTree.patch_line_prefix):
+                        origpatch = line[len(oe.patch.GitApplyTree.patch_line_prefix):].split(':', 1)[-1].strip()
+                        if not origpatch in seen_patches:
+                            seen_patches.append(origpatch)
+                            branch_patches[branch].append(origpatch)
+
+        # Need to grab this here in case the source is within a subdirectory
+        srctreebase = srctree
+
+        # Check that recipe isn't using a shared workdir
+        s = os.path.abspath(rd.getVar('S'))
+        workdir = os.path.abspath(rd.getVar('WORKDIR'))
+        if s.startswith(workdir) and s != workdir and os.path.dirname(s) != workdir:
+            # Handle if S is set to a subdirectory of the source
+            srcsubdir = os.path.relpath(s, workdir).split(os.sep, 1)[1]
+            srctree = os.path.join(srctree, srcsubdir)
+
+        bb.utils.mkdirhier(os.path.dirname(appendfile))
+        with open(appendfile, 'w') as f:
+            f.write('FILESEXTRAPATHS_prepend := "${THISDIR}/${PN}:"\n')
+            # Local files can be modified/tracked in separate subdir under srctree
+            # Mostly useful for packages with S != WORKDIR
+            f.write('FILESPATH_prepend := "%s:"\n' %
+                    os.path.join(srctreebase, 'oe-local-files'))
+            f.write('# srctreebase: %s\n' % srctreebase)
+
+            f.write('\ninherit externalsrc\n')
+            f.write('# NOTE: We use pn- overrides here to avoid affecting multiple variants in the case where the recipe uses BBCLASSEXTEND\n')
+            f.write('EXTERNALSRC_pn-%s = "%s"\n' % (pn, srctree))
+
+            b_is_s = use_external_build(args.same_dir, args.no_same_dir, rd)
+            if b_is_s:
+                f.write('EXTERNALSRC_BUILD_pn-%s = "%s"\n' % (pn, srctree))
+
+            if bb.data.inherits_class('kernel', rd):
+                f.write('SRCTREECOVEREDTASKS = "do_validate_branches do_kernel_checkout '
+                        'do_fetch do_unpack do_kernel_configme do_kernel_configcheck"\n')
+                f.write('\ndo_patch[noexec] = "1"\n')
+                f.write('\ndo_configure_append() {\n'
+                        '    cp ${B}/.config ${S}/.config.baseline\n'
+                        '    ln -sfT ${B}/.config ${S}/.config.new\n'
+                        '}\n')
+            if initial_rev:
+                f.write('\n# initial_rev: %s\n' % initial_rev)
+                for commit in commits:
+                    f.write('# commit: %s\n' % commit)
+            if branch_patches:
+                for branch in branch_patches:
+                    if branch == args.branch:
+                        continue
+                    f.write('# patches_%s: %s\n' % (branch, ','.join(branch_patches[branch])))
+
+        update_unlockedsigs(basepath, workspace, args.fixed_setup, [pn])
+
+        _add_md5(config, pn, appendfile)
+
+        logger.info('Recipe %s now set up to build from %s' % (pn, srctree))
+
+    finally:
+        tinfoil.shutdown()
+
+    return 0
+
+
+def rename(args, config, basepath, workspace):
+    """Entry point for the devtool 'rename' subcommand"""
+    import bb
+    import oe.recipeutils
+
+    check_workspace_recipe(workspace, args.recipename)
+
+    if not (args.newname or args.version):
+        raise DevtoolError('You must specify a new name, a version with -V/--version, or both')
+
+    recipefile = workspace[args.recipename]['recipefile']
+    if not recipefile:
+        raise DevtoolError('devtool rename can only be used where the recipe file itself is in the workspace (e.g. after devtool add)')
+
+    if args.newname and args.newname != args.recipename:
+        reason = oe.recipeutils.validate_pn(args.newname)
+        if reason:
+            raise DevtoolError(reason)
+        newname = args.newname
+    else:
+        newname = args.recipename
+
+    append = workspace[args.recipename]['bbappend']
+    appendfn = os.path.splitext(os.path.basename(append))[0]
+    splitfn = appendfn.split('_')
+    if len(splitfn) > 1:
+        origfnver = appendfn.split('_')[1]
+    else:
+        origfnver = ''
+
+    recipefilemd5 = None
+    tinfoil = setup_tinfoil(basepath=basepath, tracking=True)
+    try:
+        rd = parse_recipe(config, tinfoil, args.recipename, True)
+        if not rd:
+            return 1
+
+        bp = rd.getVar('BP')
+        bpn = rd.getVar('BPN')
+        if newname != args.recipename:
+            localdata = rd.createCopy()
+            localdata.setVar('PN', newname)
+            newbpn = localdata.getVar('BPN')
+        else:
+            newbpn = bpn
+        s = rd.getVar('S', False)
+        src_uri = rd.getVar('SRC_URI', False)
+        pv = rd.getVar('PV')
+
+        # Correct variable values that refer to the upstream source - these
+        # values must stay the same, so if the name/version are changing then
+        # we need to fix them up
+        new_s = s
+        new_src_uri = src_uri
+        if newbpn != bpn:
+            # ${PN} here is technically almost always incorrect, but people do use it
+            new_s = new_s.replace('${BPN}', bpn)
+            new_s = new_s.replace('${PN}', bpn)
+            new_s = new_s.replace('${BP}', '%s-${PV}' % bpn)
+            new_src_uri = new_src_uri.replace('${BPN}', bpn)
+            new_src_uri = new_src_uri.replace('${PN}', bpn)
+            new_src_uri = new_src_uri.replace('${BP}', '%s-${PV}' % bpn)
+        if args.version and origfnver == pv:
+            new_s = new_s.replace('${PV}', pv)
+            new_s = new_s.replace('${BP}', '${BPN}-%s' % pv)
+            new_src_uri = new_src_uri.replace('${PV}', pv)
+            new_src_uri = new_src_uri.replace('${BP}', '${BPN}-%s' % pv)
+        patchfields = {}
+        if new_s != s:
+            patchfields['S'] = new_s
+        if new_src_uri != src_uri:
+            patchfields['SRC_URI'] = new_src_uri
+        if patchfields:
+            recipefilemd5 = bb.utils.md5_file(recipefile)
+            oe.recipeutils.patch_recipe(rd, recipefile, patchfields)
+            newrecipefilemd5 = bb.utils.md5_file(recipefile)
+    finally:
+        tinfoil.shutdown()
+
+    if args.version:
+        newver = args.version
+    else:
+        newver = origfnver
+
+    if newver:
+        newappend = '%s_%s.bbappend' % (newname, newver)
+        newfile =  '%s_%s.bb' % (newname, newver)
+    else:
+        newappend = '%s.bbappend' % newname
+        newfile = '%s.bb' % newname
+
+    oldrecipedir = os.path.dirname(recipefile)
+    newrecipedir = os.path.join(config.workspace_path, 'recipes', newname)
+    if oldrecipedir != newrecipedir:
+        bb.utils.mkdirhier(newrecipedir)
+
+    newappend = os.path.join(os.path.dirname(append), newappend)
+    newfile = os.path.join(newrecipedir, newfile)
+
+    # Rename bbappend
+    logger.info('Renaming %s to %s' % (append, newappend))
+    os.rename(append, newappend)
+    # Rename recipe file
+    logger.info('Renaming %s to %s' % (recipefile, newfile))
+    os.rename(recipefile, newfile)
+
+    # Rename source tree if it's the default path
+    appendmd5 = None
+    if not args.no_srctree:
+        srctree = workspace[args.recipename]['srctree']
+        if os.path.abspath(srctree) == os.path.join(config.workspace_path, 'sources', args.recipename):
+            newsrctree = os.path.join(config.workspace_path, 'sources', newname)
+            logger.info('Renaming %s to %s' % (srctree, newsrctree))
+            shutil.move(srctree, newsrctree)
+            # Correct any references (basically EXTERNALSRC*) in the .bbappend
+            appendmd5 = bb.utils.md5_file(newappend)
+            appendlines = []
+            with open(newappend, 'r') as f:
+                for line in f:
+                    appendlines.append(line)
+            with open(newappend, 'w') as f:
+                for line in appendlines:
+                    if srctree in line:
+                        line = line.replace(srctree, newsrctree)
+                    f.write(line)
+            newappendmd5 = bb.utils.md5_file(newappend)
+
+    bpndir = None
+    newbpndir = None
+    if newbpn != bpn:
+        bpndir = os.path.join(oldrecipedir, bpn)
+        if os.path.exists(bpndir):
+            newbpndir = os.path.join(newrecipedir, newbpn)
+            logger.info('Renaming %s to %s' % (bpndir, newbpndir))
+            shutil.move(bpndir, newbpndir)
+
+    bpdir = None
+    newbpdir = None
+    if newver != origfnver or newbpn != bpn:
+        bpdir = os.path.join(oldrecipedir, bp)
+        if os.path.exists(bpdir):
+            newbpdir = os.path.join(newrecipedir, '%s-%s' % (newbpn, newver))
+            logger.info('Renaming %s to %s' % (bpdir, newbpdir))
+            shutil.move(bpdir, newbpdir)
+
+    if oldrecipedir != newrecipedir:
+        # Move any stray files and delete the old recipe directory
+        for entry in os.listdir(oldrecipedir):
+            oldpath = os.path.join(oldrecipedir, entry)
+            newpath = os.path.join(newrecipedir, entry)
+            logger.info('Renaming %s to %s' % (oldpath, newpath))
+            shutil.move(oldpath, newpath)
+        os.rmdir(oldrecipedir)
+
+    # Now take care of entries in .devtool_md5
+    md5entries = []
+    with open(os.path.join(config.workspace_path, '.devtool_md5'), 'r') as f:
+        for line in f:
+            md5entries.append(line)
+
+    if bpndir and newbpndir:
+        relbpndir = os.path.relpath(bpndir, config.workspace_path) + '/'
+    else:
+        relbpndir = None
+    if bpdir and newbpdir:
+        relbpdir = os.path.relpath(bpdir, config.workspace_path) + '/'
+    else:
+        relbpdir = None
+
+    with open(os.path.join(config.workspace_path, '.devtool_md5'), 'w') as f:
+        for entry in md5entries:
+            splitentry = entry.rstrip().split('|')
+            if len(splitentry) > 2:
+                if splitentry[0] == args.recipename:
+                    splitentry[0] = newname
+                    if splitentry[1] == os.path.relpath(append, config.workspace_path):
+                        splitentry[1] = os.path.relpath(newappend, config.workspace_path)
+                        if appendmd5 and splitentry[2] == appendmd5:
+                            splitentry[2] = newappendmd5
+                    elif splitentry[1] == os.path.relpath(recipefile, config.workspace_path):
+                        splitentry[1] = os.path.relpath(newfile, config.workspace_path)
+                        if recipefilemd5 and splitentry[2] == recipefilemd5:
+                            splitentry[2] = newrecipefilemd5
+                    elif relbpndir and splitentry[1].startswith(relbpndir):
+                        splitentry[1] = os.path.relpath(os.path.join(newbpndir, splitentry[1][len(relbpndir):]), config.workspace_path)
+                    elif relbpdir and splitentry[1].startswith(relbpdir):
+                        splitentry[1] = os.path.relpath(os.path.join(newbpdir, splitentry[1][len(relbpdir):]), config.workspace_path)
+                    entry = '|'.join(splitentry) + '\n'
+            f.write(entry)
+    return 0
+
+
+def _get_patchset_revs(srctree, recipe_path, initial_rev=None, force_patch_refresh=False):
+    """Get initial and update rev of a recipe. These are the start point of the
+    whole patchset and start point for the patches to be re-generated/updated.
+    """
+    import bb
+
+    # Get current branch
+    stdout, _ = bb.process.run('git rev-parse --abbrev-ref HEAD',
+                               cwd=srctree)
+    branchname = stdout.rstrip()
+
+    # Parse initial rev from recipe if not specified
+    commits = []
+    patches = []
+    with open(recipe_path, 'r') as f:
+        for line in f:
+            if line.startswith('# initial_rev:'):
+                if not initial_rev:
+                    initial_rev = line.split(':')[-1].strip()
+            elif line.startswith('# commit:') and not force_patch_refresh:
+                commits.append(line.split(':')[-1].strip())
+            elif line.startswith('# patches_%s:' % branchname):
+                patches = line.split(':')[-1].strip().split(',')
+
+    update_rev = initial_rev
+    changed_revs = None
+    if initial_rev:
+        # Find first actually changed revision
+        stdout, _ = bb.process.run('git rev-list --reverse %s..HEAD' %
+                                   initial_rev, cwd=srctree)
+        newcommits = stdout.split()
+        for i in range(min(len(commits), len(newcommits))):
+            if newcommits[i] == commits[i]:
+                update_rev = commits[i]
+
+        try:
+            stdout, _ = bb.process.run('git cherry devtool-patched',
+                                        cwd=srctree)
+        except bb.process.ExecutionError as err:
+            stdout = None
+
+        if stdout is not None and not force_patch_refresh:
+            changed_revs = []
+            for line in stdout.splitlines():
+                if line.startswith('+ '):
+                    rev = line.split()[1]
+                    if rev in newcommits:
+                        changed_revs.append(rev)
+
+    return initial_rev, update_rev, changed_revs, patches
+
+def _remove_file_entries(srcuri, filelist):
+    """Remove file:// entries from SRC_URI"""
+    remaining = filelist[:]
+    entries = []
+    for fname in filelist:
+        basename = os.path.basename(fname)
+        for i in range(len(srcuri)):
+            if (srcuri[i].startswith('file://') and
+                    os.path.basename(srcuri[i].split(';')[0]) == basename):
+                entries.append(srcuri[i])
+                remaining.remove(fname)
+                srcuri.pop(i)
+                break
+    return entries, remaining
+
+def _replace_srcuri_entry(srcuri, filename, newentry):
+    """Replace entry corresponding to specified file with a new entry"""
+    basename = os.path.basename(filename)
+    for i in range(len(srcuri)):
+        if os.path.basename(srcuri[i].split(';')[0]) == basename:
+            srcuri.pop(i)
+            srcuri.insert(i, newentry)
+            break
+
+def _remove_source_files(append, files, destpath, no_report_remove=False, dry_run=False):
+    """Unlink existing patch files"""
+
+    dry_run_suffix = ' (dry-run)' if dry_run else ''
+
+    for path in files:
+        if append:
+            if not destpath:
+                raise Exception('destpath should be set here')
+            path = os.path.join(destpath, os.path.basename(path))
+
+        if os.path.exists(path):
+            if not no_report_remove:
+                logger.info('Removing file %s%s' % (path, dry_run_suffix))
+            if not dry_run:
+                # FIXME "git rm" here would be nice if the file in question is
+                #       tracked
+                # FIXME there's a chance that this file is referred to by
+                #       another recipe, in which case deleting wouldn't be the
+                #       right thing to do
+                os.remove(path)
+                # Remove directory if empty
+                try:
+                    os.rmdir(os.path.dirname(path))
+                except OSError as ose:
+                    if ose.errno != errno.ENOTEMPTY:
+                        raise
+
+
+def _export_patches(srctree, rd, start_rev, destdir, changed_revs=None):
+    """Export patches from srctree to given location.
+       Returns three-tuple of dicts:
+         1. updated - patches that already exist in SRCURI
+         2. added - new patches that don't exist in SRCURI
+         3  removed - patches that exist in SRCURI but not in exported patches
+      In each dict the key is the 'basepath' of the URI and value is the
+      absolute path to the existing file in recipe space (if any).
+    """
+    import oe.recipeutils
+    from oe.patch import GitApplyTree
+    updated = OrderedDict()
+    added = OrderedDict()
+    seqpatch_re = re.compile('^([0-9]{4}-)?(.+)')
+
+    existing_patches = dict((os.path.basename(path), path) for path in
+                            oe.recipeutils.get_recipe_patches(rd))
+    logger.debug('Existing patches: %s' % existing_patches)
+
+    # Generate patches from Git, exclude local files directory
+    patch_pathspec = _git_exclude_path(srctree, 'oe-local-files')
+    GitApplyTree.extractPatches(srctree, start_rev, destdir, patch_pathspec)
+
+    new_patches = sorted(os.listdir(destdir))
+    for new_patch in new_patches:
+        # Strip numbering from patch names. If it's a git sequence named patch,
+        # the numbers might not match up since we are starting from a different
+        # revision This does assume that people are using unique shortlog
+        # values, but they ought to be anyway...
+        new_basename = seqpatch_re.match(new_patch).group(2)
+        match_name = None
+        for old_patch in existing_patches:
+            old_basename = seqpatch_re.match(old_patch).group(2)
+            old_basename_splitext = os.path.splitext(old_basename)
+            if old_basename.endswith(('.gz', '.bz2', '.Z')) and old_basename_splitext[0] == new_basename:
+                old_patch_noext = os.path.splitext(old_patch)[0]
+                match_name = old_patch_noext
+                break
+            elif new_basename == old_basename:
+                match_name = old_patch
+                break
+        if match_name:
+            # Rename patch files
+            if new_patch != match_name:
+                os.rename(os.path.join(destdir, new_patch),
+                          os.path.join(destdir, match_name))
+            # Need to pop it off the list now before checking changed_revs
+            oldpath = existing_patches.pop(old_patch)
+            if changed_revs is not None:
+                # Avoid updating patches that have not actually changed
+                with open(os.path.join(destdir, match_name), 'r') as f:
+                    firstlineitems = f.readline().split()
+                    # Looking for "From <hash>" line
+                    if len(firstlineitems) > 1 and len(firstlineitems[1]) == 40:
+                        if not firstlineitems[1] in changed_revs:
+                            continue
+            # Recompress if necessary
+            if oldpath.endswith(('.gz', '.Z')):
+                bb.process.run(['gzip', match_name], cwd=destdir)
+                if oldpath.endswith('.gz'):
+                    match_name += '.gz'
+                else:
+                    match_name += '.Z'
+            elif oldpath.endswith('.bz2'):
+                bb.process.run(['bzip2', match_name], cwd=destdir)
+                match_name += '.bz2'
+            updated[match_name] = oldpath
+        else:
+            added[new_patch] = None
+    return (updated, added, existing_patches)
+
+
+def _create_kconfig_diff(srctree, rd, outfile):
+    """Create a kconfig fragment"""
+    # Only update config fragment if both config files exist
+    orig_config = os.path.join(srctree, '.config.baseline')
+    new_config = os.path.join(srctree, '.config.new')
+    if os.path.exists(orig_config) and os.path.exists(new_config):
+        cmd = ['diff', '--new-line-format=%L', '--old-line-format=',
+               '--unchanged-line-format=', orig_config, new_config]
+        pipe = subprocess.Popen(cmd, stdout=subprocess.PIPE,
+                                stderr=subprocess.PIPE)
+        stdout, stderr = pipe.communicate()
+        if pipe.returncode == 1:
+            logger.info("Updating config fragment %s" % outfile)
+            with open(outfile, 'wb') as fobj:
+                fobj.write(stdout)
+        elif pipe.returncode == 0:
+            logger.info("Would remove config fragment %s" % outfile)
+            if os.path.exists(outfile):
+                # Remove fragment file in case of empty diff
+                logger.info("Removing config fragment %s" % outfile)
+                os.unlink(outfile)
+        else:
+            raise bb.process.ExecutionError(cmd, pipe.returncode, stdout, stderr)
+        return True
+    return False
+
+
+def _export_local_files(srctree, rd, destdir, srctreebase):
+    """Copy local files from srctree to given location.
+       Returns three-tuple of dicts:
+         1. updated - files that already exist in SRCURI
+         2. added - new files files that don't exist in SRCURI
+         3  removed - files that exist in SRCURI but not in exported files
+      In each dict the key is the 'basepath' of the URI and value is the
+      absolute path to the existing file in recipe space (if any).
+    """
+    import oe.recipeutils
+
+    # Find out local files (SRC_URI files that exist in the "recipe space").
+    # Local files that reside in srctree are not included in patch generation.
+    # Instead they are directly copied over the original source files (in
+    # recipe space).
+    existing_files = oe.recipeutils.get_recipe_local_files(rd)
+    new_set = None
+    updated = OrderedDict()
+    added = OrderedDict()
+    removed = OrderedDict()
+    local_files_dir = os.path.join(srctreebase, 'oe-local-files')
+    git_files = _git_ls_tree(srctree)
+    if 'oe-local-files' in git_files:
+        # If tracked by Git, take the files from srctree HEAD. First get
+        # the tree object of the directory
+        tmp_index = os.path.join(srctree, '.git', 'index.tmp.devtool')
+        tree = git_files['oe-local-files'][2]
+        bb.process.run(['git', 'checkout', tree, '--', '.'], cwd=srctree,
+                        env=dict(os.environ, GIT_WORK_TREE=destdir,
+                                 GIT_INDEX_FILE=tmp_index))
+        new_set = list(_git_ls_tree(srctree, tree, True).keys())
+    elif os.path.isdir(local_files_dir):
+        # If not tracked by Git, just copy from working copy
+        new_set = _ls_tree(local_files_dir)
+        bb.process.run(['cp', '-ax',
+                        os.path.join(local_files_dir, '.'), destdir])
+    else:
+        new_set = []
+
+    # Special handling for kernel config
+    if bb.data.inherits_class('kernel-yocto', rd):
+        fragment_fn = 'devtool-fragment.cfg'
+        fragment_path = os.path.join(destdir, fragment_fn)
+        if _create_kconfig_diff(srctree, rd, fragment_path):
+            if os.path.exists(fragment_path):
+                if fragment_fn not in new_set:
+                    new_set.append(fragment_fn)
+                # Copy fragment to local-files
+                if os.path.isdir(local_files_dir):
+                    shutil.copy2(fragment_path, local_files_dir)
+            else:
+                if fragment_fn in new_set:
+                    new_set.remove(fragment_fn)
+                # Remove fragment from local-files
+                if os.path.exists(os.path.join(local_files_dir, fragment_fn)):
+                    os.unlink(os.path.join(local_files_dir, fragment_fn))
+
+    if new_set is not None:
+        for fname in new_set:
+            if fname in existing_files:
+                origpath = existing_files.pop(fname)
+                workpath = os.path.join(local_files_dir, fname)
+                if not filecmp.cmp(origpath, workpath):
+                    updated[fname] = origpath
+            elif fname != '.gitignore':
+                added[fname] = None
+
+        workdir = rd.getVar('WORKDIR')
+        s = rd.getVar('S')
+        if not s.endswith(os.sep):
+            s += os.sep
+
+        if workdir != s:
+            # Handle files where subdir= was specified
+            for fname in list(existing_files.keys()):
+                # FIXME handle both subdir starting with BP and not?
+                fworkpath = os.path.join(workdir, fname)
+                if fworkpath.startswith(s):
+                    fpath = os.path.join(srctree, os.path.relpath(fworkpath, s))
+                    if os.path.exists(fpath):
+                        origpath = existing_files.pop(fname)
+                        if not filecmp.cmp(origpath, fpath):
+                            updated[fpath] = origpath
+
+        removed = existing_files
+    return (updated, added, removed)
+
+
+def _determine_files_dir(rd):
+    """Determine the appropriate files directory for a recipe"""
+    recipedir = rd.getVar('FILE_DIRNAME')
+    for entry in rd.getVar('FILESPATH').split(':'):
+        relpth = os.path.relpath(entry, recipedir)
+        if not os.sep in relpth:
+            # One (or zero) levels below only, so we don't put anything in machine-specific directories
+            if os.path.isdir(entry):
+                return entry
+    return os.path.join(recipedir, rd.getVar('BPN'))
+
+
+def _update_recipe_srcrev(recipename, workspace, srctree, rd, appendlayerdir, wildcard_version, no_remove, no_report_remove, dry_run_outdir=None):
+    """Implement the 'srcrev' mode of update-recipe"""
+    import bb
+    import oe.recipeutils
+
+    dry_run_suffix = ' (dry-run)' if dry_run_outdir else ''
+
+    recipefile = rd.getVar('FILE')
+    recipedir = os.path.basename(recipefile)
+    logger.info('Updating SRCREV in recipe %s%s' % (recipedir, dry_run_suffix))
+
+    # Get HEAD revision
+    try:
+        stdout, _ = bb.process.run('git rev-parse HEAD', cwd=srctree)
+    except bb.process.ExecutionError as err:
+        raise DevtoolError('Failed to get HEAD revision in %s: %s' %
+                           (srctree, err))
+    srcrev = stdout.strip()
+    if len(srcrev) != 40:
+        raise DevtoolError('Invalid hash returned by git: %s' % stdout)
+
+    destpath = None
+    remove_files = []
+    patchfields = {}
+    patchfields['SRCREV'] = srcrev
+    orig_src_uri = rd.getVar('SRC_URI', False) or ''
+    srcuri = orig_src_uri.split()
+    tempdir = tempfile.mkdtemp(prefix='devtool')
+    update_srcuri = False
+    appendfile = None
+    try:
+        local_files_dir = tempfile.mkdtemp(dir=tempdir)
+        srctreebase = workspace[recipename]['srctreebase']
+        upd_f, new_f, del_f = _export_local_files(srctree, rd, local_files_dir, srctreebase)
+        if not no_remove:
+            # Find list of existing patches in recipe file
+            patches_dir = tempfile.mkdtemp(dir=tempdir)
+            old_srcrev = rd.getVar('SRCREV') or ''
+            upd_p, new_p, del_p = _export_patches(srctree, rd, old_srcrev,
+                                                  patches_dir)
+            logger.debug('Patches: update %s, new %s, delete %s' % (dict(upd_p), dict(new_p), dict(del_p)))
+
+            # Remove deleted local files and "overlapping" patches
+            remove_files = list(del_f.values()) + list(upd_p.values()) + list(del_p.values())
+            if remove_files:
+                removedentries = _remove_file_entries(srcuri, remove_files)[0]
+                update_srcuri = True
+
+        if appendlayerdir:
+            files = dict((os.path.join(local_files_dir, key), val) for
+                          key, val in list(upd_f.items()) + list(new_f.items()))
+            removevalues = {}
+            if update_srcuri:
+                removevalues  = {'SRC_URI': removedentries}
+                patchfields['SRC_URI'] = '\\\n    '.join(srcuri)
+            if dry_run_outdir:
+                logger.info('Creating bbappend (dry-run)')
+            else:
+                appendfile, destpath = oe.recipeutils.bbappend_recipe(
+                        rd, appendlayerdir, files, wildcardver=wildcard_version,
+                        extralines=patchfields, removevalues=removevalues,
+                        redirect_output=dry_run_outdir)
+        else:
+            files_dir = _determine_files_dir(rd)
+            for basepath, path in upd_f.items():
+                logger.info('Updating file %s%s' % (basepath, dry_run_suffix))
+                if os.path.isabs(basepath):
+                    # Original file (probably with subdir pointing inside source tree)
+                    # so we do not want to move it, just copy
+                    _copy_file(basepath, path, dry_run_outdir=dry_run_outdir, base_outdir=recipedir)
+                else:
+                    _move_file(os.path.join(local_files_dir, basepath), path,
+                               dry_run_outdir=dry_run_outdir, base_outdir=recipedir)
+                update_srcuri= True
+            for basepath, path in new_f.items():
+                logger.info('Adding new file %s%s' % (basepath, dry_run_suffix))
+                _move_file(os.path.join(local_files_dir, basepath),
+                           os.path.join(files_dir, basepath),
+                           dry_run_outdir=dry_run_outdir,
+                           base_outdir=recipedir)
+                srcuri.append('file://%s' % basepath)
+                update_srcuri = True
+            if update_srcuri:
+                patchfields['SRC_URI'] = ' '.join(srcuri)
+            ret = oe.recipeutils.patch_recipe(rd, recipefile, patchfields, redirect_output=dry_run_outdir)
+    finally:
+        shutil.rmtree(tempdir)
+    if not 'git://' in orig_src_uri:
+        logger.info('You will need to update SRC_URI within the recipe to '
+                    'point to a git repository where you have pushed your '
+                    'changes')
+
+    _remove_source_files(appendlayerdir, remove_files, destpath, no_report_remove, dry_run=dry_run_outdir)
+    return True, appendfile, remove_files
+
+def _update_recipe_patch(recipename, workspace, srctree, rd, appendlayerdir, wildcard_version, no_remove, no_report_remove, initial_rev, dry_run_outdir=None, force_patch_refresh=False):
+    """Implement the 'patch' mode of update-recipe"""
+    import bb
+    import oe.recipeutils
+
+    recipefile = rd.getVar('FILE')
+    recipedir = os.path.dirname(recipefile)
+    append = workspace[recipename]['bbappend']
+    if not os.path.exists(append):
+        raise DevtoolError('unable to find workspace bbappend for recipe %s' %
+                           recipename)
+
+    initial_rev, update_rev, changed_revs, filter_patches = _get_patchset_revs(srctree, append, initial_rev, force_patch_refresh)
+    if not initial_rev:
+        raise DevtoolError('Unable to find initial revision - please specify '
+                           'it with --initial-rev')
+
+    appendfile = None
+    dl_dir = rd.getVar('DL_DIR')
+    if not dl_dir.endswith('/'):
+        dl_dir += '/'
+
+    dry_run_suffix = ' (dry-run)' if dry_run_outdir else ''
+
+    tempdir = tempfile.mkdtemp(prefix='devtool')
+    try:
+        local_files_dir = tempfile.mkdtemp(dir=tempdir)
+        if filter_patches:
+            upd_f = {}
+            new_f = {}
+            del_f = {}
+        else:
+            srctreebase = workspace[recipename]['srctreebase']
+            upd_f, new_f, del_f = _export_local_files(srctree, rd, local_files_dir, srctreebase)
+
+        remove_files = []
+        if not no_remove:
+            # Get all patches from source tree and check if any should be removed
+            all_patches_dir = tempfile.mkdtemp(dir=tempdir)
+            _, _, del_p = _export_patches(srctree, rd, initial_rev,
+                                          all_patches_dir)
+            # Remove deleted local files and  patches
+            remove_files = list(del_f.values()) + list(del_p.values())
+
+        # Get updated patches from source tree
+        patches_dir = tempfile.mkdtemp(dir=tempdir)
+        upd_p, new_p, _ = _export_patches(srctree, rd, update_rev,
+                                          patches_dir, changed_revs)
+        logger.debug('Pre-filtering: update: %s, new: %s' % (dict(upd_p), dict(new_p)))
+        if filter_patches:
+            new_p = {}
+            upd_p = {k:v for k,v in upd_p.items() if k in filter_patches}
+            remove_files = [f for f in remove_files if f in filter_patches]
+        updatefiles = False
+        updaterecipe = False
+        destpath = None
+        srcuri = (rd.getVar('SRC_URI', False) or '').split()
+        if appendlayerdir:
+            files = dict((os.path.join(local_files_dir, key), val) for
+                         key, val in list(upd_f.items()) + list(new_f.items()))
+            files.update(dict((os.path.join(patches_dir, key), val) for
+                              key, val in list(upd_p.items()) + list(new_p.items())))
+            if files or remove_files:
+                removevalues = None
+                if remove_files:
+                    removedentries, remaining = _remove_file_entries(
+                                                    srcuri, remove_files)
+                    if removedentries or remaining:
+                        remaining = ['file://' + os.path.basename(item) for
+                                     item in remaining]
+                        removevalues = {'SRC_URI': removedentries + remaining}
+                appendfile, destpath = oe.recipeutils.bbappend_recipe(
+                                rd, appendlayerdir, files,
+                                wildcardver=wildcard_version,
+                                removevalues=removevalues,
+                                redirect_output=dry_run_outdir)
+            else:
+                logger.info('No patches or local source files needed updating')
+        else:
+            # Update existing files
+            files_dir = _determine_files_dir(rd)
+            for basepath, path in upd_f.items():
+                logger.info('Updating file %s' % basepath)
+                if os.path.isabs(basepath):
+                    # Original file (probably with subdir pointing inside source tree)
+                    # so we do not want to move it, just copy
+                    _copy_file(basepath, path,
+                               dry_run_outdir=dry_run_outdir, base_outdir=recipedir)
+                else:
+                    _move_file(os.path.join(local_files_dir, basepath), path,
+                               dry_run_outdir=dry_run_outdir, base_outdir=recipedir)
+                updatefiles = True
+            for basepath, path in upd_p.items():
+                patchfn = os.path.join(patches_dir, basepath)
+                if os.path.dirname(path) + '/' == dl_dir:
+                    # This is a a downloaded patch file - we now need to
+                    # replace the entry in SRC_URI with our local version
+                    logger.info('Replacing remote patch %s with updated local version' % basepath)
+                    path = os.path.join(files_dir, basepath)
+                    _replace_srcuri_entry(srcuri, basepath, 'file://%s' % basepath)
+                    updaterecipe = True
+                else:
+                    logger.info('Updating patch %s%s' % (basepath, dry_run_suffix))
+                _move_file(patchfn, path,
+                           dry_run_outdir=dry_run_outdir, base_outdir=recipedir)
+                updatefiles = True
+            # Add any new files
+            for basepath, path in new_f.items():
+                logger.info('Adding new file %s%s' % (basepath, dry_run_suffix))
+                _move_file(os.path.join(local_files_dir, basepath),
+                           os.path.join(files_dir, basepath),
+                           dry_run_outdir=dry_run_outdir,
+                           base_outdir=recipedir)
+                srcuri.append('file://%s' % basepath)
+                updaterecipe = True
+            for basepath, path in new_p.items():
+                logger.info('Adding new patch %s%s' % (basepath, dry_run_suffix))
+                _move_file(os.path.join(patches_dir, basepath),
+                           os.path.join(files_dir, basepath),
+                           dry_run_outdir=dry_run_outdir,
+                           base_outdir=recipedir)
+                srcuri.append('file://%s' % basepath)
+                updaterecipe = True
+            # Update recipe, if needed
+            if _remove_file_entries(srcuri, remove_files)[0]:
+                updaterecipe = True
+            if updaterecipe:
+                if not dry_run_outdir:
+                    logger.info('Updating recipe %s' % os.path.basename(recipefile))
+                ret = oe.recipeutils.patch_recipe(rd, recipefile,
+                                                  {'SRC_URI': ' '.join(srcuri)},
+                                                  redirect_output=dry_run_outdir)
+            elif not updatefiles:
+                # Neither patches nor recipe were updated
+                logger.info('No patches or files need updating')
+                return False, None, []
+    finally:
+        shutil.rmtree(tempdir)
+
+    _remove_source_files(appendlayerdir, remove_files, destpath, no_report_remove, dry_run=dry_run_outdir)
+    return True, appendfile, remove_files
+
+def _guess_recipe_update_mode(srctree, rdata):
+    """Guess the recipe update mode to use"""
+    src_uri = (rdata.getVar('SRC_URI', False) or '').split()
+    git_uris = [uri for uri in src_uri if uri.startswith('git://')]
+    if not git_uris:
+        return 'patch'
+    # Just use the first URI for now
+    uri = git_uris[0]
+    # Check remote branch
+    params = bb.fetch.decodeurl(uri)[5]
+    upstr_branch = params['branch'] if 'branch' in params else 'master'
+    # Check if current branch HEAD is found in upstream branch
+    stdout, _ = bb.process.run('git rev-parse HEAD', cwd=srctree)
+    head_rev = stdout.rstrip()
+    stdout, _ = bb.process.run('git branch -r --contains %s' % head_rev,
+                               cwd=srctree)
+    remote_brs = [branch.strip() for branch in stdout.splitlines()]
+    if 'origin/' + upstr_branch in remote_brs:
+        return 'srcrev'
+
+    return 'patch'
+
+def _update_recipe(recipename, workspace, rd, mode, appendlayerdir, wildcard_version, no_remove, initial_rev, no_report_remove=False, dry_run_outdir=None, no_overrides=False, force_patch_refresh=False):
+    srctree = workspace[recipename]['srctree']
+    if mode == 'auto':
+        mode = _guess_recipe_update_mode(srctree, rd)
+
+    override_branches = []
+    mainbranch = None
+    startbranch = None
+    if not no_overrides:
+        stdout, _ = bb.process.run('git branch', cwd=srctree)
+        other_branches = []
+        for line in stdout.splitlines():
+            branchname = line[2:]
+            if line.startswith('* '):
+                startbranch = branchname
+            if branchname.startswith(override_branch_prefix):
+                override_branches.append(branchname)
+            else:
+                other_branches.append(branchname)
+
+        if override_branches:
+            logger.debug('_update_recipe: override branches: %s' % override_branches)
+            logger.debug('_update_recipe: other branches: %s' % other_branches)
+            if startbranch.startswith(override_branch_prefix):
+                if len(other_branches) == 1:
+                    mainbranch = other_branches[1]
+                else:
+                    raise DevtoolError('Unable to determine main branch - please check out the main branch in source tree first')
+            else:
+                mainbranch = startbranch
+
+    checkedout = None
+    anyupdated = False
+    appendfile = None
+    allremoved = []
+    if override_branches:
+        logger.info('Handling main branch (%s)...' % mainbranch)
+        if startbranch != mainbranch:
+            bb.process.run('git checkout %s' % mainbranch, cwd=srctree)
+        checkedout = mainbranch
+    try:
+        branchlist = [mainbranch] + override_branches
+        for branch in branchlist:
+            crd = bb.data.createCopy(rd)
+            if branch != mainbranch:
+                logger.info('Handling branch %s...' % branch)
+                override = branch[len(override_branch_prefix):]
+                crd.appendVar('OVERRIDES', ':%s' % override)
+                bb.process.run('git checkout %s' % branch, cwd=srctree)
+                checkedout = branch
+
+            if mode == 'srcrev':
+                updated, appendf, removed = _update_recipe_srcrev(recipename, workspace, srctree, crd, appendlayerdir, wildcard_version, no_remove, no_report_remove, dry_run_outdir)
+            elif mode == 'patch':
+                updated, appendf, removed = _update_recipe_patch(recipename, workspace, srctree, crd, appendlayerdir, wildcard_version, no_remove, no_report_remove, initial_rev, dry_run_outdir, force_patch_refresh)
+            else:
+                raise DevtoolError('update_recipe: invalid mode %s' % mode)
+            if updated:
+                anyupdated = True
+            if appendf:
+                appendfile = appendf
+            allremoved.extend(removed)
+    finally:
+        if startbranch and checkedout != startbranch:
+            bb.process.run('git checkout %s' % startbranch, cwd=srctree)
+
+    return anyupdated, appendfile, allremoved
+
+def update_recipe(args, config, basepath, workspace):
+    """Entry point for the devtool 'update-recipe' subcommand"""
+    check_workspace_recipe(workspace, args.recipename)
+
+    if args.append:
+        if not os.path.exists(args.append):
+            raise DevtoolError('bbappend destination layer directory "%s" '
+                               'does not exist' % args.append)
+        if not os.path.exists(os.path.join(args.append, 'conf', 'layer.conf')):
+            raise DevtoolError('conf/layer.conf not found in bbappend '
+                               'destination layer "%s"' % args.append)
+
+    tinfoil = setup_tinfoil(basepath=basepath, tracking=True)
+    try:
+
+        rd = parse_recipe(config, tinfoil, args.recipename, True)
+        if not rd:
+            return 1
+
+        dry_run_output = None
+        dry_run_outdir = None
+        if args.dry_run:
+            dry_run_output = tempfile.TemporaryDirectory(prefix='devtool')
+            dry_run_outdir = dry_run_output.name
+        updated, _, _ = _update_recipe(args.recipename, workspace, rd, args.mode, args.append, args.wildcard_version, args.no_remove, args.initial_rev, dry_run_outdir=dry_run_outdir, no_overrides=args.no_overrides, force_patch_refresh=args.force_patch_refresh)
+
+        if updated:
+            rf = rd.getVar('FILE')
+            if rf.startswith(config.workspace_path):
+                logger.warning('Recipe file %s has been updated but is inside the workspace - you will need to move it (and any associated files next to it) out to the desired layer before using "devtool reset" in order to keep any changes' % rf)
+    finally:
+        tinfoil.shutdown()
+
+    return 0
+
+
+def status(args, config, basepath, workspace):
+    """Entry point for the devtool 'status' subcommand"""
+    if workspace:
+        for recipe, value in sorted(workspace.items()):
+            recipefile = value['recipefile']
+            if recipefile:
+                recipestr = ' (%s)' % recipefile
+            else:
+                recipestr = ''
+            print("%s: %s%s" % (recipe, value['srctree'], recipestr))
+    else:
+        logger.info('No recipes currently in your workspace - you can use "devtool modify" to work on an existing recipe or "devtool add" to add a new one')
+    return 0
+
+
+def _reset(recipes, no_clean, config, basepath, workspace):
+    """Reset one or more recipes"""
+    import oe.path
+
+    def clean_preferred_provider(pn, layerconf_path):
+        """Remove PREFERRED_PROVIDER from layer.conf'"""
+        import re
+        layerconf_file = os.path.join(layerconf_path, 'conf', 'layer.conf')
+        new_layerconf_file = os.path.join(layerconf_path, 'conf', '.layer.conf')
+        pprovider_found = False
+        with open(layerconf_file, 'r') as f:
+            lines = f.readlines()
+            with open(new_layerconf_file, 'a') as nf:
+                for line in lines:
+                    pprovider_exp = r'^PREFERRED_PROVIDER_.*? = "' + pn + r'"$'
+                    if not re.match(pprovider_exp, line):
+                        nf.write(line)
+                    else:
+                        pprovider_found = True
+        if pprovider_found:
+            shutil.move(new_layerconf_file, layerconf_file)
+        else:
+            os.remove(new_layerconf_file)
+
+    if recipes and not no_clean:
+        if len(recipes) == 1:
+            logger.info('Cleaning sysroot for recipe %s...' % recipes[0])
+        else:
+            logger.info('Cleaning sysroot for recipes %s...' % ', '.join(recipes))
+        # If the recipe file itself was created in the workspace, and
+        # it uses BBCLASSEXTEND, then we need to also clean the other
+        # variants
+        targets = []
+        for recipe in recipes:
+            targets.append(recipe)
+            recipefile = workspace[recipe]['recipefile']
+            if recipefile and os.path.exists(recipefile):
+                targets.extend(get_bbclassextend_targets(recipefile, recipe))
+        try:
+            exec_build_env_command(config.init_path, basepath, 'bitbake -c clean %s' % ' '.join(targets))
+        except bb.process.ExecutionError as e:
+            raise DevtoolError('Command \'%s\' failed, output:\n%s\nIf you '
+                                'wish, you may specify -n/--no-clean to '
+                                'skip running this command when resetting' %
+                                (e.command, e.stdout))
+
+    for pn in recipes:
+        _check_preserve(config, pn)
+
+        appendfile = workspace[pn]['bbappend']
+        if os.path.exists(appendfile):
+            # This shouldn't happen, but is possible if devtool errored out prior to
+            # writing the md5 file. We need to delete this here or the recipe won't
+            # actually be reset
+            os.remove(appendfile)
+
+        preservepath = os.path.join(config.workspace_path, 'attic', pn, pn)
+        def preservedir(origdir):
+            if os.path.exists(origdir):
+                for root, dirs, files in os.walk(origdir):
+                    for fn in files:
+                        logger.warning('Preserving %s in %s' % (fn, preservepath))
+                        _move_file(os.path.join(origdir, fn),
+                                   os.path.join(preservepath, fn))
+                    for dn in dirs:
+                        preservedir(os.path.join(root, dn))
+                os.rmdir(origdir)
+
+        recipefile = workspace[pn]['recipefile']
+        if recipefile and oe.path.is_path_parent(config.workspace_path, recipefile):
+            # This should always be true if recipefile is set, but just in case
+            preservedir(os.path.dirname(recipefile))
+        # We don't automatically create this dir next to appends, but the user can
+        preservedir(os.path.join(config.workspace_path, 'appends', pn))
+
+        srctreebase = workspace[pn]['srctreebase']
+        if os.path.isdir(srctreebase):
+            if os.listdir(srctreebase):
+                # We don't want to risk wiping out any work in progress
+                logger.info('Leaving source tree %s as-is; if you no '
+                            'longer need it then please delete it manually'
+                            % srctreebase)
+            else:
+                # This is unlikely, but if it's empty we can just remove it
+                os.rmdir(srctreebase)
+
+        clean_preferred_provider(pn, config.workspace_path)
+
+def reset(args, config, basepath, workspace):
+    """Entry point for the devtool 'reset' subcommand"""
+    import bb
+    if args.recipename:
+        if args.all:
+            raise DevtoolError("Recipe cannot be specified if -a/--all is used")
+        else:
+            for recipe in args.recipename:
+                check_workspace_recipe(workspace, recipe, checksrc=False)
+    elif not args.all:
+        raise DevtoolError("Recipe must be specified, or specify -a/--all to "
+                           "reset all recipes")
+    if args.all:
+        recipes = list(workspace.keys())
+    else:
+        recipes = args.recipename
+
+    _reset(recipes, args.no_clean, config, basepath, workspace)
+
+    return 0
+
+
+def _get_layer(layername, d):
+    """Determine the base layer path for the specified layer name/path"""
+    layerdirs = d.getVar('BBLAYERS').split()
+    layers = {os.path.basename(p): p for p in layerdirs}
+    # Provide some shortcuts
+    if layername.lower() in ['oe-core', 'openembedded-core']:
+        layerdir = layers.get('meta', None)
+    else:
+        layerdir = layers.get(layername, None)
+    return os.path.abspath(layerdir or layername)
+
+def finish(args, config, basepath, workspace):
+    """Entry point for the devtool 'finish' subcommand"""
+    import bb
+    import oe.recipeutils
+
+    check_workspace_recipe(workspace, args.recipename)
+
+    dry_run_suffix = ' (dry-run)' if args.dry_run else ''
+
+    # Grab the equivalent of COREBASE without having to initialise tinfoil
+    corebasedir = os.path.abspath(os.path.join(os.path.dirname(__file__), '..', '..', '..'))
+
+    srctree = workspace[args.recipename]['srctree']
+    check_git_repo_op(srctree, [corebasedir])
+    dirty = check_git_repo_dirty(srctree)
+    if dirty:
+        if args.force:
+            logger.warning('Source tree is not clean, continuing as requested by -f/--force')
+        else:
+            raise DevtoolError('Source tree is not clean:\n\n%s\nEnsure you have committed your changes or use -f/--force if you are sure there\'s nothing that needs to be committed' % dirty)
+
+    no_clean = False
+    tinfoil = setup_tinfoil(basepath=basepath, tracking=True)
+    try:
+        rd = parse_recipe(config, tinfoil, args.recipename, True)
+        if not rd:
+            return 1
+
+        destlayerdir = _get_layer(args.destination, tinfoil.config_data)
+        recipefile = rd.getVar('FILE')
+        recipedir = os.path.dirname(recipefile)
+        origlayerdir = oe.recipeutils.find_layerdir(recipefile)
+
+        if not os.path.isdir(destlayerdir):
+            raise DevtoolError('Unable to find layer or directory matching "%s"' % args.destination)
+
+        if os.path.abspath(destlayerdir) == config.workspace_path:
+            raise DevtoolError('"%s" specifies the workspace layer - that is not a valid destination' % args.destination)
+
+        # If it's an upgrade, grab the original path
+        origpath = None
+        origfilelist = None
+        append = workspace[args.recipename]['bbappend']
+        with open(append, 'r') as f:
+            for line in f:
+                if line.startswith('# original_path:'):
+                    origpath = line.split(':')[1].strip()
+                elif line.startswith('# original_files:'):
+                    origfilelist = line.split(':')[1].split()
+
+        destlayerbasedir = oe.recipeutils.find_layerdir(destlayerdir)
+
+        if origlayerdir == config.workspace_path:
+            # Recipe file itself is in workspace, update it there first
+            appendlayerdir = None
+            origrelpath = None
+            if origpath:
+                origlayerpath = oe.recipeutils.find_layerdir(origpath)
+                if origlayerpath:
+                    origrelpath = os.path.relpath(origpath, origlayerpath)
+            destpath = oe.recipeutils.get_bbfile_path(rd, destlayerdir, origrelpath)
+            if not destpath:
+                raise DevtoolError("Unable to determine destination layer path - check that %s specifies an actual layer and %s/conf/layer.conf specifies BBFILES. You may also need to specify a more complete path." % (args.destination, destlayerdir))
+            # Warn if the layer isn't in bblayers.conf (the code to create a bbappend will do this in other cases)
+            layerdirs = [os.path.abspath(layerdir) for layerdir in rd.getVar('BBLAYERS').split()]
+            if not os.path.abspath(destlayerbasedir) in layerdirs:
+                bb.warn('Specified destination layer is not currently enabled in bblayers.conf, so the %s recipe will now be unavailable in your current configuration until you add the layer there' % args.recipename)
+
+        elif destlayerdir == origlayerdir:
+            # Same layer, update the original recipe
+            appendlayerdir = None
+            destpath = None
+        else:
+            # Create/update a bbappend in the specified layer
+            appendlayerdir = destlayerdir
+            destpath = None
+
+        # Actually update the recipe / bbappend
+        removing_original = (origpath and origfilelist and oe.recipeutils.find_layerdir(origpath) == destlayerbasedir)
+        dry_run_output = None
+        dry_run_outdir = None
+        if args.dry_run:
+            dry_run_output = tempfile.TemporaryDirectory(prefix='devtool')
+            dry_run_outdir = dry_run_output.name
+        updated, appendfile, removed = _update_recipe(args.recipename, workspace, rd, args.mode, appendlayerdir, wildcard_version=True, no_remove=False, no_report_remove=removing_original, initial_rev=args.initial_rev, dry_run_outdir=dry_run_outdir, no_overrides=args.no_overrides, force_patch_refresh=args.force_patch_refresh)
+        removed = [os.path.relpath(pth, recipedir) for pth in removed]
+
+        # Remove any old files in the case of an upgrade
+        if removing_original:
+            for fn in origfilelist:
+                fnp = os.path.join(origpath, fn)
+                if fn in removed or not os.path.exists(os.path.join(recipedir, fn)):
+                    logger.info('Removing file %s%s' % (fnp, dry_run_suffix))
+                if not args.dry_run:
+                    try:
+                        os.remove(fnp)
+                    except FileNotFoundError:
+                        pass
+
+        if origlayerdir == config.workspace_path and destpath:
+            # Recipe file itself is in the workspace - need to move it and any
+            # associated files to the specified layer
+            no_clean = True
+            logger.info('Moving recipe file to %s%s' % (destpath, dry_run_suffix))
+            for root, _, files in os.walk(recipedir):
+                for fn in files:
+                    srcpath = os.path.join(root, fn)
+                    relpth = os.path.relpath(os.path.dirname(srcpath), recipedir)
+                    destdir = os.path.abspath(os.path.join(destpath, relpth))
+                    destfp = os.path.join(destdir, fn)
+                    _move_file(srcpath, destfp, dry_run_outdir=dry_run_outdir, base_outdir=destpath)
+
+        if dry_run_outdir:
+            import difflib
+            comparelist = []
+            for root, _, files in os.walk(dry_run_outdir):
+                for fn in files:
+                    outf = os.path.join(root, fn)
+                    relf = os.path.relpath(outf, dry_run_outdir)
+                    logger.debug('dry-run: output file %s' % relf)
+                    if fn.endswith('.bb'):
+                        if origfilelist and origpath and destpath:
+                            # Need to match this up with the pre-upgrade recipe file
+                            for origf in origfilelist:
+                                if origf.endswith('.bb'):
+                                    comparelist.append((os.path.abspath(os.path.join(origpath, origf)),
+                                                        outf,
+                                                        os.path.abspath(os.path.join(destpath, relf))))
+                                    break
+                        else:
+                            # Compare to the existing recipe
+                            comparelist.append((recipefile, outf, recipefile))
+                    elif fn.endswith('.bbappend'):
+                        if appendfile:
+                            if os.path.exists(appendfile):
+                                comparelist.append((appendfile, outf, appendfile))
+                            else:
+                                comparelist.append((None, outf, appendfile))
+                    else:
+                        if destpath:
+                            recipedest = destpath
+                        elif appendfile:
+                            recipedest = os.path.dirname(appendfile)
+                        else:
+                            recipedest = os.path.dirname(recipefile)
+                        destfp = os.path.join(recipedest, relf)
+                        if os.path.exists(destfp):
+                            comparelist.append((destfp, outf, destfp))
+            output = ''
+            for oldfile, newfile, newfileshow in comparelist:
+                if oldfile:
+                    with open(oldfile, 'r') as f:
+                        oldlines = f.readlines()
+                else:
+                    oldfile = '/dev/null'
+                    oldlines = []
+                with open(newfile, 'r') as f:
+                    newlines = f.readlines()
+                if not newfileshow:
+                    newfileshow = newfile
+                diff = difflib.unified_diff(oldlines, newlines, oldfile, newfileshow)
+                difflines = list(diff)
+                if difflines:
+                    output += ''.join(difflines)
+            if output:
+                logger.info('Diff of changed files:\n%s' % output)
+    finally:
+        tinfoil.shutdown()
+
+    # Everything else has succeeded, we can now reset
+    if args.dry_run:
+        logger.info('Resetting recipe (dry-run)')
+    else:
+        _reset([args.recipename], no_clean=no_clean, config=config, basepath=basepath, workspace=workspace)
+
+    return 0
+
+
+def get_default_srctree(config, recipename=''):
+    """Get the default srctree path"""
+    srctreeparent = config.get('General', 'default_source_parent_dir', config.workspace_path)
+    if recipename:
+        return os.path.join(srctreeparent, 'sources', recipename)
+    else:
+        return os.path.join(srctreeparent, 'sources')
+
+def register_commands(subparsers, context):
+    """Register devtool subcommands from this plugin"""
+
+    defsrctree = get_default_srctree(context.config)
+    parser_add = subparsers.add_parser('add', help='Add a new recipe',
+                                       description='Adds a new recipe to the workspace to build a specified source tree. Can optionally fetch a remote URI and unpack it to create the source tree.',
+                                       group='starting', order=100)
+    parser_add.add_argument('recipename', nargs='?', help='Name for new recipe to add (just name - no version, path or extension). If not specified, will attempt to auto-detect it.')
+    parser_add.add_argument('srctree', nargs='?', help='Path to external source tree. If not specified, a subdirectory of %s will be used.' % defsrctree)
+    parser_add.add_argument('fetchuri', nargs='?', help='Fetch the specified URI and extract it to create the source tree')
+    group = parser_add.add_mutually_exclusive_group()
+    group.add_argument('--same-dir', '-s', help='Build in same directory as source', action="store_true")
+    group.add_argument('--no-same-dir', help='Force build in a separate build directory', action="store_true")
+    parser_add.add_argument('--fetch', '-f', help='Fetch the specified URI and extract it to create the source tree (deprecated - pass as positional argument instead)', metavar='URI')
+    parser_add.add_argument('--fetch-dev', help='For npm, also fetch devDependencies', action="store_true")
+    parser_add.add_argument('--version', '-V', help='Version to use within recipe (PV)')
+    parser_add.add_argument('--no-git', '-g', help='If fetching source, do not set up source tree as a git repository', action="store_true")
+    group = parser_add.add_mutually_exclusive_group()
+    group.add_argument('--srcrev', '-S', help='Source revision to fetch if fetching from an SCM such as git (default latest)')
+    group.add_argument('--autorev', '-a', help='When fetching from a git repository, set SRCREV in the recipe to a floating revision instead of fixed', action="store_true")
+    parser_add.add_argument('--srcbranch', '-B', help='Branch in source repository if fetching from an SCM such as git (default master)')
+    parser_add.add_argument('--binary', '-b', help='Treat the source tree as something that should be installed verbatim (no compilation, same directory structure). Useful with binary packages e.g. RPMs.', action='store_true')
+    parser_add.add_argument('--also-native', help='Also add native variant (i.e. support building recipe for the build host as well as the target machine)', action='store_true')
+    parser_add.add_argument('--src-subdir', help='Specify subdirectory within source tree to use', metavar='SUBDIR')
+    parser_add.add_argument('--mirrors', help='Enable PREMIRRORS and MIRRORS for source tree fetching (disable by default).', action="store_true")
+    parser_add.add_argument('--provides', '-p', help='Specify an alias for the item provided by the recipe. E.g. virtual/libgl')
+    parser_add.set_defaults(func=add, fixed_setup=context.fixed_setup)
+
+    parser_modify = subparsers.add_parser('modify', help='Modify the source for an existing recipe',
+                                       description='Sets up the build environment to modify the source for an existing recipe. The default behaviour is to extract the source being fetched by the recipe into a git tree so you can work on it; alternatively if you already have your own pre-prepared source tree you can specify -n/--no-extract.',
+                                       group='starting', order=90)
+    parser_modify.add_argument('recipename', help='Name of existing recipe to edit (just name - no version, path or extension)')
+    parser_modify.add_argument('srctree', nargs='?', help='Path to external source tree. If not specified, a subdirectory of %s will be used.' % defsrctree)
+    parser_modify.add_argument('--wildcard', '-w', action="store_true", help='Use wildcard for unversioned bbappend')
+    group = parser_modify.add_mutually_exclusive_group()
+    group.add_argument('--extract', '-x', action="store_true", help='Extract source for recipe (default)')
+    group.add_argument('--no-extract', '-n', action="store_true", help='Do not extract source, expect it to exist')
+    group = parser_modify.add_mutually_exclusive_group()
+    group.add_argument('--same-dir', '-s', help='Build in same directory as source', action="store_true")
+    group.add_argument('--no-same-dir', help='Force build in a separate build directory', action="store_true")
+    parser_modify.add_argument('--branch', '-b', default="devtool", help='Name for development branch to checkout (when not using -n/--no-extract) (default "%(default)s")')
+    parser_modify.add_argument('--no-overrides', '-O', action="store_true", help='Do not create branches for other override configurations')
+    parser_modify.add_argument('--keep-temp', help='Keep temporary directory (for debugging)', action="store_true")
+    parser_modify.set_defaults(func=modify, fixed_setup=context.fixed_setup)
+
+    parser_extract = subparsers.add_parser('extract', help='Extract the source for an existing recipe',
+                                       description='Extracts the source for an existing recipe',
+                                       group='advanced')
+    parser_extract.add_argument('recipename', help='Name of recipe to extract the source for')
+    parser_extract.add_argument('srctree', help='Path to where to extract the source tree')
+    parser_extract.add_argument('--branch', '-b', default="devtool", help='Name for development branch to checkout (default "%(default)s")')
+    parser_extract.add_argument('--no-overrides', '-O', action="store_true", help='Do not create branches for other override configurations')
+    parser_extract.add_argument('--keep-temp', action="store_true", help='Keep temporary directory (for debugging)')
+    parser_extract.set_defaults(func=extract, fixed_setup=context.fixed_setup)
+
+    parser_sync = subparsers.add_parser('sync', help='Synchronize the source tree for an existing recipe',
+                                       description='Synchronize the previously extracted source tree for an existing recipe',
+                                       formatter_class=argparse.ArgumentDefaultsHelpFormatter,
+                                       group='advanced')
+    parser_sync.add_argument('recipename', help='Name of recipe to sync the source for')
+    parser_sync.add_argument('srctree', help='Path to the source tree')
+    parser_sync.add_argument('--branch', '-b', default="devtool", help='Name for development branch to checkout')
+    parser_sync.add_argument('--keep-temp', action="store_true", help='Keep temporary directory (for debugging)')
+    parser_sync.set_defaults(func=sync, fixed_setup=context.fixed_setup)
+
+    parser_rename = subparsers.add_parser('rename', help='Rename a recipe file in the workspace',
+                                       description='Renames the recipe file for a recipe in the workspace, changing the name or version part or both, ensuring that all references within the workspace are updated at the same time. Only works when the recipe file itself is in the workspace, e.g. after devtool add. Particularly useful when devtool add did not automatically determine the correct name.',
+                                       group='working', order=10)
+    parser_rename.add_argument('recipename', help='Current name of recipe to rename')
+    parser_rename.add_argument('newname', nargs='?', help='New name for recipe (optional, not needed if you only want to change the version)')
+    parser_rename.add_argument('--version', '-V', help='Change the version (NOTE: this does not change the version fetched by the recipe, just the version in the recipe file name)')
+    parser_rename.add_argument('--no-srctree', '-s', action='store_true', help='Do not rename the source tree directory (if the default source tree path has been used) - keeping the old name may be desirable if there are internal/other external references to this path')
+    parser_rename.set_defaults(func=rename)
+
+    parser_update_recipe = subparsers.add_parser('update-recipe', help='Apply changes from external source tree to recipe',
+                                       description='Applies changes from external source tree to a recipe (updating/adding/removing patches as necessary, or by updating SRCREV). Note that these changes need to have been committed to the git repository in order to be recognised.',
+                                       group='working', order=-90)
+    parser_update_recipe.add_argument('recipename', help='Name of recipe to update')
+    parser_update_recipe.add_argument('--mode', '-m', choices=['patch', 'srcrev', 'auto'], default='auto', help='Update mode (where %(metavar)s is %(choices)s; default is %(default)s)', metavar='MODE')
+    parser_update_recipe.add_argument('--initial-rev', help='Override starting revision for patches')
+    parser_update_recipe.add_argument('--append', '-a', help='Write changes to a bbappend in the specified layer instead of the recipe', metavar='LAYERDIR')
+    parser_update_recipe.add_argument('--wildcard-version', '-w', help='In conjunction with -a/--append, use a wildcard to make the bbappend apply to any recipe version', action='store_true')
+    parser_update_recipe.add_argument('--no-remove', '-n', action="store_true", help='Don\'t remove patches, only add or update')
+    parser_update_recipe.add_argument('--no-overrides', '-O', action="store_true", help='Do not handle other override branches (if they exist)')
+    parser_update_recipe.add_argument('--dry-run', '-N', action="store_true", help='Dry-run (just report changes instead of writing them)')
+    parser_update_recipe.add_argument('--force-patch-refresh', action="store_true", help='Update patches in the layer even if they have not been modified (useful for refreshing patch context)')
+    parser_update_recipe.set_defaults(func=update_recipe)
+
+    parser_status = subparsers.add_parser('status', help='Show workspace status',
+                                          description='Lists recipes currently in your workspace and the paths to their respective external source trees',
+                                          group='info', order=100)
+    parser_status.set_defaults(func=status)
+
+    parser_reset = subparsers.add_parser('reset', help='Remove a recipe from your workspace',
+                                         description='Removes the specified recipe(s) from your workspace (resetting its state back to that defined by the metadata).',
+                                         group='working', order=-100)
+    parser_reset.add_argument('recipename', nargs='*', help='Recipe to reset')
+    parser_reset.add_argument('--all', '-a', action="store_true", help='Reset all recipes (clear workspace)')
+    parser_reset.add_argument('--no-clean', '-n', action="store_true", help='Don\'t clean the sysroot to remove recipe output')
+    parser_reset.set_defaults(func=reset)
+
+    parser_finish = subparsers.add_parser('finish', help='Finish working on a recipe in your workspace',
+                                         description='Pushes any committed changes to the specified recipe to the specified layer and removes it from your workspace. Roughly equivalent to an update-recipe followed by reset, except the update-recipe step will do the "right thing" depending on the recipe and the destination layer specified. Note that your changes must have been committed to the git repository in order to be recognised.',
+                                         group='working', order=-100)
+    parser_finish.add_argument('recipename', help='Recipe to finish')
+    parser_finish.add_argument('destination', help='Layer/path to put recipe into. Can be the name of a layer configured in your bblayers.conf, the path to the base of a layer, or a partial path inside a layer. %(prog)s will attempt to complete the path based on the layer\'s structure.')
+    parser_finish.add_argument('--mode', '-m', choices=['patch', 'srcrev', 'auto'], default='auto', help='Update mode (where %(metavar)s is %(choices)s; default is %(default)s)', metavar='MODE')
+    parser_finish.add_argument('--initial-rev', help='Override starting revision for patches')
+    parser_finish.add_argument('--force', '-f', action="store_true", help='Force continuing even if there are uncommitted changes in the source tree repository')
+    parser_finish.add_argument('--no-overrides', '-O', action="store_true", help='Do not handle other override branches (if they exist)')
+    parser_finish.add_argument('--dry-run', '-N', action="store_true", help='Dry-run (just report changes instead of writing them)')
+    parser_finish.add_argument('--force-patch-refresh', action="store_true", help='Update patches in the layer even if they have not been modified (useful for refreshing patch context)')
+    parser_finish.set_defaults(func=finish)
diff --git a/meta/poky/scripts/lib/devtool/upgrade.py b/meta/poky/scripts/lib/devtool/upgrade.py
new file mode 100644
index 0000000..2020077
--- /dev/null
+++ b/meta/poky/scripts/lib/devtool/upgrade.py
@@ -0,0 +1,629 @@
+# Development tool - upgrade command plugin
+#
+# Copyright (C) 2014-2017 Intel Corporation
+#
+# 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.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+"""Devtool upgrade plugin"""
+
+import os
+import sys
+import re
+import shutil
+import tempfile
+import logging
+import argparse
+import scriptutils
+import errno
+import bb
+
+devtool_path = os.path.dirname(os.path.realpath(__file__)) + '/../../../meta/lib'
+sys.path = sys.path + [devtool_path]
+
+import oe.recipeutils
+from devtool import standard
+from devtool import exec_build_env_command, setup_tinfoil, DevtoolError, parse_recipe, use_external_build, update_unlockedsigs, check_prerelease_version
+
+logger = logging.getLogger('devtool')
+
+def _run(cmd, cwd=''):
+    logger.debug("Running command %s> %s" % (cwd,cmd))
+    return bb.process.run('%s' % cmd, cwd=cwd)
+
+def _get_srctree(tmpdir):
+    srctree = tmpdir
+    dirs = os.listdir(tmpdir)
+    if len(dirs) == 1:
+        srctree = os.path.join(tmpdir, dirs[0])
+    return srctree
+
+def _copy_source_code(orig, dest):
+    for path in standard._ls_tree(orig):
+        dest_dir = os.path.join(dest, os.path.dirname(path))
+        bb.utils.mkdirhier(dest_dir)
+        dest_path = os.path.join(dest, path)
+        shutil.move(os.path.join(orig, path), dest_path)
+
+def _remove_patch_dirs(recipefolder):
+    for root, dirs, files in os.walk(recipefolder):
+        for d in dirs:
+            shutil.rmtree(os.path.join(root,d))
+
+def _recipe_contains(rd, var):
+    rf = rd.getVar('FILE')
+    varfiles = oe.recipeutils.get_var_files(rf, [var], rd)
+    for var, fn in varfiles.items():
+        if fn and fn.startswith(os.path.dirname(rf) + os.sep):
+            return True
+    return False
+
+def _rename_recipe_dirs(oldpv, newpv, path):
+    for root, dirs, files in os.walk(path):
+        # Rename directories with the version in their name
+        for olddir in dirs:
+            if olddir.find(oldpv) != -1:
+                newdir = olddir.replace(oldpv, newpv)
+                if olddir != newdir:
+                    shutil.move(os.path.join(path, olddir), os.path.join(path, newdir))
+        # Rename any inc files with the version in their name (unusual, but possible)
+        for oldfile in files:
+            if oldfile.endswith('.inc'):
+                if oldfile.find(oldpv) != -1:
+                    newfile = oldfile.replace(oldpv, newpv)
+                    if oldfile != newfile:
+                        os.rename(os.path.join(path, oldfile), os.path.join(path, newfile))
+
+def _rename_recipe_file(oldrecipe, bpn, oldpv, newpv, path):
+    oldrecipe = os.path.basename(oldrecipe)
+    if oldrecipe.endswith('_%s.bb' % oldpv):
+        newrecipe = '%s_%s.bb' % (bpn, newpv)
+        if oldrecipe != newrecipe:
+            shutil.move(os.path.join(path, oldrecipe), os.path.join(path, newrecipe))
+    else:
+        newrecipe = oldrecipe
+    return os.path.join(path, newrecipe)
+
+def _rename_recipe_files(oldrecipe, bpn, oldpv, newpv, path):
+    _rename_recipe_dirs(oldpv, newpv, path)
+    return _rename_recipe_file(oldrecipe, bpn, oldpv, newpv, path)
+
+def _write_append(rc, srctree, same_dir, no_same_dir, rev, copied, workspace, d):
+    """Writes an append file"""
+    if not os.path.exists(rc):
+        raise DevtoolError("bbappend not created because %s does not exist" % rc)
+
+    appendpath = os.path.join(workspace, 'appends')
+    if not os.path.exists(appendpath):
+        bb.utils.mkdirhier(appendpath)
+
+    brf = os.path.basename(os.path.splitext(rc)[0]) # rc basename
+
+    srctree = os.path.abspath(srctree)
+    pn = d.getVar('PN')
+    af = os.path.join(appendpath, '%s.bbappend' % brf)
+    with open(af, 'w') as f:
+        f.write('FILESEXTRAPATHS_prepend := "${THISDIR}/${PN}:"\n\n')
+        f.write('inherit externalsrc\n')
+        f.write(('# NOTE: We use pn- overrides here to avoid affecting'
+                 'multiple variants in the case where the recipe uses BBCLASSEXTEND\n'))
+        f.write('EXTERNALSRC_pn-%s = "%s"\n' % (pn, srctree))
+        b_is_s = use_external_build(same_dir, no_same_dir, d)
+        if b_is_s:
+            f.write('EXTERNALSRC_BUILD_pn-%s = "%s"\n' % (pn, srctree))
+        f.write('\n')
+        if rev:
+            f.write('# initial_rev: %s\n' % rev)
+        if copied:
+            f.write('# original_path: %s\n' % os.path.dirname(d.getVar('FILE')))
+            f.write('# original_files: %s\n' % ' '.join(copied))
+    return af
+
+def _cleanup_on_error(rf, srctree):
+    rfp = os.path.split(rf)[0] # recipe folder
+    rfpp = os.path.split(rfp)[0] # recipes folder
+    if os.path.exists(rfp):
+        shutil.rmtree(b)
+    if not len(os.listdir(rfpp)):
+        os.rmdir(rfpp)
+    srctree = os.path.abspath(srctree)
+    if os.path.exists(srctree):
+        shutil.rmtree(srctree)
+
+def _upgrade_error(e, rf, srctree):
+    if rf:
+        cleanup_on_error(rf, srctree)
+    logger.error(e)
+    raise DevtoolError(e)
+
+def _get_uri(rd):
+    srcuris = rd.getVar('SRC_URI').split()
+    if not len(srcuris):
+        raise DevtoolError('SRC_URI not found on recipe')
+    # Get first non-local entry in SRC_URI - usually by convention it's
+    # the first entry, but not always!
+    srcuri = None
+    for entry in srcuris:
+        if not entry.startswith('file://'):
+            srcuri = entry
+            break
+    if not srcuri:
+        raise DevtoolError('Unable to find non-local entry in SRC_URI')
+    srcrev = '${AUTOREV}'
+    if '://' in srcuri:
+        # Fetch a URL
+        rev_re = re.compile(';rev=([^;]+)')
+        res = rev_re.search(srcuri)
+        if res:
+            srcrev = res.group(1)
+            srcuri = rev_re.sub('', srcuri)
+    return srcuri, srcrev
+
+def _extract_new_source(newpv, srctree, no_patch, srcrev, srcbranch, branch, keep_temp, tinfoil, rd):
+    """Extract sources of a recipe with a new version"""
+
+    def __run(cmd):
+        """Simple wrapper which calls _run with srctree as cwd"""
+        return _run(cmd, srctree)
+
+    crd = rd.createCopy()
+
+    pv = crd.getVar('PV')
+    crd.setVar('PV', newpv)
+
+    tmpsrctree = None
+    uri, rev = _get_uri(crd)
+    if srcrev:
+        rev = srcrev
+    if uri.startswith('git://'):
+        __run('git fetch')
+        __run('git checkout %s' % rev)
+        __run('git tag -f devtool-base-new')
+        md5 = None
+        sha256 = None
+        _, _, _, _, _, params = bb.fetch2.decodeurl(uri)
+        srcsubdir_rel = params.get('destsuffix', 'git')
+        if not srcbranch:
+            check_branch, check_branch_err = __run('git branch -r --contains %s' % srcrev)
+            get_branch = [x.strip() for x in check_branch.splitlines()]
+            # Remove HEAD reference point and drop remote prefix
+            get_branch = [x.split('/', 1)[1] for x in get_branch if not x.startswith('origin/HEAD')]
+            if 'master' in get_branch:
+                # If it is master, we do not need to append 'branch=master' as this is default.
+                # Even with the case where get_branch has multiple objects, if 'master' is one
+                # of them, we should default take from 'master'
+                srcbranch = ''
+            elif len(get_branch) == 1:
+                # If 'master' isn't in get_branch and get_branch contains only ONE object, then store result into 'srcbranch'
+                srcbranch = get_branch[0]
+            else:
+                # If get_branch contains more than one objects, then display error and exit.
+                mbrch = '\n  ' + '\n  '.join(get_branch)
+                raise DevtoolError('Revision %s was found on multiple branches: %s\nPlease provide the correct branch in the devtool command with "--srcbranch" or "-B" option.' % (srcrev, mbrch))
+    else:
+        __run('git checkout devtool-base -b devtool-%s' % newpv)
+
+        tmpdir = tempfile.mkdtemp(prefix='devtool')
+        try:
+            checksums, ftmpdir = scriptutils.fetch_url(tinfoil, uri, rev, tmpdir, logger, preserve_tmp=keep_temp)
+        except scriptutils.FetchUrlFailure as e:
+            raise DevtoolError(e)
+
+        if ftmpdir and keep_temp:
+            logger.info('Fetch temp directory is %s' % ftmpdir)
+
+        md5 = checksums['md5sum']
+        sha256 = checksums['sha256sum']
+
+        tmpsrctree = _get_srctree(tmpdir)
+        srctree = os.path.abspath(srctree)
+        srcsubdir_rel = os.path.relpath(tmpsrctree, tmpdir)
+
+        # Delete all sources so we ensure no stray files are left over
+        for item in os.listdir(srctree):
+            if item in ['.git', 'oe-local-files']:
+                continue
+            itempath = os.path.join(srctree, item)
+            if os.path.isdir(itempath):
+                shutil.rmtree(itempath)
+            else:
+                os.remove(itempath)
+
+        # Copy in new ones
+        _copy_source_code(tmpsrctree, srctree)
+
+        (stdout,_) = __run('git ls-files --modified --others --exclude-standard')
+        filelist = stdout.splitlines()
+        pbar = bb.ui.knotty.BBProgress('Adding changed files', len(filelist))
+        pbar.start()
+        batchsize = 100
+        for i in range(0, len(filelist), batchsize):
+            batch = filelist[i:i+batchsize]
+            __run('git add -A %s' % ' '.join(['"%s"' % item for item in batch]))
+            pbar.update(i)
+        pbar.finish()
+
+        useroptions = []
+        oe.patch.GitApplyTree.gitCommandUserOptions(useroptions, d=rd)
+        __run('git %s commit -q -m "Commit of upstream changes at version %s" --allow-empty' % (' '.join(useroptions), newpv))
+        __run('git tag -f devtool-base-%s' % newpv)
+
+    (stdout, _) = __run('git rev-parse HEAD')
+    rev = stdout.rstrip()
+
+    if no_patch:
+        patches = oe.recipeutils.get_recipe_patches(crd)
+        if patches:
+            logger.warning('By user choice, the following patches will NOT be applied to the new source tree:\n  %s' % '\n  '.join([os.path.basename(patch) for patch in patches]))
+    else:
+        __run('git checkout devtool-patched -b %s' % branch)
+        skiptag = False
+        try:
+            __run('git rebase %s' % rev)
+        except bb.process.ExecutionError as e:
+            skiptag = True
+            if 'conflict' in e.stdout:
+                logger.warning('Command \'%s\' failed:\n%s\n\nYou will need to resolve conflicts in order to complete the upgrade.' % (e.command, e.stdout.rstrip()))
+            else:
+                logger.warning('Command \'%s\' failed:\n%s' % (e.command, e.stdout))
+        if not skiptag:
+            if uri.startswith('git://'):
+                suffix = 'new'
+            else:
+                suffix = newpv
+            __run('git tag -f devtool-patched-%s' % suffix)
+
+    if tmpsrctree:
+        if keep_temp:
+            logger.info('Preserving temporary directory %s' % tmpsrctree)
+        else:
+            shutil.rmtree(tmpsrctree)
+
+    return (rev, md5, sha256, srcbranch, srcsubdir_rel)
+
+def _add_license_diff_to_recipe(path, diff):
+    notice_text = """# FIXME: the LIC_FILES_CHKSUM values have been updated by 'devtool upgrade'.
+# The following is the difference between the old and the new license text.
+# Please update the LICENSE value if needed, and summarize the changes in
+# the commit message via 'License-Update:' tag.
+# (example: 'License-Update: copyright years updated.')
+#
+# The changes:
+#
+"""
+    commented_diff = "\n".join(["# {}".format(l) for l in diff.split('\n')])
+    with open(path, 'rb') as f:
+        orig_content = f.read()
+    with open(path, 'wb') as f:
+        f.write(notice_text.encode())
+        f.write(commented_diff.encode())
+        f.write("\n#\n\n".encode())
+        f.write(orig_content)
+
+def _create_new_recipe(newpv, md5, sha256, srcrev, srcbranch, srcsubdir_old, srcsubdir_new, workspace, tinfoil, rd, license_diff, new_licenses):
+    """Creates the new recipe under workspace"""
+
+    bpn = rd.getVar('BPN')
+    path = os.path.join(workspace, 'recipes', bpn)
+    bb.utils.mkdirhier(path)
+    copied, _ = oe.recipeutils.copy_recipe_files(rd, path, all_variants=True)
+    if not copied:
+        raise DevtoolError('Internal error - no files were copied for recipe %s' % bpn)
+    logger.debug('Copied %s to %s' % (copied, path))
+
+    oldpv = rd.getVar('PV')
+    if not newpv:
+        newpv = oldpv
+    origpath = rd.getVar('FILE')
+    fullpath = _rename_recipe_files(origpath, bpn, oldpv, newpv, path)
+    logger.debug('Upgraded %s => %s' % (origpath, fullpath))
+
+    newvalues = {}
+    if _recipe_contains(rd, 'PV') and newpv != oldpv:
+        newvalues['PV'] = newpv
+
+    if srcrev:
+        newvalues['SRCREV'] = srcrev
+
+    if srcbranch:
+        src_uri = oe.recipeutils.split_var_value(rd.getVar('SRC_URI', False) or '')
+        changed = False
+        replacing = True
+        new_src_uri = []
+        for entry in src_uri:
+            scheme, network, path, user, passwd, params = bb.fetch2.decodeurl(entry)
+            if replacing and scheme in ['git', 'gitsm']:
+                branch = params.get('branch', 'master')
+                if rd.expand(branch) != srcbranch:
+                    # Handle case where branch is set through a variable
+                    res = re.match(r'\$\{([^}@]+)\}', branch)
+                    if res:
+                        newvalues[res.group(1)] = srcbranch
+                        # We know we won't change SRC_URI now, so break out
+                        break
+                    else:
+                        params['branch'] = srcbranch
+                        entry = bb.fetch2.encodeurl((scheme, network, path, user, passwd, params))
+                        changed = True
+                replacing = False
+            new_src_uri.append(entry)
+        if changed:
+            newvalues['SRC_URI'] = ' '.join(new_src_uri)
+
+    newvalues['PR'] = None
+
+    # Work out which SRC_URI entries have changed in case the entry uses a name
+    crd = rd.createCopy()
+    crd.setVar('PV', newpv)
+    for var, value in newvalues.items():
+        crd.setVar(var, value)
+    old_src_uri = (rd.getVar('SRC_URI') or '').split()
+    new_src_uri = (crd.getVar('SRC_URI') or '').split()
+    newnames = []
+    addnames = []
+    for newentry in new_src_uri:
+        _, _, _, _, _, params = bb.fetch2.decodeurl(newentry)
+        if 'name' in params:
+            newnames.append(params['name'])
+            if newentry not in old_src_uri:
+                addnames.append(params['name'])
+    # Find what's been set in the original recipe
+    oldnames = []
+    noname = False
+    for varflag in rd.getVarFlags('SRC_URI'):
+        if varflag.endswith(('.md5sum', '.sha256sum')):
+            name = varflag.rsplit('.', 1)[0]
+            if name not in oldnames:
+                oldnames.append(name)
+        elif varflag in ['md5sum', 'sha256sum']:
+            noname = True
+    # Even if SRC_URI has named entries it doesn't have to actually use the name
+    if noname and addnames and addnames[0] not in oldnames:
+        addnames = []
+    # Drop any old names (the name actually might include ${PV})
+    for name in oldnames:
+        if name not in newnames:
+            newvalues['SRC_URI[%s.md5sum]' % name] = None
+            newvalues['SRC_URI[%s.sha256sum]' % name] = None
+
+    if md5 and sha256:
+        if addnames:
+            nameprefix = '%s.' % addnames[0]
+        else:
+            nameprefix = ''
+        newvalues['SRC_URI[%smd5sum]' % nameprefix] = md5
+        newvalues['SRC_URI[%ssha256sum]' % nameprefix] = sha256
+
+    if srcsubdir_new != srcsubdir_old:
+        s_subdir_old = os.path.relpath(os.path.abspath(rd.getVar('S')), rd.getVar('WORKDIR'))
+        s_subdir_new = os.path.relpath(os.path.abspath(crd.getVar('S')), crd.getVar('WORKDIR'))
+        if srcsubdir_old == s_subdir_old and srcsubdir_new != s_subdir_new:
+            # Subdir for old extracted source matches what S points to (it should!)
+            # but subdir for new extracted source doesn't match what S will be
+            newvalues['S'] = '${WORKDIR}/%s' % srcsubdir_new.replace(newpv, '${PV}')
+            if crd.expand(newvalues['S']) == crd.expand('${WORKDIR}/${BP}'):
+                # It's the default, drop it
+                # FIXME what if S is being set in a .inc?
+                newvalues['S'] = None
+                logger.info('Source subdirectory has changed, dropping S value since it now matches the default ("${WORKDIR}/${BP}")')
+            else:
+                logger.info('Source subdirectory has changed, updating S value')
+
+    if license_diff:
+        newlicchksum = " ".join(["file://{}".format(l['path']) +
+                                 (";beginline={}".format(l['beginline']) if l['beginline'] else "") +
+                                 (";endline={}".format(l['endline']) if l['endline'] else "") +
+                                 (";md5={}".format(l['actual_md5'])) for l in new_licenses])
+        newvalues["LIC_FILES_CHKSUM"] = newlicchksum
+        _add_license_diff_to_recipe(fullpath, license_diff)
+
+    rd = tinfoil.parse_recipe_file(fullpath, False)
+    oe.recipeutils.patch_recipe(rd, fullpath, newvalues)
+
+    return fullpath, copied
+
+
+def _check_git_config():
+    def getconfig(name):
+        try:
+            value = bb.process.run('git config --global %s' % name)[0].strip()
+        except bb.process.ExecutionError as e:
+            if e.exitcode == 1:
+                value = None
+            else:
+                raise
+        return value
+
+    username = getconfig('user.name')
+    useremail = getconfig('user.email')
+    configerr = []
+    if not username:
+        configerr.append('Please set your name using:\n  git config --global user.name')
+    if not useremail:
+        configerr.append('Please set your email using:\n  git config --global user.email')
+    if configerr:
+        raise DevtoolError('Your git configuration is incomplete which will prevent rebases from working:\n' + '\n'.join(configerr))
+
+def _extract_licenses(srcpath, recipe_licenses):
+    licenses = []
+    for url in recipe_licenses.split():
+        license = {}
+        (type, host, path, user, pswd, parm) = bb.fetch.decodeurl(url)
+        license['path'] = path
+        license['md5'] = parm.get('md5', '')
+        license['beginline'], license['endline'] = 0, 0
+        if 'beginline' in parm:
+            license['beginline'] = int(parm['beginline'])
+        if 'endline' in parm:
+            license['endline'] = int(parm['endline'])
+        license['text'] = []
+        with open(os.path.join(srcpath, path), 'rb') as f:
+            import hashlib
+            actual_md5 = hashlib.md5()
+            lineno = 0
+            for line in f:
+                lineno += 1
+                if (lineno >= license['beginline']) and ((lineno <= license['endline']) or not license['endline']):
+                    license['text'].append(line.decode(errors='ignore'))
+                    actual_md5.update(line)
+        license['actual_md5'] = actual_md5.hexdigest()
+        licenses.append(license)
+    return licenses
+
+def _generate_license_diff(old_licenses, new_licenses):
+    need_diff = False
+    for l in new_licenses:
+        if l['md5'] != l['actual_md5']:
+            need_diff = True
+            break
+    if need_diff == False:
+        return None
+
+    import difflib
+    diff = ''
+    for old, new in zip(old_licenses, new_licenses):
+        for line in difflib.unified_diff(old['text'], new['text'], old['path'], new['path']):
+            diff = diff + line
+    return diff
+
+def upgrade(args, config, basepath, workspace):
+    """Entry point for the devtool 'upgrade' subcommand"""
+
+    if args.recipename in workspace:
+        raise DevtoolError("recipe %s is already in your workspace" % args.recipename)
+    if args.srcbranch and not args.srcrev:
+        raise DevtoolError("If you specify --srcbranch/-B then you must use --srcrev/-S to specify the revision" % args.recipename)
+
+    _check_git_config()
+
+    tinfoil = setup_tinfoil(basepath=basepath, tracking=True)
+    try:
+        rd = parse_recipe(config, tinfoil, args.recipename, True)
+        if not rd:
+            return 1
+
+        pn = rd.getVar('PN')
+        if pn != args.recipename:
+            logger.info('Mapping %s to %s' % (args.recipename, pn))
+        if pn in workspace:
+            raise DevtoolError("recipe %s is already in your workspace" % pn)
+
+        if args.srctree:
+            srctree = os.path.abspath(args.srctree)
+        else:
+            srctree = standard.get_default_srctree(config, pn)
+
+        # try to automatically discover latest version and revision if not provided on command line
+        if not args.version and not args.srcrev:
+            version_info = oe.recipeutils.get_recipe_upstream_version(rd)
+            if version_info['version'] and not version_info['version'].endswith("new-commits-available"):
+                args.version = version_info['version']
+            if version_info['revision']:
+                args.srcrev = version_info['revision']
+        if not args.version and not args.srcrev:
+            raise DevtoolError("Automatic discovery of latest version/revision failed - you must provide a version using the --version/-V option, or for recipes that fetch from an SCM such as git, the --srcrev/-S option.")
+
+        standard._check_compatible_recipe(pn, rd)
+        old_srcrev = rd.getVar('SRCREV')
+        if old_srcrev == 'INVALID':
+            old_srcrev = None
+        if old_srcrev and not args.srcrev:
+            raise DevtoolError("Recipe specifies a SRCREV value; you must specify a new one when upgrading")
+        old_ver = rd.getVar('PV')
+        if old_ver == args.version and old_srcrev == args.srcrev:
+            raise DevtoolError("Current and upgrade versions are the same version")
+        if args.version:
+            if bb.utils.vercmp_string(args.version, old_ver) < 0:
+                logger.warning('Upgrade version %s compares as less than the current version %s. If you are using a package feed for on-target upgrades or providing this recipe for general consumption, then you should increment PE in the recipe (or if there is no current PE value set, set it to "1")' % (args.version, old_ver))
+            check_prerelease_version(args.version, 'devtool upgrade')
+
+        rf = None
+        license_diff = None
+        try:
+            logger.info('Extracting current version source...')
+            rev1, srcsubdir1 = standard._extract_source(srctree, False, 'devtool-orig', False, config, basepath, workspace, args.fixed_setup, rd, tinfoil, no_overrides=args.no_overrides)
+            old_licenses = _extract_licenses(srctree, rd.getVar('LIC_FILES_CHKSUM'))
+            logger.info('Extracting upgraded version source...')
+            rev2, md5, sha256, srcbranch, srcsubdir2 = _extract_new_source(args.version, srctree, args.no_patch,
+                                                    args.srcrev, args.srcbranch, args.branch, args.keep_temp,
+                                                    tinfoil, rd)
+            new_licenses = _extract_licenses(srctree, rd.getVar('LIC_FILES_CHKSUM'))
+            license_diff = _generate_license_diff(old_licenses, new_licenses)
+            rf, copied = _create_new_recipe(args.version, md5, sha256, args.srcrev, srcbranch, srcsubdir1, srcsubdir2, config.workspace_path, tinfoil, rd, license_diff, new_licenses)
+        except bb.process.CmdError as e:
+            _upgrade_error(e, rf, srctree)
+        except DevtoolError as e:
+            _upgrade_error(e, rf, srctree)
+        standard._add_md5(config, pn, os.path.dirname(rf))
+
+        af = _write_append(rf, srctree, args.same_dir, args.no_same_dir, rev2,
+                        copied, config.workspace_path, rd)
+        standard._add_md5(config, pn, af)
+
+        update_unlockedsigs(basepath, workspace, args.fixed_setup, [pn])
+
+        logger.info('Upgraded source extracted to %s' % srctree)
+        logger.info('New recipe is %s' % rf)
+        if license_diff:
+            logger.info('License checksums have been updated in the new recipe; please refer to it for the difference between the old and the new license texts.')
+    finally:
+        tinfoil.shutdown()
+    return 0
+
+def latest_version(args, config, basepath, workspace):
+    """Entry point for the devtool 'latest_version' subcommand"""
+    tinfoil = setup_tinfoil(basepath=basepath, tracking=True)
+    try:
+        rd = parse_recipe(config, tinfoil, args.recipename, True)
+        if not rd:
+            return 1
+        version_info = oe.recipeutils.get_recipe_upstream_version(rd)
+        # "new-commits-available" is an indication that upstream never issues version tags
+        if not version_info['version'].endswith("new-commits-available"):
+            logger.info("Current version: {}".format(version_info['current_version']))
+            logger.info("Latest version: {}".format(version_info['version']))
+            if version_info['revision']:
+                logger.info("Latest version's commit: {}".format(version_info['revision']))
+        else:
+            logger.info("Latest commit: {}".format(version_info['revision']))
+    finally:
+        tinfoil.shutdown()
+    return 0
+
+def register_commands(subparsers, context):
+    """Register devtool subcommands from this plugin"""
+
+    defsrctree = standard.get_default_srctree(context.config)
+
+    parser_upgrade = subparsers.add_parser('upgrade', help='Upgrade an existing recipe',
+                                           description='Upgrades an existing recipe to a new upstream version. Puts the upgraded recipe file into the workspace along with any associated files, and extracts the source tree to a specified location (in case patches need rebasing or adding to as a result of the upgrade).',
+                                           group='starting')
+    parser_upgrade.add_argument('recipename', help='Name of recipe to upgrade (just name - no version, path or extension)')
+    parser_upgrade.add_argument('srctree',  nargs='?', help='Path to where to extract the source tree. If not specified, a subdirectory of %s will be used.' % defsrctree)
+    parser_upgrade.add_argument('--version', '-V', help='Version to upgrade to (PV). If omitted, latest upstream version will be determined and used, if possible.')
+    parser_upgrade.add_argument('--srcrev', '-S', help='Source revision to upgrade to (useful when fetching from an SCM such as git)')
+    parser_upgrade.add_argument('--srcbranch', '-B', help='Branch in source repository containing the revision to use (if fetching from an SCM such as git)')
+    parser_upgrade.add_argument('--branch', '-b', default="devtool", help='Name for new development branch to checkout (default "%(default)s")')
+    parser_upgrade.add_argument('--no-patch', action="store_true", help='Do not apply patches from the recipe to the new source code')
+    parser_upgrade.add_argument('--no-overrides', '-O', action="store_true", help='Do not create branches for other override configurations')
+    group = parser_upgrade.add_mutually_exclusive_group()
+    group.add_argument('--same-dir', '-s', help='Build in same directory as source', action="store_true")
+    group.add_argument('--no-same-dir', help='Force build in a separate build directory', action="store_true")
+    parser_upgrade.add_argument('--keep-temp', action="store_true", help='Keep temporary directory (for debugging)')
+    parser_upgrade.set_defaults(func=upgrade, fixed_setup=context.fixed_setup)
+
+    parser_latest_version = subparsers.add_parser('latest-version', help='Report the latest version of an existing recipe',
+                                                  description='Queries the upstream server for what the latest upstream release is (for git, tags are checked, for tarballs, a list of them is obtained, and one with the highest version number is reported)',
+                                                  group='info')
+    parser_latest_version.add_argument('recipename', help='Name of recipe to query (just name - no version, path or extension)')
+    parser_latest_version.set_defaults(func=latest_version)
diff --git a/meta/poky/scripts/lib/devtool/utilcmds.py b/meta/poky/scripts/lib/devtool/utilcmds.py
new file mode 100644
index 0000000..7cd139f
--- /dev/null
+++ b/meta/poky/scripts/lib/devtool/utilcmds.py
@@ -0,0 +1,252 @@
+# Development tool - utility commands plugin
+#
+# Copyright (C) 2015-2016 Intel Corporation
+#
+# 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.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+"""Devtool utility plugins"""
+
+import os
+import sys
+import shutil
+import tempfile
+import logging
+import argparse
+import subprocess
+import scriptutils
+from devtool import exec_build_env_command, setup_tinfoil, check_workspace_recipe, DevtoolError
+from devtool import parse_recipe
+
+logger = logging.getLogger('devtool')
+
+def _find_recipe_path(args, config, basepath, workspace):
+    if args.any_recipe:
+        logger.warning('-a/--any-recipe option is now always active, and thus the option will be removed in a future release')
+    if args.recipename in workspace:
+        recipefile = workspace[args.recipename]['recipefile']
+    else:
+        recipefile = None
+    if not recipefile:
+        tinfoil = setup_tinfoil(config_only=False, basepath=basepath)
+        try:
+            rd = parse_recipe(config, tinfoil, args.recipename, True)
+            if not rd:
+                raise DevtoolError("Failed to find specified recipe")
+            recipefile = rd.getVar('FILE')
+        finally:
+            tinfoil.shutdown()
+    return recipefile
+
+
+def find_recipe(args, config, basepath, workspace):
+    """Entry point for the devtool 'find-recipe' subcommand"""
+    recipefile = _find_recipe_path(args, config, basepath, workspace)
+    print(recipefile)
+    return 0
+
+
+def edit_recipe(args, config, basepath, workspace):
+    """Entry point for the devtool 'edit-recipe' subcommand"""
+    return scriptutils.run_editor(_find_recipe_path(args, config, basepath, workspace), logger)
+
+
+def configure_help(args, config, basepath, workspace):
+    """Entry point for the devtool 'configure-help' subcommand"""
+    import oe.utils
+
+    check_workspace_recipe(workspace, args.recipename)
+    tinfoil = setup_tinfoil(config_only=False, basepath=basepath)
+    try:
+        rd = parse_recipe(config, tinfoil, args.recipename, appends=True, filter_workspace=False)
+        if not rd:
+            return 1
+        b = rd.getVar('B')
+        s = rd.getVar('S')
+        configurescript = os.path.join(s, 'configure')
+        confdisabled = 'noexec' in rd.getVarFlags('do_configure') or 'do_configure' not in (rd.getVar('__BBTASKS', False) or [])
+        configureopts = oe.utils.squashspaces(rd.getVar('CONFIGUREOPTS') or '')
+        extra_oeconf = oe.utils.squashspaces(rd.getVar('EXTRA_OECONF') or '')
+        extra_oecmake = oe.utils.squashspaces(rd.getVar('EXTRA_OECMAKE') or '')
+        do_configure = rd.getVar('do_configure') or ''
+        do_configure_noexpand = rd.getVar('do_configure', False) or ''
+        packageconfig = rd.getVarFlags('PACKAGECONFIG') or []
+        autotools = bb.data.inherits_class('autotools', rd) and ('oe_runconf' in do_configure or 'autotools_do_configure' in do_configure)
+        cmake = bb.data.inherits_class('cmake', rd) and ('cmake_do_configure' in do_configure)
+        cmake_do_configure = rd.getVar('cmake_do_configure')
+        pn = rd.getVar('PN')
+    finally:
+        tinfoil.shutdown()
+
+    if 'doc' in packageconfig:
+        del packageconfig['doc']
+
+    if autotools and not os.path.exists(configurescript):
+        logger.info('Running do_configure to generate configure script')
+        try:
+            stdout, _ = exec_build_env_command(config.init_path, basepath,
+                                               'bitbake -c configure %s' % args.recipename,
+                                               stderr=subprocess.STDOUT)
+        except bb.process.ExecutionError:
+            pass
+
+    if confdisabled or do_configure.strip() in ('', ':'):
+        raise DevtoolError("do_configure task has been disabled for this recipe")
+    elif args.no_pager and not os.path.exists(configurescript):
+        raise DevtoolError("No configure script found and no other information to display")
+    else:
+        configopttext = ''
+        if autotools and configureopts:
+            configopttext = '''
+Arguments currently passed to the configure script:
+
+%s
+
+Some of those are fixed.''' % (configureopts + ' ' + extra_oeconf)
+            if extra_oeconf:
+                configopttext += ''' The ones that are specified through EXTRA_OECONF (which you can change or add to easily):
+
+%s''' % extra_oeconf
+
+        elif cmake:
+            in_cmake = False
+            cmake_cmd = ''
+            for line in cmake_do_configure.splitlines():
+                if in_cmake:
+                    cmake_cmd = cmake_cmd + ' ' + line.strip().rstrip('\\')
+                    if not line.endswith('\\'):
+                        break
+                if line.lstrip().startswith('cmake '):
+                    cmake_cmd = line.strip().rstrip('\\')
+                    if line.endswith('\\'):
+                        in_cmake = True
+                    else:
+                        break
+            if cmake_cmd:
+                configopttext = '''
+The current cmake command line:
+
+%s
+
+Arguments specified through EXTRA_OECMAKE (which you can change or add to easily)
+
+%s''' % (oe.utils.squashspaces(cmake_cmd), extra_oecmake)
+            else:
+                configopttext = '''
+The current implementation of cmake_do_configure:
+
+cmake_do_configure() {
+%s
+}
+
+Arguments specified through EXTRA_OECMAKE (which you can change or add to easily)
+
+%s''' % (cmake_do_configure.rstrip(), extra_oecmake)
+
+        elif do_configure:
+            configopttext = '''
+The current implementation of do_configure:
+
+do_configure() {
+%s
+}''' % do_configure.rstrip()
+            if '${EXTRA_OECONF}' in do_configure_noexpand:
+                configopttext += '''
+
+Arguments specified through EXTRA_OECONF (which you can change or add to easily):
+
+%s''' % extra_oeconf
+
+        if packageconfig:
+            configopttext += '''
+
+Some of these options may be controlled through PACKAGECONFIG; for more details please see the recipe.'''
+
+        if args.arg:
+            helpargs = ' '.join(args.arg)
+        elif cmake:
+            helpargs = '-LH'
+        else:
+            helpargs = '--help'
+
+        msg = '''configure information for %s
+------------------------------------------
+%s''' % (pn, configopttext)
+
+        if cmake:
+            msg += '''
+
+The cmake %s output for %s follows. After "-- Cache values" you should see a list of variables you can add to EXTRA_OECMAKE (prefixed with -D and suffixed with = followed by the desired value, without any spaces).
+------------------------------------------''' % (helpargs, pn)
+        elif os.path.exists(configurescript):
+            msg += '''
+
+The ./configure %s output for %s follows.
+------------------------------------------''' % (helpargs, pn)
+
+        olddir = os.getcwd()
+        tmppath = tempfile.mkdtemp()
+        with tempfile.NamedTemporaryFile('w', delete=False) as tf:
+            if not args.no_header:
+                tf.write(msg + '\n')
+            tf.close()
+            try:
+                try:
+                    cmd = 'cat %s' % tf.name
+                    if cmake:
+                        cmd += '; cmake %s %s 2>&1' % (helpargs, s)
+                        os.chdir(b)
+                    elif os.path.exists(configurescript):
+                        cmd += '; %s %s' % (configurescript, helpargs)
+                    if sys.stdout.isatty() and not args.no_pager:
+                        pager = os.environ.get('PAGER', 'less')
+                        cmd = '(%s) | %s' % (cmd, pager)
+                    subprocess.check_call(cmd, shell=True)
+                except subprocess.CalledProcessError as e:
+                    return e.returncode
+            finally:
+                os.chdir(olddir)
+                shutil.rmtree(tmppath)
+                os.remove(tf.name)
+
+
+def register_commands(subparsers, context):
+    """Register devtool subcommands from this plugin"""
+    parser_edit_recipe = subparsers.add_parser('edit-recipe', help='Edit a recipe file',
+                                         description='Runs the default editor (as specified by the EDITOR variable) on the specified recipe. Note that this will be quicker for recipes in the workspace as the cache does not need to be loaded in that case.',
+                                         group='working')
+    parser_edit_recipe.add_argument('recipename', help='Recipe to edit')
+    # FIXME drop -a at some point in future
+    parser_edit_recipe.add_argument('--any-recipe', '-a', action="store_true", help='Does nothing (exists for backwards-compatibility)')
+    parser_edit_recipe.set_defaults(func=edit_recipe)
+
+    # Find-recipe
+    parser_find_recipe = subparsers.add_parser('find-recipe', help='Find a recipe file',
+                                         description='Finds a recipe file. Note that this will be quicker for recipes in the workspace as the cache does not need to be loaded in that case.',
+                                         group='working')
+    parser_find_recipe.add_argument('recipename', help='Recipe to find')
+    # FIXME drop -a at some point in future
+    parser_find_recipe.add_argument('--any-recipe', '-a', action="store_true", help='Does nothing (exists for backwards-compatibility)')
+    parser_find_recipe.set_defaults(func=find_recipe)
+
+    # NOTE: Needed to override the usage string here since the default
+    # gets the order wrong - recipename must come before --arg
+    parser_configure_help = subparsers.add_parser('configure-help', help='Get help on configure script options',
+                                         usage='devtool configure-help [options] recipename [--arg ...]',
+                                         description='Displays the help for the configure script for the specified recipe (i.e. runs ./configure --help) prefaced by a header describing the current options being specified. Output is piped through less (or whatever PAGER is set to, if set) for easy browsing.',
+                                         group='working')
+    parser_configure_help.add_argument('recipename', help='Recipe to show configure help for')
+    parser_configure_help.add_argument('-p', '--no-pager', help='Disable paged output', action="store_true")
+    parser_configure_help.add_argument('-n', '--no-header', help='Disable explanatory header text', action="store_true")
+    parser_configure_help.add_argument('--arg', help='Pass remaining arguments to the configure script instead of --help (useful if the script has additional help options)', nargs=argparse.REMAINDER)
+    parser_configure_help.set_defaults(func=configure_help)
diff --git a/meta/poky/scripts/lib/recipetool/__init__.py b/meta/poky/scripts/lib/recipetool/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/meta/poky/scripts/lib/recipetool/__init__.py
diff --git a/meta/poky/scripts/lib/recipetool/append.py b/meta/poky/scripts/lib/recipetool/append.py
new file mode 100644
index 0000000..3f2c134
--- /dev/null
+++ b/meta/poky/scripts/lib/recipetool/append.py
@@ -0,0 +1,457 @@
+# Recipe creation tool - append plugin
+#
+# Copyright (C) 2015 Intel Corporation
+#
+# 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.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+import sys
+import os
+import argparse
+import glob
+import fnmatch
+import re
+import subprocess
+import logging
+import stat
+import shutil
+import scriptutils
+import errno
+from collections import defaultdict
+
+logger = logging.getLogger('recipetool')
+
+tinfoil = None
+
+def tinfoil_init(instance):
+    global tinfoil
+    tinfoil = instance
+
+
+# FIXME guessing when we don't have pkgdata?
+# FIXME mode to create patch rather than directly substitute
+
+class InvalidTargetFileError(Exception):
+    pass
+
+def find_target_file(targetpath, d, pkglist=None):
+    """Find the recipe installing the specified target path, optionally limited to a select list of packages"""
+    import json
+
+    pkgdata_dir = d.getVar('PKGDATA_DIR')
+
+    # The mix between /etc and ${sysconfdir} here may look odd, but it is just
+    # being consistent with usage elsewhere
+    invalidtargets = {'${sysconfdir}/version': '${sysconfdir}/version is written out at image creation time',
+                      '/etc/timestamp': '/etc/timestamp is written out at image creation time',
+                      '/dev/*': '/dev is handled by udev (or equivalent) and the kernel (devtmpfs)',
+                      '/etc/passwd': '/etc/passwd should be managed through the useradd and extrausers classes',
+                      '/etc/group': '/etc/group should be managed through the useradd and extrausers classes',
+                      '/etc/shadow': '/etc/shadow should be managed through the useradd and extrausers classes',
+                      '/etc/gshadow': '/etc/gshadow should be managed through the useradd and extrausers classes',
+                      '${sysconfdir}/hostname': '${sysconfdir}/hostname contents should be set by setting hostname_pn-base-files = "value" in configuration',}
+
+    for pthspec, message in invalidtargets.items():
+        if fnmatch.fnmatchcase(targetpath, d.expand(pthspec)):
+            raise InvalidTargetFileError(d.expand(message))
+
+    targetpath_re = re.compile(r'\s+(\$D)?%s(\s|$)' % targetpath)
+
+    recipes = defaultdict(list)
+    for root, dirs, files in os.walk(os.path.join(pkgdata_dir, 'runtime')):
+        if pkglist:
+            filelist = pkglist
+        else:
+            filelist = files
+        for fn in filelist:
+            pkgdatafile = os.path.join(root, fn)
+            if pkglist and not os.path.exists(pkgdatafile):
+                continue
+            with open(pkgdatafile, 'r') as f:
+                pn = ''
+                # This does assume that PN comes before other values, but that's a fairly safe assumption
+                for line in f:
+                    if line.startswith('PN:'):
+                        pn = line.split(':', 1)[1].strip()
+                    elif line.startswith('FILES_INFO:'):
+                        val = line.split(':', 1)[1].strip()
+                        dictval = json.loads(val)
+                        for fullpth in dictval.keys():
+                            if fnmatch.fnmatchcase(fullpth, targetpath):
+                                recipes[targetpath].append(pn)
+                    elif line.startswith('pkg_preinst_') or line.startswith('pkg_postinst_'):
+                        scriptval = line.split(':', 1)[1].strip().encode('utf-8').decode('unicode_escape')
+                        if 'update-alternatives --install %s ' % targetpath in scriptval:
+                            recipes[targetpath].append('?%s' % pn)
+                        elif targetpath_re.search(scriptval):
+                            recipes[targetpath].append('!%s' % pn)
+    return recipes
+
+def _parse_recipe(pn, tinfoil):
+    try:
+        rd = tinfoil.parse_recipe(pn)
+    except bb.providers.NoProvider as e:
+        logger.error(str(e))
+        return None
+    return rd
+
+def determine_file_source(targetpath, rd):
+    """Assuming we know a file came from a specific recipe, figure out exactly where it came from"""
+    import oe.recipeutils
+
+    # See if it's in do_install for the recipe
+    workdir = rd.getVar('WORKDIR')
+    src_uri = rd.getVar('SRC_URI')
+    srcfile = ''
+    modpatches = []
+    elements = check_do_install(rd, targetpath)
+    if elements:
+        logger.debug('do_install line:\n%s' % ' '.join(elements))
+        srcpath = get_source_path(elements)
+        logger.debug('source path: %s' % srcpath)
+        if not srcpath.startswith('/'):
+            # Handle non-absolute path
+            srcpath = os.path.abspath(os.path.join(rd.getVarFlag('do_install', 'dirs').split()[-1], srcpath))
+        if srcpath.startswith(workdir):
+            # OK, now we have the source file name, look for it in SRC_URI
+            workdirfile = os.path.relpath(srcpath, workdir)
+            # FIXME this is where we ought to have some code in the fetcher, because this is naive
+            for item in src_uri.split():
+                localpath = bb.fetch2.localpath(item, rd)
+                # Source path specified in do_install might be a glob
+                if fnmatch.fnmatch(os.path.basename(localpath), workdirfile):
+                    srcfile = 'file://%s' % localpath
+                elif '/' in workdirfile:
+                    if item == 'file://%s' % workdirfile:
+                        srcfile = 'file://%s' % localpath
+
+        # Check patches
+        srcpatches = []
+        patchedfiles = oe.recipeutils.get_recipe_patched_files(rd)
+        for patch, filelist in patchedfiles.items():
+            for fileitem in filelist:
+                if fileitem[0] == srcpath:
+                    srcpatches.append((patch, fileitem[1]))
+        if srcpatches:
+            addpatch = None
+            for patch in srcpatches:
+                if patch[1] == 'A':
+                    addpatch = patch[0]
+                else:
+                    modpatches.append(patch[0])
+            if addpatch:
+                srcfile = 'patch://%s' % addpatch
+
+    return (srcfile, elements, modpatches)
+
+def get_source_path(cmdelements):
+    """Find the source path specified within a command"""
+    command = cmdelements[0]
+    if command in ['install', 'cp']:
+        helptext = subprocess.check_output('LC_ALL=C %s --help' % command, shell=True).decode('utf-8')
+        argopts = ''
+        argopt_line_re = re.compile('^-([a-zA-Z0-9]), --[a-z-]+=')
+        for line in helptext.splitlines():
+            line = line.lstrip()
+            res = argopt_line_re.search(line)
+            if res:
+                argopts += res.group(1)
+        if not argopts:
+            # Fallback
+            if command == 'install':
+                argopts = 'gmoSt'
+            elif command == 'cp':
+                argopts = 't'
+            else:
+                raise Exception('No fallback arguments for command %s' % command)
+
+        skipnext = False
+        for elem in cmdelements[1:-1]:
+            if elem.startswith('-'):
+                if len(elem) > 1 and elem[1] in argopts:
+                    skipnext = True
+                continue
+            if skipnext:
+                skipnext = False
+                continue
+            return elem
+    else:
+        raise Exception('get_source_path: no handling for command "%s"')
+
+def get_func_deps(func, d):
+    """Find the function dependencies of a shell function"""
+    deps = bb.codeparser.ShellParser(func, logger).parse_shell(d.getVar(func))
+    deps |= set((d.getVarFlag(func, "vardeps") or "").split())
+    funcdeps = []
+    for dep in deps:
+        if d.getVarFlag(dep, 'func'):
+            funcdeps.append(dep)
+    return funcdeps
+
+def check_do_install(rd, targetpath):
+    """Look at do_install for a command that installs/copies the specified target path"""
+    instpath = os.path.abspath(os.path.join(rd.getVar('D'), targetpath.lstrip('/')))
+    do_install = rd.getVar('do_install')
+    # Handle where do_install calls other functions (somewhat crudely, but good enough for this purpose)
+    deps = get_func_deps('do_install', rd)
+    for dep in deps:
+        do_install = do_install.replace(dep, rd.getVar(dep))
+
+    # Look backwards through do_install as we want to catch where a later line (perhaps
+    # from a bbappend) is writing over the top
+    for line in reversed(do_install.splitlines()):
+        line = line.strip()
+        if (line.startswith('install ') and ' -m' in line) or line.startswith('cp '):
+            elements = line.split()
+            destpath = os.path.abspath(elements[-1])
+            if destpath == instpath:
+                return elements
+            elif destpath.rstrip('/') == os.path.dirname(instpath):
+                # FIXME this doesn't take recursive copy into account; unsure if it's practical to do so
+                srcpath = get_source_path(elements)
+                if fnmatch.fnmatchcase(os.path.basename(instpath), os.path.basename(srcpath)):
+                    return elements
+    return None
+
+
+def appendfile(args):
+    import oe.recipeutils
+
+    stdout = ''
+    try:
+        (stdout, _) = bb.process.run('LANG=C file -b %s' % args.newfile, shell=True)
+        if 'cannot open' in stdout:
+            raise bb.process.ExecutionError(stdout)
+    except bb.process.ExecutionError as err:
+        logger.debug('file command returned error: %s' % err)
+        stdout = ''
+    if stdout:
+        logger.debug('file command output: %s' % stdout.rstrip())
+        if ('executable' in stdout and not 'shell script' in stdout) or 'shared object' in stdout:
+            logger.warning('This file looks like it is a binary or otherwise the output of compilation. If it is, you should consider building it properly instead of substituting a binary file directly.')
+
+    if args.recipe:
+        recipes = {args.targetpath: [args.recipe],}
+    else:
+        try:
+            recipes = find_target_file(args.targetpath, tinfoil.config_data)
+        except InvalidTargetFileError as e:
+            logger.error('%s cannot be handled by this tool: %s' % (args.targetpath, e))
+            return 1
+        if not recipes:
+            logger.error('Unable to find any package producing path %s - this may be because the recipe packaging it has not been built yet' % args.targetpath)
+            return 1
+
+    alternative_pns = []
+    postinst_pns = []
+
+    selectpn = None
+    for targetpath, pnlist in recipes.items():
+        for pn in pnlist:
+            if pn.startswith('?'):
+                alternative_pns.append(pn[1:])
+            elif pn.startswith('!'):
+                postinst_pns.append(pn[1:])
+            elif selectpn:
+                # hit here with multilibs
+                continue
+            else:
+                selectpn = pn
+
+    if not selectpn and len(alternative_pns) == 1:
+        selectpn = alternative_pns[0]
+        logger.error('File %s is an alternative possibly provided by recipe %s but seemingly no other, selecting it by default - you should double check other recipes' % (args.targetpath, selectpn))
+
+    if selectpn:
+        logger.debug('Selecting recipe %s for file %s' % (selectpn, args.targetpath))
+        if postinst_pns:
+            logger.warning('%s be modified by postinstall scripts for the following recipes:\n  %s\nThis may or may not be an issue depending on what modifications these postinstall scripts make.' % (args.targetpath, '\n  '.join(postinst_pns)))
+        rd = _parse_recipe(selectpn, tinfoil)
+        if not rd:
+            # Error message already shown
+            return 1
+        sourcefile, instelements, modpatches = determine_file_source(args.targetpath, rd)
+        sourcepath = None
+        if sourcefile:
+            sourcetype, sourcepath = sourcefile.split('://', 1)
+            logger.debug('Original source file is %s (%s)' % (sourcepath, sourcetype))
+            if sourcetype == 'patch':
+                logger.warning('File %s is added by the patch %s - you may need to remove or replace this patch in order to replace the file.' % (args.targetpath, sourcepath))
+                sourcepath = None
+        else:
+            logger.debug('Unable to determine source file, proceeding anyway')
+        if modpatches:
+            logger.warning('File %s is modified by the following patches:\n  %s' % (args.targetpath, '\n  '.join(modpatches)))
+
+        if instelements and sourcepath:
+            install = None
+        else:
+            # Auto-determine permissions
+            # Check destination
+            binpaths = '${bindir}:${sbindir}:${base_bindir}:${base_sbindir}:${libexecdir}:${sysconfdir}/init.d'
+            perms = '0644'
+            if os.path.abspath(os.path.dirname(args.targetpath)) in rd.expand(binpaths).split(':'):
+                # File is going into a directory normally reserved for executables, so it should be executable
+                perms = '0755'
+            else:
+                # Check source
+                st = os.stat(args.newfile)
+                if st.st_mode & stat.S_IXUSR:
+                    perms = '0755'
+            install = {args.newfile: (args.targetpath, perms)}
+        oe.recipeutils.bbappend_recipe(rd, args.destlayer, {args.newfile: sourcepath}, install, wildcardver=args.wildcard_version, machine=args.machine)
+        return 0
+    else:
+        if alternative_pns:
+            logger.error('File %s is an alternative possibly provided by the following recipes:\n  %s\nPlease select recipe with -r/--recipe' % (targetpath, '\n  '.join(alternative_pns)))
+        elif postinst_pns:
+            logger.error('File %s may be written out in a pre/postinstall script of the following recipes:\n  %s\nPlease select recipe with -r/--recipe' % (targetpath, '\n  '.join(postinst_pns)))
+        return 3
+
+
+def appendsrc(args, files, rd, extralines=None):
+    import oe.recipeutils
+
+    srcdir = rd.getVar('S')
+    workdir = rd.getVar('WORKDIR')
+
+    import bb.fetch
+    simplified = {}
+    src_uri = rd.getVar('SRC_URI').split()
+    for uri in src_uri:
+        if uri.endswith(';'):
+            uri = uri[:-1]
+        simple_uri = bb.fetch.URI(uri)
+        simple_uri.params = {}
+        simplified[str(simple_uri)] = uri
+
+    copyfiles = {}
+    extralines = extralines or []
+    for newfile, srcfile in files.items():
+        src_destdir = os.path.dirname(srcfile)
+        if not args.use_workdir:
+            if rd.getVar('S') == rd.getVar('STAGING_KERNEL_DIR'):
+                srcdir = os.path.join(workdir, 'git')
+                if not bb.data.inherits_class('kernel-yocto', rd):
+                    logger.warning('S == STAGING_KERNEL_DIR and non-kernel-yocto, unable to determine path to srcdir, defaulting to ${WORKDIR}/git')
+            src_destdir = os.path.join(os.path.relpath(srcdir, workdir), src_destdir)
+        src_destdir = os.path.normpath(src_destdir)
+
+        source_uri = 'file://{0}'.format(os.path.basename(srcfile))
+        if src_destdir and src_destdir != '.':
+            source_uri += ';subdir={0}'.format(src_destdir)
+
+        simple = bb.fetch.URI(source_uri)
+        simple.params = {}
+        simple_str = str(simple)
+        if simple_str in simplified:
+            existing = simplified[simple_str]
+            if source_uri != existing:
+                logger.warning('{0!r} is already in SRC_URI, with different parameters: {1!r}, not adding'.format(source_uri, existing))
+            else:
+                logger.warning('{0!r} is already in SRC_URI, not adding'.format(source_uri))
+        else:
+            extralines.append('SRC_URI += {0}'.format(source_uri))
+        copyfiles[newfile] = srcfile
+
+    oe.recipeutils.bbappend_recipe(rd, args.destlayer, copyfiles, None, wildcardver=args.wildcard_version, machine=args.machine, extralines=extralines)
+
+
+def appendsrcfiles(parser, args):
+    recipedata = _parse_recipe(args.recipe, tinfoil)
+    if not recipedata:
+        parser.error('RECIPE must be a valid recipe name')
+
+    files = dict((f, os.path.join(args.destdir, os.path.basename(f)))
+                 for f in args.files)
+    return appendsrc(args, files, recipedata)
+
+
+def appendsrcfile(parser, args):
+    recipedata = _parse_recipe(args.recipe, tinfoil)
+    if not recipedata:
+        parser.error('RECIPE must be a valid recipe name')
+
+    if not args.destfile:
+        args.destfile = os.path.basename(args.file)
+    elif args.destfile.endswith('/'):
+        args.destfile = os.path.join(args.destfile, os.path.basename(args.file))
+
+    return appendsrc(args, {args.file: args.destfile}, recipedata)
+
+
+def layer(layerpath):
+    if not os.path.exists(os.path.join(layerpath, 'conf', 'layer.conf')):
+        raise argparse.ArgumentTypeError('{0!r} must be a path to a valid layer'.format(layerpath))
+    return layerpath
+
+
+def existing_path(filepath):
+    if not os.path.exists(filepath):
+        raise argparse.ArgumentTypeError('{0!r} must be an existing path'.format(filepath))
+    return filepath
+
+
+def existing_file(filepath):
+    filepath = existing_path(filepath)
+    if os.path.isdir(filepath):
+        raise argparse.ArgumentTypeError('{0!r} must be a file, not a directory'.format(filepath))
+    return filepath
+
+
+def destination_path(destpath):
+    if os.path.isabs(destpath):
+        raise argparse.ArgumentTypeError('{0!r} must be a relative path, not absolute'.format(destpath))
+    return destpath
+
+
+def target_path(targetpath):
+    if not os.path.isabs(targetpath):
+        raise argparse.ArgumentTypeError('{0!r} must be an absolute path, not relative'.format(targetpath))
+    return targetpath
+
+
+def register_commands(subparsers):
+    common = argparse.ArgumentParser(add_help=False)
+    common.add_argument('-m', '--machine', help='Make bbappend changes specific to a machine only', metavar='MACHINE')
+    common.add_argument('-w', '--wildcard-version', help='Use wildcard to make the bbappend apply to any recipe version', action='store_true')
+    common.add_argument('destlayer', metavar='DESTLAYER', help='Base directory of the destination layer to write the bbappend to', type=layer)
+
+    parser_appendfile = subparsers.add_parser('appendfile',
+                                              parents=[common],
+                                              help='Create/update a bbappend to replace a target file',
+                                              description='Creates a bbappend (or updates an existing one) to replace the specified file that appears in the target system, determining the recipe that packages the file and the required path and name for the bbappend automatically. Note that the ability to determine the recipe packaging a particular file depends upon the recipe\'s do_packagedata task having already run prior to running this command (which it will have when the recipe has been built successfully, which in turn will have happened if one or more of the recipe\'s packages is included in an image that has been built successfully).')
+    parser_appendfile.add_argument('targetpath', help='Path to the file to be replaced (as it would appear within the target image, e.g. /etc/motd)', type=target_path)
+    parser_appendfile.add_argument('newfile', help='Custom file to replace the target file with', type=existing_file)
+    parser_appendfile.add_argument('-r', '--recipe', help='Override recipe to apply to (default is to find which recipe already packages the file)')
+    parser_appendfile.set_defaults(func=appendfile, parserecipes=True)
+
+    common_src = argparse.ArgumentParser(add_help=False, parents=[common])
+    common_src.add_argument('-W', '--workdir', help='Unpack file into WORKDIR rather than S', dest='use_workdir', action='store_true')
+    common_src.add_argument('recipe', metavar='RECIPE', help='Override recipe to apply to')
+
+    parser = subparsers.add_parser('appendsrcfiles',
+                                   parents=[common_src],
+                                   help='Create/update a bbappend to add or replace source files',
+                                   description='Creates a bbappend (or updates an existing one) to add or replace the specified file in the recipe sources, either those in WORKDIR or those in the source tree. This command lets you specify multiple files with a destination directory, so cannot specify the destination filename. See the `appendsrcfile` command for the other behavior.')
+    parser.add_argument('-D', '--destdir', help='Destination directory (relative to S or WORKDIR, defaults to ".")', default='', type=destination_path)
+    parser.add_argument('files', nargs='+', metavar='FILE', help='File(s) to be added to the recipe sources (WORKDIR or S)', type=existing_path)
+    parser.set_defaults(func=lambda a: appendsrcfiles(parser, a), parserecipes=True)
+
+    parser = subparsers.add_parser('appendsrcfile',
+                                   parents=[common_src],
+                                   help='Create/update a bbappend to add or replace a source file',
+                                   description='Creates a bbappend (or updates an existing one) to add or replace the specified files in the recipe sources, either those in WORKDIR or those in the source tree. This command lets you specify the destination filename, not just destination directory, but only works for one file. See the `appendsrcfiles` command for the other behavior.')
+    parser.add_argument('file', metavar='FILE', help='File to be added to the recipe sources (WORKDIR or S)', type=existing_path)
+    parser.add_argument('destfile', metavar='DESTFILE', nargs='?', help='Destination path (relative to S or WORKDIR, optional)', type=destination_path)
+    parser.set_defaults(func=lambda a: appendsrcfile(parser, a), parserecipes=True)
diff --git a/meta/poky/scripts/lib/recipetool/create.py b/meta/poky/scripts/lib/recipetool/create.py
new file mode 100644
index 0000000..dbd74a1
--- /dev/null
+++ b/meta/poky/scripts/lib/recipetool/create.py
@@ -0,0 +1,1329 @@
+# Recipe creation tool - create command plugin
+#
+# Copyright (C) 2014-2017 Intel Corporation
+#
+# 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.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+import sys
+import os
+import argparse
+import glob
+import fnmatch
+import re
+import json
+import logging
+import scriptutils
+from urllib.parse import urlparse, urldefrag, urlsplit
+import hashlib
+import bb.fetch2
+logger = logging.getLogger('recipetool')
+
+tinfoil = None
+plugins = None
+
+def log_error_cond(message, debugonly):
+    if debugonly:
+        logger.debug(message)
+    else:
+        logger.error(message)
+
+def log_info_cond(message, debugonly):
+    if debugonly:
+        logger.debug(message)
+    else:
+        logger.info(message)
+
+def plugin_init(pluginlist):
+    # Take a reference to the list so we can use it later
+    global plugins
+    plugins = pluginlist
+
+def tinfoil_init(instance):
+    global tinfoil
+    tinfoil = instance
+
+class RecipeHandler(object):
+    recipelibmap = {}
+    recipeheadermap = {}
+    recipecmakefilemap = {}
+    recipebinmap = {}
+
+    def __init__(self):
+        self._devtool = False
+
+    @staticmethod
+    def load_libmap(d):
+        '''Load library->recipe mapping'''
+        import oe.package
+
+        if RecipeHandler.recipelibmap:
+            return
+        # First build up library->package mapping
+        shlib_providers = oe.package.read_shlib_providers(d)
+        libdir = d.getVar('libdir')
+        base_libdir = d.getVar('base_libdir')
+        libpaths = list(set([base_libdir, libdir]))
+        libname_re = re.compile('^lib(.+)\.so.*$')
+        pkglibmap = {}
+        for lib, item in shlib_providers.items():
+            for path, pkg in item.items():
+                if path in libpaths:
+                    res = libname_re.match(lib)
+                    if res:
+                        libname = res.group(1)
+                        if not libname in pkglibmap:
+                            pkglibmap[libname] = pkg[0]
+                    else:
+                        logger.debug('unable to extract library name from %s' % lib)
+
+        # Now turn it into a library->recipe mapping
+        pkgdata_dir = d.getVar('PKGDATA_DIR')
+        for libname, pkg in pkglibmap.items():
+            try:
+                with open(os.path.join(pkgdata_dir, 'runtime', pkg)) as f:
+                    for line in f:
+                        if line.startswith('PN:'):
+                            RecipeHandler.recipelibmap[libname] = line.split(':', 1)[-1].strip()
+                            break
+            except IOError as ioe:
+                if ioe.errno == 2:
+                    logger.warning('unable to find a pkgdata file for package %s' % pkg)
+                else:
+                    raise
+
+        # Some overrides - these should be mapped to the virtual
+        RecipeHandler.recipelibmap['GL'] = 'virtual/libgl'
+        RecipeHandler.recipelibmap['EGL'] = 'virtual/egl'
+        RecipeHandler.recipelibmap['GLESv2'] = 'virtual/libgles2'
+
+    @staticmethod
+    def load_devel_filemap(d):
+        '''Build up development file->recipe mapping'''
+        if RecipeHandler.recipeheadermap:
+            return
+        pkgdata_dir = d.getVar('PKGDATA_DIR')
+        includedir = d.getVar('includedir')
+        cmakedir = os.path.join(d.getVar('libdir'), 'cmake')
+        for pkg in glob.glob(os.path.join(pkgdata_dir, 'runtime', '*-dev')):
+            with open(os.path.join(pkgdata_dir, 'runtime', pkg)) as f:
+                pn = None
+                headers = []
+                cmakefiles = []
+                for line in f:
+                    if line.startswith('PN:'):
+                        pn = line.split(':', 1)[-1].strip()
+                    elif line.startswith('FILES_INFO:'):
+                        val = line.split(':', 1)[1].strip()
+                        dictval = json.loads(val)
+                        for fullpth in sorted(dictval):
+                            if fullpth.startswith(includedir) and fullpth.endswith('.h'):
+                                headers.append(os.path.relpath(fullpth, includedir))
+                            elif fullpth.startswith(cmakedir) and fullpth.endswith('.cmake'):
+                                cmakefiles.append(os.path.relpath(fullpth, cmakedir))
+                if pn and headers:
+                    for header in headers:
+                        RecipeHandler.recipeheadermap[header] = pn
+                if pn and cmakefiles:
+                    for fn in cmakefiles:
+                        RecipeHandler.recipecmakefilemap[fn] = pn
+
+    @staticmethod
+    def load_binmap(d):
+        '''Build up native binary->recipe mapping'''
+        if RecipeHandler.recipebinmap:
+            return
+        sstate_manifests = d.getVar('SSTATE_MANIFESTS')
+        staging_bindir_native = d.getVar('STAGING_BINDIR_NATIVE')
+        build_arch = d.getVar('BUILD_ARCH')
+        fileprefix = 'manifest-%s-' % build_arch
+        for fn in glob.glob(os.path.join(sstate_manifests, '%s*-native.populate_sysroot' % fileprefix)):
+            with open(fn, 'r') as f:
+                pn = os.path.basename(fn).rsplit('.', 1)[0][len(fileprefix):]
+                for line in f:
+                    if line.startswith(staging_bindir_native):
+                        prog = os.path.basename(line.rstrip())
+                        RecipeHandler.recipebinmap[prog] = pn
+
+    @staticmethod
+    def checkfiles(path, speclist, recursive=False, excludedirs=None):
+        results = []
+        if recursive:
+            for root, dirs, files in os.walk(path, topdown=True):
+                if excludedirs:
+                    dirs[:] = [d for d in dirs if d not in excludedirs]
+                for fn in files:
+                    for spec in speclist:
+                        if fnmatch.fnmatch(fn, spec):
+                            results.append(os.path.join(root, fn))
+        else:
+            for spec in speclist:
+                results.extend(glob.glob(os.path.join(path, spec)))
+        return results
+
+    @staticmethod
+    def handle_depends(libdeps, pcdeps, deps, outlines, values, d):
+        if pcdeps:
+            recipemap = read_pkgconfig_provides(d)
+        if libdeps:
+            RecipeHandler.load_libmap(d)
+
+        ignorelibs = ['socket']
+        ignoredeps = ['gcc-runtime', 'glibc', 'uclibc', 'musl', 'tar-native', 'binutils-native', 'coreutils-native']
+
+        unmappedpc = []
+        pcdeps = list(set(pcdeps))
+        for pcdep in pcdeps:
+            if isinstance(pcdep, str):
+                recipe = recipemap.get(pcdep, None)
+                if recipe:
+                    deps.append(recipe)
+                else:
+                    if not pcdep.startswith('$'):
+                        unmappedpc.append(pcdep)
+            else:
+                for item in pcdep:
+                    recipe = recipemap.get(pcdep, None)
+                    if recipe:
+                        deps.append(recipe)
+                        break
+                else:
+                    unmappedpc.append('(%s)' % ' or '.join(pcdep))
+
+        unmappedlibs = []
+        for libdep in libdeps:
+            if isinstance(libdep, tuple):
+                lib, header = libdep
+            else:
+                lib = libdep
+                header = None
+
+            if lib in ignorelibs:
+                logger.debug('Ignoring library dependency %s' % lib)
+                continue
+
+            recipe = RecipeHandler.recipelibmap.get(lib, None)
+            if recipe:
+                deps.append(recipe)
+            elif recipe is None:
+                if header:
+                    RecipeHandler.load_devel_filemap(d)
+                    recipe = RecipeHandler.recipeheadermap.get(header, None)
+                    if recipe:
+                        deps.append(recipe)
+                    elif recipe is None:
+                        unmappedlibs.append(lib)
+                else:
+                    unmappedlibs.append(lib)
+
+        deps = set(deps).difference(set(ignoredeps))
+
+        if unmappedpc:
+            outlines.append('# NOTE: unable to map the following pkg-config dependencies: %s' % ' '.join(unmappedpc))
+            outlines.append('#       (this is based on recipes that have previously been built and packaged)')
+
+        if unmappedlibs:
+            outlines.append('# NOTE: the following library dependencies are unknown, ignoring: %s' % ' '.join(list(set(unmappedlibs))))
+            outlines.append('#       (this is based on recipes that have previously been built and packaged)')
+
+        if deps:
+            values['DEPENDS'] = ' '.join(deps)
+
+    @staticmethod
+    def genfunction(outlines, funcname, content, python=False, forcespace=False):
+        if python:
+            prefix = 'python '
+        else:
+            prefix = ''
+        outlines.append('%s%s () {' % (prefix, funcname))
+        if python or forcespace:
+            indent = '    '
+        else:
+            indent = '\t'
+        addnoop = not python
+        for line in content:
+            outlines.append('%s%s' % (indent, line))
+            if addnoop:
+                strippedline = line.lstrip()
+                if strippedline and not strippedline.startswith('#'):
+                    addnoop = False
+        if addnoop:
+            # Without this there'll be a syntax error
+            outlines.append('%s:' % indent)
+        outlines.append('}')
+        outlines.append('')
+
+    def process(self, srctree, classes, lines_before, lines_after, handled, extravalues):
+        return False
+
+
+def validate_pv(pv):
+    if not pv or '_version' in pv.lower() or pv[0] not in '0123456789':
+        return False
+    return True
+
+def determine_from_filename(srcfile):
+    """Determine name and version from a filename"""
+    if is_package(srcfile):
+        # Force getting the value from the package metadata
+        return None, None
+
+    if '.tar.' in srcfile:
+        namepart = srcfile.split('.tar.')[0]
+    else:
+        namepart = os.path.splitext(srcfile)[0]
+    namepart = namepart.lower().replace('_', '-')
+    if namepart.endswith('.src'):
+        namepart = namepart[:-4]
+    if namepart.endswith('.orig'):
+        namepart = namepart[:-5]
+    splitval = namepart.split('-')
+    logger.debug('determine_from_filename: split name %s into: %s' % (srcfile, splitval))
+
+    ver_re = re.compile('^v?[0-9]')
+
+    pv = None
+    pn = None
+    if len(splitval) == 1:
+        # Try to split the version out if there is no separator (or a .)
+        res = re.match('^([^0-9]+)([0-9.]+.*)$', namepart)
+        if res:
+            if len(res.group(1)) > 1 and len(res.group(2)) > 1:
+                pn = res.group(1).rstrip('.')
+                pv = res.group(2)
+        else:
+            pn = namepart
+    else:
+        if splitval[-1] in ['source', 'src']:
+            splitval.pop()
+        if len(splitval) > 2 and re.match('^(alpha|beta|stable|release|rc[0-9]|pre[0-9]|p[0-9]|[0-9]{8})', splitval[-1]) and ver_re.match(splitval[-2]):
+            pv = '-'.join(splitval[-2:])
+            if pv.endswith('-release'):
+                pv = pv[:-8]
+            splitval = splitval[:-2]
+        elif ver_re.match(splitval[-1]):
+            pv = splitval.pop()
+        pn = '-'.join(splitval)
+        if pv and pv.startswith('v'):
+            pv = pv[1:]
+    logger.debug('determine_from_filename: name = "%s" version = "%s"' % (pn, pv))
+    return (pn, pv)
+
+def determine_from_url(srcuri):
+    """Determine name and version from a URL"""
+    pn = None
+    pv = None
+    parseres = urlparse(srcuri.lower().split(';', 1)[0])
+    if parseres.path:
+        if 'github.com' in parseres.netloc:
+            res = re.search(r'.*/(.*?)/archive/(.*)-final\.(tar|zip)', parseres.path)
+            if res:
+                pn = res.group(1).strip().replace('_', '-')
+                pv = res.group(2).strip().replace('_', '.')
+            else:
+                res = re.search(r'.*/(.*?)/archive/v?(.*)\.(tar|zip)', parseres.path)
+                if res:
+                    pn = res.group(1).strip().replace('_', '-')
+                    pv = res.group(2).strip().replace('_', '.')
+        elif 'bitbucket.org' in parseres.netloc:
+            res = re.search(r'.*/(.*?)/get/[a-zA-Z_-]*([0-9][0-9a-zA-Z_.]*)\.(tar|zip)', parseres.path)
+            if res:
+                pn = res.group(1).strip().replace('_', '-')
+                pv = res.group(2).strip().replace('_', '.')
+
+        if not pn and not pv:
+            if parseres.scheme not in ['git', 'gitsm', 'svn', 'hg']:
+                srcfile = os.path.basename(parseres.path.rstrip('/'))
+                pn, pv = determine_from_filename(srcfile)
+            elif parseres.scheme in ['git', 'gitsm']:
+                pn = os.path.basename(parseres.path.rstrip('/')).lower().replace('_', '-')
+                if pn.endswith('.git'):
+                    pn = pn[:-4]
+
+    logger.debug('Determined from source URL: name = "%s", version = "%s"' % (pn, pv))
+    return (pn, pv)
+
+def supports_srcrev(uri):
+    localdata = bb.data.createCopy(tinfoil.config_data)
+    # This is a bit sad, but if you don't have this set there can be some
+    # odd interactions with the urldata cache which lead to errors
+    localdata.setVar('SRCREV', '${AUTOREV}')
+    try:
+        fetcher = bb.fetch2.Fetch([uri], localdata)
+        urldata = fetcher.ud
+        for u in urldata:
+            if urldata[u].method.supports_srcrev():
+                return True
+    except bb.fetch2.FetchError as e:
+        logger.debug('FetchError in supports_srcrev: %s' % str(e))
+        # Fall back to basic check
+        if uri.startswith(('git://', 'gitsm://')):
+            return True
+    return False
+
+def reformat_git_uri(uri):
+    '''Convert any http[s]://....git URI into git://...;protocol=http[s]'''
+    checkuri = uri.split(';', 1)[0]
+    if checkuri.endswith('.git') or '/git/' in checkuri or re.match('https?://github.com/[^/]+/[^/]+/?$', checkuri):
+        # Appends scheme if the scheme is missing
+        if not '://' in uri:
+            uri = 'git://' + uri
+        scheme, host, path, user, pswd, parms = bb.fetch2.decodeurl(uri)
+        # Detection mechanism, this is required due to certain URL are formatter with ":" rather than "/"
+        # which causes decodeurl to fail getting the right host and path
+        if len(host.split(':')) > 1:
+            splitslash = host.split(':')
+            # Port number should not be split from host
+            if not re.match('^[0-9]+$', splitslash[1]):
+                host = splitslash[0]
+                path = '/' + splitslash[1] + path
+        #Algorithm:
+        # if user is defined, append protocol=ssh or if a protocol is defined, then honor the user-defined protocol
+        # if no user & password is defined, check for scheme type and append the protocol with the scheme type
+        # finally if protocols or if the url is well-formed, do nothing and rejoin everything back to normal
+        # Need to repackage the arguments for encodeurl, the format is: (scheme, host, path, user, password, OrderedDict([('key', 'value')]))
+        if user:
+            if not 'protocol' in parms:
+                parms.update({('protocol', 'ssh')})
+        elif (scheme == "http" or scheme == 'https' or scheme == 'ssh') and not ('protocol' in parms):
+            parms.update({('protocol', scheme)})
+        # Always append 'git://'
+        fUrl = bb.fetch2.encodeurl(('git', host, path, user, pswd, parms))
+        return fUrl
+    else:
+        return uri
+
+def is_package(url):
+    '''Check if a URL points to a package'''
+    checkurl = url.split(';', 1)[0]
+    if checkurl.endswith(('.deb', '.ipk', '.rpm', '.srpm')):
+        return True
+    return False
+
+def create_recipe(args):
+    import bb.process
+    import tempfile
+    import shutil
+    import oe.recipeutils
+
+    pkgarch = ""
+    if args.machine:
+        pkgarch = "${MACHINE_ARCH}"
+
+    extravalues = {}
+    checksums = {}
+    tempsrc = ''
+    source = args.source
+    srcsubdir = ''
+    srcrev = '${AUTOREV}'
+    srcbranch = ''
+    scheme = ''
+    storeTagName = ''
+    pv_srcpv = False
+
+    if os.path.isfile(source):
+        source = 'file://%s' % os.path.abspath(source)
+
+    if scriptutils.is_src_url(source):
+        # Warn about github archive URLs
+        if re.match('https?://github.com/[^/]+/[^/]+/archive/.+(\.tar\..*|\.zip)$', source):
+            logger.warning('github archive files are not guaranteed to be stable and may be re-generated over time. If the latter occurs, the checksums will likely change and the recipe will fail at do_fetch. It is recommended that you point to an actual commit or tag in the repository instead (using the repository URL in conjunction with the -S/--srcrev option).')
+        # Fetch a URL
+        fetchuri = reformat_git_uri(urldefrag(source)[0])
+        if args.binary:
+            # Assume the archive contains the directory structure verbatim
+            # so we need to extract to a subdirectory
+            fetchuri += ';subdir=${BP}'
+        srcuri = fetchuri
+        rev_re = re.compile(';rev=([^;]+)')
+        res = rev_re.search(srcuri)
+        if res:
+            if args.srcrev:
+                logger.error('rev= parameter and -S/--srcrev option cannot both be specified - use one or the other')
+                sys.exit(1)
+            if args.autorev:
+                logger.error('rev= parameter and -a/--autorev option cannot both be specified - use one or the other')
+                sys.exit(1)
+            srcrev = res.group(1)
+            srcuri = rev_re.sub('', srcuri)
+        elif args.srcrev:
+            srcrev = args.srcrev
+
+        # Check whether users provides any branch info in fetchuri.
+        # If true, we will skip all branch checking process to honor all user's input.
+        scheme, network, path, user, passwd, params = bb.fetch2.decodeurl(fetchuri)
+        srcbranch = params.get('branch')
+        if args.srcbranch:
+            if srcbranch:
+                logger.error('branch= parameter and -B/--srcbranch option cannot both be specified - use one or the other')
+                sys.exit(1)
+            srcbranch = args.srcbranch
+        nobranch = params.get('nobranch')
+        if nobranch and srcbranch:
+            logger.error('nobranch= cannot be used if you specify a branch')
+            sys.exit(1)
+        tag = params.get('tag')
+        if not srcbranch and not nobranch and srcrev != '${AUTOREV}':
+            # Append nobranch=1 in the following conditions:
+            # 1. User did not set 'branch=' in srcuri, and
+            # 2. User did not set 'nobranch=1' in srcuri, and
+            # 3. Source revision is not '${AUTOREV}'
+            params['nobranch'] = '1'
+        if tag:
+            # Keep a copy of tag and append nobranch=1 then remove tag from URL.
+            # Bitbake fetcher unable to fetch when {AUTOREV} and tag is set at the same time.
+            storeTagName = params['tag']
+            params['nobranch'] = '1'
+            del params['tag']
+        if scheme == 'npm':
+            params['noverify'] = '1'
+        fetchuri = bb.fetch2.encodeurl((scheme, network, path, user, passwd, params))
+
+        tmpparent = tinfoil.config_data.getVar('BASE_WORKDIR')
+        bb.utils.mkdirhier(tmpparent)
+        tempsrc = tempfile.mkdtemp(prefix='recipetool-', dir=tmpparent)
+        srctree = os.path.join(tempsrc, 'source')
+
+        try:
+            checksums, ftmpdir = scriptutils.fetch_url(tinfoil, fetchuri, srcrev, srctree, logger, preserve_tmp=args.keep_temp)
+        except scriptutils.FetchUrlFailure as e:
+            logger.error(str(e))
+            sys.exit(1)
+
+        if ftmpdir and args.keep_temp:
+            logger.info('Fetch temp directory is %s' % ftmpdir)
+
+        dirlist = os.listdir(srctree)
+        filterout = ['git.indirectionsymlink']
+        dirlist = [x for x in dirlist if x not in filterout]
+        logger.debug('Directory listing (excluding filtered out):\n  %s' % '\n  '.join(dirlist))
+        if len(dirlist) == 1:
+            singleitem = os.path.join(srctree, dirlist[0])
+            if os.path.isdir(singleitem):
+                # We unpacked a single directory, so we should use that
+                srcsubdir = dirlist[0]
+                srctree = os.path.join(srctree, srcsubdir)
+            else:
+                check_single_file(dirlist[0], fetchuri)
+        elif len(dirlist) == 0:
+            if '/' in fetchuri:
+                fn = os.path.join(tinfoil.config_data.getVar('DL_DIR'), fetchuri.split('/')[-1])
+                if os.path.isfile(fn):
+                    check_single_file(fn, fetchuri)
+            # If we've got to here then there's no source so we might as well give up
+            logger.error('URL %s resulted in an empty source tree' % fetchuri)
+            sys.exit(1)
+
+        # We need this checking mechanism to improve the recipe created by recipetool and devtool
+        # is able to parse and build by bitbake.
+        # If there is no input for branch name, then check for branch name with SRCREV provided.
+        if not srcbranch and not nobranch and srcrev and (srcrev != '${AUTOREV}') and scheme in ['git', 'gitsm']:
+            try:
+                cmd = 'git branch -r --contains'
+                check_branch, check_branch_err = bb.process.run('%s %s' % (cmd, srcrev), cwd=srctree)
+            except bb.process.ExecutionError as err:
+                logger.error(str(err))
+                sys.exit(1)
+            get_branch = [x.strip() for x in check_branch.splitlines()]
+            # Remove HEAD reference point and drop remote prefix
+            get_branch = [x.split('/', 1)[1] for x in get_branch if not x.startswith('origin/HEAD')]
+            if 'master' in get_branch:
+                # If it is master, we do not need to append 'branch=master' as this is default.
+                # Even with the case where get_branch has multiple objects, if 'master' is one
+                # of them, we should default take from 'master'
+                srcbranch = ''
+            elif len(get_branch) == 1:
+                # If 'master' isn't in get_branch and get_branch contains only ONE object, then store result into 'srcbranch'
+                srcbranch = get_branch[0]
+            else:
+                # If get_branch contains more than one objects, then display error and exit.
+                mbrch = '\n  ' + '\n  '.join(get_branch)
+                logger.error('Revision %s was found on multiple branches: %s\nPlease provide the correct branch with -B/--srcbranch' % (srcrev, mbrch))
+                sys.exit(1)
+
+        # Since we might have a value in srcbranch, we need to
+        # recontruct the srcuri to include 'branch' in params.
+        scheme, network, path, user, passwd, params = bb.fetch2.decodeurl(srcuri)
+        if srcbranch:
+            params['branch'] = srcbranch
+
+        if storeTagName and scheme in ['git', 'gitsm']:
+            # Check srcrev using tag and check validity of the tag
+            cmd = ('git rev-parse --verify %s' % (storeTagName))
+            try:
+                check_tag, check_tag_err = bb.process.run('%s' % cmd, cwd=srctree)
+                srcrev = check_tag.split()[0]
+            except bb.process.ExecutionError as err:
+                logger.error(str(err))
+                logger.error("Possibly wrong tag name is provided")
+                sys.exit(1)
+            # Drop tag from srcuri as it will have conflicts with SRCREV during recipe parse.
+            del params['tag']
+        srcuri = bb.fetch2.encodeurl((scheme, network, path, user, passwd, params))
+
+        if os.path.exists(os.path.join(srctree, '.gitmodules')) and srcuri.startswith('git://'):
+            srcuri = 'gitsm://' + srcuri[6:]
+            logger.info('Fetching submodules...')
+            bb.process.run('git submodule update --init --recursive', cwd=srctree)
+
+        if is_package(fetchuri):
+            localdata = bb.data.createCopy(tinfoil.config_data)
+            pkgfile = bb.fetch2.localpath(fetchuri, localdata)
+            if pkgfile:
+                tmpfdir = tempfile.mkdtemp(prefix='recipetool-')
+                try:
+                    if pkgfile.endswith(('.deb', '.ipk')):
+                        stdout, _ = bb.process.run('ar x %s' % pkgfile, cwd=tmpfdir)
+                        stdout, _ = bb.process.run('tar xf control.tar.gz', cwd=tmpfdir)
+                        values = convert_debian(tmpfdir)
+                        extravalues.update(values)
+                    elif pkgfile.endswith(('.rpm', '.srpm')):
+                        stdout, _ = bb.process.run('rpm -qp --xml %s > pkginfo.xml' % pkgfile, cwd=tmpfdir)
+                        values = convert_rpm_xml(os.path.join(tmpfdir, 'pkginfo.xml'))
+                        extravalues.update(values)
+                finally:
+                    shutil.rmtree(tmpfdir)
+    else:
+        # Assume we're pointing to an existing source tree
+        if args.extract_to:
+            logger.error('--extract-to cannot be specified if source is a directory')
+            sys.exit(1)
+        if not os.path.isdir(source):
+            logger.error('Invalid source directory %s' % source)
+            sys.exit(1)
+        srctree = source
+        srcuri = ''
+        if os.path.exists(os.path.join(srctree, '.git')):
+            # Try to get upstream repo location from origin remote
+            try:
+                stdout, _ = bb.process.run('git remote -v', cwd=srctree, shell=True)
+            except bb.process.ExecutionError as e:
+                stdout = None
+            if stdout:
+                for line in stdout.splitlines():
+                    splitline = line.split()
+                    if len(splitline) > 1:
+                        if splitline[0] == 'origin' and scriptutils.is_src_url(splitline[1]):
+                            srcuri = reformat_git_uri(splitline[1])
+                            srcsubdir = 'git'
+                            break
+
+    if args.src_subdir:
+        srcsubdir = os.path.join(srcsubdir, args.src_subdir)
+        srctree_use = os.path.abspath(os.path.join(srctree, args.src_subdir))
+    else:
+        srctree_use = os.path.abspath(srctree)
+
+    if args.outfile and os.path.isdir(args.outfile):
+        outfile = None
+        outdir = args.outfile
+    else:
+        outfile = args.outfile
+        outdir = None
+    if outfile and outfile != '-':
+        if os.path.exists(outfile):
+            logger.error('Output file %s already exists' % outfile)
+            sys.exit(1)
+
+    lines_before = []
+    lines_after = []
+
+    lines_before.append('# Recipe created by %s' % os.path.basename(sys.argv[0]))
+    lines_before.append('# This is the basis of a recipe and may need further editing in order to be fully functional.')
+    lines_before.append('# (Feel free to remove these comments when editing.)')
+    # We need a blank line here so that patch_recipe_lines can rewind before the LICENSE comments
+    lines_before.append('')
+
+    # We'll come back and replace this later in handle_license_vars()
+    lines_before.append('##LICENSE_PLACEHOLDER##')
+
+    handled = []
+    classes = []
+
+    # FIXME This is kind of a hack, we probably ought to be using bitbake to do this
+    pn = None
+    pv = None
+    if outfile:
+        recipefn = os.path.splitext(os.path.basename(outfile))[0]
+        fnsplit = recipefn.split('_')
+        if len(fnsplit) > 1:
+            pn = fnsplit[0]
+            pv = fnsplit[1]
+        else:
+            pn = recipefn
+
+    if args.version:
+        pv = args.version
+
+    if args.name:
+        pn = args.name
+        if args.name.endswith('-native'):
+            if args.also_native:
+                logger.error('--also-native cannot be specified for a recipe named *-native (*-native denotes a recipe that is already only for native) - either remove the -native suffix from the name or drop --also-native')
+                sys.exit(1)
+            classes.append('native')
+        elif args.name.startswith('nativesdk-'):
+            if args.also_native:
+                logger.error('--also-native cannot be specified for a recipe named nativesdk-* (nativesdk-* denotes a recipe that is already only for nativesdk)')
+                sys.exit(1)
+            classes.append('nativesdk')
+
+    if pv and pv not in 'git svn hg'.split():
+        realpv = pv
+    else:
+        realpv = None
+
+    if not srcuri:
+        lines_before.append('# No information for SRC_URI yet (only an external source tree was specified)')
+    lines_before.append('SRC_URI = "%s"' % srcuri)
+    for key, value in sorted(checksums.items()):
+        lines_before.append('SRC_URI[%s] = "%s"' % (key, value))
+    if srcuri and supports_srcrev(srcuri):
+        lines_before.append('')
+        lines_before.append('# Modify these as desired')
+        # Note: we have code to replace realpv further down if it gets set to some other value
+        scheme, _, _, _, _, _ = bb.fetch2.decodeurl(srcuri)
+        if scheme in ['git', 'gitsm']:
+            srcpvprefix = 'git'
+        elif scheme == 'svn':
+            srcpvprefix = 'svnr'
+        else:
+            srcpvprefix = scheme
+        lines_before.append('PV = "%s+%s${SRCPV}"' % (realpv or '1.0', srcpvprefix))
+        pv_srcpv = True
+        if not args.autorev and srcrev == '${AUTOREV}':
+            if os.path.exists(os.path.join(srctree, '.git')):
+                (stdout, _) = bb.process.run('git rev-parse HEAD', cwd=srctree)
+                srcrev = stdout.rstrip()
+        lines_before.append('SRCREV = "%s"' % srcrev)
+    if args.provides:
+        lines_before.append('PROVIDES = "%s"' % args.provides)
+    lines_before.append('')
+
+    if srcsubdir and not args.binary:
+        # (for binary packages we explicitly specify subdir= when fetching to
+        # match the default value of S, so we don't need to set it in that case)
+        lines_before.append('S = "${WORKDIR}/%s"' % srcsubdir)
+        lines_before.append('')
+
+    if pkgarch:
+        lines_after.append('PACKAGE_ARCH = "%s"' % pkgarch)
+        lines_after.append('')
+
+    if args.binary:
+        lines_after.append('INSANE_SKIP_${PN} += "already-stripped"')
+        lines_after.append('')
+
+    if args.fetch_dev:
+        extravalues['fetchdev'] = True
+    else:
+        extravalues['fetchdev'] = None
+
+    # Find all plugins that want to register handlers
+    logger.debug('Loading recipe handlers')
+    raw_handlers = []
+    for plugin in plugins:
+        if hasattr(plugin, 'register_recipe_handlers'):
+            plugin.register_recipe_handlers(raw_handlers)
+    # Sort handlers by priority
+    handlers = []
+    for i, handler in enumerate(raw_handlers):
+        if isinstance(handler, tuple):
+            handlers.append((handler[0], handler[1], i))
+        else:
+            handlers.append((handler, 0, i))
+    handlers.sort(key=lambda item: (item[1], -item[2]), reverse=True)
+    for handler, priority, _ in handlers:
+        logger.debug('Handler: %s (priority %d)' % (handler.__class__.__name__, priority))
+        setattr(handler, '_devtool', args.devtool)
+    handlers = [item[0] for item in handlers]
+
+    # Apply the handlers
+    if args.binary:
+        classes.append('bin_package')
+        handled.append('buildsystem')
+
+    for handler in handlers:
+        handler.process(srctree_use, classes, lines_before, lines_after, handled, extravalues)
+
+    extrafiles = extravalues.pop('extrafiles', {})
+    extra_pn = extravalues.pop('PN', None)
+    extra_pv = extravalues.pop('PV', None)
+
+    if extra_pv and not realpv:
+        realpv = extra_pv
+        if not validate_pv(realpv):
+            realpv = None
+        else:
+            realpv = realpv.lower().split()[0]
+            if '_' in realpv:
+                realpv = realpv.replace('_', '-')
+    if extra_pn and not pn:
+        pn = extra_pn
+        if pn.startswith('GNU '):
+            pn = pn[4:]
+        if ' ' in pn:
+            # Probably a descriptive identifier rather than a proper name
+            pn = None
+        else:
+            pn = pn.lower()
+            if '_' in pn:
+                pn = pn.replace('_', '-')
+
+    if srcuri and not realpv or not pn:
+        name_pn, name_pv = determine_from_url(srcuri)
+        if name_pn and not pn:
+            pn = name_pn
+        if name_pv and not realpv:
+            realpv = name_pv
+
+    licvalues = handle_license_vars(srctree_use, lines_before, handled, extravalues, tinfoil.config_data)
+
+    if not outfile:
+        if not pn:
+            log_error_cond('Unable to determine short program name from source tree - please specify name with -N/--name or output file name with -o/--outfile', args.devtool)
+            # devtool looks for this specific exit code, so don't change it
+            sys.exit(15)
+        else:
+            if srcuri and srcuri.startswith(('gitsm://', 'git://', 'hg://', 'svn://')):
+                suffix = srcuri.split(':', 1)[0]
+                if suffix == 'gitsm':
+                    suffix = 'git'
+                outfile = '%s_%s.bb' % (pn, suffix)
+            elif realpv:
+                outfile = '%s_%s.bb' % (pn, realpv)
+            else:
+                outfile = '%s.bb' % pn
+            if outdir:
+                outfile = os.path.join(outdir, outfile)
+            # We need to check this again
+            if os.path.exists(outfile):
+                logger.error('Output file %s already exists' % outfile)
+                sys.exit(1)
+
+    # Move any extra files the plugins created to a directory next to the recipe
+    if extrafiles:
+        if outfile == '-':
+            extraoutdir = pn
+        else:
+            extraoutdir = os.path.join(os.path.dirname(outfile), pn)
+        bb.utils.mkdirhier(extraoutdir)
+        for destfn, extrafile in extrafiles.items():
+            shutil.move(extrafile, os.path.join(extraoutdir, destfn))
+
+    lines = lines_before
+    lines_before = []
+    skipblank = True
+    for line in lines:
+        if skipblank:
+            skipblank = False
+            if not line:
+                continue
+        if line.startswith('S = '):
+            if realpv and pv not in 'git svn hg'.split():
+                line = line.replace(realpv, '${PV}')
+            if pn:
+                line = line.replace(pn, '${BPN}')
+            if line == 'S = "${WORKDIR}/${BPN}-${PV}"':
+                skipblank = True
+                continue
+        elif line.startswith('SRC_URI = '):
+            if realpv and not pv_srcpv:
+                line = line.replace(realpv, '${PV}')
+        elif line.startswith('PV = '):
+            if realpv:
+                # Replace the first part of the PV value
+                line = re.sub('"[^+]*\+', '"%s+' % realpv, line)
+        lines_before.append(line)
+
+    if args.also_native:
+        lines = lines_after
+        lines_after = []
+        bbclassextend = None
+        for line in lines:
+            if line.startswith('BBCLASSEXTEND ='):
+                splitval = line.split('"')
+                if len(splitval) > 1:
+                    bbclassextend = splitval[1].split()
+                    if not 'native' in bbclassextend:
+                        bbclassextend.insert(0, 'native')
+                line = 'BBCLASSEXTEND = "%s"' % ' '.join(bbclassextend)
+            lines_after.append(line)
+        if not bbclassextend:
+            lines_after.append('BBCLASSEXTEND = "native"')
+
+    postinst = ("postinst", extravalues.pop('postinst', None))
+    postrm = ("postrm", extravalues.pop('postrm', None))
+    preinst = ("preinst", extravalues.pop('preinst', None))
+    prerm = ("prerm", extravalues.pop('prerm', None))
+    funcs = [postinst, postrm, preinst, prerm]
+    for func in funcs:
+        if func[1]:
+            RecipeHandler.genfunction(lines_after, 'pkg_%s_${PN}' % func[0], func[1])
+
+    outlines = []
+    outlines.extend(lines_before)
+    if classes:
+        if outlines[-1] and not outlines[-1].startswith('#'):
+            outlines.append('')
+        outlines.append('inherit %s' % ' '.join(classes))
+        outlines.append('')
+    outlines.extend(lines_after)
+
+    if extravalues:
+        _, outlines = oe.recipeutils.patch_recipe_lines(outlines, extravalues, trailing_newline=False)
+
+    if args.extract_to:
+        scriptutils.git_convert_standalone_clone(srctree)
+        if os.path.isdir(args.extract_to):
+            # If the directory exists we'll move the temp dir into it instead of
+            # its contents - of course, we could try to always move its contents
+            # but that is a pain if there are symlinks; the simplest solution is
+            # to just remove it first
+            os.rmdir(args.extract_to)
+        shutil.move(srctree, args.extract_to)
+        if tempsrc == srctree:
+            tempsrc = None
+        log_info_cond('Source extracted to %s' % args.extract_to, args.devtool)
+
+    if outfile == '-':
+        sys.stdout.write('\n'.join(outlines) + '\n')
+    else:
+        with open(outfile, 'w') as f:
+            lastline = None
+            for line in outlines:
+                if not lastline and not line:
+                    # Skip extra blank lines
+                    continue
+                f.write('%s\n' % line)
+                lastline = line
+        log_info_cond('Recipe %s has been created; further editing may be required to make it fully functional' % outfile, args.devtool)
+
+    if tempsrc:
+        if args.keep_temp:
+            logger.info('Preserving temporary directory %s' % tempsrc)
+        else:
+            shutil.rmtree(tempsrc)
+
+    return 0
+
+def check_single_file(fn, fetchuri):
+    """Determine if a single downloaded file is something we can't handle"""
+    with open(fn, 'r', errors='surrogateescape') as f:
+        if '<html' in f.read(100).lower():
+            logger.error('Fetching "%s" returned a single HTML page - check the URL is correct and functional' % fetchuri)
+            sys.exit(1)
+
+def split_value(value):
+    if isinstance(value, str):
+        return value.split()
+    else:
+        return value
+
+def handle_license_vars(srctree, lines_before, handled, extravalues, d):
+    lichandled = [x for x in handled if x[0] == 'license']
+    if lichandled:
+        # Someone else has already handled the license vars, just return their value
+        return lichandled[0][1]
+
+    licvalues = guess_license(srctree, d)
+    licenses = []
+    lic_files_chksum = []
+    lic_unknown = []
+    lines = []
+    if licvalues:
+        for licvalue in licvalues:
+            if not licvalue[0] in licenses:
+                licenses.append(licvalue[0])
+            lic_files_chksum.append('file://%s;md5=%s' % (licvalue[1], licvalue[2]))
+            if licvalue[0] == 'Unknown':
+                lic_unknown.append(licvalue[1])
+        if lic_unknown:
+            lines.append('#')
+            lines.append('# The following license files were not able to be identified and are')
+            lines.append('# represented as "Unknown" below, you will need to check them yourself:')
+            for licfile in lic_unknown:
+                lines.append('#   %s' % licfile)
+
+    extra_license = split_value(extravalues.pop('LICENSE', []))
+    if '&' in extra_license:
+        extra_license.remove('&')
+    if extra_license:
+        if licenses == ['Unknown']:
+            licenses = extra_license
+        else:
+            for item in extra_license:
+                if item not in licenses:
+                    licenses.append(item)
+    extra_lic_files_chksum = split_value(extravalues.pop('LIC_FILES_CHKSUM', []))
+    for item in extra_lic_files_chksum:
+        if item not in lic_files_chksum:
+            lic_files_chksum.append(item)
+
+    if lic_files_chksum:
+        # We are going to set the vars, so prepend the standard disclaimer
+        lines.insert(0, '# WARNING: the following LICENSE and LIC_FILES_CHKSUM values are best guesses - it is')
+        lines.insert(1, '# your responsibility to verify that the values are complete and correct.')
+    else:
+        # Without LIC_FILES_CHKSUM we set LICENSE = "CLOSED" to allow the
+        # user to get started easily
+        lines.append('# Unable to find any files that looked like license statements. Check the accompanying')
+        lines.append('# documentation and source headers and set LICENSE and LIC_FILES_CHKSUM accordingly.')
+        lines.append('#')
+        lines.append('# NOTE: LICENSE is being set to "CLOSED" to allow you to at least start building - if')
+        lines.append('# this is not accurate with respect to the licensing of the software being built (it')
+        lines.append('# will not be in most cases) you must specify the correct value before using this')
+        lines.append('# recipe for anything other than initial testing/development!')
+        licenses = ['CLOSED']
+
+    if extra_license and sorted(licenses) != sorted(extra_license):
+        lines.append('# NOTE: Original package / source metadata indicates license is: %s' % ' & '.join(extra_license))
+
+    if len(licenses) > 1:
+        lines.append('#')
+        lines.append('# NOTE: multiple licenses have been detected; they have been separated with &')
+        lines.append('# in the LICENSE value for now since it is a reasonable assumption that all')
+        lines.append('# of the licenses apply. If instead there is a choice between the multiple')
+        lines.append('# licenses then you should change the value to separate the licenses with |')
+        lines.append('# instead of &. If there is any doubt, check the accompanying documentation')
+        lines.append('# to determine which situation is applicable.')
+
+    lines.append('LICENSE = "%s"' % ' & '.join(licenses))
+    lines.append('LIC_FILES_CHKSUM = "%s"' % ' \\\n                    '.join(lic_files_chksum))
+    lines.append('')
+
+    # Replace the placeholder so we get the values in the right place in the recipe file
+    try:
+        pos = lines_before.index('##LICENSE_PLACEHOLDER##')
+    except ValueError:
+        pos = -1
+    if pos == -1:
+        lines_before.extend(lines)
+    else:
+        lines_before[pos:pos+1] = lines
+
+    handled.append(('license', licvalues))
+    return licvalues
+
+def get_license_md5sums(d, static_only=False):
+    import bb.utils
+    md5sums = {}
+    if not static_only:
+        # Gather md5sums of license files in common license dir
+        commonlicdir = d.getVar('COMMON_LICENSE_DIR')
+        for fn in os.listdir(commonlicdir):
+            md5value = bb.utils.md5_file(os.path.join(commonlicdir, fn))
+            md5sums[md5value] = fn
+    # The following were extracted from common values in various recipes
+    # (double checking the license against the license file itself, not just
+    # the LICENSE value in the recipe)
+    md5sums['94d55d512a9ba36caa9b7df079bae19f'] = 'GPLv2'
+    md5sums['b234ee4d69f5fce4486a80fdaf4a4263'] = 'GPLv2'
+    md5sums['59530bdf33659b29e73d4adb9f9f6552'] = 'GPLv2'
+    md5sums['0636e73ff0215e8d672dc4c32c317bb3'] = 'GPLv2'
+    md5sums['eb723b61539feef013de476e68b5c50a'] = 'GPLv2'
+    md5sums['751419260aa954499f7abaabaa882bbe'] = 'GPLv2'
+    md5sums['393a5ca445f6965873eca0259a17f833'] = 'GPLv2'
+    md5sums['12f884d2ae1ff87c09e5b7ccc2c4ca7e'] = 'GPLv2'
+    md5sums['8ca43cbc842c2336e835926c2166c28b'] = 'GPLv2'
+    md5sums['ebb5c50ab7cab4baeffba14977030c07'] = 'GPLv2'
+    md5sums['c93c0550bd3173f4504b2cbd8991e50b'] = 'GPLv2'
+    md5sums['9ac2e7cff1ddaf48b6eab6028f23ef88'] = 'GPLv2'
+    md5sums['4325afd396febcb659c36b49533135d4'] = 'GPLv2'
+    md5sums['18810669f13b87348459e611d31ab760'] = 'GPLv2'
+    md5sums['d7810fab7487fb0aad327b76f1be7cd7'] = 'GPLv2' # the Linux kernel's COPYING file
+    md5sums['bbb461211a33b134d42ed5ee802b37ff'] = 'LGPLv2.1'
+    md5sums['7fbc338309ac38fefcd64b04bb903e34'] = 'LGPLv2.1'
+    md5sums['4fbd65380cdd255951079008b364516c'] = 'LGPLv2.1'
+    md5sums['2d5025d4aa3495befef8f17206a5b0a1'] = 'LGPLv2.1'
+    md5sums['fbc093901857fcd118f065f900982c24'] = 'LGPLv2.1'
+    md5sums['a6f89e2100d9b6cdffcea4f398e37343'] = 'LGPLv2.1'
+    md5sums['d8045f3b8f929c1cb29a1e3fd737b499'] = 'LGPLv2.1'
+    md5sums['fad9b3332be894bab9bc501572864b29'] = 'LGPLv2.1'
+    md5sums['3bf50002aefd002f49e7bb854063f7e7'] = 'LGPLv2'
+    md5sums['9f604d8a4f8e74f4f5140845a21b6674'] = 'LGPLv2'
+    md5sums['5f30f0716dfdd0d91eb439ebec522ec2'] = 'LGPLv2'
+    md5sums['55ca817ccb7d5b5b66355690e9abc605'] = 'LGPLv2'
+    md5sums['252890d9eee26aab7b432e8b8a616475'] = 'LGPLv2'
+    md5sums['3214f080875748938ba060314b4f727d'] = 'LGPLv2'
+    md5sums['db979804f025cf55aabec7129cb671ed'] = 'LGPLv2'
+    md5sums['d32239bcb673463ab874e80d47fae504'] = 'GPLv3'
+    md5sums['f27defe1e96c2e1ecd4e0c9be8967949'] = 'GPLv3'
+    md5sums['6a6a8e020838b23406c81b19c1d46df6'] = 'LGPLv3'
+    md5sums['3b83ef96387f14655fc854ddc3c6bd57'] = 'Apache-2.0'
+    md5sums['385c55653886acac3821999a3ccd17b3'] = 'Artistic-1.0 | GPL-2.0' # some perl modules
+    md5sums['54c7042be62e169199200bc6477f04d1'] = 'BSD-3-Clause'
+    return md5sums
+
+def crunch_license(licfile):
+    '''
+    Remove non-material text from a license file and then check
+    its md5sum against a known list. This works well for licenses
+    which contain a copyright statement, but is also a useful way
+    to handle people's insistence upon reformatting the license text
+    slightly (with no material difference to the text of the
+    license).
+    '''
+
+    import oe.utils
+
+    # Note: these are carefully constructed!
+    license_title_re = re.compile('^\(?(#+ *)?(The )?.{1,10} [Ll]icen[sc]e( \(.{1,10}\))?\)?:?$')
+    license_statement_re = re.compile('^(This (project|software) is( free software)? (released|licen[sc]ed)|(Released|Licen[cs]ed)) under the .{1,10} [Ll]icen[sc]e:?$')
+    copyright_re = re.compile('^(#+)? *Copyright .*$')
+
+    crunched_md5sums = {}
+    # The following two were gleaned from the "forever" npm package
+    crunched_md5sums['0a97f8e4cbaf889d6fa51f84b89a79f6'] = 'ISC'
+    crunched_md5sums['eecf6429523cbc9693547cf2db790b5c'] = 'MIT'
+    # https://github.com/vasi/pixz/blob/master/LICENSE
+    crunched_md5sums['2f03392b40bbe663597b5bd3cc5ebdb9'] = 'BSD-2-Clause'
+    # https://github.com/waffle-gl/waffle/blob/master/LICENSE.txt
+    crunched_md5sums['e72e5dfef0b1a4ca8a3d26a60587db66'] = 'BSD-2-Clause'
+    # https://github.com/spigwitmer/fakeds1963s/blob/master/LICENSE
+    crunched_md5sums['8be76ac6d191671f347ee4916baa637e'] = 'GPLv2'
+    # https://github.com/datto/dattobd/blob/master/COPYING
+    # http://git.savannah.gnu.org/cgit/freetype/freetype2.git/tree/docs/GPLv2.TXT
+    crunched_md5sums['1d65c5ad4bf6489f85f4812bf08ae73d'] = 'GPLv2'
+    # http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt
+    # http://git.neil.brown.name/?p=mdadm.git;a=blob;f=COPYING;h=d159169d1050894d3ea3b98e1c965c4058208fe1;hb=HEAD
+    crunched_md5sums['fb530f66a7a89ce920f0e912b5b66d4b'] = 'GPLv2'
+    # https://github.com/gkos/nrf24/blob/master/COPYING
+    crunched_md5sums['7b6aaa4daeafdfa6ed5443fd2684581b'] = 'GPLv2'
+    # https://github.com/josch09/resetusb/blob/master/COPYING
+    crunched_md5sums['8b8ac1d631a4d220342e83bcf1a1fbc3'] = 'GPLv3'
+    # https://github.com/FFmpeg/FFmpeg/blob/master/COPYING.LGPLv2.1
+    crunched_md5sums['2ea316ed973ae176e502e2297b574bb3'] = 'LGPLv2.1'
+    # unixODBC-2.3.4 COPYING
+    crunched_md5sums['1daebd9491d1e8426900b4fa5a422814'] = 'LGPLv2.1'
+    # https://github.com/FFmpeg/FFmpeg/blob/master/COPYING.LGPLv3
+    crunched_md5sums['2ebfb3bb49b9a48a075cc1425e7f4129'] = 'LGPLv3'
+    # https://raw.githubusercontent.com/eclipse/mosquitto/v1.4.14/epl-v10
+    crunched_md5sums['efe2cb9a35826992b9df68224e3c2628'] = 'EPL-1.0'
+    # https://raw.githubusercontent.com/eclipse/mosquitto/v1.4.14/edl-v10
+    crunched_md5sums['0a9c78c0a398d1bbce4a166757d60387'] = 'EDL-1.0'
+    lictext = []
+    with open(licfile, 'r', errors='surrogateescape') as f:
+        for line in f:
+            # Drop opening statements
+            if copyright_re.match(line):
+                continue
+            elif license_title_re.match(line):
+                continue
+            elif license_statement_re.match(line):
+                continue
+            # Squash spaces, and replace smart quotes, double quotes
+            # and backticks with single quotes
+            line = oe.utils.squashspaces(line.strip())
+            line = line.replace(u"\u2018", "'").replace(u"\u2019", "'").replace(u"\u201c","'").replace(u"\u201d", "'").replace('"', '\'').replace('`', '\'')
+            if line:
+                lictext.append(line)
+
+    m = hashlib.md5()
+    try:
+        m.update(' '.join(lictext).encode('utf-8'))
+        md5val = m.hexdigest()
+    except UnicodeEncodeError:
+        md5val = None
+        lictext = ''
+    license = crunched_md5sums.get(md5val, None)
+    return license, md5val, lictext
+
+def guess_license(srctree, d):
+    import bb
+    md5sums = get_license_md5sums(d)
+
+    licenses = []
+    licspecs = ['*LICEN[CS]E*', 'COPYING*', '*[Ll]icense*', 'LEGAL*', '[Ll]egal*', '*GPL*', 'README.lic*', 'COPYRIGHT*', '[Cc]opyright*', 'e[dp]l-v10']
+    licfiles = []
+    for root, dirs, files in os.walk(srctree):
+        for fn in files:
+            for spec in licspecs:
+                if fnmatch.fnmatch(fn, spec):
+                    fullpath = os.path.join(root, fn)
+                    if not fullpath in licfiles:
+                        licfiles.append(fullpath)
+    for licfile in licfiles:
+        md5value = bb.utils.md5_file(licfile)
+        license = md5sums.get(md5value, None)
+        if not license:
+            license, crunched_md5, lictext = crunch_license(licfile)
+            if not license:
+                license = 'Unknown'
+        licenses.append((license, os.path.relpath(licfile, srctree), md5value))
+
+    # FIXME should we grab at least one source file with a license header and add that too?
+
+    return licenses
+
+def split_pkg_licenses(licvalues, packages, outlines, fallback_licenses=None, pn='${PN}'):
+    """
+    Given a list of (license, path, md5sum) as returned by guess_license(),
+    a dict of package name to path mappings, write out a set of
+    package-specific LICENSE values.
+    """
+    pkglicenses = {pn: []}
+    for license, licpath, _ in licvalues:
+        for pkgname, pkgpath in packages.items():
+            if licpath.startswith(pkgpath + '/'):
+                if pkgname in pkglicenses:
+                    pkglicenses[pkgname].append(license)
+                else:
+                    pkglicenses[pkgname] = [license]
+                break
+        else:
+            # Accumulate on the main package
+            pkglicenses[pn].append(license)
+    outlicenses = {}
+    for pkgname in packages:
+        license = ' '.join(list(set(pkglicenses.get(pkgname, ['Unknown'])))) or 'Unknown'
+        if license == 'Unknown' and pkgname in fallback_licenses:
+            license = fallback_licenses[pkgname]
+        outlines.append('LICENSE_%s = "%s"' % (pkgname, license))
+        outlicenses[pkgname] = license.split()
+    return outlicenses
+
+def read_pkgconfig_provides(d):
+    pkgdatadir = d.getVar('PKGDATA_DIR')
+    pkgmap = {}
+    for fn in glob.glob(os.path.join(pkgdatadir, 'shlibs2', '*.pclist')):
+        with open(fn, 'r') as f:
+            for line in f:
+                pkgmap[os.path.basename(line.rstrip())] = os.path.splitext(os.path.basename(fn))[0]
+    recipemap = {}
+    for pc, pkg in pkgmap.items():
+        pkgdatafile = os.path.join(pkgdatadir, 'runtime', pkg)
+        if os.path.exists(pkgdatafile):
+            with open(pkgdatafile, 'r') as f:
+                for line in f:
+                    if line.startswith('PN: '):
+                        recipemap[pc] = line.split(':', 1)[1].strip()
+    return recipemap
+
+def convert_debian(debpath):
+    value_map = {'Package': 'PN',
+                 'Version': 'PV',
+                 'Section': 'SECTION',
+                 'License': 'LICENSE',
+                 'Homepage': 'HOMEPAGE'}
+
+    # FIXME extend this mapping - perhaps use distro_alias.inc?
+    depmap = {'libz-dev': 'zlib'}
+
+    values = {}
+    depends = []
+    with open(os.path.join(debpath, 'control'), 'r', errors='surrogateescape') as f:
+        indesc = False
+        for line in f:
+            if indesc:
+                if line.startswith(' '):
+                    if line.startswith(' This package contains'):
+                        indesc = False
+                    else:
+                        if 'DESCRIPTION' in values:
+                            values['DESCRIPTION'] += ' ' + line.strip()
+                        else:
+                            values['DESCRIPTION'] = line.strip()
+                else:
+                    indesc = False
+            if not indesc:
+                splitline = line.split(':', 1)
+                if len(splitline) < 2:
+                    continue
+                key = splitline[0]
+                value = splitline[1].strip()
+                if key == 'Build-Depends':
+                    for dep in value.split(','):
+                        dep = dep.split()[0]
+                        mapped = depmap.get(dep, '')
+                        if mapped:
+                            depends.append(mapped)
+                elif key == 'Description':
+                    values['SUMMARY'] = value
+                    indesc = True
+                else:
+                    varname = value_map.get(key, None)
+                    if varname:
+                        values[varname] = value
+    postinst = os.path.join(debpath, 'postinst')
+    postrm = os.path.join(debpath, 'postrm')
+    preinst = os.path.join(debpath, 'preinst')
+    prerm = os.path.join(debpath, 'prerm')
+    sfiles = [postinst, postrm, preinst, prerm]
+    for sfile in sfiles:
+        if os.path.isfile(sfile):
+            logger.info("Converting %s file to recipe function..." %
+                    os.path.basename(sfile).upper())
+            content = []
+            with open(sfile) as f:
+                for line in f:
+                    if "#!/" in line:
+                        continue
+                    line = line.rstrip("\n")
+                    if line.strip():
+                        content.append(line)
+                if content:
+                    values[os.path.basename(f.name)] = content
+
+    #if depends:
+    #    values['DEPENDS'] = ' '.join(depends)
+
+    return values
+
+def convert_rpm_xml(xmlfile):
+    '''Converts the output from rpm -qp --xml to a set of variable values'''
+    import xml.etree.ElementTree as ElementTree
+    rpmtag_map = {'Name': 'PN',
+                  'Version': 'PV',
+                  'Summary': 'SUMMARY',
+                  'Description': 'DESCRIPTION',
+                  'License': 'LICENSE',
+                  'Url': 'HOMEPAGE'}
+
+    values = {}
+    tree = ElementTree.parse(xmlfile)
+    root = tree.getroot()
+    for child in root:
+        if child.tag == 'rpmTag':
+            name = child.attrib.get('name', None)
+            if name:
+                varname = rpmtag_map.get(name, None)
+                if varname:
+                    values[varname] = child[0].text
+    return values
+
+
+def register_commands(subparsers):
+    parser_create = subparsers.add_parser('create',
+                                          help='Create a new recipe',
+                                          description='Creates a new recipe from a source tree')
+    parser_create.add_argument('source', help='Path or URL to source')
+    parser_create.add_argument('-o', '--outfile', help='Specify filename for recipe to create')
+    parser_create.add_argument('-p', '--provides', help='Specify an alias for the item provided by the recipe')
+    parser_create.add_argument('-m', '--machine', help='Make recipe machine-specific as opposed to architecture-specific', action='store_true')
+    parser_create.add_argument('-x', '--extract-to', metavar='EXTRACTPATH', help='Assuming source is a URL, fetch it and extract it to the directory specified as %(metavar)s')
+    parser_create.add_argument('-N', '--name', help='Name to use within recipe (PN)')
+    parser_create.add_argument('-V', '--version', help='Version to use within recipe (PV)')
+    parser_create.add_argument('-b', '--binary', help='Treat the source tree as something that should be installed verbatim (no compilation, same directory structure)', action='store_true')
+    parser_create.add_argument('--also-native', help='Also add native variant (i.e. support building recipe for the build host as well as the target machine)', action='store_true')
+    parser_create.add_argument('--src-subdir', help='Specify subdirectory within source tree to use', metavar='SUBDIR')
+    group = parser_create.add_mutually_exclusive_group()
+    group.add_argument('-a', '--autorev', help='When fetching from a git repository, set SRCREV in the recipe to a floating revision instead of fixed', action="store_true")
+    group.add_argument('-S', '--srcrev', help='Source revision to fetch if fetching from an SCM such as git (default latest)')
+    parser_create.add_argument('-B', '--srcbranch', help='Branch in source repository if fetching from an SCM such as git (default master)')
+    parser_create.add_argument('--keep-temp', action="store_true", help='Keep temporary directory (for debugging)')
+    parser_create.add_argument('--fetch-dev', action="store_true", help='For npm, also fetch devDependencies')
+    parser_create.add_argument('--devtool', action="store_true", help=argparse.SUPPRESS)
+    parser_create.add_argument('--mirrors', action="store_true", help='Enable PREMIRRORS and MIRRORS for source tree fetching (disabled by default).')
+    parser_create.set_defaults(func=create_recipe)
+
diff --git a/meta/poky/scripts/lib/recipetool/create_buildsys.py b/meta/poky/scripts/lib/recipetool/create_buildsys.py
new file mode 100644
index 0000000..4743c74
--- /dev/null
+++ b/meta/poky/scripts/lib/recipetool/create_buildsys.py
@@ -0,0 +1,893 @@
+# Recipe creation tool - create command build system handlers
+#
+# Copyright (C) 2014-2016 Intel Corporation
+#
+# 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.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+import re
+import logging
+import glob
+from recipetool.create import RecipeHandler, validate_pv
+
+logger = logging.getLogger('recipetool')
+
+tinfoil = None
+plugins = None
+
+def plugin_init(pluginlist):
+    # Take a reference to the list so we can use it later
+    global plugins
+    plugins = pluginlist
+
+def tinfoil_init(instance):
+    global tinfoil
+    tinfoil = instance
+
+
+class CmakeRecipeHandler(RecipeHandler):
+    def process(self, srctree, classes, lines_before, lines_after, handled, extravalues):
+        if 'buildsystem' in handled:
+            return False
+
+        if RecipeHandler.checkfiles(srctree, ['CMakeLists.txt']):
+            classes.append('cmake')
+            values = CmakeRecipeHandler.extract_cmake_deps(lines_before, srctree, extravalues)
+            classes.extend(values.pop('inherit', '').split())
+            for var, value in values.items():
+                lines_before.append('%s = "%s"' % (var, value))
+            lines_after.append('# Specify any options you want to pass to cmake using EXTRA_OECMAKE:')
+            lines_after.append('EXTRA_OECMAKE = ""')
+            lines_after.append('')
+            handled.append('buildsystem')
+            return True
+        return False
+
+    @staticmethod
+    def extract_cmake_deps(outlines, srctree, extravalues, cmakelistsfile=None):
+        # Find all plugins that want to register handlers
+        logger.debug('Loading cmake handlers')
+        handlers = []
+        for plugin in plugins:
+            if hasattr(plugin, 'register_cmake_handlers'):
+                plugin.register_cmake_handlers(handlers)
+
+        values = {}
+        inherits = []
+
+        if cmakelistsfile:
+            srcfiles = [cmakelistsfile]
+        else:
+            srcfiles = RecipeHandler.checkfiles(srctree, ['CMakeLists.txt'])
+
+        # Note that some of these are non-standard, but probably better to
+        # be able to map them anyway if we see them
+        cmake_pkgmap = {'alsa': 'alsa-lib',
+                        'aspell': 'aspell',
+                        'atk': 'atk',
+                        'bison': 'bison-native',
+                        'boost': 'boost',
+                        'bzip2': 'bzip2',
+                        'cairo': 'cairo',
+                        'cups': 'cups',
+                        'curl': 'curl',
+                        'curses': 'ncurses',
+                        'cvs': 'cvs',
+                        'drm': 'libdrm',
+                        'dbus': 'dbus',
+                        'dbusglib': 'dbus-glib',
+                        'egl': 'virtual/egl',
+                        'expat': 'expat',
+                        'flex': 'flex-native',
+                        'fontconfig': 'fontconfig',
+                        'freetype': 'freetype',
+                        'gettext': '',
+                        'git': '',
+                        'gio': 'glib-2.0',
+                        'giounix': 'glib-2.0',
+                        'glew': 'glew',
+                        'glib': 'glib-2.0',
+                        'glib2': 'glib-2.0',
+                        'glu': 'libglu',
+                        'glut': 'freeglut',
+                        'gobject': 'glib-2.0',
+                        'gperf': 'gperf-native',
+                        'gnutls': 'gnutls',
+                        'gtk2': 'gtk+',
+                        'gtk3': 'gtk+3',
+                        'gtk': 'gtk+3',
+                        'harfbuzz': 'harfbuzz',
+                        'icu': 'icu',
+                        'intl': 'virtual/libintl',
+                        'jpeg': 'jpeg',
+                        'libarchive': 'libarchive',
+                        'libiconv': 'virtual/libiconv',
+                        'liblzma': 'xz',
+                        'libxml2': 'libxml2',
+                        'libxslt': 'libxslt',
+                        'opengl': 'virtual/libgl',
+                        'openmp': '',
+                        'openssl': 'openssl',
+                        'pango': 'pango',
+                        'perl': '',
+                        'perllibs': '',
+                        'pkgconfig': '',
+                        'png': 'libpng',
+                        'pthread': '',
+                        'pythoninterp': '',
+                        'pythonlibs': '',
+                        'ruby': 'ruby-native',
+                        'sdl': 'libsdl',
+                        'sdl2': 'libsdl2',
+                        'subversion': 'subversion-native',
+                        'swig': 'swig-native',
+                        'tcl': 'tcl-native',
+                        'threads': '',
+                        'tiff': 'tiff',
+                        'wget': 'wget',
+                        'x11': 'libx11',
+                        'xcb': 'libxcb',
+                        'xext': 'libxext',
+                        'xfixes': 'libxfixes',
+                        'zlib': 'zlib',
+                        }
+
+        pcdeps = []
+        libdeps = []
+        deps = []
+        unmappedpkgs = []
+
+        proj_re = re.compile('project\s*\(([^)]*)\)', re.IGNORECASE)
+        pkgcm_re = re.compile('pkg_check_modules\s*\(\s*[a-zA-Z0-9-_]+\s*(REQUIRED)?\s+([^)\s]+)\s*\)', re.IGNORECASE)
+        pkgsm_re = re.compile('pkg_search_module\s*\(\s*[a-zA-Z0-9-_]+\s*(REQUIRED)?((\s+[^)\s]+)+)\s*\)', re.IGNORECASE)
+        findpackage_re = re.compile('find_package\s*\(\s*([a-zA-Z0-9-_]+)\s*.*', re.IGNORECASE)
+        findlibrary_re = re.compile('find_library\s*\(\s*[a-zA-Z0-9-_]+\s*(NAMES\s+)?([a-zA-Z0-9-_ ]+)\s*.*')
+        checklib_re = re.compile('check_library_exists\s*\(\s*([^\s)]+)\s*.*', re.IGNORECASE)
+        include_re = re.compile('include\s*\(\s*([^)\s]*)\s*\)', re.IGNORECASE)
+        subdir_re = re.compile('add_subdirectory\s*\(\s*([^)\s]*)\s*([^)\s]*)\s*\)', re.IGNORECASE)
+        dep_re = re.compile('([^ ><=]+)( *[<>=]+ *[^ ><=]+)?')
+
+        def find_cmake_package(pkg):
+            RecipeHandler.load_devel_filemap(tinfoil.config_data)
+            for fn, pn in RecipeHandler.recipecmakefilemap.items():
+                splitname = fn.split('/')
+                if len(splitname) > 1:
+                    if splitname[0].lower().startswith(pkg.lower()):
+                        if splitname[1] == '%s-config.cmake' % pkg.lower() or splitname[1] == '%sConfig.cmake' % pkg or splitname[1] == 'Find%s.cmake' % pkg:
+                            return pn
+            return None
+
+        def interpret_value(value):
+            return value.strip('"')
+
+        def parse_cmake_file(fn, paths=None):
+            searchpaths = (paths or []) + [os.path.dirname(fn)]
+            logger.debug('Parsing file %s' % fn)
+            with open(fn, 'r', errors='surrogateescape') as f:
+                for line in f:
+                    line = line.strip()
+                    for handler in handlers:
+                        if handler.process_line(srctree, fn, line, libdeps, pcdeps, deps, outlines, inherits, values):
+                            continue
+                    res = include_re.match(line)
+                    if res:
+                        includefn = bb.utils.which(':'.join(searchpaths), res.group(1))
+                        if includefn:
+                            parse_cmake_file(includefn, searchpaths)
+                        else:
+                            logger.debug('Unable to recurse into include file %s' % res.group(1))
+                        continue
+                    res = subdir_re.match(line)
+                    if res:
+                        subdirfn = os.path.join(os.path.dirname(fn), res.group(1), 'CMakeLists.txt')
+                        if os.path.exists(subdirfn):
+                            parse_cmake_file(subdirfn, searchpaths)
+                        else:
+                            logger.debug('Unable to recurse into subdirectory file %s' % subdirfn)
+                        continue
+                    res = proj_re.match(line)
+                    if res:
+                        extravalues['PN'] = interpret_value(res.group(1).split()[0])
+                        continue
+                    res = pkgcm_re.match(line)
+                    if res:
+                        res = dep_re.findall(res.group(2))
+                        if res:
+                            pcdeps.extend([interpret_value(x[0]) for x in res])
+                        inherits.append('pkgconfig')
+                        continue
+                    res = pkgsm_re.match(line)
+                    if res:
+                        res = dep_re.findall(res.group(2))
+                        if res:
+                            # Note: appending a tuple here!
+                            item = tuple((interpret_value(x[0]) for x in res))
+                            if len(item) == 1:
+                                item = item[0]
+                            pcdeps.append(item)
+                        inherits.append('pkgconfig')
+                        continue
+                    res = findpackage_re.match(line)
+                    if res:
+                        origpkg = res.group(1)
+                        pkg = interpret_value(origpkg)
+                        found = False
+                        for handler in handlers:
+                            if handler.process_findpackage(srctree, fn, pkg, deps, outlines, inherits, values):
+                                logger.debug('Mapped CMake package %s via handler %s' % (pkg, handler.__class__.__name__))
+                                found = True
+                                break
+                        if found:
+                            continue
+                        elif pkg == 'Gettext':
+                            inherits.append('gettext')
+                        elif pkg == 'Perl':
+                            inherits.append('perlnative')
+                        elif pkg == 'PkgConfig':
+                            inherits.append('pkgconfig')
+                        elif pkg == 'PythonInterp':
+                            inherits.append('pythonnative')
+                        elif pkg == 'PythonLibs':
+                            inherits.append('python-dir')
+                        else:
+                            # Try to map via looking at installed CMake packages in pkgdata
+                            dep = find_cmake_package(pkg)
+                            if dep:
+                                logger.debug('Mapped CMake package %s to recipe %s via pkgdata' % (pkg, dep))
+                                deps.append(dep)
+                            else:
+                                dep = cmake_pkgmap.get(pkg.lower(), None)
+                                if dep:
+                                    logger.debug('Mapped CMake package %s to recipe %s via internal list' % (pkg, dep))
+                                    deps.append(dep)
+                                elif dep is None:
+                                    unmappedpkgs.append(origpkg)
+                        continue
+                    res = checklib_re.match(line)
+                    if res:
+                        lib = interpret_value(res.group(1))
+                        if not lib.startswith('$'):
+                            libdeps.append(lib)
+                    res = findlibrary_re.match(line)
+                    if res:
+                        libs = res.group(2).split()
+                        for lib in libs:
+                            if lib in ['HINTS', 'PATHS', 'PATH_SUFFIXES', 'DOC', 'NAMES_PER_DIR'] or lib.startswith(('NO_', 'CMAKE_', 'ONLY_CMAKE_')):
+                                break
+                            lib = interpret_value(lib)
+                            if not lib.startswith('$'):
+                                libdeps.append(lib)
+                    if line.lower().startswith('useswig'):
+                        deps.append('swig-native')
+                        continue
+
+        parse_cmake_file(srcfiles[0])
+
+        if unmappedpkgs:
+            outlines.append('# NOTE: unable to map the following CMake package dependencies: %s' % ' '.join(list(set(unmappedpkgs))))
+
+        RecipeHandler.handle_depends(libdeps, pcdeps, deps, outlines, values, tinfoil.config_data)
+
+        for handler in handlers:
+            handler.post_process(srctree, libdeps, pcdeps, deps, outlines, inherits, values)
+
+        if inherits:
+            values['inherit'] = ' '.join(list(set(inherits)))
+
+        return values
+
+
+class CmakeExtensionHandler(object):
+    '''Base class for CMake extension handlers'''
+    def process_line(self, srctree, fn, line, libdeps, pcdeps, deps, outlines, inherits, values):
+        '''
+        Handle a line parsed out of an CMake file.
+        Return True if you've completely handled the passed in line, otherwise return False.
+        '''
+        return False
+
+    def process_findpackage(self, srctree, fn, pkg, deps, outlines, inherits, values):
+        '''
+        Handle a find_package package parsed out of a CMake file.
+        Return True if you've completely handled the passed in package, otherwise return False.
+        '''
+        return False
+
+    def post_process(self, srctree, fn, pkg, deps, outlines, inherits, values):
+        '''
+        Apply any desired post-processing on the output
+        '''
+        return
+
+
+
+class SconsRecipeHandler(RecipeHandler):
+    def process(self, srctree, classes, lines_before, lines_after, handled, extravalues):
+        if 'buildsystem' in handled:
+            return False
+
+        if RecipeHandler.checkfiles(srctree, ['SConstruct', 'Sconstruct', 'sconstruct']):
+            classes.append('scons')
+            lines_after.append('# Specify any options you want to pass to scons using EXTRA_OESCONS:')
+            lines_after.append('EXTRA_OESCONS = ""')
+            lines_after.append('')
+            handled.append('buildsystem')
+            return True
+        return False
+
+
+class QmakeRecipeHandler(RecipeHandler):
+    def process(self, srctree, classes, lines_before, lines_after, handled, extravalues):
+        if 'buildsystem' in handled:
+            return False
+
+        if RecipeHandler.checkfiles(srctree, ['*.pro']):
+            classes.append('qmake2')
+            handled.append('buildsystem')
+            return True
+        return False
+
+
+class AutotoolsRecipeHandler(RecipeHandler):
+    def process(self, srctree, classes, lines_before, lines_after, handled, extravalues):
+        if 'buildsystem' in handled:
+            return False
+
+        autoconf = False
+        if RecipeHandler.checkfiles(srctree, ['configure.ac', 'configure.in']):
+            autoconf = True
+            values = AutotoolsRecipeHandler.extract_autotools_deps(lines_before, srctree, extravalues)
+            classes.extend(values.pop('inherit', '').split())
+            for var, value in values.items():
+                lines_before.append('%s = "%s"' % (var, value))
+        else:
+            conffile = RecipeHandler.checkfiles(srctree, ['configure'])
+            if conffile:
+                # Check if this is just a pre-generated autoconf configure script
+                with open(conffile[0], 'r', errors='surrogateescape') as f:
+                    for i in range(1, 10):
+                        if 'Generated by GNU Autoconf' in f.readline():
+                            autoconf = True
+                            break
+
+        if autoconf and not ('PV' in extravalues and 'PN' in extravalues):
+            # Last resort
+            conffile = RecipeHandler.checkfiles(srctree, ['configure'])
+            if conffile:
+                with open(conffile[0], 'r', errors='surrogateescape') as f:
+                    for line in f:
+                        line = line.strip()
+                        if line.startswith('VERSION=') or line.startswith('PACKAGE_VERSION='):
+                            pv = line.split('=')[1].strip('"\'')
+                            if pv and not 'PV' in extravalues and validate_pv(pv):
+                                extravalues['PV'] = pv
+                        elif line.startswith('PACKAGE_NAME=') or line.startswith('PACKAGE='):
+                            pn = line.split('=')[1].strip('"\'')
+                            if pn and not 'PN' in extravalues:
+                                extravalues['PN'] = pn
+
+        if autoconf:
+            lines_before.append('')
+            lines_before.append('# NOTE: if this software is not capable of being built in a separate build directory')
+            lines_before.append('# from the source, you should replace autotools with autotools-brokensep in the')
+            lines_before.append('# inherit line')
+            classes.append('autotools')
+            lines_after.append('# Specify any options you want to pass to the configure script using EXTRA_OECONF:')
+            lines_after.append('EXTRA_OECONF = ""')
+            lines_after.append('')
+            handled.append('buildsystem')
+            return True
+
+        return False
+
+    @staticmethod
+    def extract_autotools_deps(outlines, srctree, extravalues=None, acfile=None):
+        import shlex
+
+        # Find all plugins that want to register handlers
+        logger.debug('Loading autotools handlers')
+        handlers = []
+        for plugin in plugins:
+            if hasattr(plugin, 'register_autotools_handlers'):
+                plugin.register_autotools_handlers(handlers)
+
+        values = {}
+        inherits = []
+
+        # Hardcoded map, we also use a dynamic one based on what's in the sysroot
+        progmap = {'flex': 'flex-native',
+                'bison': 'bison-native',
+                'm4': 'm4-native',
+                'tar': 'tar-native',
+                'ar': 'binutils-native',
+                'ranlib': 'binutils-native',
+                'ld': 'binutils-native',
+                'strip': 'binutils-native',
+                'libtool': '',
+                'autoconf': '',
+                'autoheader': '',
+                'automake': '',
+                'uname': '',
+                'rm': '',
+                'cp': '',
+                'mv': '',
+                'find': '',
+                'awk': '',
+                'sed': '',
+                }
+        progclassmap = {'gconftool-2': 'gconf',
+                'pkg-config': 'pkgconfig',
+                'python': 'pythonnative',
+                'python3': 'python3native',
+                'perl': 'perlnative',
+                'makeinfo': 'texinfo',
+                }
+
+        pkg_re = re.compile('PKG_CHECK_MODULES\(\s*\[?[a-zA-Z0-9_]*\]?,\s*\[?([^,\]]*)\]?[),].*')
+        pkgce_re = re.compile('PKG_CHECK_EXISTS\(\s*\[?([^,\]]*)\]?[),].*')
+        lib_re = re.compile('AC_CHECK_LIB\(\s*\[?([^,\]]*)\]?,.*')
+        libx_re = re.compile('AX_CHECK_LIBRARY\(\s*\[?[^,\]]*\]?,\s*\[?([^,\]]*)\]?,\s*\[?([a-zA-Z0-9-]*)\]?,.*')
+        progs_re = re.compile('_PROGS?\(\s*\[?[a-zA-Z0-9_]*\]?,\s*\[?([^,\]]*)\]?[),].*')
+        dep_re = re.compile('([^ ><=]+)( [<>=]+ [^ ><=]+)?')
+        ac_init_re = re.compile('AC_INIT\(\s*([^,]+),\s*([^,]+)[,)].*')
+        am_init_re = re.compile('AM_INIT_AUTOMAKE\(\s*([^,]+),\s*([^,]+)[,)].*')
+        define_re = re.compile('\s*(m4_)?define\(\s*([^,]+),\s*([^,]+)\)')
+        version_re = re.compile('([0-9.]+)')
+
+        defines = {}
+        def subst_defines(value):
+            newvalue = value
+            for define, defval in defines.items():
+                newvalue = newvalue.replace(define, defval)
+            if newvalue != value:
+                return subst_defines(newvalue)
+            return value
+
+        def process_value(value):
+            value = value.replace('[', '').replace(']', '')
+            if value.startswith('m4_esyscmd(') or value.startswith('m4_esyscmd_s('):
+                cmd = subst_defines(value[value.index('(')+1:-1])
+                try:
+                    if '|' in cmd:
+                        cmd = 'set -o pipefail; ' + cmd
+                    stdout, _ = bb.process.run(cmd, cwd=srctree, shell=True)
+                    ret = stdout.rstrip()
+                except bb.process.ExecutionError as e:
+                    ret = ''
+            elif value.startswith('m4_'):
+                return None
+            ret = subst_defines(value)
+            if ret:
+                ret = ret.strip('"\'')
+            return ret
+
+        # Since a configure.ac file is essentially a program, this is only ever going to be
+        # a hack unfortunately; but it ought to be enough of an approximation
+        if acfile:
+            srcfiles = [acfile]
+        else:
+            srcfiles = RecipeHandler.checkfiles(srctree, ['acinclude.m4', 'configure.ac', 'configure.in'])
+
+        pcdeps = []
+        libdeps = []
+        deps = []
+        unmapped = []
+
+        RecipeHandler.load_binmap(tinfoil.config_data)
+
+        def process_macro(keyword, value):
+            for handler in handlers:
+                if handler.process_macro(srctree, keyword, value, process_value, libdeps, pcdeps, deps, outlines, inherits, values):
+                    return
+            logger.debug('Found keyword %s with value "%s"' % (keyword, value))
+            if keyword == 'PKG_CHECK_MODULES':
+                res = pkg_re.search(value)
+                if res:
+                    res = dep_re.findall(res.group(1))
+                    if res:
+                        pcdeps.extend([x[0] for x in res])
+                inherits.append('pkgconfig')
+            elif keyword == 'PKG_CHECK_EXISTS':
+                res = pkgce_re.search(value)
+                if res:
+                    res = dep_re.findall(res.group(1))
+                    if res:
+                        pcdeps.extend([x[0] for x in res])
+                inherits.append('pkgconfig')
+            elif keyword in ('AM_GNU_GETTEXT', 'AM_GLIB_GNU_GETTEXT', 'GETTEXT_PACKAGE'):
+                inherits.append('gettext')
+            elif keyword in ('AC_PROG_INTLTOOL', 'IT_PROG_INTLTOOL'):
+                deps.append('intltool-native')
+            elif keyword == 'AM_PATH_GLIB_2_0':
+                deps.append('glib-2.0')
+            elif keyword in ('AC_CHECK_PROG', 'AC_PATH_PROG', 'AX_WITH_PROG'):
+                res = progs_re.search(value)
+                if res:
+                    for prog in shlex.split(res.group(1)):
+                        prog = prog.split()[0]
+                        for handler in handlers:
+                            if handler.process_prog(srctree, keyword, value, prog, deps, outlines, inherits, values):
+                                return
+                        progclass = progclassmap.get(prog, None)
+                        if progclass:
+                            inherits.append(progclass)
+                        else:
+                            progdep = RecipeHandler.recipebinmap.get(prog, None)
+                            if not progdep:
+                                progdep = progmap.get(prog, None)
+                            if progdep:
+                                deps.append(progdep)
+                            elif progdep is None:
+                                if not prog.startswith('$'):
+                                    unmapped.append(prog)
+            elif keyword == 'AC_CHECK_LIB':
+                res = lib_re.search(value)
+                if res:
+                    lib = res.group(1)
+                    if not lib.startswith('$'):
+                        libdeps.append(lib)
+            elif keyword == 'AX_CHECK_LIBRARY':
+                res = libx_re.search(value)
+                if res:
+                    lib = res.group(2)
+                    if not lib.startswith('$'):
+                        header = res.group(1)
+                        libdeps.append((lib, header))
+            elif keyword == 'AC_PATH_X':
+                deps.append('libx11')
+            elif keyword in ('AX_BOOST', 'BOOST_REQUIRE'):
+                deps.append('boost')
+            elif keyword in ('AC_PROG_LEX', 'AM_PROG_LEX', 'AX_PROG_FLEX'):
+                deps.append('flex-native')
+            elif keyword in ('AC_PROG_YACC', 'AX_PROG_BISON'):
+                deps.append('bison-native')
+            elif keyword == 'AX_CHECK_ZLIB':
+                deps.append('zlib')
+            elif keyword in ('AX_CHECK_OPENSSL', 'AX_LIB_CRYPTO'):
+                deps.append('openssl')
+            elif keyword == 'AX_LIB_CURL':
+                deps.append('curl')
+            elif keyword == 'AX_LIB_BEECRYPT':
+                deps.append('beecrypt')
+            elif keyword == 'AX_LIB_EXPAT':
+                deps.append('expat')
+            elif keyword == 'AX_LIB_GCRYPT':
+                deps.append('libgcrypt')
+            elif keyword == 'AX_LIB_NETTLE':
+                deps.append('nettle')
+            elif keyword == 'AX_LIB_READLINE':
+                deps.append('readline')
+            elif keyword == 'AX_LIB_SQLITE3':
+                deps.append('sqlite3')
+            elif keyword == 'AX_LIB_TAGLIB':
+                deps.append('taglib')
+            elif keyword in ['AX_PKG_SWIG', 'AC_PROG_SWIG']:
+                deps.append('swig-native')
+            elif keyword == 'AX_PROG_XSLTPROC':
+                deps.append('libxslt-native')
+            elif keyword in ['AC_PYTHON_DEVEL', 'AX_PYTHON_DEVEL', 'AM_PATH_PYTHON']:
+                pythonclass = 'pythonnative'
+                res = version_re.search(value)
+                if res:
+                    if res.group(1).startswith('3'):
+                        pythonclass = 'python3native'
+                # Avoid replacing python3native with pythonnative
+                if not pythonclass in inherits and not 'python3native' in inherits:
+                    if 'pythonnative' in inherits:
+                        inherits.remove('pythonnative')
+                    inherits.append(pythonclass)
+            elif keyword == 'AX_WITH_CURSES':
+                deps.append('ncurses')
+            elif keyword == 'AX_PATH_BDB':
+                deps.append('db')
+            elif keyword == 'AX_PATH_LIB_PCRE':
+                deps.append('libpcre')
+            elif keyword == 'AC_INIT':
+                if extravalues is not None:
+                    res = ac_init_re.match(value)
+                    if res:
+                        extravalues['PN'] = process_value(res.group(1))
+                        pv = process_value(res.group(2))
+                        if validate_pv(pv):
+                            extravalues['PV'] = pv
+            elif keyword == 'AM_INIT_AUTOMAKE':
+                if extravalues is not None:
+                    if 'PN' not in extravalues:
+                        res = am_init_re.match(value)
+                        if res:
+                            if res.group(1) != 'AC_PACKAGE_NAME':
+                                extravalues['PN'] = process_value(res.group(1))
+                            pv = process_value(res.group(2))
+                            if validate_pv(pv):
+                                extravalues['PV'] = pv
+            elif keyword == 'define(':
+                res = define_re.match(value)
+                if res:
+                    key = res.group(2).strip('[]')
+                    value = process_value(res.group(3))
+                    if value is not None:
+                        defines[key] = value
+
+        keywords = ['PKG_CHECK_MODULES',
+                    'PKG_CHECK_EXISTS',
+                    'AM_GNU_GETTEXT',
+                    'AM_GLIB_GNU_GETTEXT',
+                    'GETTEXT_PACKAGE',
+                    'AC_PROG_INTLTOOL',
+                    'IT_PROG_INTLTOOL',
+                    'AM_PATH_GLIB_2_0',
+                    'AC_CHECK_PROG',
+                    'AC_PATH_PROG',
+                    'AX_WITH_PROG',
+                    'AC_CHECK_LIB',
+                    'AX_CHECK_LIBRARY',
+                    'AC_PATH_X',
+                    'AX_BOOST',
+                    'BOOST_REQUIRE',
+                    'AC_PROG_LEX',
+                    'AM_PROG_LEX',
+                    'AX_PROG_FLEX',
+                    'AC_PROG_YACC',
+                    'AX_PROG_BISON',
+                    'AX_CHECK_ZLIB',
+                    'AX_CHECK_OPENSSL',
+                    'AX_LIB_CRYPTO',
+                    'AX_LIB_CURL',
+                    'AX_LIB_BEECRYPT',
+                    'AX_LIB_EXPAT',
+                    'AX_LIB_GCRYPT',
+                    'AX_LIB_NETTLE',
+                    'AX_LIB_READLINE'
+                    'AX_LIB_SQLITE3',
+                    'AX_LIB_TAGLIB',
+                    'AX_PKG_SWIG',
+                    'AC_PROG_SWIG',
+                    'AX_PROG_XSLTPROC',
+                    'AC_PYTHON_DEVEL',
+                    'AX_PYTHON_DEVEL',
+                    'AM_PATH_PYTHON',
+                    'AX_WITH_CURSES',
+                    'AX_PATH_BDB',
+                    'AX_PATH_LIB_PCRE',
+                    'AC_INIT',
+                    'AM_INIT_AUTOMAKE',
+                    'define(',
+                    ]
+
+        for handler in handlers:
+            handler.extend_keywords(keywords)
+
+        for srcfile in srcfiles:
+            nesting = 0
+            in_keyword = ''
+            partial = ''
+            with open(srcfile, 'r', errors='surrogateescape') as f:
+                for line in f:
+                    if in_keyword:
+                        partial += ' ' + line.strip()
+                        if partial.endswith('\\'):
+                            partial = partial[:-1]
+                        nesting = nesting + line.count('(') - line.count(')')
+                        if nesting == 0:
+                            process_macro(in_keyword, partial)
+                            partial = ''
+                            in_keyword = ''
+                    else:
+                        for keyword in keywords:
+                            if keyword in line:
+                                nesting = line.count('(') - line.count(')')
+                                if nesting > 0:
+                                    partial = line.strip()
+                                    if partial.endswith('\\'):
+                                        partial = partial[:-1]
+                                    in_keyword = keyword
+                                else:
+                                    process_macro(keyword, line.strip())
+                                break
+
+            if in_keyword:
+                process_macro(in_keyword, partial)
+
+        if extravalues:
+            for k,v in list(extravalues.items()):
+                if v:
+                    if v.startswith('$') or v.startswith('@') or v.startswith('%'):
+                        del extravalues[k]
+                    else:
+                        extravalues[k] = v.strip('"\'').rstrip('()')
+
+        if unmapped:
+            outlines.append('# NOTE: the following prog dependencies are unknown, ignoring: %s' % ' '.join(list(set(unmapped))))
+
+        RecipeHandler.handle_depends(libdeps, pcdeps, deps, outlines, values, tinfoil.config_data)
+
+        for handler in handlers:
+            handler.post_process(srctree, libdeps, pcdeps, deps, outlines, inherits, values)
+
+        if inherits:
+            values['inherit'] = ' '.join(list(set(inherits)))
+
+        return values
+
+
+class AutotoolsExtensionHandler(object):
+    '''Base class for Autotools extension handlers'''
+    def process_macro(self, srctree, keyword, value, process_value, libdeps, pcdeps, deps, outlines, inherits, values):
+        '''
+        Handle a macro parsed out of an autotools file. Note that if you want this to be called
+        for any macro other than the ones AutotoolsRecipeHandler already looks for, you'll need
+        to add it to the keywords list in extend_keywords().
+        Return True if you've completely handled the passed in macro, otherwise return False.
+        '''
+        return False
+
+    def extend_keywords(self, keywords):
+        '''Adds keywords to be recognised by the parser (so that you get a call to process_macro)'''
+        return
+
+    def process_prog(self, srctree, keyword, value, prog, deps, outlines, inherits, values):
+        '''
+        Handle an AC_PATH_PROG, AC_CHECK_PROG etc. line
+        Return True if you've completely handled the passed in macro, otherwise return False.
+        '''
+        return False
+
+    def post_process(self, srctree, fn, pkg, deps, outlines, inherits, values):
+        '''
+        Apply any desired post-processing on the output
+        '''
+        return
+
+
+class MakefileRecipeHandler(RecipeHandler):
+    def process(self, srctree, classes, lines_before, lines_after, handled, extravalues):
+        if 'buildsystem' in handled:
+            return False
+
+        makefile = RecipeHandler.checkfiles(srctree, ['Makefile', 'makefile', 'GNUmakefile'])
+        if makefile:
+            lines_after.append('# NOTE: this is a Makefile-only piece of software, so we cannot generate much of the')
+            lines_after.append('# recipe automatically - you will need to examine the Makefile yourself and ensure')
+            lines_after.append('# that the appropriate arguments are passed in.')
+            lines_after.append('')
+
+            scanfile = os.path.join(srctree, 'configure.scan')
+            skipscan = False
+            try:
+                stdout, stderr = bb.process.run('autoscan', cwd=srctree, shell=True)
+            except bb.process.ExecutionError as e:
+                skipscan = True
+            if scanfile and os.path.exists(scanfile):
+                values = AutotoolsRecipeHandler.extract_autotools_deps(lines_before, srctree, acfile=scanfile)
+                classes.extend(values.pop('inherit', '').split())
+                for var, value in values.items():
+                    if var == 'DEPENDS':
+                        lines_before.append('# NOTE: some of these dependencies may be optional, check the Makefile and/or upstream documentation')
+                    lines_before.append('%s = "%s"' % (var, value))
+                lines_before.append('')
+                for f in ['configure.scan', 'autoscan.log']:
+                    fp = os.path.join(srctree, f)
+                    if os.path.exists(fp):
+                        os.remove(fp)
+
+            self.genfunction(lines_after, 'do_configure', ['# Specify any needed configure commands here'])
+
+            func = []
+            func.append('# You will almost certainly need to add additional arguments here')
+            func.append('oe_runmake')
+            self.genfunction(lines_after, 'do_compile', func)
+
+            installtarget = True
+            try:
+                stdout, stderr = bb.process.run('make -n install', cwd=srctree, shell=True)
+            except bb.process.ExecutionError as e:
+                if e.exitcode != 1:
+                    installtarget = False
+            func = []
+            if installtarget:
+                func.append('# This is a guess; additional arguments may be required')
+                makeargs = ''
+                with open(makefile[0], 'r', errors='surrogateescape') as f:
+                    for i in range(1, 100):
+                        if 'DESTDIR' in f.readline():
+                            makeargs += " 'DESTDIR=${D}'"
+                            break
+                func.append('oe_runmake install%s' % makeargs)
+            else:
+                func.append('# NOTE: unable to determine what to put here - there is a Makefile but no')
+                func.append('# target named "install", so you will need to define this yourself')
+            self.genfunction(lines_after, 'do_install', func)
+
+            handled.append('buildsystem')
+        else:
+            lines_after.append('# NOTE: no Makefile found, unable to determine what needs to be done')
+            lines_after.append('')
+            self.genfunction(lines_after, 'do_configure', ['# Specify any needed configure commands here'])
+            self.genfunction(lines_after, 'do_compile', ['# Specify compilation commands here'])
+            self.genfunction(lines_after, 'do_install', ['# Specify install commands here'])
+
+
+class VersionFileRecipeHandler(RecipeHandler):
+    def process(self, srctree, classes, lines_before, lines_after, handled, extravalues):
+        if 'PV' not in extravalues:
+            # Look for a VERSION or version file containing a single line consisting
+            # only of a version number
+            filelist = RecipeHandler.checkfiles(srctree, ['VERSION', 'version'])
+            version = None
+            for fileitem in filelist:
+                linecount = 0
+                with open(fileitem, 'r', errors='surrogateescape') as f:
+                    for line in f:
+                        line = line.rstrip().strip('"\'')
+                        linecount += 1
+                        if line:
+                            if linecount > 1:
+                                version = None
+                                break
+                            else:
+                                if validate_pv(line):
+                                    version = line
+                if version:
+                    extravalues['PV'] = version
+                    break
+
+
+class SpecFileRecipeHandler(RecipeHandler):
+    def process(self, srctree, classes, lines_before, lines_after, handled, extravalues):
+        if 'PV' in extravalues and 'PN' in extravalues:
+            return
+        filelist = RecipeHandler.checkfiles(srctree, ['*.spec'], recursive=True)
+        valuemap = {'Name': 'PN',
+                    'Version': 'PV',
+                    'Summary': 'SUMMARY',
+                    'Url': 'HOMEPAGE',
+                    'License': 'LICENSE'}
+        foundvalues = {}
+        for fileitem in filelist:
+            linecount = 0
+            with open(fileitem, 'r', errors='surrogateescape') as f:
+                for line in f:
+                    for value, varname in valuemap.items():
+                        if line.startswith(value + ':') and not varname in foundvalues:
+                            foundvalues[varname] = line.split(':', 1)[1].strip()
+                            break
+                    if len(foundvalues) == len(valuemap):
+                        break
+        # Drop values containing unexpanded RPM macros
+        for k in list(foundvalues.keys()):
+            if '%' in foundvalues[k]:
+                del foundvalues[k]
+        if 'PV' in foundvalues:
+            if not validate_pv(foundvalues['PV']):
+                del foundvalues['PV']
+        license = foundvalues.pop('LICENSE', None)
+        if license:
+            liccomment = '# NOTE: spec file indicates the license may be "%s"' % license
+            for i, line in enumerate(lines_before):
+                if line.startswith('LICENSE ='):
+                    lines_before.insert(i, liccomment)
+                    break
+            else:
+                lines_before.append(liccomment)
+        extravalues.update(foundvalues)
+
+def register_recipe_handlers(handlers):
+    # Set priorities with some gaps so that other plugins can insert
+    # their own handlers (so avoid changing these numbers)
+    handlers.append((CmakeRecipeHandler(), 50))
+    handlers.append((AutotoolsRecipeHandler(), 40))
+    handlers.append((SconsRecipeHandler(), 30))
+    handlers.append((QmakeRecipeHandler(), 20))
+    handlers.append((MakefileRecipeHandler(), 10))
+    handlers.append((VersionFileRecipeHandler(), -1))
+    handlers.append((SpecFileRecipeHandler(), -1))
diff --git a/meta/poky/scripts/lib/recipetool/create_buildsys_python.py b/meta/poky/scripts/lib/recipetool/create_buildsys_python.py
new file mode 100644
index 0000000..5bd2aa3
--- /dev/null
+++ b/meta/poky/scripts/lib/recipetool/create_buildsys_python.py
@@ -0,0 +1,719 @@
+# Recipe creation tool - create build system handler for python
+#
+# Copyright (C) 2015 Mentor Graphics Corporation
+#
+# 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.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+import ast
+import codecs
+import collections
+import distutils.command.build_py
+import email
+import imp
+import glob
+import itertools
+import logging
+import os
+import re
+import sys
+import subprocess
+from recipetool.create import RecipeHandler
+
+logger = logging.getLogger('recipetool')
+
+tinfoil = None
+
+
+def tinfoil_init(instance):
+    global tinfoil
+    tinfoil = instance
+
+
+class PythonRecipeHandler(RecipeHandler):
+    base_pkgdeps = ['python-core']
+    excluded_pkgdeps = ['python-dbg']
+    # os.path is provided by python-core
+    assume_provided = ['builtins', 'os.path']
+    # Assumes that the host python builtin_module_names is sane for target too
+    assume_provided = assume_provided + list(sys.builtin_module_names)
+
+    bbvar_map = {
+        'Name': 'PN',
+        'Version': 'PV',
+        'Home-page': 'HOMEPAGE',
+        'Summary': 'SUMMARY',
+        'Description': 'DESCRIPTION',
+        'License': 'LICENSE',
+        'Requires': 'RDEPENDS_${PN}',
+        'Provides': 'RPROVIDES_${PN}',
+        'Obsoletes': 'RREPLACES_${PN}',
+    }
+    # PN/PV are already set by recipetool core & desc can be extremely long
+    excluded_fields = [
+        'Description',
+    ]
+    setup_parse_map = {
+        'Url': 'Home-page',
+        'Classifiers': 'Classifier',
+        'Description': 'Summary',
+    }
+    setuparg_map = {
+        'Home-page': 'url',
+        'Classifier': 'classifiers',
+        'Summary': 'description',
+        'Description': 'long-description',
+    }
+    # Values which are lists, used by the setup.py argument based metadata
+    # extraction method, to determine how to process the setup.py output.
+    setuparg_list_fields = [
+        'Classifier',
+        'Requires',
+        'Provides',
+        'Obsoletes',
+        'Platform',
+        'Supported-Platform',
+    ]
+    setuparg_multi_line_values = ['Description']
+    replacements = [
+        ('License', r' +$', ''),
+        ('License', r'^ +', ''),
+        ('License', r' ', '-'),
+        ('License', r'^GNU-', ''),
+        ('License', r'-[Ll]icen[cs]e(,?-[Vv]ersion)?', ''),
+        ('License', r'^UNKNOWN$', ''),
+
+        # Remove currently unhandled version numbers from these variables
+        ('Requires', r' *\([^)]*\)', ''),
+        ('Provides', r' *\([^)]*\)', ''),
+        ('Obsoletes', r' *\([^)]*\)', ''),
+        ('Install-requires', r'^([^><= ]+).*', r'\1'),
+        ('Extras-require', r'^([^><= ]+).*', r'\1'),
+        ('Tests-require', r'^([^><= ]+).*', r'\1'),
+
+        # Remove unhandled dependency on particular features (e.g. foo[PDF])
+        ('Install-requires', r'\[[^\]]+\]$', ''),
+    ]
+
+    classifier_license_map = {
+        'License :: OSI Approved :: Academic Free License (AFL)': 'AFL',
+        'License :: OSI Approved :: Apache Software License': 'Apache',
+        'License :: OSI Approved :: Apple Public Source License': 'APSL',
+        'License :: OSI Approved :: Artistic License': 'Artistic',
+        'License :: OSI Approved :: Attribution Assurance License': 'AAL',
+        'License :: OSI Approved :: BSD License': 'BSD',
+        'License :: OSI Approved :: Common Public License': 'CPL',
+        'License :: OSI Approved :: Eiffel Forum License': 'EFL',
+        'License :: OSI Approved :: European Union Public Licence 1.0 (EUPL 1.0)': 'EUPL-1.0',
+        'License :: OSI Approved :: European Union Public Licence 1.1 (EUPL 1.1)': 'EUPL-1.1',
+        'License :: OSI Approved :: GNU Affero General Public License v3 or later (AGPLv3+)': 'AGPL-3.0+',
+        'License :: OSI Approved :: GNU Affero General Public License v3': 'AGPL-3.0',
+        'License :: OSI Approved :: GNU Free Documentation License (FDL)': 'GFDL',
+        'License :: OSI Approved :: GNU General Public License (GPL)': 'GPL',
+        'License :: OSI Approved :: GNU General Public License v2 (GPLv2)': 'GPL-2.0',
+        'License :: OSI Approved :: GNU General Public License v2 or later (GPLv2+)': 'GPL-2.0+',
+        'License :: OSI Approved :: GNU General Public License v3 (GPLv3)': 'GPL-3.0',
+        'License :: OSI Approved :: GNU General Public License v3 or later (GPLv3+)': 'GPL-3.0+',
+        'License :: OSI Approved :: GNU Lesser General Public License v2 (LGPLv2)': 'LGPL-2.0',
+        'License :: OSI Approved :: GNU Lesser General Public License v2 or later (LGPLv2+)': 'LGPL-2.0+',
+        'License :: OSI Approved :: GNU Lesser General Public License v3 (LGPLv3)': 'LGPL-3.0',
+        'License :: OSI Approved :: GNU Lesser General Public License v3 or later (LGPLv3+)': 'LGPL-3.0+',
+        'License :: OSI Approved :: GNU Library or Lesser General Public License (LGPL)': 'LGPL',
+        'License :: OSI Approved :: IBM Public License': 'IPL',
+        'License :: OSI Approved :: ISC License (ISCL)': 'ISC',
+        'License :: OSI Approved :: Intel Open Source License': 'Intel',
+        'License :: OSI Approved :: Jabber Open Source License': 'Jabber',
+        'License :: OSI Approved :: MIT License': 'MIT',
+        'License :: OSI Approved :: MITRE Collaborative Virtual Workspace License (CVW)': 'CVWL',
+        'License :: OSI Approved :: Motosoto License': 'Motosoto',
+        'License :: OSI Approved :: Mozilla Public License 1.0 (MPL)': 'MPL-1.0',
+        'License :: OSI Approved :: Mozilla Public License 1.1 (MPL 1.1)': 'MPL-1.1',
+        'License :: OSI Approved :: Mozilla Public License 2.0 (MPL 2.0)': 'MPL-2.0',
+        'License :: OSI Approved :: Nethack General Public License': 'NGPL',
+        'License :: OSI Approved :: Nokia Open Source License': 'Nokia',
+        'License :: OSI Approved :: Open Group Test Suite License': 'OGTSL',
+        'License :: OSI Approved :: Python License (CNRI Python License)': 'CNRI-Python',
+        'License :: OSI Approved :: Python Software Foundation License': 'PSF',
+        'License :: OSI Approved :: Qt Public License (QPL)': 'QPL',
+        'License :: OSI Approved :: Ricoh Source Code Public License': 'RSCPL',
+        'License :: OSI Approved :: Sleepycat License': 'Sleepycat',
+        'License :: OSI Approved :: Sun Industry Standards Source License (SISSL)': '--  Sun Industry Standards Source License (SISSL)',
+        'License :: OSI Approved :: Sun Public License': 'SPL',
+        'License :: OSI Approved :: University of Illinois/NCSA Open Source License': 'NCSA',
+        'License :: OSI Approved :: Vovida Software License 1.0': 'VSL-1.0',
+        'License :: OSI Approved :: W3C License': 'W3C',
+        'License :: OSI Approved :: X.Net License': 'Xnet',
+        'License :: OSI Approved :: Zope Public License': 'ZPL',
+        'License :: OSI Approved :: zlib/libpng License': 'Zlib',
+    }
+
+    def __init__(self):
+        pass
+
+    def process(self, srctree, classes, lines_before, lines_after, handled, extravalues):
+        if 'buildsystem' in handled:
+            return False
+
+        if not RecipeHandler.checkfiles(srctree, ['setup.py']):
+            return
+
+        # setup.py is always parsed to get at certain required information, such as
+        # distutils vs setuptools
+        #
+        # If egg info is available, we use it for both its PKG-INFO metadata
+        # and for its requires.txt for install_requires.
+        # If PKG-INFO is available but no egg info is, we use that for metadata in preference to
+        # the parsed setup.py, but use the install_requires info from the
+        # parsed setup.py.
+
+        setupscript = os.path.join(srctree, 'setup.py')
+        try:
+            setup_info, uses_setuptools, setup_non_literals, extensions = self.parse_setup_py(setupscript)
+        except Exception:
+            logger.exception("Failed to parse setup.py")
+            setup_info, uses_setuptools, setup_non_literals, extensions = {}, True, [], []
+
+        egginfo = glob.glob(os.path.join(srctree, '*.egg-info'))
+        if egginfo:
+            info = self.get_pkginfo(os.path.join(egginfo[0], 'PKG-INFO'))
+            requires_txt = os.path.join(egginfo[0], 'requires.txt')
+            if os.path.exists(requires_txt):
+                with codecs.open(requires_txt) as f:
+                    inst_req = []
+                    extras_req = collections.defaultdict(list)
+                    current_feature = None
+                    for line in f.readlines():
+                        line = line.rstrip()
+                        if not line:
+                            continue
+
+                        if line.startswith('['):
+                            current_feature = line[1:-1]
+                        elif current_feature:
+                            extras_req[current_feature].append(line)
+                        else:
+                            inst_req.append(line)
+                    info['Install-requires'] = inst_req
+                    info['Extras-require'] = extras_req
+        elif RecipeHandler.checkfiles(srctree, ['PKG-INFO']):
+            info = self.get_pkginfo(os.path.join(srctree, 'PKG-INFO'))
+
+            if setup_info:
+                if 'Install-requires' in setup_info:
+                    info['Install-requires'] = setup_info['Install-requires']
+                if 'Extras-require' in setup_info:
+                    info['Extras-require'] = setup_info['Extras-require']
+        else:
+            if setup_info:
+                info = setup_info
+            else:
+                info = self.get_setup_args_info(setupscript)
+
+        # Grab the license value before applying replacements
+        license_str = info.get('License', '').strip()
+
+        self.apply_info_replacements(info)
+
+        if uses_setuptools:
+            classes.append('setuptools')
+        else:
+            classes.append('distutils')
+
+        if license_str:
+            for i, line in enumerate(lines_before):
+                if line.startswith('LICENSE = '):
+                    lines_before.insert(i, '# NOTE: License in setup.py/PKGINFO is: %s' % license_str)
+                    break
+
+        if 'Classifier' in info:
+            existing_licenses = info.get('License', '')
+            licenses = []
+            for classifier in info['Classifier']:
+                if classifier in self.classifier_license_map:
+                    license = self.classifier_license_map[classifier]
+                    if license == 'Apache' and 'Apache-2.0' in existing_licenses:
+                        license = 'Apache-2.0'
+                    elif license == 'GPL':
+                        if 'GPL-2.0' in existing_licenses or 'GPLv2' in existing_licenses:
+                            license = 'GPL-2.0'
+                        elif 'GPL-3.0' in existing_licenses or 'GPLv3' in existing_licenses:
+                            license = 'GPL-3.0'
+                    elif license == 'LGPL':
+                        if 'LGPL-2.1' in existing_licenses or 'LGPLv2.1' in existing_licenses:
+                            license = 'LGPL-2.1'
+                        elif 'LGPL-2.0' in existing_licenses or 'LGPLv2' in existing_licenses:
+                            license = 'LGPL-2.0'
+                        elif 'LGPL-3.0' in existing_licenses or 'LGPLv3' in existing_licenses:
+                            license = 'LGPL-3.0'
+                    licenses.append(license)
+
+            if licenses:
+                info['License'] = ' & '.join(licenses)
+
+        # Map PKG-INFO & setup.py fields to bitbake variables
+        for field, values in info.items():
+            if field in self.excluded_fields:
+                continue
+
+            if field not in self.bbvar_map:
+                continue
+
+            if isinstance(values, str):
+                value = values
+            else:
+                value = ' '.join(str(v) for v in values if v)
+
+            bbvar = self.bbvar_map[field]
+            if bbvar not in extravalues and value:
+                extravalues[bbvar] = value
+
+        mapped_deps, unmapped_deps = self.scan_setup_python_deps(srctree, setup_info, setup_non_literals)
+
+        extras_req = set()
+        if 'Extras-require' in info:
+            extras_req = info['Extras-require']
+            if extras_req:
+                lines_after.append('# The following configs & dependencies are from setuptools extras_require.')
+                lines_after.append('# These dependencies are optional, hence can be controlled via PACKAGECONFIG.')
+                lines_after.append('# The upstream names may not correspond exactly to bitbake package names.')
+                lines_after.append('#')
+                lines_after.append('# Uncomment this line to enable all the optional features.')
+                lines_after.append('#PACKAGECONFIG ?= "{}"'.format(' '.join(k.lower() for k in extras_req)))
+                for feature, feature_reqs in extras_req.items():
+                    unmapped_deps.difference_update(feature_reqs)
+
+                    feature_req_deps = ('python-' + r.replace('.', '-').lower() for r in sorted(feature_reqs))
+                    lines_after.append('PACKAGECONFIG[{}] = ",,,{}"'.format(feature.lower(), ' '.join(feature_req_deps)))
+
+        inst_reqs = set()
+        if 'Install-requires' in info:
+            if extras_req:
+                lines_after.append('')
+            inst_reqs = info['Install-requires']
+            if inst_reqs:
+                unmapped_deps.difference_update(inst_reqs)
+
+                inst_req_deps = ('python-' + r.replace('.', '-').lower() for r in sorted(inst_reqs))
+                lines_after.append('# WARNING: the following rdepends are from setuptools install_requires. These')
+                lines_after.append('# upstream names may not correspond exactly to bitbake package names.')
+                lines_after.append('RDEPENDS_${{PN}} += "{}"'.format(' '.join(inst_req_deps)))
+
+        if mapped_deps:
+            name = info.get('Name')
+            if name and name[0] in mapped_deps:
+                # Attempt to avoid self-reference
+                mapped_deps.remove(name[0])
+            mapped_deps -= set(self.excluded_pkgdeps)
+            if inst_reqs or extras_req:
+                lines_after.append('')
+            lines_after.append('# WARNING: the following rdepends are determined through basic analysis of the')
+            lines_after.append('# python sources, and might not be 100% accurate.')
+            lines_after.append('RDEPENDS_${{PN}} += "{}"'.format(' '.join(sorted(mapped_deps))))
+
+        unmapped_deps -= set(extensions)
+        unmapped_deps -= set(self.assume_provided)
+        if unmapped_deps:
+            if mapped_deps:
+                lines_after.append('')
+            lines_after.append('# WARNING: We were unable to map the following python package/module')
+            lines_after.append('# dependencies to the bitbake packages which include them:')
+            lines_after.extend('#    {}'.format(d) for d in sorted(unmapped_deps))
+
+        handled.append('buildsystem')
+
+    def get_pkginfo(self, pkginfo_fn):
+        msg = email.message_from_file(open(pkginfo_fn, 'r'))
+        msginfo = {}
+        for field in msg.keys():
+            values = msg.get_all(field)
+            if len(values) == 1:
+                msginfo[field] = values[0]
+            else:
+                msginfo[field] = values
+        return msginfo
+
+    def parse_setup_py(self, setupscript='./setup.py'):
+        with codecs.open(setupscript) as f:
+            info, imported_modules, non_literals, extensions = gather_setup_info(f)
+
+        def _map(key):
+            key = key.replace('_', '-')
+            key = key[0].upper() + key[1:]
+            if key in self.setup_parse_map:
+                key = self.setup_parse_map[key]
+            return key
+
+        # Naive mapping of setup() arguments to PKG-INFO field names
+        for d in [info, non_literals]:
+            for key, value in list(d.items()):
+                if key is None:
+                    continue
+                new_key = _map(key)
+                if new_key != key:
+                    del d[key]
+                    d[new_key] = value
+
+        return info, 'setuptools' in imported_modules, non_literals, extensions
+
+    def get_setup_args_info(self, setupscript='./setup.py'):
+        cmd = ['python', setupscript]
+        info = {}
+        keys = set(self.bbvar_map.keys())
+        keys |= set(self.setuparg_list_fields)
+        keys |= set(self.setuparg_multi_line_values)
+        grouped_keys = itertools.groupby(keys, lambda k: (k in self.setuparg_list_fields, k in self.setuparg_multi_line_values))
+        for index, keys in grouped_keys:
+            if index == (True, False):
+                # Splitlines output for each arg as a list value
+                for key in keys:
+                    arg = self.setuparg_map.get(key, key.lower())
+                    try:
+                        arg_info = self.run_command(cmd + ['--' + arg], cwd=os.path.dirname(setupscript))
+                    except (OSError, subprocess.CalledProcessError):
+                        pass
+                    else:
+                        info[key] = [l.rstrip() for l in arg_info.splitlines()]
+            elif index == (False, True):
+                # Entire output for each arg
+                for key in keys:
+                    arg = self.setuparg_map.get(key, key.lower())
+                    try:
+                        arg_info = self.run_command(cmd + ['--' + arg], cwd=os.path.dirname(setupscript))
+                    except (OSError, subprocess.CalledProcessError):
+                        pass
+                    else:
+                        info[key] = arg_info
+            else:
+                info.update(self.get_setup_byline(list(keys), setupscript))
+        return info
+
+    def get_setup_byline(self, fields, setupscript='./setup.py'):
+        info = {}
+
+        cmd = ['python', setupscript]
+        cmd.extend('--' + self.setuparg_map.get(f, f.lower()) for f in fields)
+        try:
+            info_lines = self.run_command(cmd, cwd=os.path.dirname(setupscript)).splitlines()
+        except (OSError, subprocess.CalledProcessError):
+            pass
+        else:
+            if len(fields) != len(info_lines):
+                logger.error('Mismatch between setup.py output lines and number of fields')
+                sys.exit(1)
+
+            for lineno, line in enumerate(info_lines):
+                line = line.rstrip()
+                info[fields[lineno]] = line
+        return info
+
+    def apply_info_replacements(self, info):
+        for variable, search, replace in self.replacements:
+            if variable not in info:
+                continue
+
+            def replace_value(search, replace, value):
+                if replace is None:
+                    if re.search(search, value):
+                        return None
+                else:
+                    new_value = re.sub(search, replace, value)
+                    if value != new_value:
+                        return new_value
+                return value
+
+            value = info[variable]
+            if isinstance(value, str):
+                new_value = replace_value(search, replace, value)
+                if new_value is None:
+                    del info[variable]
+                elif new_value != value:
+                    info[variable] = new_value
+            elif hasattr(value, 'items'):
+                for dkey, dvalue in list(value.items()):
+                    new_list = []
+                    for pos, a_value in enumerate(dvalue):
+                        new_value = replace_value(search, replace, a_value)
+                        if new_value is not None and new_value != value:
+                            new_list.append(new_value)
+
+                    if value != new_list:
+                        value[dkey] = new_list
+            else:
+                new_list = []
+                for pos, a_value in enumerate(value):
+                    new_value = replace_value(search, replace, a_value)
+                    if new_value is not None and new_value != value:
+                        new_list.append(new_value)
+
+                if value != new_list:
+                    info[variable] = new_list
+
+    def scan_setup_python_deps(self, srctree, setup_info, setup_non_literals):
+        if 'Package-dir' in setup_info:
+            package_dir = setup_info['Package-dir']
+        else:
+            package_dir = {}
+
+        class PackageDir(distutils.command.build_py.build_py):
+            def __init__(self, package_dir):
+                self.package_dir = package_dir
+
+        pd = PackageDir(package_dir)
+        to_scan = []
+        if not any(v in setup_non_literals for v in ['Py-modules', 'Scripts', 'Packages']):
+            if 'Py-modules' in setup_info:
+                for module in setup_info['Py-modules']:
+                    try:
+                        package, module = module.rsplit('.', 1)
+                    except ValueError:
+                        package, module = '.', module
+                    module_path = os.path.join(pd.get_package_dir(package), module + '.py')
+                    to_scan.append(module_path)
+
+            if 'Packages' in setup_info:
+                for package in setup_info['Packages']:
+                    to_scan.append(pd.get_package_dir(package))
+
+            if 'Scripts' in setup_info:
+                to_scan.extend(setup_info['Scripts'])
+        else:
+            logger.info("Scanning the entire source tree, as one or more of the following setup keywords are non-literal: py_modules, scripts, packages.")
+
+        if not to_scan:
+            to_scan = ['.']
+
+        logger.info("Scanning paths for packages & dependencies: %s", ', '.join(to_scan))
+
+        provided_packages = self.parse_pkgdata_for_python_packages()
+        scanned_deps = self.scan_python_dependencies([os.path.join(srctree, p) for p in to_scan])
+        mapped_deps, unmapped_deps = set(self.base_pkgdeps), set()
+        for dep in scanned_deps:
+            mapped = provided_packages.get(dep)
+            if mapped:
+                logger.debug('Mapped %s to %s' % (dep, mapped))
+                mapped_deps.add(mapped)
+            else:
+                logger.debug('Could not map %s' % dep)
+                unmapped_deps.add(dep)
+        return mapped_deps, unmapped_deps
+
+    def scan_python_dependencies(self, paths):
+        deps = set()
+        try:
+            dep_output = self.run_command(['pythondeps', '-d'] + paths)
+        except (OSError, subprocess.CalledProcessError):
+            pass
+        else:
+            for line in dep_output.splitlines():
+                line = line.rstrip()
+                dep, filename = line.split('\t', 1)
+                if filename.endswith('/setup.py'):
+                    continue
+                deps.add(dep)
+
+        try:
+            provides_output = self.run_command(['pythondeps', '-p'] + paths)
+        except (OSError, subprocess.CalledProcessError):
+            pass
+        else:
+            provides_lines = (l.rstrip() for l in provides_output.splitlines())
+            provides = set(l for l in provides_lines if l and l != 'setup')
+            deps -= provides
+
+        return deps
+
+    def parse_pkgdata_for_python_packages(self):
+        suffixes = [t[0] for t in imp.get_suffixes()]
+        pkgdata_dir = tinfoil.config_data.getVar('PKGDATA_DIR')
+
+        ldata = tinfoil.config_data.createCopy()
+        bb.parse.handle('classes/python-dir.bbclass', ldata, True)
+        python_sitedir = ldata.getVar('PYTHON_SITEPACKAGES_DIR')
+
+        dynload_dir = os.path.join(os.path.dirname(python_sitedir), 'lib-dynload')
+        python_dirs = [python_sitedir + os.sep,
+                       os.path.join(os.path.dirname(python_sitedir), 'dist-packages') + os.sep,
+                       os.path.dirname(python_sitedir) + os.sep]
+        packages = {}
+        for pkgdatafile in glob.glob('{}/runtime/*'.format(pkgdata_dir)):
+            files_info = None
+            with open(pkgdatafile, 'r') as f:
+                for line in f.readlines():
+                    field, value = line.split(': ', 1)
+                    if field == 'FILES_INFO':
+                        files_info = ast.literal_eval(value)
+                        break
+                else:
+                    continue
+
+            for fn in files_info:
+                for suffix in suffixes:
+                    if fn.endswith(suffix):
+                        break
+                else:
+                    continue
+
+                if fn.startswith(dynload_dir + os.sep):
+                    if '/.debug/' in fn:
+                        continue
+                    base = os.path.basename(fn)
+                    provided = base.split('.', 1)[0]
+                    packages[provided] = os.path.basename(pkgdatafile)
+                    continue
+
+                for python_dir in python_dirs:
+                    if fn.startswith(python_dir):
+                        relpath = fn[len(python_dir):]
+                        relstart, _, relremaining = relpath.partition(os.sep)
+                        if relstart.endswith('.egg'):
+                            relpath = relremaining
+                        base, _ = os.path.splitext(relpath)
+
+                        if '/.debug/' in base:
+                            continue
+                        if os.path.basename(base) == '__init__':
+                            base = os.path.dirname(base)
+                        base = base.replace(os.sep + os.sep, os.sep)
+                        provided = base.replace(os.sep, '.')
+                        packages[provided] = os.path.basename(pkgdatafile)
+        return packages
+
+    @classmethod
+    def run_command(cls, cmd, **popenargs):
+        if 'stderr' not in popenargs:
+            popenargs['stderr'] = subprocess.STDOUT
+        try:
+            return subprocess.check_output(cmd, **popenargs).decode('utf-8')
+        except OSError as exc:
+            logger.error('Unable to run `{}`: {}', ' '.join(cmd), exc)
+            raise
+        except subprocess.CalledProcessError as exc:
+            logger.error('Unable to run `{}`: {}', ' '.join(cmd), exc.output)
+            raise
+
+
+def gather_setup_info(fileobj):
+    parsed = ast.parse(fileobj.read(), fileobj.name)
+    visitor = SetupScriptVisitor()
+    visitor.visit(parsed)
+
+    non_literals, extensions = {}, []
+    for key, value in list(visitor.keywords.items()):
+        if key == 'ext_modules':
+            if isinstance(value, list):
+                for ext in value:
+                    if  (isinstance(ext, ast.Call) and
+                         isinstance(ext.func, ast.Name) and
+                         ext.func.id == 'Extension' and
+                         not has_non_literals(ext.args)):
+                        extensions.append(ext.args[0])
+        elif has_non_literals(value):
+            non_literals[key] = value
+            del visitor.keywords[key]
+
+    return visitor.keywords, visitor.imported_modules, non_literals, extensions
+
+
+class SetupScriptVisitor(ast.NodeVisitor):
+    def __init__(self):
+        ast.NodeVisitor.__init__(self)
+        self.keywords = {}
+        self.non_literals = []
+        self.imported_modules = set()
+
+    def visit_Expr(self, node):
+        if isinstance(node.value, ast.Call) and \
+           isinstance(node.value.func, ast.Name) and \
+           node.value.func.id == 'setup':
+            self.visit_setup(node.value)
+
+    def visit_setup(self, node):
+        call = LiteralAstTransform().visit(node)
+        self.keywords = call.keywords
+        for k, v in self.keywords.items():
+            if has_non_literals(v):
+               self.non_literals.append(k)
+
+    def visit_Import(self, node):
+        for alias in node.names:
+            self.imported_modules.add(alias.name)
+
+    def visit_ImportFrom(self, node):
+        self.imported_modules.add(node.module)
+
+
+class LiteralAstTransform(ast.NodeTransformer):
+    """Simplify the ast through evaluation of literals."""
+    excluded_fields = ['ctx']
+
+    def visit(self, node):
+        if not isinstance(node, ast.AST):
+            return node
+        else:
+            return ast.NodeTransformer.visit(self, node)
+
+    def generic_visit(self, node):
+        try:
+            return ast.literal_eval(node)
+        except ValueError:
+            for field, value in ast.iter_fields(node):
+                if field in self.excluded_fields:
+                    delattr(node, field)
+                if value is None:
+                    continue
+
+                if isinstance(value, list):
+                    if field in ('keywords', 'kwargs'):
+                        new_value = dict((kw.arg, self.visit(kw.value)) for kw in value)
+                    else:
+                        new_value = [self.visit(i) for i in value]
+                else:
+                    new_value = self.visit(value)
+                setattr(node, field, new_value)
+            return node
+
+    def visit_Name(self, node):
+        if hasattr('__builtins__', node.id):
+            return getattr(__builtins__, node.id)
+        else:
+            return self.generic_visit(node)
+
+    def visit_Tuple(self, node):
+        return tuple(self.visit(v) for v in node.elts)
+
+    def visit_List(self, node):
+        return [self.visit(v) for v in node.elts]
+
+    def visit_Set(self, node):
+        return set(self.visit(v) for v in node.elts)
+
+    def visit_Dict(self, node):
+        keys = (self.visit(k) for k in node.keys)
+        values = (self.visit(v) for v in node.values)
+        return dict(zip(keys, values))
+
+
+def has_non_literals(value):
+    if isinstance(value, ast.AST):
+        return True
+    elif isinstance(value, str):
+        return False
+    elif hasattr(value, 'values'):
+        return any(has_non_literals(v) for v in value.values())
+    elif hasattr(value, '__iter__'):
+        return any(has_non_literals(v) for v in value)
+
+
+def register_recipe_handlers(handlers):
+    # We need to make sure this is ahead of the makefile fallback handler
+    handlers.append((PythonRecipeHandler(), 70))
diff --git a/meta/poky/scripts/lib/recipetool/create_kernel.py b/meta/poky/scripts/lib/recipetool/create_kernel.py
new file mode 100644
index 0000000..ca4996c
--- /dev/null
+++ b/meta/poky/scripts/lib/recipetool/create_kernel.py
@@ -0,0 +1,99 @@
+# Recipe creation tool - kernel support plugin
+#
+# Copyright (C) 2016 Intel Corporation
+#
+# 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.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+import re
+import logging
+from recipetool.create import RecipeHandler, read_pkgconfig_provides, validate_pv
+
+logger = logging.getLogger('recipetool')
+
+tinfoil = None
+
+def tinfoil_init(instance):
+    global tinfoil
+    tinfoil = instance
+
+
+class KernelRecipeHandler(RecipeHandler):
+    def process(self, srctree, classes, lines_before, lines_after, handled, extravalues):
+        import bb.process
+        if 'buildsystem' in handled:
+            return False
+
+        for tell in ['arch', 'firmware', 'Kbuild', 'Kconfig']:
+            if not os.path.exists(os.path.join(srctree, tell)):
+                return False
+
+        handled.append('buildsystem')
+        del lines_after[:]
+        del classes[:]
+        template = os.path.join(tinfoil.config_data.getVar('COREBASE'), 'meta-skeleton', 'recipes-kernel', 'linux', 'linux-yocto-custom.bb')
+        def handle_var(varname, origvalue, op, newlines):
+            if varname in ['SRCREV', 'SRCREV_machine']:
+                while newlines[-1].startswith('#'):
+                    del newlines[-1]
+                try:
+                    stdout, _ = bb.process.run('git rev-parse HEAD', cwd=srctree, shell=True)
+                except bb.process.ExecutionError as e:
+                    stdout = None
+                if stdout:
+                    return stdout.strip(), op, 0, True
+            elif varname == 'LINUX_VERSION':
+                makefile = os.path.join(srctree, 'Makefile')
+                if os.path.exists(makefile):
+                    kversion = -1
+                    kpatchlevel = -1
+                    ksublevel = -1
+                    kextraversion = ''
+                    with open(makefile, 'r', errors='surrogateescape') as f:
+                        for i, line in enumerate(f):
+                            if i > 10:
+                                break
+                            if line.startswith('VERSION ='):
+                                kversion = int(line.split('=')[1].strip())
+                            elif line.startswith('PATCHLEVEL ='):
+                                kpatchlevel = int(line.split('=')[1].strip())
+                            elif line.startswith('SUBLEVEL ='):
+                                ksublevel = int(line.split('=')[1].strip())
+                            elif line.startswith('EXTRAVERSION ='):
+                                kextraversion = line.split('=')[1].strip()
+                    version = ''
+                    if kversion > -1 and kpatchlevel > -1:
+                        version = '%d.%d' % (kversion, kpatchlevel)
+                        if ksublevel > -1:
+                            version += '.%d' % ksublevel
+                        version += kextraversion
+                    if version:
+                        return version, op, 0, True
+            elif varname == 'SRC_URI':
+                while newlines[-1].startswith('#'):
+                    del newlines[-1]
+            elif varname == 'COMPATIBLE_MACHINE':
+                while newlines[-1].startswith('#'):
+                    del newlines[-1]
+                machine = tinfoil.config_data.getVar('MACHINE')
+                return machine, op, 0, True
+            return origvalue, op, 0, True
+        with open(template, 'r') as f:
+            varlist = ['SRCREV', 'SRCREV_machine', 'SRC_URI', 'LINUX_VERSION', 'COMPATIBLE_MACHINE']
+            (_, newlines) = bb.utils.edit_metadata(f, varlist, handle_var)
+        lines_before[:] = [line.rstrip('\n') for line in newlines]
+
+        return True
+
+def register_recipe_handlers(handlers):
+    handlers.append((KernelRecipeHandler(), 100))
diff --git a/meta/poky/scripts/lib/recipetool/create_kmod.py b/meta/poky/scripts/lib/recipetool/create_kmod.py
new file mode 100644
index 0000000..3982537
--- /dev/null
+++ b/meta/poky/scripts/lib/recipetool/create_kmod.py
@@ -0,0 +1,152 @@
+# Recipe creation tool - kernel module support plugin
+#
+# Copyright (C) 2016 Intel Corporation
+#
+# 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.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+import re
+import logging
+from recipetool.create import RecipeHandler, read_pkgconfig_provides, validate_pv
+
+logger = logging.getLogger('recipetool')
+
+tinfoil = None
+
+def tinfoil_init(instance):
+    global tinfoil
+    tinfoil = instance
+
+
+class KernelModuleRecipeHandler(RecipeHandler):
+    def process(self, srctree, classes, lines_before, lines_after, handled, extravalues):
+        import bb.process
+        if 'buildsystem' in handled:
+            return False
+
+        module_inc_re = re.compile(r'^#include\s+<linux/module.h>$')
+        makefiles = []
+        is_module = False
+
+        makefiles = []
+
+        files = RecipeHandler.checkfiles(srctree, ['*.c', '*.h'], recursive=True, excludedirs=['contrib', 'test', 'examples'])
+        if files:
+            for cfile in files:
+                # Look in same dir or parent for Makefile
+                for makefile in [os.path.join(os.path.dirname(cfile), 'Makefile'), os.path.join(os.path.dirname(os.path.dirname(cfile)), 'Makefile')]:
+                    if makefile in makefiles:
+                        break
+                    else:
+                        if os.path.exists(makefile):
+                            makefiles.append(makefile)
+                            break
+                else:
+                    continue
+                with open(cfile, 'r', errors='surrogateescape') as f:
+                    for line in f:
+                        if module_inc_re.match(line.strip()):
+                            is_module = True
+                            break
+                if is_module:
+                    break
+
+        if is_module:
+            classes.append('module')
+            handled.append('buildsystem')
+            # module.bbclass and the classes it inherits do most of the hard
+            # work, but we need to tweak it slightly depending on what the
+            # Makefile does (and there is a range of those)
+            # Check the makefile for the appropriate install target
+            install_lines = []
+            compile_lines = []
+            in_install = False
+            in_compile = False
+            install_target = None
+            with open(makefile, 'r', errors='surrogateescape') as f:
+                for line in f:
+                    if line.startswith('install:'):
+                        if not install_lines:
+                            in_install = True
+                            install_target = 'install'
+                    elif line.startswith('modules_install:'):
+                        install_lines = []
+                        in_install = True
+                        install_target = 'modules_install'
+                    elif line.startswith('modules:'):
+                        compile_lines = []
+                        in_compile = True
+                    elif line.startswith(('all:', 'default:')):
+                        if not compile_lines:
+                            in_compile = True
+                    elif line:
+                        if line[0] == '\t':
+                            if in_install:
+                                install_lines.append(line)
+                            elif in_compile:
+                                compile_lines.append(line)
+                        elif ':' in line:
+                            in_install = False
+                            in_compile = False
+
+            def check_target(lines, install):
+                kdirpath = ''
+                manual_install = False
+                for line in lines:
+                    splitline = line.split()
+                    if splitline[0] in ['make', 'gmake', '$(MAKE)']:
+                        if '-C' in splitline:
+                            idx = splitline.index('-C') + 1
+                            if idx < len(splitline):
+                                kdirpath = splitline[idx]
+                                break
+                    elif install and splitline[0] == 'install':
+                        if '.ko' in line:
+                            manual_install = True
+                return kdirpath, manual_install
+
+            kdirpath = None
+            manual_install = False
+            if install_lines:
+                kdirpath, manual_install = check_target(install_lines, install=True)
+            if compile_lines and not kdirpath:
+                kdirpath, _ = check_target(compile_lines, install=False)
+
+            if manual_install or not install_lines:
+                lines_after.append('EXTRA_OEMAKE_append_task-install = " -C ${STAGING_KERNEL_DIR} M=${S}"')
+            elif install_target and install_target != 'modules_install':
+                lines_after.append('MODULES_INSTALL_TARGET = "install"')
+
+            warnmsg = None
+            kdirvar = None
+            if kdirpath:
+                res = re.match(r'\$\(([^$)]+)\)', kdirpath)
+                if res:
+                    kdirvar = res.group(1)
+                    if kdirvar != 'KERNEL_SRC':
+                        lines_after.append('EXTRA_OEMAKE += "%s=${STAGING_KERNEL_DIR}"' % kdirvar)
+                elif kdirpath.startswith('/lib/'):
+                    warnmsg = 'Kernel path in install makefile is hardcoded - you will need to patch the makefile'
+            if not kdirvar and not warnmsg:
+                warnmsg = 'Unable to find means of passing kernel path into install makefile - if kernel path is hardcoded you will need to patch the makefile'
+            if warnmsg:
+                warnmsg += '. Note that the variable KERNEL_SRC will be passed in as the kernel source path.'
+                logger.warning(warnmsg)
+                lines_after.append('# %s' % warnmsg)
+
+            return True
+
+        return False
+
+def register_recipe_handlers(handlers):
+    handlers.append((KernelModuleRecipeHandler(), 15))
diff --git a/meta/poky/scripts/lib/recipetool/create_npm.py b/meta/poky/scripts/lib/recipetool/create_npm.py
new file mode 100644
index 0000000..0b09ed0
--- /dev/null
+++ b/meta/poky/scripts/lib/recipetool/create_npm.py
@@ -0,0 +1,331 @@
+# Recipe creation tool - node.js NPM module support plugin
+#
+# Copyright (C) 2016 Intel Corporation
+#
+# 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.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+import os
+import sys
+import logging
+import subprocess
+import tempfile
+import shutil
+import json
+from recipetool.create import RecipeHandler, split_pkg_licenses, handle_license_vars
+
+logger = logging.getLogger('recipetool')
+
+
+tinfoil = None
+
+def tinfoil_init(instance):
+    global tinfoil
+    tinfoil = instance
+
+
+class NpmRecipeHandler(RecipeHandler):
+    lockdownpath = None
+
+    def _ensure_npm(self, fixed_setup=False):
+        if not tinfoil.recipes_parsed:
+            tinfoil.parse_recipes()
+        try:
+            rd = tinfoil.parse_recipe('nodejs-native')
+        except bb.providers.NoProvider:
+            if fixed_setup:
+                msg = 'nodejs-native is required for npm but is not available within this SDK'
+            else:
+                msg = 'nodejs-native is required for npm but is not available - you will likely need to add a layer that provides nodejs'
+            logger.error(msg)
+            return None
+        bindir = rd.getVar('STAGING_BINDIR_NATIVE')
+        npmpath = os.path.join(bindir, 'npm')
+        if not os.path.exists(npmpath):
+            tinfoil.build_targets('nodejs-native', 'addto_recipe_sysroot')
+            if not os.path.exists(npmpath):
+                logger.error('npm required to process specified source, but nodejs-native did not seem to populate it')
+                return None
+        return bindir
+
+    def _handle_license(self, data):
+        '''
+        Handle the license value from an npm package.json file
+        '''
+        license = None
+        if 'license' in data:
+            license = data['license']
+            if isinstance(license, dict):
+                license = license.get('type', None)
+            if license:
+                if 'OR' in license:
+                    license = license.replace('OR', '|')
+                    license = license.replace('AND', '&')
+                    license = license.replace(' ', '_')
+                    if not license[0] == '(':
+                        license = '(' + license + ')'
+                else:
+                    license = license.replace('AND', '&')
+                    if license[0] == '(':
+                        license = license[1:]
+                    if license[-1] == ')':
+                        license = license[:-1]
+                license = license.replace('MIT/X11', 'MIT')
+                license = license.replace('Public Domain', 'PD')
+                license = license.replace('SEE LICENSE IN EULA',
+                                          'SEE-LICENSE-IN-EULA')
+        return license
+
+    def _shrinkwrap(self, srctree, localfilesdir, extravalues, lines_before, d):
+        try:
+            runenv = dict(os.environ, PATH=d.getVar('PATH'))
+            bb.process.run('npm shrinkwrap', cwd=srctree, stderr=subprocess.STDOUT, env=runenv, shell=True)
+        except bb.process.ExecutionError as e:
+            logger.warning('npm shrinkwrap failed:\n%s' % e.stdout)
+            return
+
+        tmpfile = os.path.join(localfilesdir, 'npm-shrinkwrap.json')
+        shutil.move(os.path.join(srctree, 'npm-shrinkwrap.json'), tmpfile)
+        extravalues.setdefault('extrafiles', {})
+        extravalues['extrafiles']['npm-shrinkwrap.json'] = tmpfile
+        lines_before.append('NPM_SHRINKWRAP := "${THISDIR}/${PN}/npm-shrinkwrap.json"')
+
+    def _lockdown(self, srctree, localfilesdir, extravalues, lines_before, d):
+        runenv = dict(os.environ, PATH=d.getVar('PATH'))
+        if not NpmRecipeHandler.lockdownpath:
+            NpmRecipeHandler.lockdownpath = tempfile.mkdtemp('recipetool-npm-lockdown')
+            bb.process.run('npm install lockdown --prefix %s' % NpmRecipeHandler.lockdownpath,
+                           cwd=srctree, stderr=subprocess.STDOUT, env=runenv, shell=True)
+        relockbin = os.path.join(NpmRecipeHandler.lockdownpath, 'node_modules', 'lockdown', 'relock.js')
+        if not os.path.exists(relockbin):
+            logger.warning('Could not find relock.js within lockdown directory; skipping lockdown')
+            return
+        try:
+            bb.process.run('node %s' % relockbin, cwd=srctree, stderr=subprocess.STDOUT, env=runenv, shell=True)
+        except bb.process.ExecutionError as e:
+            logger.warning('lockdown-relock failed:\n%s' % e.stdout)
+            return
+
+        tmpfile = os.path.join(localfilesdir, 'lockdown.json')
+        shutil.move(os.path.join(srctree, 'lockdown.json'), tmpfile)
+        extravalues.setdefault('extrafiles', {})
+        extravalues['extrafiles']['lockdown.json'] = tmpfile
+        lines_before.append('NPM_LOCKDOWN := "${THISDIR}/${PN}/lockdown.json"')
+
+    def _handle_dependencies(self, d, deps, optdeps, devdeps, lines_before, srctree):
+        import scriptutils
+        # If this isn't a single module we need to get the dependencies
+        # and add them to SRC_URI
+        def varfunc(varname, origvalue, op, newlines):
+            if varname == 'SRC_URI':
+                if not origvalue.startswith('npm://'):
+                    src_uri = origvalue.split()
+                    deplist = {}
+                    for dep, depver in optdeps.items():
+                        depdata = self.get_npm_data(dep, depver, d)
+                        if self.check_npm_optional_dependency(depdata):
+                            deplist[dep] = depdata
+                    for dep, depver in devdeps.items():
+                        depdata = self.get_npm_data(dep, depver, d)
+                        if self.check_npm_optional_dependency(depdata):
+                            deplist[dep] = depdata
+                    for dep, depver in deps.items():
+                        depdata = self.get_npm_data(dep, depver, d)
+                        deplist[dep] = depdata
+
+                    extra_urls = []
+                    for dep, depdata in deplist.items():
+                        version = depdata.get('version', None)
+                        if version:
+                            url = 'npm://registry.npmjs.org;name=%s;version=%s;subdir=node_modules/%s' % (dep, version, dep)
+                            extra_urls.append(url)
+                    if extra_urls:
+                        scriptutils.fetch_url(tinfoil, ' '.join(extra_urls), None, srctree, logger)
+                        src_uri.extend(extra_urls)
+                        return src_uri, None, -1, True
+            return origvalue, None, 0, True
+        updated, newlines = bb.utils.edit_metadata(lines_before, ['SRC_URI'], varfunc)
+        if updated:
+            del lines_before[:]
+            for line in newlines:
+                # Hack to avoid newlines that edit_metadata inserts
+                if line.endswith('\n'):
+                    line = line[:-1]
+                lines_before.append(line)
+        return updated
+
+    def process(self, srctree, classes, lines_before, lines_after, handled, extravalues):
+        import bb.utils
+        import oe.package
+        from collections import OrderedDict
+
+        if 'buildsystem' in handled:
+            return False
+
+        def read_package_json(fn):
+            with open(fn, 'r', errors='surrogateescape') as f:
+                return json.loads(f.read())
+
+        files = RecipeHandler.checkfiles(srctree, ['package.json'])
+        if files:
+            d = bb.data.createCopy(tinfoil.config_data)
+            npm_bindir = self._ensure_npm()
+            if not npm_bindir:
+                sys.exit(14)
+            d.prependVar('PATH', '%s:' % npm_bindir)
+
+            data = read_package_json(files[0])
+            if 'name' in data and 'version' in data:
+                extravalues['PN'] = data['name']
+                extravalues['PV'] = data['version']
+                classes.append('npm')
+                handled.append('buildsystem')
+                if 'description' in data:
+                    extravalues['SUMMARY'] = data['description']
+                if 'homepage' in data:
+                    extravalues['HOMEPAGE'] = data['homepage']
+
+                fetchdev = extravalues['fetchdev'] or None
+                deps, optdeps, devdeps = self.get_npm_package_dependencies(data, fetchdev)
+                self._handle_dependencies(d, deps, optdeps, devdeps, lines_before, srctree)
+
+                # Shrinkwrap
+                localfilesdir = tempfile.mkdtemp(prefix='recipetool-npm')
+                self._shrinkwrap(srctree, localfilesdir, extravalues, lines_before, d)
+
+                # Lockdown
+                self._lockdown(srctree, localfilesdir, extravalues, lines_before, d)
+
+                # Split each npm module out to is own package
+                npmpackages = oe.package.npm_split_package_dirs(srctree)
+                licvalues = None
+                for item in handled:
+                    if isinstance(item, tuple):
+                        if item[0] == 'license':
+                            licvalues = item[1]
+                            break
+                if not licvalues:
+                    licvalues = handle_license_vars(srctree, lines_before, handled, extravalues, d)
+                if licvalues:
+                    # Augment the license list with information we have in the packages
+                    licenses = {}
+                    license = self._handle_license(data)
+                    if license:
+                        licenses['${PN}'] = license
+                    for pkgname, pkgitem in npmpackages.items():
+                        _, pdata = pkgitem
+                        license = self._handle_license(pdata)
+                        if license:
+                            licenses[pkgname] = license
+                    # Now write out the package-specific license values
+                    # We need to strip out the json data dicts for this since split_pkg_licenses
+                    # isn't expecting it
+                    packages = OrderedDict((x,y[0]) for x,y in npmpackages.items())
+                    packages['${PN}'] = ''
+                    pkglicenses = split_pkg_licenses(licvalues, packages, lines_after, licenses)
+                    all_licenses = list(set([item.replace('_', ' ') for pkglicense in pkglicenses.values() for item in pkglicense]))
+                    if '&' in all_licenses:
+                        all_licenses.remove('&')
+                    extravalues['LICENSE'] = ' & '.join(all_licenses)
+
+                # Need to move S setting after inherit npm
+                for i, line in enumerate(lines_before):
+                    if line.startswith('S ='):
+                        lines_before.pop(i)
+                        lines_after.insert(0, '# Must be set after inherit npm since that itself sets S')
+                        lines_after.insert(1, line)
+                        break
+
+                return True
+
+        return False
+
+    # FIXME this is duplicated from lib/bb/fetch2/npm.py
+    def _parse_view(self, output):
+        '''
+        Parse the output of npm view --json; the last JSON result
+        is assumed to be the one that we're interested in.
+        '''
+        pdata = None
+        outdeps = {}
+        datalines = []
+        bracelevel = 0
+        for line in output.splitlines():
+            if bracelevel:
+                datalines.append(line)
+            elif '{' in line:
+                datalines = []
+                datalines.append(line)
+            bracelevel = bracelevel + line.count('{') - line.count('}')
+        if datalines:
+            pdata = json.loads('\n'.join(datalines))
+        return pdata
+
+    # FIXME this is effectively duplicated from lib/bb/fetch2/npm.py
+    # (split out from _getdependencies())
+    def get_npm_data(self, pkg, version, d):
+        import bb.fetch2
+        pkgfullname = pkg
+        if version != '*' and not '/' in version:
+            pkgfullname += "@'%s'" % version
+        logger.debug(2, "Calling getdeps on %s" % pkg)
+        runenv = dict(os.environ, PATH=d.getVar('PATH'))
+        fetchcmd = "npm view %s --json" % pkgfullname
+        output, _ = bb.process.run(fetchcmd, stderr=subprocess.STDOUT, env=runenv, shell=True)
+        data = self._parse_view(output)
+        return data
+
+    # FIXME this is effectively duplicated from lib/bb/fetch2/npm.py
+    # (split out from _getdependencies())
+    def get_npm_package_dependencies(self, pdata, fetchdev):
+        dependencies = pdata.get('dependencies', {})
+        optionalDependencies = pdata.get('optionalDependencies', {})
+        dependencies.update(optionalDependencies)
+        if fetchdev:
+            devDependencies = pdata.get('devDependencies', {})
+            dependencies.update(devDependencies)
+        else:
+            devDependencies = {}
+        depsfound = {}
+        optdepsfound = {}
+        devdepsfound = {}
+        for dep in dependencies:
+            if dep in optionalDependencies:
+                optdepsfound[dep] = dependencies[dep]
+            elif dep in devDependencies:
+                devdepsfound[dep] = dependencies[dep]
+            else:
+                depsfound[dep] = dependencies[dep]
+        return depsfound, optdepsfound, devdepsfound
+
+    # FIXME this is effectively duplicated from lib/bb/fetch2/npm.py
+    # (split out from _getdependencies())
+    def check_npm_optional_dependency(self, pdata):
+        pkg_os = pdata.get('os', None)
+        if pkg_os:
+            if not isinstance(pkg_os, list):
+                pkg_os = [pkg_os]
+            blacklist = False
+            for item in pkg_os:
+                if item.startswith('!'):
+                    blacklist = True
+                    break
+            if (not blacklist and 'linux' not in pkg_os) or '!linux' in pkg_os:
+                pkg = pdata.get('name', 'Unnamed package')
+                logger.debug(2, "Skipping %s since it's incompatible with Linux" % pkg)
+                return False
+        return True
+
+
+def register_recipe_handlers(handlers):
+    handlers.append((NpmRecipeHandler(), 60))
diff --git a/meta/poky/scripts/lib/recipetool/edit.py b/meta/poky/scripts/lib/recipetool/edit.py
new file mode 100644
index 0000000..c4789a9
--- /dev/null
+++ b/meta/poky/scripts/lib/recipetool/edit.py
@@ -0,0 +1,54 @@
+# Recipe creation tool - edit plugin
+#
+# This sub-command edits the recipe and appends for the specified target
+#
+# Example: recipetool edit busybox
+#
+# Copyright (C) 2018 Mentor Graphics Corporation
+#
+# 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.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+import argparse
+import errno
+import logging
+import os
+import re
+import subprocess
+import sys
+import scriptutils
+
+
+logger = logging.getLogger('recipetool')
+tinfoil = None
+
+
+def tinfoil_init(instance):
+    global tinfoil
+    tinfoil = instance
+
+
+def edit(args):
+    import oe.recipeutils
+
+    recipe_path = tinfoil.get_recipe_file(args.target)
+    appends = tinfoil.get_file_appends(recipe_path)
+
+    return scriptutils.run_editor([recipe_path] + appends, logger)
+
+
+def register_commands(subparsers):
+    parser = subparsers.add_parser('edit',
+                                   help='Edit the recipe and appends for the specified target. This obeys $VISUAL if set, otherwise $EDITOR, otherwise vi.')
+    parser.add_argument('target', help='Target recipe/provide to edit')
+    parser.set_defaults(func=edit, parserecipes=True)
diff --git a/meta/poky/scripts/lib/recipetool/newappend.py b/meta/poky/scripts/lib/recipetool/newappend.py
new file mode 100644
index 0000000..76707b4
--- /dev/null
+++ b/meta/poky/scripts/lib/recipetool/newappend.py
@@ -0,0 +1,89 @@
+# Recipe creation tool - newappend plugin
+#
+# This sub-command creates a bbappend for the specified target and prints the
+# path to the bbappend.
+#
+# Example: recipetool newappend meta-mylayer busybox
+#
+# Copyright (C) 2015 Christopher Larson <kergoth@gmail.com>
+#
+# 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.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+import argparse
+import errno
+import logging
+import os
+import re
+import subprocess
+import sys
+import scriptutils
+
+
+logger = logging.getLogger('recipetool')
+tinfoil = None
+
+
+def tinfoil_init(instance):
+    global tinfoil
+    tinfoil = instance
+
+
+def layer(layerpath):
+    if not os.path.exists(os.path.join(layerpath, 'conf', 'layer.conf')):
+        raise argparse.ArgumentTypeError('{0!r} must be a path to a valid layer'.format(layerpath))
+    return layerpath
+
+
+def newappend(args):
+    import oe.recipeutils
+
+    recipe_path = tinfoil.get_recipe_file(args.target)
+
+    rd = tinfoil.config_data.createCopy()
+    rd.setVar('FILE', recipe_path)
+    append_path, path_ok = oe.recipeutils.get_bbappend_path(rd, args.destlayer, args.wildcard_version)
+    if not append_path:
+        logger.error('Unable to determine layer directory containing %s', recipe_path)
+        return 1
+
+    if not path_ok:
+        logger.warning('Unable to determine correct subdirectory path for bbappend file - check that what %s adds to BBFILES also matches .bbappend files. Using %s for now, but until you fix this the bbappend will not be applied.', os.path.join(args.destlayer, 'conf', 'layer.conf'), os.path.dirname(append_path))
+
+    layerdirs = [os.path.abspath(layerdir) for layerdir in rd.getVar('BBLAYERS').split()]
+    if not os.path.abspath(args.destlayer) in layerdirs:
+        logger.warning('Specified layer is not currently enabled in bblayers.conf, you will need to add it before this bbappend will be active')
+
+    if not os.path.exists(append_path):
+        bb.utils.mkdirhier(os.path.dirname(append_path))
+
+        try:
+            open(append_path, 'a').close()
+        except (OSError, IOError) as exc:
+            logger.critical(str(exc))
+            return 1
+
+    if args.edit:
+        return scriptutils.run_editor([append_path, recipe_path], logger)
+    else:
+        print(append_path)
+
+
+def register_commands(subparsers):
+    parser = subparsers.add_parser('newappend',
+                                   help='Create a bbappend for the specified target in the specified layer')
+    parser.add_argument('-e', '--edit', help='Edit the new append. This obeys $VISUAL if set, otherwise $EDITOR, otherwise vi.', action='store_true')
+    parser.add_argument('-w', '--wildcard-version', help='Use wildcard to make the bbappend apply to any recipe version', action='store_true')
+    parser.add_argument('destlayer', help='Base directory of the destination layer to write the bbappend to', type=layer)
+    parser.add_argument('target', help='Target recipe/provide to append')
+    parser.set_defaults(func=newappend, parserecipes=True)
diff --git a/meta/poky/scripts/lib/recipetool/setvar.py b/meta/poky/scripts/lib/recipetool/setvar.py
new file mode 100644
index 0000000..9de315a
--- /dev/null
+++ b/meta/poky/scripts/lib/recipetool/setvar.py
@@ -0,0 +1,75 @@
+# Recipe creation tool - set variable plugin
+#
+# Copyright (C) 2015 Intel Corporation
+#
+# 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.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+import sys
+import os
+import argparse
+import glob
+import fnmatch
+import re
+import logging
+import scriptutils
+
+logger = logging.getLogger('recipetool')
+
+tinfoil = None
+plugins = None
+
+def tinfoil_init(instance):
+    global tinfoil
+    tinfoil = instance
+
+def setvar(args):
+    import oe.recipeutils
+
+    if args.delete:
+        if args.value:
+            logger.error('-D/--delete and specifying a value are mutually exclusive')
+            return 1
+        value = None
+    else:
+        if args.value is None:
+            logger.error('You must specify a value if not using -D/--delete')
+            return 1
+        value = args.value
+    varvalues = {args.varname: value}
+
+    if args.recipe_only:
+        patches = [oe.recipeutils.patch_recipe_file(args.recipefile, varvalues, patch=args.patch)]
+    else:
+        rd = tinfoil.parse_recipe_file(args.recipefile, False)
+        if not rd:
+            return 1
+        patches = oe.recipeutils.patch_recipe(rd, args.recipefile, varvalues, patch=args.patch)
+    if args.patch:
+        for patch in patches:
+            for line in patch:
+                sys.stdout.write(line)
+    return 0
+
+
+def register_commands(subparsers):
+    parser_setvar = subparsers.add_parser('setvar',
+                                          help='Set a variable within a recipe',
+                                          description='Adds/updates the value a variable is set to in a recipe')
+    parser_setvar.add_argument('recipefile', help='Recipe file to update')
+    parser_setvar.add_argument('varname', help='Variable name to set')
+    parser_setvar.add_argument('value', nargs='?', help='New value to set the variable to')
+    parser_setvar.add_argument('--recipe-only', '-r', help='Do not set variable in any include file if present', action='store_true')
+    parser_setvar.add_argument('--patch', '-p', help='Create a patch to make the change instead of modifying the recipe', action='store_true')
+    parser_setvar.add_argument('--delete', '-D', help='Delete the specified value instead of setting it', action='store_true')
+    parser_setvar.set_defaults(func=setvar)
diff --git a/meta/poky/scripts/lib/resulttool/__init__.py b/meta/poky/scripts/lib/resulttool/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/meta/poky/scripts/lib/resulttool/__init__.py
diff --git a/meta/poky/scripts/lib/resulttool/log.py b/meta/poky/scripts/lib/resulttool/log.py
new file mode 100644
index 0000000..4981635
--- /dev/null
+++ b/meta/poky/scripts/lib/resulttool/log.py
@@ -0,0 +1,78 @@
+# resulttool - Show logs
+#
+# Copyright (c) 2019 Garmin International
+#
+# This program is free software; you can redistribute it and/or modify it
+# under the terms and conditions of the GNU General Public License,
+# version 2, as published by the Free Software Foundation.
+#
+# This program is distributed in the hope 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.
+#
+import os
+import resulttool.resultutils as resultutils
+
+def show_ptest(result, ptest, logger):
+    if 'ptestresult.sections' in result:
+        if ptest in result['ptestresult.sections'] and 'log' in result['ptestresult.sections'][ptest]:
+            print(result['ptestresult.sections'][ptest]['log'])
+            return 0
+
+    print("ptest '%s' not found" % ptest)
+    return 1
+
+def log(args, logger):
+    results = resultutils.load_resultsdata(args.source)
+
+    ptest_count = sum(1 for _, _, _, r in resultutils.test_run_results(results) if 'ptestresult.sections' in r)
+    if ptest_count > 1 and not args.prepend_run:
+        print("%i ptest sections found. '--prepend-run' is required" % ptest_count)
+        return 1
+
+    for _, run_name, _, r in resultutils.test_run_results(results):
+        if args.dump_ptest:
+            if 'ptestresult.sections' in r:
+                for name, ptest in r['ptestresult.sections'].items():
+                    if 'log' in ptest:
+                        dest_dir = args.dump_ptest
+                        if args.prepend_run:
+                            dest_dir = os.path.join(dest_dir, run_name)
+
+                        os.makedirs(dest_dir, exist_ok=True)
+
+                        dest = os.path.join(dest_dir, '%s.log' % name)
+                        print(dest)
+                        with open(dest, 'w') as f:
+                            f.write(ptest['log'])
+
+        if args.raw:
+            if 'ptestresult.rawlogs' in r:
+                print(r['ptestresult.rawlogs']['log'])
+            else:
+                print('Raw logs not found')
+                return 1
+
+        for ptest in args.ptest:
+            if not show_ptest(r, ptest, logger):
+                return 1
+
+def register_commands(subparsers):
+    """Register subcommands from this plugin"""
+    parser = subparsers.add_parser('log', help='show logs',
+                                         description='show the logs from test results',
+                                         group='analysis')
+    parser.set_defaults(func=log)
+    parser.add_argument('source',
+            help='the results file/directory/URL to import')
+    parser.add_argument('--ptest', action='append', default=[],
+            help='show logs for a ptest')
+    parser.add_argument('--dump-ptest', metavar='DIR',
+            help='Dump all ptest log files to the specified directory.')
+    parser.add_argument('--prepend-run', action='store_true',
+            help='''Dump ptest results to a subdirectory named after the test run when using --dump-ptest.
+                    Required if more than one test run is present in the result file''')
+    parser.add_argument('--raw', action='store_true',
+            help='show raw logs')
+
diff --git a/meta/poky/scripts/lib/resulttool/manualexecution.py b/meta/poky/scripts/lib/resulttool/manualexecution.py
new file mode 100755
index 0000000..dc368f3
--- /dev/null
+++ b/meta/poky/scripts/lib/resulttool/manualexecution.py
@@ -0,0 +1,212 @@
+# test case management tool - manual execution from testopia test cases
+#
+# Copyright (c) 2018, Intel Corporation.
+#
+# This program is free software; you can redistribute it and/or modify it
+# under the terms and conditions of the GNU General Public License,
+# version 2, as published by the Free Software Foundation.
+#
+# This program is distributed in the hope 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.
+#
+import argparse
+import json
+import os
+import sys
+import datetime
+import re
+import copy
+from oeqa.core.runner import OETestResultJSONHelper
+
+
+def load_json_file(f):
+    with open(f, "r") as filedata:
+        return json.load(filedata)
+
+def write_json_file(f, json_data):
+    os.makedirs(os.path.dirname(f), exist_ok=True)
+    with open(f, 'w') as filedata:
+        filedata.write(json.dumps(json_data, sort_keys=True, indent=4))
+
+class ManualTestRunner(object):
+
+    def _get_test_module(self, case_file):
+        return os.path.basename(case_file).split('.')[0]
+
+    def _get_input(self, config):
+        while True:
+            output = input('{} = '.format(config))
+            if re.match('^[a-z0-9-.]+$', output):
+                break
+            print('Only lowercase alphanumeric, hyphen and dot are allowed. Please try again')
+        return output
+
+    def _get_available_config_options(self, config_options, test_module, target_config):
+        avail_config_options = None
+        if test_module in config_options:
+            avail_config_options = config_options[test_module].get(target_config)
+        return avail_config_options
+
+    def _choose_config_option(self, options):
+        while True:
+            output = input('{} = '.format('Option index number'))
+            if output in options:
+                break
+            print('Only integer index inputs from above available configuration options are allowed. Please try again.')
+        return options[output]
+
+    def _get_config(self, config_options, test_module):
+        from oeqa.utils.metadata import get_layers
+        from oeqa.utils.commands import get_bb_var
+        from resulttool.resultutils import store_map
+
+        layers = get_layers(get_bb_var('BBLAYERS'))
+        configurations = {}
+        configurations['LAYERS'] = layers
+        configurations['STARTTIME'] = datetime.datetime.now().strftime('%Y%m%d%H%M%S')
+        configurations['TEST_TYPE'] = 'manual'
+        configurations['TEST_MODULE'] = test_module
+
+        extra_config = set(store_map['manual']) - set(configurations)
+        for config in sorted(extra_config):
+            avail_config_options = self._get_available_config_options(config_options, test_module, config)
+            if avail_config_options:
+                print('---------------------------------------------')
+                print('These are available configuration #%s options:' % config)
+                print('---------------------------------------------')
+                for option, _ in sorted(avail_config_options.items(), key=lambda x: int(x[0])):
+                    print('%s: %s' % (option, avail_config_options[option]))
+                print('Please select configuration option, enter the integer index number.')
+                value_conf = self._choose_config_option(avail_config_options)
+                print('---------------------------------------------\n')
+            else:
+                print('---------------------------------------------')
+                print('This is configuration #%s. Please provide configuration value(use "None" if not applicable).' % config)
+                print('---------------------------------------------')
+                value_conf = self._get_input('Configuration Value')
+                print('---------------------------------------------\n')
+            configurations[config] = value_conf
+        return configurations
+
+    def _execute_test_steps(self, case):
+        test_result = {}
+        print('------------------------------------------------------------------------')
+        print('Executing test case: %s' % case['test']['@alias'])
+        print('------------------------------------------------------------------------')
+        print('You have total %s test steps to be executed.' % len(case['test']['execution']))
+        print('------------------------------------------------------------------------\n')
+        for step, _ in sorted(case['test']['execution'].items(), key=lambda x: int(x[0])):
+            print('Step %s: %s' % (step, case['test']['execution'][step]['action']))
+            expected_output = case['test']['execution'][step]['expected_results']
+            if expected_output:
+                print('Expected output: %s' % expected_output)
+        while True:
+            done = input('\nPlease provide test results: (P)assed/(F)ailed/(B)locked/(S)kipped? \n').lower()
+            result_types = {'p':'PASSED',
+                            'f':'FAILED',
+                            'b':'BLOCKED',
+                            's':'SKIPPED'}
+            if done in result_types:
+                for r in result_types:
+                    if done == r:
+                        res = result_types[r]
+                        if res == 'FAILED':
+                            log_input = input('\nPlease enter the error and the description of the log: (Ex:log:211 Error Bitbake)\n')
+                            test_result.update({case['test']['@alias']: {'status': '%s' % res, 'log': '%s' % log_input}})
+                        else:
+                            test_result.update({case['test']['@alias']: {'status': '%s' % res}})
+                break
+            print('Invalid input!')
+        return test_result
+
+    def _get_write_dir(self):
+        return os.environ['BUILDDIR'] + '/tmp/log/manual/'
+
+    def run_test(self, case_file, config_options_file, testcase_config_file):
+        test_module = self._get_test_module(case_file)
+        cases = load_json_file(case_file)
+        config_options = {}
+        if config_options_file:
+            config_options = load_json_file(config_options_file)
+        configurations = self._get_config(config_options, test_module)
+        result_id = 'manual_%s_%s' % (test_module, configurations['STARTTIME'])
+        test_results = {}
+        if testcase_config_file:
+            test_case_config = load_json_file(testcase_config_file)
+            test_case_to_execute = test_case_config['testcases']
+            for case in copy.deepcopy(cases) :
+                if case['test']['@alias'] not in test_case_to_execute:
+                    cases.remove(case)
+
+        print('\nTotal number of test cases in this test suite: %s\n' % len(cases))
+        for c in cases:
+            test_result = self._execute_test_steps(c)
+            test_results.update(test_result)
+        return configurations, result_id, self._get_write_dir(), test_results
+
+    def _get_true_false_input(self, input_message):
+        yes_list = ['Y', 'YES']
+        no_list = ['N', 'NO']
+        while True:
+            more_config_option = input(input_message).upper()
+            if more_config_option in yes_list or more_config_option in no_list:
+                break
+            print('Invalid input!')
+        if more_config_option in no_list:
+            return False
+        return True
+
+    def make_config_option_file(self, logger, case_file, config_options_file):
+        config_options = {}
+        if config_options_file:
+            config_options = load_json_file(config_options_file)
+        new_test_module = self._get_test_module(case_file)
+        print('Creating configuration options file for test module: %s' % new_test_module)
+        new_config_options = {}
+
+        while True:
+            config_name = input('\nPlease provide test configuration to create:\n').upper()
+            new_config_options[config_name] = {}
+            while True:
+                config_value = self._get_input('Configuration possible option value')
+                config_option_index = len(new_config_options[config_name]) + 1
+                new_config_options[config_name][config_option_index] = config_value
+                more_config_option = self._get_true_false_input('\nIs there more configuration option input: (Y)es/(N)o\n')
+                if not more_config_option:
+                    break
+            more_config = self._get_true_false_input('\nIs there more configuration to create: (Y)es/(N)o\n')
+            if not more_config:
+                break
+
+        if new_config_options:
+            config_options[new_test_module] = new_config_options
+        if not config_options_file:
+            config_options_file = os.path.join(self._get_write_dir(), 'manual_config_options.json')
+        write_json_file(config_options_file, config_options)
+        logger.info('Configuration option file created at %s' % config_options_file)
+
+def manualexecution(args, logger):
+    testrunner = ManualTestRunner()
+    if args.make_config_options_file:
+        testrunner.make_config_option_file(logger, args.file, args.config_options_file)
+        return 0
+    configurations, result_id, write_dir, test_results = testrunner.run_test(args.file, args.config_options_file, args.testcase_config_file)
+    resultjsonhelper = OETestResultJSONHelper()
+    resultjsonhelper.dump_testresult_file(write_dir, configurations, result_id, test_results)
+    return 0
+
+def register_commands(subparsers):
+    """Register subcommands from this plugin"""
+    parser_build = subparsers.add_parser('manualexecution', help='helper script for results populating during manual test execution.',
+                                         description='helper script for results populating during manual test execution. You can find manual test case JSON file in meta/lib/oeqa/manual/',
+                                         group='manualexecution')
+    parser_build.set_defaults(func=manualexecution)
+    parser_build.add_argument('file', help='specify path to manual test case JSON file.Note: Please use \"\" to encapsulate the file path.')
+    parser_build.add_argument('-c', '--config-options-file', default='',
+                              help='the config options file to import and used as available configuration option selection or make config option file')
+    parser_build.add_argument('-m', '--make-config-options-file', action='store_true',
+                              help='make the configuration options file based on provided inputs')
+    parser_build.add_argument('-t', '--testcase-config-file', default='',
+                              help='the testcase configuration file to enable user to run a selected set of test case')
\ No newline at end of file
diff --git a/meta/poky/scripts/lib/resulttool/merge.py b/meta/poky/scripts/lib/resulttool/merge.py
new file mode 100644
index 0000000..7159463
--- /dev/null
+++ b/meta/poky/scripts/lib/resulttool/merge.py
@@ -0,0 +1,42 @@
+# resulttool - merge multiple testresults.json files into a file or directory
+#
+# Copyright (c) 2019, Intel Corporation.
+# Copyright (c) 2019, Linux Foundation
+#
+# This program is free software; you can redistribute it and/or modify it
+# under the terms and conditions of the GNU General Public License,
+# version 2, as published by the Free Software Foundation.
+#
+# This program is distributed in the hope 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.
+#
+import os
+import json
+import resulttool.resultutils as resultutils
+
+def merge(args, logger):
+    if resultutils.is_url(args.target_results) or os.path.isdir(args.target_results):
+        results = resultutils.load_resultsdata(args.target_results, configmap=resultutils.store_map)
+        resultutils.append_resultsdata(results, args.base_results, configmap=resultutils.store_map)
+        resultutils.save_resultsdata(results, args.target_results)
+    else:
+        results = resultutils.load_resultsdata(args.base_results, configmap=resultutils.flatten_map)
+        if os.path.exists(args.target_results):
+            resultutils.append_resultsdata(results, args.target_results, configmap=resultutils.flatten_map)
+        resultutils.save_resultsdata(results, os.path.dirname(args.target_results), fn=os.path.basename(args.target_results))
+
+    return 0
+
+def register_commands(subparsers):
+    """Register subcommands from this plugin"""
+    parser_build = subparsers.add_parser('merge', help='merge test result files/directories/URLs',
+                                         description='merge the results from multiple files/directories/URLs into the target file or directory',
+                                         group='setup')
+    parser_build.set_defaults(func=merge)
+    parser_build.add_argument('base_results',
+                              help='the results file/directory/URL to import')
+    parser_build.add_argument('target_results',
+                              help='the target file or directory to merge the base_results with')
+
diff --git a/meta/poky/scripts/lib/resulttool/regression.py b/meta/poky/scripts/lib/resulttool/regression.py
new file mode 100644
index 0000000..fa90ab1
--- /dev/null
+++ b/meta/poky/scripts/lib/resulttool/regression.py
@@ -0,0 +1,192 @@
+# resulttool - regression analysis
+#
+# Copyright (c) 2019, Intel Corporation.
+# Copyright (c) 2019, Linux Foundation
+#
+# This program is free software; you can redistribute it and/or modify it
+# under the terms and conditions of the GNU General Public License,
+# version 2, as published by the Free Software Foundation.
+#
+# This program is distributed in the hope 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.
+#
+import resulttool.resultutils as resultutils
+import json
+
+from oeqa.utils.git import GitRepo
+import oeqa.utils.gitarchive as gitarchive
+
+def compare_result(logger, base_name, target_name, base_result, target_result):
+    base_result = base_result.get('result')
+    target_result = target_result.get('result')
+    result = {}
+    if base_result and target_result:
+        for k in base_result:
+            base_testcase = base_result[k]
+            base_status = base_testcase.get('status')
+            if base_status:
+                target_testcase = target_result.get(k, {})
+                target_status = target_testcase.get('status')
+                if base_status != target_status:
+                    result[k] = {'base': base_status, 'target': target_status}
+            else:
+                logger.error('Failed to retrieved base test case status: %s' % k)
+    if result:
+        resultstring = "Regression: %s\n            %s\n" % (base_name, target_name)
+        for k in sorted(result):
+            resultstring += '    %s: %s -> %s\n' % (k, result[k]['base'], result[k]['target'])
+    else:
+        resultstring = "Match: %s\n       %s" % (base_name, target_name)
+    return result, resultstring
+
+def get_results(logger, source):
+    return resultutils.load_resultsdata(source, configmap=resultutils.regression_map)
+
+def regression(args, logger):
+    base_results = get_results(logger, args.base_result)
+    target_results = get_results(logger, args.target_result)
+
+    regression_common(args, logger, base_results, target_results)
+
+def regression_common(args, logger, base_results, target_results):
+    if args.base_result_id:
+        base_results = resultutils.filter_resultsdata(base_results, args.base_result_id)
+    if args.target_result_id:
+        target_results = resultutils.filter_resultsdata(target_results, args.target_result_id)
+
+    matches = []
+    regressions = []
+    notfound = []
+
+    for a in base_results:
+        if a in target_results:
+            base = list(base_results[a].keys())
+            target = list(target_results[a].keys())
+            # We may have multiple base/targets which are for different configurations. Start by
+            # removing any pairs which match
+            for c in base.copy():
+                for b in target.copy():
+                    res, resstr = compare_result(logger, c, b, base_results[a][c], target_results[a][b])
+                    if not res:
+                        matches.append(resstr)
+                        base.remove(c)
+                        target.remove(b)
+                        break
+            # Should only now see regressions, we may not be able to match multiple pairs directly
+            for c in base:
+                for b in target:
+                    res, resstr = compare_result(logger, c, b, base_results[a][c], target_results[a][b])
+                    if res:
+                        regressions.append(resstr)
+        else:
+            notfound.append("%s not found in target" % a)
+    print("\n".join(sorted(matches)))
+    print("\n".join(sorted(regressions)))
+    print("\n".join(sorted(notfound)))
+
+    return 0
+
+def regression_git(args, logger):
+    base_results = {}
+    target_results = {}
+
+    tag_name = "{branch}/{commit_number}-g{commit}/{tag_number}"
+    repo = GitRepo(args.repo)
+
+    revs = gitarchive.get_test_revs(logger, repo, tag_name, branch=args.branch)
+
+    if args.branch2:
+        revs2 = gitarchive.get_test_revs(logger, repo, tag_name, branch=args.branch2)
+        if not len(revs2):
+            logger.error("No revisions found to compare against")
+            return 1
+        if not len(revs):
+            logger.error("No revision to report on found")
+            return 1
+    else:
+        if len(revs) < 2:
+            logger.error("Only %d tester revisions found, unable to generate report" % len(revs))
+            return 1
+
+    # Pick revisions
+    if args.commit:
+        if args.commit_number:
+            logger.warning("Ignoring --commit-number as --commit was specified")
+        index1 = gitarchive.rev_find(revs, 'commit', args.commit)
+    elif args.commit_number:
+        index1 = gitarchive.rev_find(revs, 'commit_number', args.commit_number)
+    else:
+        index1 = len(revs) - 1
+
+    if args.branch2:
+        revs2.append(revs[index1])
+        index1 = len(revs2) - 1
+        revs = revs2
+
+    if args.commit2:
+        if args.commit_number2:
+            logger.warning("Ignoring --commit-number2 as --commit2 was specified")
+        index2 = gitarchive.rev_find(revs, 'commit', args.commit2)
+    elif args.commit_number2:
+        index2 = gitarchive.rev_find(revs, 'commit_number', args.commit_number2)
+    else:
+        if index1 > 0:
+            index2 = index1 - 1
+            # Find the closest matching commit number for comparision
+            # In future we could check the commit is a common ancestor and
+            # continue back if not but this good enough for now
+            while index2 > 0 and revs[index2].commit_number > revs[index1].commit_number:
+                index2 = index2 - 1
+        else:
+            logger.error("Unable to determine the other commit, use "
+                      "--commit2 or --commit-number2 to specify it")
+            return 1
+
+    logger.info("Comparing:\n%s\nto\n%s\n" % (revs[index1], revs[index2]))
+
+    base_results = resultutils.git_get_result(repo, revs[index1][2])
+    target_results = resultutils.git_get_result(repo, revs[index2][2])
+
+    regression_common(args, logger, base_results, target_results)
+
+    return 0
+
+def register_commands(subparsers):
+    """Register subcommands from this plugin"""
+
+    parser_build = subparsers.add_parser('regression', help='regression file/directory analysis',
+                                         description='regression analysis comparing the base set of results to the target results',
+                                         group='analysis')
+    parser_build.set_defaults(func=regression)
+    parser_build.add_argument('base_result',
+                              help='base result file/directory/URL for the comparison')
+    parser_build.add_argument('target_result',
+                              help='target result file/directory/URL to compare with')
+    parser_build.add_argument('-b', '--base-result-id', default='',
+                              help='(optional) filter the base results to this result ID')
+    parser_build.add_argument('-t', '--target-result-id', default='',
+                              help='(optional) filter the target results to this result ID')
+
+    parser_build = subparsers.add_parser('regression-git', help='regression git analysis',
+                                         description='regression analysis comparing base result set to target '
+                                                     'result set',
+                                         group='analysis')
+    parser_build.set_defaults(func=regression_git)
+    parser_build.add_argument('repo',
+                              help='the git repository containing the data')
+    parser_build.add_argument('-b', '--base-result-id', default='',
+                              help='(optional) default select regression based on configurations unless base result '
+                                   'id was provided')
+    parser_build.add_argument('-t', '--target-result-id', default='',
+                              help='(optional) default select regression based on configurations unless target result '
+                                   'id was provided')
+
+    parser_build.add_argument('--branch', '-B', default='master', help="Branch to find commit in")
+    parser_build.add_argument('--branch2', help="Branch to find comparision revisions in")
+    parser_build.add_argument('--commit', help="Revision to search for")
+    parser_build.add_argument('--commit-number', help="Revision number to search for, redundant if --commit is specified")
+    parser_build.add_argument('--commit2', help="Revision to compare with")
+    parser_build.add_argument('--commit-number2', help="Revision number to compare with, redundant if --commit2 is specified")
+
diff --git a/meta/poky/scripts/lib/resulttool/report.py b/meta/poky/scripts/lib/resulttool/report.py
new file mode 100644
index 0000000..8ae4272
--- /dev/null
+++ b/meta/poky/scripts/lib/resulttool/report.py
@@ -0,0 +1,150 @@
+# test result tool - report text based test results
+#
+# Copyright (c) 2019, Intel Corporation.
+# Copyright (c) 2019, Linux Foundation
+#
+# This program is free software; you can redistribute it and/or modify it
+# under the terms and conditions of the GNU General Public License,
+# version 2, as published by the Free Software Foundation.
+#
+# This program is distributed in the hope 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.
+#
+import os
+import glob
+import json
+import resulttool.resultutils as resultutils
+from oeqa.utils.git import GitRepo
+import oeqa.utils.gitarchive as gitarchive
+
+
+class ResultsTextReport(object):
+    def __init__(self):
+        self.ptests = {}
+        self.result_types = {'passed': ['PASSED', 'passed'],
+                             'failed': ['FAILED', 'failed', 'ERROR', 'error', 'UNKNOWN'],
+                             'skipped': ['SKIPPED', 'skipped']}
+
+
+    def handle_ptest_result(self, k, status, result):
+        if k == 'ptestresult.sections':
+            # Ensure tests without any test results still show up on the report
+            for suite in result['ptestresult.sections']:
+                if suite not in self.ptests:
+                    self.ptests[suite] = {'passed': 0, 'failed': 0, 'skipped': 0, 'duration' : '-', 'failed_testcases': []}
+                if 'duration' in result['ptestresult.sections'][suite]:
+                    self.ptests[suite]['duration'] = result['ptestresult.sections'][suite]['duration']
+                if 'timeout' in result['ptestresult.sections'][suite]:
+                    self.ptests[suite]['duration'] += " T"
+            return
+        try:
+            _, suite, test = k.split(".", 2)
+        except ValueError:
+            return
+        # Handle 'glib-2.0'
+        if 'ptestresult.sections' in result and suite not in result['ptestresult.sections']:
+            try:
+                _, suite, suite1, test = k.split(".", 3)
+                if suite + "." + suite1 in result['ptestresult.sections']:
+                    suite = suite + "." + suite1
+            except ValueError:
+                pass
+        if suite not in self.ptests:
+            self.ptests[suite] = {'passed': 0, 'failed': 0, 'skipped': 0, 'duration' : '-', 'failed_testcases': []}
+        for tk in self.result_types:
+            if status in self.result_types[tk]:
+                self.ptests[suite][tk] += 1
+
+    def get_aggregated_test_result(self, logger, testresult):
+        test_count_report = {'passed': 0, 'failed': 0, 'skipped': 0, 'failed_testcases': []}
+        result = testresult.get('result', [])
+        for k in result:
+            test_status = result[k].get('status', [])
+            for tk in self.result_types:
+                if test_status in self.result_types[tk]:
+                    test_count_report[tk] += 1
+            if test_status in self.result_types['failed']:
+                test_count_report['failed_testcases'].append(k)
+            if k.startswith("ptestresult."):
+                self.handle_ptest_result(k, test_status, result)
+        return test_count_report
+
+    def print_test_report(self, template_file_name, test_count_reports):
+        from jinja2 import Environment, FileSystemLoader
+        script_path = os.path.dirname(os.path.realpath(__file__))
+        file_loader = FileSystemLoader(script_path + '/template')
+        env = Environment(loader=file_loader, trim_blocks=True)
+        template = env.get_template(template_file_name)
+        havefailed = False
+        haveptest = bool(self.ptests)
+        reportvalues = []
+        cols = ['passed', 'failed', 'skipped']
+        maxlen = {'passed' : 0, 'failed' : 0, 'skipped' : 0, 'result_id': 0, 'testseries' : 0, 'ptest' : 0 }
+        for line in test_count_reports:
+            total_tested = line['passed'] + line['failed'] + line['skipped']
+            vals = {}
+            vals['result_id'] = line['result_id']
+            vals['testseries'] = line['testseries']
+            vals['sort'] = line['testseries'] + "_" + line['result_id']
+            vals['failed_testcases'] = line['failed_testcases']
+            for k in cols:
+                vals[k] = "%d (%s%%)" % (line[k], format(line[k] / total_tested * 100, '.0f'))
+            for k in maxlen:
+                if k in vals and len(vals[k]) > maxlen[k]:
+                    maxlen[k] = len(vals[k])
+            reportvalues.append(vals)
+            if line['failed_testcases']:
+                havefailed = True
+        for ptest in self.ptests:
+            if len(ptest) > maxlen['ptest']:
+                maxlen['ptest'] = len(ptest)
+        output = template.render(reportvalues=reportvalues,
+                                 havefailed=havefailed,
+                                 haveptest=haveptest,
+                                 ptests=self.ptests,
+                                 maxlen=maxlen)
+        print(output)
+
+    def view_test_report(self, logger, source_dir, branch, commit, tag):
+        test_count_reports = []
+        if commit:
+            if tag:
+                logger.warning("Ignoring --tag as --commit was specified")
+            tag_name = "{branch}/{commit_number}-g{commit}/{tag_number}"
+            repo = GitRepo(source_dir)
+            revs = gitarchive.get_test_revs(logger, repo, tag_name, branch=branch)
+            rev_index = gitarchive.rev_find(revs, 'commit', commit)
+            testresults = resultutils.git_get_result(repo, revs[rev_index][2])
+        elif tag:
+            repo = GitRepo(source_dir)
+            testresults = resultutils.git_get_result(repo, [tag])
+        else:
+            testresults = resultutils.load_resultsdata(source_dir)
+        for testsuite in testresults:
+            for resultid in testresults[testsuite]:
+                result = testresults[testsuite][resultid]
+                test_count_report = self.get_aggregated_test_result(logger, result)
+                test_count_report['testseries'] = result['configuration']['TESTSERIES']
+                test_count_report['result_id'] = resultid
+                test_count_reports.append(test_count_report)
+        self.print_test_report('test_report_full_text.txt', test_count_reports)
+
+def report(args, logger):
+    report = ResultsTextReport()
+    report.view_test_report(logger, args.source_dir, args.branch, args.commit, args.tag)
+    return 0
+
+def register_commands(subparsers):
+    """Register subcommands from this plugin"""
+    parser_build = subparsers.add_parser('report', help='summarise test results',
+                                         description='print a text-based summary of the test results',
+                                         group='analysis')
+    parser_build.set_defaults(func=report)
+    parser_build.add_argument('source_dir',
+                              help='source file/directory/URL that contain the test result files to summarise')
+    parser_build.add_argument('--branch', '-B', default='master', help="Branch to find commit in")
+    parser_build.add_argument('--commit', help="Revision to report")
+    parser_build.add_argument('-t', '--tag', default='',
+                              help='source_dir is a git repository, report on the tag specified from that repository')
diff --git a/meta/poky/scripts/lib/resulttool/resultutils.py b/meta/poky/scripts/lib/resulttool/resultutils.py
new file mode 100644
index 0000000..07dab4c
--- /dev/null
+++ b/meta/poky/scripts/lib/resulttool/resultutils.py
@@ -0,0 +1,185 @@
+# resulttool - common library/utility functions
+#
+# Copyright (c) 2019, Intel Corporation.
+# Copyright (c) 2019, Linux Foundation
+#
+# This program is free software; you can redistribute it and/or modify it
+# under the terms and conditions of the GNU General Public License,
+# version 2, as published by the Free Software Foundation.
+#
+# This program is distributed in the hope 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.
+#
+import os
+import json
+import scriptpath
+import copy
+import urllib.request
+import posixpath
+scriptpath.add_oe_lib_path()
+
+flatten_map = {
+    "oeselftest": [],
+    "runtime": [],
+    "sdk": [],
+    "sdkext": [],
+    "manual": []
+}
+regression_map = {
+    "oeselftest": ['TEST_TYPE', 'MACHINE'],
+    "runtime": ['TESTSERIES', 'TEST_TYPE', 'IMAGE_BASENAME', 'MACHINE', 'IMAGE_PKGTYPE', 'DISTRO'],
+    "sdk": ['TESTSERIES', 'TEST_TYPE', 'IMAGE_BASENAME', 'MACHINE', 'SDKMACHINE'],
+    "sdkext": ['TESTSERIES', 'TEST_TYPE', 'IMAGE_BASENAME', 'MACHINE', 'SDKMACHINE'],
+    "manual": ['TEST_TYPE', 'TEST_MODULE', 'IMAGE_BASENAME', 'MACHINE']
+}
+store_map = {
+    "oeselftest": ['TEST_TYPE'],
+    "runtime": ['TEST_TYPE', 'DISTRO', 'MACHINE', 'IMAGE_BASENAME'],
+    "sdk": ['TEST_TYPE', 'MACHINE', 'SDKMACHINE', 'IMAGE_BASENAME'],
+    "sdkext": ['TEST_TYPE', 'MACHINE', 'SDKMACHINE', 'IMAGE_BASENAME'],
+    "manual": ['TEST_TYPE', 'TEST_MODULE', 'MACHINE', 'IMAGE_BASENAME']
+}
+
+def is_url(p):
+    """
+    Helper for determining if the given path is a URL
+    """
+    return p.startswith('http://') or p.startswith('https://')
+
+#
+# Load the json file and append the results data into the provided results dict
+#
+def append_resultsdata(results, f, configmap=store_map):
+    if type(f) is str:
+        if is_url(f):
+            with urllib.request.urlopen(f) as response:
+                data = json.loads(response.read().decode('utf-8'))
+            url = urllib.parse.urlparse(f)
+            testseries = posixpath.basename(posixpath.dirname(url.path))
+        else:
+            with open(f, "r") as filedata:
+                data = json.load(filedata)
+            testseries = os.path.basename(os.path.dirname(f))
+    else:
+        data = f
+    for res in data:
+        if "configuration" not in data[res] or "result" not in data[res]:
+            raise ValueError("Test results data without configuration or result section?")
+        if "TESTSERIES" not in data[res]["configuration"]:
+            data[res]["configuration"]["TESTSERIES"] = testseries
+        testtype = data[res]["configuration"].get("TEST_TYPE")
+        if testtype not in configmap:
+            raise ValueError("Unknown test type %s" % testtype)
+        configvars = configmap[testtype]
+        testpath = "/".join(data[res]["configuration"].get(i) for i in configmap[testtype])
+        if testpath not in results:
+            results[testpath] = {}
+        results[testpath][res] = data[res]
+
+#
+# Walk a directory and find/load results data
+# or load directly from a file
+#
+def load_resultsdata(source, configmap=store_map):
+    results = {}
+    if is_url(source) or os.path.isfile(source):
+        append_resultsdata(results, source, configmap)
+        return results
+    for root, dirs, files in os.walk(source):
+        for name in files:
+            f = os.path.join(root, name)
+            if name == "testresults.json":
+                append_resultsdata(results, f, configmap)
+    return results
+
+def filter_resultsdata(results, resultid):
+    newresults = {}
+    for r in results:
+        for i in results[r]:
+            if i == resultsid:
+                 newresults[r] = {}
+                 newresults[r][i] = results[r][i]
+    return newresults
+
+def strip_ptestresults(results):
+    newresults = copy.deepcopy(results)
+    #for a in newresults2:
+    #  newresults = newresults2[a]
+    for res in newresults:
+        if 'result' not in newresults[res]:
+            continue
+        if 'ptestresult.rawlogs' in newresults[res]['result']:
+            del newresults[res]['result']['ptestresult.rawlogs']
+        if 'ptestresult.sections' in newresults[res]['result']:
+            for i in newresults[res]['result']['ptestresult.sections']:
+                if 'log' in newresults[res]['result']['ptestresult.sections'][i]:
+                    del newresults[res]['result']['ptestresult.sections'][i]['log']
+    return newresults
+
+def save_resultsdata(results, destdir, fn="testresults.json", ptestjson=False, ptestlogs=False):
+    for res in results:
+        if res:
+            dst = destdir + "/" + res + "/" + fn
+        else:
+            dst = destdir + "/" + fn
+        os.makedirs(os.path.dirname(dst), exist_ok=True)
+        resultsout = results[res]
+        if not ptestjson:
+            resultsout = strip_ptestresults(results[res])
+        with open(dst, 'w') as f:
+            f.write(json.dumps(resultsout, sort_keys=True, indent=4))
+        for res2 in results[res]:
+            if ptestlogs and 'result' in results[res][res2]:
+                if 'ptestresult.rawlogs' in results[res][res2]['result']:
+                    with open(dst.replace(fn, "ptest-raw.log"), "w+") as f:
+                        f.write(results[res][res2]['result']['ptestresult.rawlogs']['log'])
+                if 'ptestresult.sections' in results[res][res2]['result']:
+                    for i in results[res][res2]['result']['ptestresult.sections']:
+                        if 'log' in results[res][res2]['result']['ptestresult.sections'][i]:
+                            with open(dst.replace(fn, "ptest-%s.log" % i), "w+") as f:
+                                f.write(results[res][res2]['result']['ptestresult.sections'][i]['log'])
+
+def git_get_result(repo, tags):
+    git_objs = []
+    for tag in tags:
+        files = repo.run_cmd(['ls-tree', "--name-only", "-r", tag]).splitlines()
+        git_objs.extend([tag + ':' + f for f in files if f.endswith("testresults.json")])
+
+    def parse_json_stream(data):
+        """Parse multiple concatenated JSON objects"""
+        objs = []
+        json_d = ""
+        for line in data.splitlines():
+            if line == '}{':
+                json_d += '}'
+                objs.append(json.loads(json_d))
+                json_d = '{'
+            else:
+                json_d += line
+        objs.append(json.loads(json_d))
+        return objs
+
+    # Optimize by reading all data with one git command
+    results = {}
+    for obj in parse_json_stream(repo.run_cmd(['show'] + git_objs + ['--'])):
+        append_resultsdata(results, obj)
+
+    return results
+
+def test_run_results(results):
+    """
+    Convenient generator function that iterates over all test runs that have a
+    result section.
+
+    Generates a tuple of:
+        (result json file path, test run name, test run (dict), test run "results" (dict))
+    for each test run that has a "result" section
+    """
+    for path in results:
+        for run_name, test_run in results[path].items():
+            if not 'result' in test_run:
+                continue
+            yield path, run_name, test_run, test_run['result']
+
diff --git a/meta/poky/scripts/lib/resulttool/store.py b/meta/poky/scripts/lib/resulttool/store.py
new file mode 100644
index 0000000..acdfbd9
--- /dev/null
+++ b/meta/poky/scripts/lib/resulttool/store.py
@@ -0,0 +1,102 @@
+# resulttool - store test results
+#
+# Copyright (c) 2019, Intel Corporation.
+# Copyright (c) 2019, Linux Foundation
+#
+# This program is free software; you can redistribute it and/or modify it
+# under the terms and conditions of the GNU General Public License,
+# version 2, as published by the Free Software Foundation.
+#
+# This program is distributed in the hope 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.
+#
+import tempfile
+import os
+import subprocess
+import json
+import shutil
+import scriptpath
+scriptpath.add_bitbake_lib_path()
+scriptpath.add_oe_lib_path()
+import resulttool.resultutils as resultutils
+import oeqa.utils.gitarchive as gitarchive
+
+
+def store(args, logger):
+    tempdir = tempfile.mkdtemp(prefix='testresults.')
+    try:
+        results = {}
+        logger.info('Reading files from %s' % args.source)
+        if resultutils.is_url(args.source) or os.path.isfile(args.source):
+            resultutils.append_resultsdata(results, args.source)
+        else:
+            for root, dirs,  files in os.walk(args.source):
+                for name in files:
+                    f = os.path.join(root, name)
+                    if name == "testresults.json":
+                        resultutils.append_resultsdata(results, f)
+                    elif args.all:
+                        dst = f.replace(args.source, tempdir + "/")
+                        os.makedirs(os.path.dirname(dst), exist_ok=True)
+                        shutil.copyfile(f, dst)
+
+        revisions = {}
+
+        if not results and not args.all:
+            if args.allow_empty:
+                logger.info("No results found to store")
+                return 0
+            logger.error("No results found to store")
+            return 1
+
+        # Find the branch/commit/commit_count and ensure they all match
+        for suite in results:
+            for result in results[suite]:
+                config = results[suite][result]['configuration']['LAYERS']['meta']
+                revision = (config['commit'], config['branch'], str(config['commit_count']))
+                if revision not in revisions:
+                    revisions[revision] = {}
+                if suite not in revisions[revision]:
+                    revisions[revision][suite] = {}
+                revisions[revision][suite][result] = results[suite][result]
+
+        logger.info("Found %d revisions to store" % len(revisions))
+
+        for r in revisions:
+            results = revisions[r]
+            keywords = {'commit': r[0], 'branch': r[1], "commit_count": r[2]}
+            subprocess.check_call(["find", tempdir, "!", "-path", "./.git/*", "-delete"])
+            resultutils.save_resultsdata(results, tempdir, ptestlogs=True)
+
+            logger.info('Storing test result into git repository %s' % args.git_dir)
+
+            gitarchive.gitarchive(tempdir, args.git_dir, False, False,
+                                  "Results of {branch}:{commit}", "branch: {branch}\ncommit: {commit}", "{branch}",
+                                  False, "{branch}/{commit_count}-g{commit}/{tag_number}",
+                                  'Test run #{tag_number} of {branch}:{commit}', '',
+                                  [], [], False, keywords, logger)
+
+    finally:
+        subprocess.check_call(["rm", "-rf",  tempdir])
+
+    return 0
+
+def register_commands(subparsers):
+    """Register subcommands from this plugin"""
+    parser_build = subparsers.add_parser('store', help='store test results into a git repository',
+                                         description='takes a results file or directory of results files and stores '
+                                                     'them into the destination git repository, splitting out the results '
+                                                     'files as configured',
+                                         group='setup')
+    parser_build.set_defaults(func=store)
+    parser_build.add_argument('source',
+                              help='source file/directory/URL that contain the test result files to be stored')
+    parser_build.add_argument('git_dir',
+                              help='the location of the git repository to store the results in')
+    parser_build.add_argument('-a', '--all', action='store_true',
+                              help='include all files, not just testresults.json files')
+    parser_build.add_argument('-e', '--allow-empty', action='store_true',
+                              help='don\'t error if no results to store are found')
+
diff --git a/meta/poky/scripts/lib/resulttool/template/test_report_full_text.txt b/meta/poky/scripts/lib/resulttool/template/test_report_full_text.txt
new file mode 100644
index 0000000..590f35c
--- /dev/null
+++ b/meta/poky/scripts/lib/resulttool/template/test_report_full_text.txt
@@ -0,0 +1,44 @@
+==============================================================================================================
+Test Result Status Summary (Counts/Percentages sorted by testseries, ID)
+==============================================================================================================
+--------------------------------------------------------------------------------------------------------------
+{{ 'Test Series'.ljust(maxlen['testseries']) }} | {{ 'ID'.ljust(maxlen['result_id']) }} | {{ 'Passed'.ljust(maxlen['passed']) }} | {{ 'Failed'.ljust(maxlen['failed']) }} | {{ 'Skipped'.ljust(maxlen['skipped']) }}
+--------------------------------------------------------------------------------------------------------------
+{% for report in reportvalues |sort(attribute='sort') %}
+{{ report.testseries.ljust(maxlen['testseries']) }} | {{ report.result_id.ljust(maxlen['result_id']) }} | {{ (report.passed|string).ljust(maxlen['passed']) }} | {{ (report.failed|string).ljust(maxlen['failed']) }} | {{ (report.skipped|string).ljust(maxlen['skipped']) }}
+{% endfor %}
+--------------------------------------------------------------------------------------------------------------
+
+{% if haveptest %}
+==============================================================================================================
+PTest Result Summary
+==============================================================================================================
+--------------------------------------------------------------------------------------------------------------
+{{ 'Recipe'.ljust(maxlen['ptest']) }} | {{ 'Passed'.ljust(maxlen['passed']) }} | {{ 'Failed'.ljust(maxlen['failed']) }} | {{ 'Skipped'.ljust(maxlen['skipped']) }} | {{ 'Time(s)'.ljust(10) }}
+--------------------------------------------------------------------------------------------------------------
+{% for ptest in ptests |sort %}
+{{ ptest.ljust(maxlen['ptest']) }} | {{ (ptests[ptest]['passed']|string).ljust(maxlen['passed']) }} | {{ (ptests[ptest]['failed']|string).ljust(maxlen['failed']) }} | {{ (ptests[ptest]['skipped']|string).ljust(maxlen['skipped']) }} | {{ (ptests[ptest]['duration']|string) }}
+{% endfor %}
+--------------------------------------------------------------------------------------------------------------
+
+{% else %}
+There was no ptest data
+{% endif %}
+
+==============================================================================================================
+Failed test cases (sorted by testseries, ID)
+==============================================================================================================
+{% if havefailed %}
+--------------------------------------------------------------------------------------------------------------
+{% for report in reportvalues |sort(attribute='sort') %}
+{% if report.failed_testcases %}
+testseries | result_id : {{ report.testseries }} | {{ report.result_id }}
+{% for testcase in report.failed_testcases %}
+    {{ testcase }}
+{% endfor %}
+{% endif %}
+{% endfor %}
+--------------------------------------------------------------------------------------------------------------
+{% else %}
+There were no test failures
+{% endif %}
diff --git a/meta/poky/scripts/lib/scriptpath.py b/meta/poky/scripts/lib/scriptpath.py
new file mode 100644
index 0000000..d00317e
--- /dev/null
+++ b/meta/poky/scripts/lib/scriptpath.py
@@ -0,0 +1,42 @@
+# Path utility functions for OE python scripts
+#
+# Copyright (C) 2012-2014 Intel Corporation
+# Copyright (C) 2011 Mentor Graphics Corporation
+#
+# 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.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+import sys
+import os
+import os.path
+
+def add_oe_lib_path():
+    basepath = os.path.abspath(os.path.dirname(__file__) + '/../..')
+    newpath = basepath + '/meta/lib'
+    sys.path.insert(0, newpath)
+
+def add_bitbake_lib_path():
+    basepath = os.path.abspath(os.path.dirname(__file__) + '/../..')
+    bitbakepath = None
+    if os.path.exists(basepath + '/bitbake/lib/bb'):
+        bitbakepath = basepath + '/bitbake'
+    else:
+        # look for bitbake/bin dir in PATH
+        for pth in os.environ['PATH'].split(':'):
+            if os.path.exists(os.path.join(pth, '../lib/bb')):
+                bitbakepath = os.path.abspath(os.path.join(pth, '..'))
+                break
+
+    if bitbakepath:
+        sys.path.insert(0, bitbakepath + '/lib')
+    return bitbakepath
diff --git a/meta/poky/scripts/lib/scriptutils.py b/meta/poky/scripts/lib/scriptutils.py
new file mode 100644
index 0000000..3c60c3a
--- /dev/null
+++ b/meta/poky/scripts/lib/scriptutils.py
@@ -0,0 +1,240 @@
+# Script utility functions
+#
+# Copyright (C) 2014 Intel Corporation
+#
+# 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.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+import argparse
+import glob
+import logging
+import os
+import random
+import shlex
+import shutil
+import string
+import subprocess
+import sys
+import tempfile
+import importlib
+from importlib import machinery
+
+def logger_create(name, stream=None):
+    logger = logging.getLogger(name)
+    loggerhandler = logging.StreamHandler(stream=stream)
+    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()
+
+
+def load_plugins(logger, plugins, pluginpath):
+    import imp
+
+    def load_plugin(name):
+        logger.debug('Loading plugin %s' % name)
+        spec = importlib.machinery.PathFinder.find_spec(name, path=[pluginpath] )
+        if spec:
+            return spec.loader.load_module()
+
+    def plugin_name(filename):
+        return os.path.splitext(os.path.basename(filename))[0]
+
+    known_plugins = [plugin_name(p.__name__) for p in plugins]
+    logger.debug('Loading plugins from %s...' % pluginpath)
+    for fn in glob.glob(os.path.join(pluginpath, '*.py')):
+        name = plugin_name(fn)
+        if name != '__init__' and name not in known_plugins:
+            plugin = load_plugin(name)
+            if hasattr(plugin, 'plugin_init'):
+                plugin.plugin_init(plugins)
+            plugins.append(plugin)
+
+def git_convert_standalone_clone(repodir):
+    """If specified directory is a git repository, ensure it's a standalone clone"""
+    import bb.process
+    if os.path.exists(os.path.join(repodir, '.git')):
+        alternatesfile = os.path.join(repodir, '.git', 'objects', 'info', 'alternates')
+        if os.path.exists(alternatesfile):
+            # This will have been cloned with -s, so we need to convert it so none
+            # of the contents is shared
+            bb.process.run('git repack -a', cwd=repodir)
+            os.remove(alternatesfile)
+
+def _get_temp_recipe_dir(d):
+    # This is a little bit hacky but we need to find a place where we can put
+    # the recipe so that bitbake can find it. We're going to delete it at the
+    # end so it doesn't really matter where we put it.
+    bbfiles = d.getVar('BBFILES').split()
+    fetchrecipedir = None
+    for pth in bbfiles:
+        if pth.endswith('.bb'):
+            pthdir = os.path.dirname(pth)
+            if os.access(os.path.dirname(os.path.dirname(pthdir)), os.W_OK):
+                fetchrecipedir = pthdir.replace('*', 'recipetool')
+                if pthdir.endswith('workspace/recipes/*'):
+                    # Prefer the workspace
+                    break
+    return fetchrecipedir
+
+class FetchUrlFailure(Exception):
+    def __init__(self, url):
+        self.url = url
+    def __str__(self):
+        return "Failed to fetch URL %s" % self.url
+
+def fetch_url(tinfoil, srcuri, srcrev, destdir, logger, preserve_tmp=False, mirrors=False):
+    """
+    Fetch the specified URL using normal do_fetch and do_unpack tasks, i.e.
+    any dependencies that need to be satisfied in order to support the fetch
+    operation will be taken care of
+    """
+
+    import bb
+
+    checksums = {}
+    fetchrecipepn = None
+
+    # We need to put our temp directory under ${BASE_WORKDIR} otherwise
+    # we may have problems with the recipe-specific sysroot population
+    tmpparent = tinfoil.config_data.getVar('BASE_WORKDIR')
+    bb.utils.mkdirhier(tmpparent)
+    tmpdir = tempfile.mkdtemp(prefix='recipetool-', dir=tmpparent)
+    try:
+        tmpworkdir = os.path.join(tmpdir, 'work')
+        logger.debug('fetch_url: temp dir is %s' % tmpdir)
+
+        fetchrecipedir = _get_temp_recipe_dir(tinfoil.config_data)
+        if not fetchrecipedir:
+            logger.error('Searched BBFILES but unable to find a writeable place to put temporary recipe')
+            sys.exit(1)
+        fetchrecipe = None
+        bb.utils.mkdirhier(fetchrecipedir)
+        try:
+            # Generate a dummy recipe so we can follow more or less normal paths
+            # for do_fetch and do_unpack
+            # I'd use tempfile functions here but underscores can be produced by that and those
+            # aren't allowed in recipe file names except to separate the version
+            rndstring = ''.join(random.choice(string.ascii_lowercase + string.digits) for _ in range(8))
+            fetchrecipe = os.path.join(fetchrecipedir, 'tmp-recipetool-%s.bb' % rndstring)
+            fetchrecipepn = os.path.splitext(os.path.basename(fetchrecipe))[0]
+            logger.debug('Generating initial recipe %s for fetching' % fetchrecipe)
+            with open(fetchrecipe, 'w') as f:
+                # We don't want to have to specify LIC_FILES_CHKSUM
+                f.write('LICENSE = "CLOSED"\n')
+                # We don't need the cross-compiler
+                f.write('INHIBIT_DEFAULT_DEPS = "1"\n')
+                # We don't have the checksums yet so we can't require them
+                f.write('BB_STRICT_CHECKSUM = "ignore"\n')
+                f.write('SRC_URI = "%s"\n' % srcuri)
+                f.write('SRCREV = "%s"\n' % srcrev)
+                f.write('WORKDIR = "%s"\n' % tmpworkdir)
+                # Set S out of the way so it doesn't get created under the workdir
+                f.write('S = "%s"\n' % os.path.join(tmpdir, 'emptysrc'))
+                if not mirrors:
+                    # We do not need PREMIRRORS since we are almost certainly
+                    # fetching new source rather than something that has already
+                    # been fetched. Hence, we disable them by default.
+                    # However, we provide an option for users to enable it.
+                    f.write('PREMIRRORS = ""\n')
+                    f.write('MIRRORS = ""\n')
+
+            logger.info('Fetching %s...' % srcuri)
+
+            # FIXME this is too noisy at the moment
+
+            # Parse recipes so our new recipe gets picked up
+            tinfoil.parse_recipes()
+
+            def eventhandler(event):
+                if isinstance(event, bb.fetch2.MissingChecksumEvent):
+                    checksums.update(event.checksums)
+                    return True
+                return False
+
+            # Run the fetch + unpack tasks
+            res = tinfoil.build_targets(fetchrecipepn,
+                                        'do_unpack',
+                                        handle_events=True,
+                                        extra_events=['bb.fetch2.MissingChecksumEvent'],
+                                        event_callback=eventhandler)
+            if not res:
+                raise FetchUrlFailure(srcuri)
+
+            # Remove unneeded directories
+            rd = tinfoil.parse_recipe(fetchrecipepn)
+            if rd:
+                pathvars = ['T', 'RECIPE_SYSROOT', 'RECIPE_SYSROOT_NATIVE']
+                for pathvar in pathvars:
+                    path = rd.getVar(pathvar)
+                    shutil.rmtree(path)
+        finally:
+            if fetchrecipe:
+                try:
+                    os.remove(fetchrecipe)
+                except FileNotFoundError:
+                    pass
+            try:
+                os.rmdir(fetchrecipedir)
+            except OSError as e:
+                import errno
+                if e.errno != errno.ENOTEMPTY:
+                    raise
+
+        bb.utils.mkdirhier(destdir)
+        for fn in os.listdir(tmpworkdir):
+            shutil.move(os.path.join(tmpworkdir, fn), destdir)
+
+    finally:
+        if not preserve_tmp:
+            shutil.rmtree(tmpdir)
+            tmpdir = None
+
+    return checksums, tmpdir
+
+
+def run_editor(fn, logger=None):
+    if isinstance(fn, str):
+        files = [fn]
+    else:
+        files = fn
+
+    editor = os.getenv('VISUAL', os.getenv('EDITOR', 'vi'))
+    try:
+        #print(shlex.split(editor) + files)
+        return subprocess.check_call(shlex.split(editor) + files)
+    except subprocess.CalledProcessError as exc:
+        logger.error("Execution of '%s' failed: %s" % (editor, exc))
+        return 1
+
+def is_src_url(param):
+    """
+    Check if a parameter is a URL and return True if so
+    NOTE: be careful about changing this as it will influence how devtool/recipetool command line handling works
+    """
+    if not param:
+        return False
+    elif '://' in param:
+        return True
+    elif param.startswith('git@') or ('@' in param and param.endswith('.git')):
+        return True
+    return False
diff --git a/meta/poky/scripts/lib/wic/__init__.py b/meta/poky/scripts/lib/wic/__init__.py
new file mode 100644
index 0000000..85876b1
--- /dev/null
+++ b/meta/poky/scripts/lib/wic/__init__.py
@@ -0,0 +1,20 @@
+#!/usr/bin/env python -tt
+#
+# Copyright (c) 2007 Red Hat, Inc.
+# Copyright (c) 2011 Intel, Inc.
+#
+# This program is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by the Free
+# Software Foundation; version 2 of the License
+#
+# 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.
+
+class WicError(Exception):
+    pass
diff --git a/meta/poky/scripts/lib/wic/canned-wks/common.wks.inc b/meta/poky/scripts/lib/wic/canned-wks/common.wks.inc
new file mode 100644
index 0000000..89880b4
--- /dev/null
+++ b/meta/poky/scripts/lib/wic/canned-wks/common.wks.inc
@@ -0,0 +1,3 @@
+# This file is included into 3 canned wks files from this directory
+part /boot --source bootimg-pcbios --ondisk sda --label boot --active --align 1024
+part / --source rootfs --use-uuid --fstype=ext4 --label platform --align 1024
diff --git a/meta/poky/scripts/lib/wic/canned-wks/directdisk-bootloader-config.cfg b/meta/poky/scripts/lib/wic/canned-wks/directdisk-bootloader-config.cfg
new file mode 100644
index 0000000..c58e74a
--- /dev/null
+++ b/meta/poky/scripts/lib/wic/canned-wks/directdisk-bootloader-config.cfg
@@ -0,0 +1,27 @@
+# This is an example configuration file for syslinux.
+TIMEOUT 50
+ALLOWOPTIONS 1
+SERIAL 0 115200
+PROMPT 0
+
+UI vesamenu.c32
+menu title Select boot options
+menu tabmsg Press [Tab] to edit, [Return] to select
+
+DEFAULT Graphics console boot
+
+LABEL Graphics console boot
+KERNEL /vmlinuz
+APPEND label=boot rootwait
+
+LABEL Serial console boot
+KERNEL /vmlinuz
+APPEND label=boot rootwait console=ttyS0,115200
+
+LABEL Graphics console install
+KERNEL /vmlinuz
+APPEND label=install rootwait
+
+LABEL Serial console install
+KERNEL /vmlinuz
+APPEND label=install rootwait console=ttyS0,115200
diff --git a/meta/poky/scripts/lib/wic/canned-wks/directdisk-bootloader-config.wks b/meta/poky/scripts/lib/wic/canned-wks/directdisk-bootloader-config.wks
new file mode 100644
index 0000000..3529e05
--- /dev/null
+++ b/meta/poky/scripts/lib/wic/canned-wks/directdisk-bootloader-config.wks
@@ -0,0 +1,8 @@
+# short-description: Create a 'pcbios' direct disk image with custom bootloader config
+# long-description: Creates a partitioned legacy BIOS disk image that the user
+# can directly dd to boot media. The bootloader configuration source is a user file.
+
+include common.wks.inc
+
+bootloader --configfile="directdisk-bootloader-config.cfg"
+
diff --git a/meta/poky/scripts/lib/wic/canned-wks/directdisk-gpt.wks b/meta/poky/scripts/lib/wic/canned-wks/directdisk-gpt.wks
new file mode 100644
index 0000000..8d7d8de
--- /dev/null
+++ b/meta/poky/scripts/lib/wic/canned-wks/directdisk-gpt.wks
@@ -0,0 +1,10 @@
+# short-description: Create a 'pcbios' direct disk image
+# long-description: Creates a partitioned legacy BIOS disk image that the user
+# can directly dd to boot media.
+
+
+part /boot --source bootimg-pcbios --ondisk sda --label boot --active --align 1024
+part / --source rootfs --ondisk sda --fstype=ext4 --label platform --align 1024 --use-uuid
+
+bootloader  --ptable gpt --timeout=0  --append="rootwait rootfstype=ext4 video=vesafb vga=0x318 console=tty0 console=ttyS0,115200n8"
+
diff --git a/meta/poky/scripts/lib/wic/canned-wks/directdisk-multi-rootfs.wks b/meta/poky/scripts/lib/wic/canned-wks/directdisk-multi-rootfs.wks
new file mode 100644
index 0000000..f61d941
--- /dev/null
+++ b/meta/poky/scripts/lib/wic/canned-wks/directdisk-multi-rootfs.wks
@@ -0,0 +1,23 @@
+# short-description: Create multi rootfs image using rootfs plugin
+# long-description: Creates a partitioned disk image with two rootfs partitions
+# using rootfs plugin.
+#
+# Partitions can use either
+#   - indirect rootfs references to image recipe(s):
+#     wic create directdisk-multi-indirect-recipes -e core-image-minimal \
+#         --rootfs-dir rootfs1=core-image-minimal
+#         --rootfs-dir rootfs2=core-image-minimal-dev
+#
+#   - or paths to rootfs directories:
+#     wic create directdisk-multi-rootfs \
+#         --rootfs-dir rootfs1=tmp/work/qemux86_64-poky-linux/core-image-minimal/1.0-r0/rootfs/
+#         --rootfs-dir rootfs2=tmp/work/qemux86_64-poky-linux/core-image-minimal-dev/1.0-r0/rootfs/
+#
+#   - or any combinations of -r and --rootfs command line options
+
+part /boot --source bootimg-pcbios --ondisk sda --label boot --active --align 1024
+part / --source rootfs --rootfs-dir=rootfs1 --ondisk sda --fstype=ext4 --label platform --align 1024
+part /rescue --source rootfs --rootfs-dir=rootfs2 --ondisk sda --fstype=ext4 --label secondary --align 1024
+
+bootloader  --timeout=0  --append="rootwait rootfstype=ext4 video=vesafb vga=0x318 console=tty0 console=ttyS0,115200n8"
+
diff --git a/meta/poky/scripts/lib/wic/canned-wks/directdisk.wks b/meta/poky/scripts/lib/wic/canned-wks/directdisk.wks
new file mode 100644
index 0000000..8c8e06b
--- /dev/null
+++ b/meta/poky/scripts/lib/wic/canned-wks/directdisk.wks
@@ -0,0 +1,8 @@
+# short-description: Create a 'pcbios' direct disk image
+# long-description: Creates a partitioned legacy BIOS disk image that the user
+# can directly dd to boot media.
+
+include common.wks.inc
+
+bootloader  --timeout=0  --append="rootwait rootfstype=ext4 video=vesafb vga=0x318 console=tty0 console=ttyS0,115200n8"
+
diff --git a/meta/poky/scripts/lib/wic/canned-wks/efi-bootdisk.wks.in b/meta/poky/scripts/lib/wic/canned-wks/efi-bootdisk.wks.in
new file mode 100644
index 0000000..7300e65
--- /dev/null
+++ b/meta/poky/scripts/lib/wic/canned-wks/efi-bootdisk.wks.in
@@ -0,0 +1,3 @@
+bootloader --ptable gpt
+part /boot --source rootfs --rootfs-dir=${IMAGE_ROOTFS}/boot --fstype=vfat --label boot --active --align 1024 --use-uuid --overhead-factor 1.0
+part / --source rootfs --fstype=ext4 --label root --align 1024 --exclude-path boot/
diff --git a/meta/poky/scripts/lib/wic/canned-wks/mkefidisk.wks b/meta/poky/scripts/lib/wic/canned-wks/mkefidisk.wks
new file mode 100644
index 0000000..9f534fe
--- /dev/null
+++ b/meta/poky/scripts/lib/wic/canned-wks/mkefidisk.wks
@@ -0,0 +1,11 @@
+# short-description: Create an EFI disk image
+# long-description: Creates a partitioned EFI disk image that the user
+# can directly dd to boot media.
+
+part /boot --source bootimg-efi --sourceparams="loader=grub-efi" --ondisk sda --label msdos --active --align 1024
+
+part / --source rootfs --ondisk sda --fstype=ext4 --label platform --align 1024 --use-uuid
+
+part swap --ondisk sda --size 44 --label swap1 --fstype=swap
+
+bootloader --ptable gpt --timeout=5 --append="rootfstype=ext4 console=ttyS0,115200 console=tty0"
diff --git a/meta/poky/scripts/lib/wic/canned-wks/mkhybridiso.wks b/meta/poky/scripts/lib/wic/canned-wks/mkhybridiso.wks
new file mode 100644
index 0000000..48c5ac4
--- /dev/null
+++ b/meta/poky/scripts/lib/wic/canned-wks/mkhybridiso.wks
@@ -0,0 +1,7 @@
+# short-description: Create a hybrid ISO image
+# long-description: Creates an EFI and legacy bootable hybrid ISO image
+# which can be used on optical media as well as USB media.
+
+part /boot --source isoimage-isohybrid --sourceparams="loader=grub-efi,image_name=HYBRID_ISO_IMG" --ondisk cd --label HYBRIDISO
+
+bootloader  --timeout=15  --append=""
diff --git a/meta/poky/scripts/lib/wic/canned-wks/qemux86-directdisk.wks b/meta/poky/scripts/lib/wic/canned-wks/qemux86-directdisk.wks
new file mode 100644
index 0000000..c8d9f12
--- /dev/null
+++ b/meta/poky/scripts/lib/wic/canned-wks/qemux86-directdisk.wks
@@ -0,0 +1,8 @@
+# short-description: Create a qemu machine 'pcbios' direct disk image
+# long-description: Creates a partitioned legacy BIOS disk image that the user
+# can directly use to boot a qemu machine.
+
+include common.wks.inc
+
+bootloader  --timeout=0  --append="vga=0 rw oprofile.timer=1 rootfstype=ext4 "
+
diff --git a/meta/poky/scripts/lib/wic/canned-wks/sdimage-bootpart.wks b/meta/poky/scripts/lib/wic/canned-wks/sdimage-bootpart.wks
new file mode 100644
index 0000000..63bc4da
--- /dev/null
+++ b/meta/poky/scripts/lib/wic/canned-wks/sdimage-bootpart.wks
@@ -0,0 +1,6 @@
+# short-description: Create SD card image with a boot partition
+# long-description: Creates a partitioned SD card image. Boot files
+# are located in the first vfat partition.
+
+part /boot --source bootimg-partition --ondisk mmcblk0 --fstype=vfat --label boot --active --align 4 --size 16
+part / --source rootfs --ondisk mmcblk0 --fstype=ext4 --label root --align 4
diff --git a/meta/poky/scripts/lib/wic/canned-wks/systemd-bootdisk.wks b/meta/poky/scripts/lib/wic/canned-wks/systemd-bootdisk.wks
new file mode 100644
index 0000000..95d7b97
--- /dev/null
+++ b/meta/poky/scripts/lib/wic/canned-wks/systemd-bootdisk.wks
@@ -0,0 +1,11 @@
+# short-description: Create an EFI disk image with systemd-boot
+# long-description: Creates a partitioned EFI disk image that the user
+# can directly dd to boot media. The selected bootloader is systemd-boot.
+
+part /boot --source bootimg-efi --sourceparams="loader=systemd-boot" --ondisk sda --label msdos --active --align 1024 --use-uuid
+
+part / --source rootfs --ondisk sda --fstype=ext4 --label platform --align 1024 --use-uuid
+
+part swap --ondisk sda --size 44 --label swap1 --fstype=swap --use-uuid
+
+bootloader --ptable gpt --timeout=5 --append="rootwait rootfstype=ext4 console=ttyS0,115200 console=tty0"
diff --git a/meta/poky/scripts/lib/wic/engine.py b/meta/poky/scripts/lib/wic/engine.py
new file mode 100644
index 0000000..ea600d2
--- /dev/null
+++ b/meta/poky/scripts/lib/wic/engine.py
@@ -0,0 +1,590 @@
+# ex:ts=4:sw=4:sts=4:et
+# -*- tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*-
+#
+# Copyright (c) 2013, Intel Corporation.
+# All rights reserved.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License 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.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# DESCRIPTION
+
+# This module implements the image creation engine used by 'wic' to
+# create images.  The engine parses through the OpenEmbedded kickstart
+# (wks) file specified and generates images that can then be directly
+# written onto media.
+#
+# AUTHORS
+# Tom Zanussi <tom.zanussi (at] linux.intel.com>
+#
+
+import logging
+import os
+import tempfile
+import json
+import subprocess
+
+from collections import namedtuple, OrderedDict
+from distutils.spawn import find_executable
+
+from wic import WicError
+from wic.filemap import sparse_copy
+from wic.pluginbase import PluginMgr
+from wic.misc import get_bitbake_var, exec_cmd
+
+logger = logging.getLogger('wic')
+
+def verify_build_env():
+    """
+    Verify that the build environment is sane.
+
+    Returns True if it is, false otherwise
+    """
+    if not os.environ.get("BUILDDIR"):
+        raise WicError("BUILDDIR not found, exiting. (Did you forget to source oe-init-build-env?)")
+
+    return True
+
+
+CANNED_IMAGE_DIR = "lib/wic/canned-wks" # relative to scripts
+SCRIPTS_CANNED_IMAGE_DIR = "scripts/" + CANNED_IMAGE_DIR
+WIC_DIR = "wic"
+
+def build_canned_image_list(path):
+    layers_path = get_bitbake_var("BBLAYERS")
+    canned_wks_layer_dirs = []
+
+    if layers_path is not None:
+        for layer_path in layers_path.split():
+            for wks_path in (WIC_DIR, SCRIPTS_CANNED_IMAGE_DIR):
+                cpath = os.path.join(layer_path, wks_path)
+                if os.path.isdir(cpath):
+                    canned_wks_layer_dirs.append(cpath)
+
+    cpath = os.path.join(path, CANNED_IMAGE_DIR)
+    canned_wks_layer_dirs.append(cpath)
+
+    return canned_wks_layer_dirs
+
+def find_canned_image(scripts_path, wks_file):
+    """
+    Find a .wks file with the given name in the canned files dir.
+
+    Return False if not found
+    """
+    layers_canned_wks_dir = build_canned_image_list(scripts_path)
+
+    for canned_wks_dir in layers_canned_wks_dir:
+        for root, dirs, files in os.walk(canned_wks_dir):
+            for fname in files:
+                if fname.endswith("~") or fname.endswith("#"):
+                    continue
+                if fname.endswith(".wks") and wks_file + ".wks" == fname:
+                    fullpath = os.path.join(canned_wks_dir, fname)
+                    return fullpath
+    return None
+
+
+def list_canned_images(scripts_path):
+    """
+    List the .wks files in the canned image dir, minus the extension.
+    """
+    layers_canned_wks_dir = build_canned_image_list(scripts_path)
+
+    for canned_wks_dir in layers_canned_wks_dir:
+        for root, dirs, files in os.walk(canned_wks_dir):
+            for fname in files:
+                if fname.endswith("~") or fname.endswith("#"):
+                    continue
+                if fname.endswith(".wks"):
+                    fullpath = os.path.join(canned_wks_dir, fname)
+                    with open(fullpath) as wks:
+                        for line in wks:
+                            desc = ""
+                            idx = line.find("short-description:")
+                            if idx != -1:
+                                desc = line[idx + len("short-description:"):].strip()
+                                break
+                    basename = os.path.splitext(fname)[0]
+                    print("  %s\t\t%s" % (basename.ljust(30), desc))
+
+
+def list_canned_image_help(scripts_path, fullpath):
+    """
+    List the help and params in the specified canned image.
+    """
+    found = False
+    with open(fullpath) as wks:
+        for line in wks:
+            if not found:
+                idx = line.find("long-description:")
+                if idx != -1:
+                    print()
+                    print(line[idx + len("long-description:"):].strip())
+                    found = True
+                continue
+            if not line.strip():
+                break
+            idx = line.find("#")
+            if idx != -1:
+                print(line[idx + len("#:"):].rstrip())
+            else:
+                break
+
+
+def list_source_plugins():
+    """
+    List the available source plugins i.e. plugins available for --source.
+    """
+    plugins = PluginMgr.get_plugins('source')
+
+    for plugin in plugins:
+        print("  %s" % plugin)
+
+
+def wic_create(wks_file, rootfs_dir, bootimg_dir, kernel_dir,
+               native_sysroot, options):
+    """
+    Create image
+
+    wks_file - user-defined OE kickstart file
+    rootfs_dir - absolute path to the build's /rootfs dir
+    bootimg_dir - absolute path to the build's boot artifacts directory
+    kernel_dir - absolute path to the build's kernel directory
+    native_sysroot - absolute path to the build's native sysroots dir
+    image_output_dir - dirname to create for image
+    options - wic command line options (debug, bmap, etc)
+
+    Normally, the values for the build artifacts values are determined
+    by 'wic -e' from the output of the 'bitbake -e' command given an
+    image name e.g. 'core-image-minimal' and a given machine set in
+    local.conf.  If that's the case, the variables get the following
+    values from the output of 'bitbake -e':
+
+    rootfs_dir:        IMAGE_ROOTFS
+    kernel_dir:        DEPLOY_DIR_IMAGE
+    native_sysroot:    STAGING_DIR_NATIVE
+
+    In the above case, bootimg_dir remains unset and the
+    plugin-specific image creation code is responsible for finding the
+    bootimg artifacts.
+
+    In the case where the values are passed in explicitly i.e 'wic -e'
+    is not used but rather the individual 'wic' options are used to
+    explicitly specify these values.
+    """
+    try:
+        oe_builddir = os.environ["BUILDDIR"]
+    except KeyError:
+        raise WicError("BUILDDIR not found, exiting. (Did you forget to source oe-init-build-env?)")
+
+    if not os.path.exists(options.outdir):
+        os.makedirs(options.outdir)
+
+    pname = options.imager
+    plugin_class = PluginMgr.get_plugins('imager').get(pname)
+    if not plugin_class:
+        raise WicError('Unknown plugin: %s' % pname)
+
+    plugin = plugin_class(wks_file, rootfs_dir, bootimg_dir, kernel_dir,
+                          native_sysroot, oe_builddir, options)
+
+    plugin.do_create()
+
+    logger.info("The image(s) were created using OE kickstart file:\n  %s", wks_file)
+
+
+def wic_list(args, scripts_path):
+    """
+    Print the list of images or source plugins.
+    """
+    if args.list_type is None:
+        return False
+
+    if args.list_type == "images":
+
+        list_canned_images(scripts_path)
+        return True
+    elif args.list_type == "source-plugins":
+        list_source_plugins()
+        return True
+    elif len(args.help_for) == 1 and args.help_for[0] == 'help':
+        wks_file = args.list_type
+        fullpath = find_canned_image(scripts_path, wks_file)
+        if not fullpath:
+            raise WicError("No image named %s found, exiting. "
+                           "(Use 'wic list images' to list available images, "
+                           "or specify a fully-qualified OE kickstart (.wks) "
+                           "filename)" % wks_file)
+
+        list_canned_image_help(scripts_path, fullpath)
+        return True
+
+    return False
+
+
+class Disk:
+    def __init__(self, imagepath, native_sysroot, fstypes=('fat', 'ext')):
+        self.imagepath = imagepath
+        self.native_sysroot = native_sysroot
+        self.fstypes = fstypes
+        self._partitions = None
+        self._partimages = {}
+        self._lsector_size = None
+        self._psector_size = None
+        self._ptable_format = None
+
+        # find parted
+        # read paths from $PATH environment variable
+        # if it fails, use hardcoded paths
+        pathlist = "/bin:/usr/bin:/usr/sbin:/sbin/"
+        try:
+            self.paths = os.environ['PATH'] + ":" + pathlist
+        except KeyError:
+            self.paths = pathlist
+
+        if native_sysroot:
+            for path in pathlist.split(':'):
+                self.paths = "%s%s:%s" % (native_sysroot, path, self.paths)
+
+        self.parted = find_executable("parted", self.paths)
+        if not self.parted:
+            raise WicError("Can't find executable parted")
+
+        self.partitions = self.get_partitions()
+
+    def __del__(self):
+        for path in self._partimages.values():
+            os.unlink(path)
+
+    def get_partitions(self):
+        if self._partitions is None:
+            self._partitions = OrderedDict()
+            out = exec_cmd("%s -sm %s unit B print" % (self.parted, self.imagepath))
+            parttype = namedtuple("Part", "pnum start end size fstype")
+            splitted = out.splitlines()
+            # skip over possible errors in exec_cmd output
+            try:
+                idx =splitted.index("BYT;")
+            except ValueError:
+                raise WicError("Error getting partition information from %s" % (self.parted))
+            lsector_size, psector_size, self._ptable_format = splitted[idx + 1].split(":")[3:6]
+            self._lsector_size = int(lsector_size)
+            self._psector_size = int(psector_size)
+            for line in splitted[idx + 2:]:
+                pnum, start, end, size, fstype = line.split(':')[:5]
+                partition = parttype(int(pnum), int(start[:-1]), int(end[:-1]),
+                                     int(size[:-1]), fstype)
+                self._partitions[pnum] = partition
+
+        return self._partitions
+
+    def __getattr__(self, name):
+        """Get path to the executable in a lazy way."""
+        if name in ("mdir", "mcopy", "mdel", "mdeltree", "sfdisk", "e2fsck",
+                    "resize2fs", "mkswap", "mkdosfs", "debugfs"):
+            aname = "_%s" % name
+            if aname not in self.__dict__:
+                setattr(self, aname, find_executable(name, self.paths))
+                if aname not in self.__dict__ or self.__dict__[aname] is None:
+                    raise WicError("Can't find executable '{}'".format(name))
+            return self.__dict__[aname]
+        return self.__dict__[name]
+
+    def _get_part_image(self, pnum):
+        if pnum not in self.partitions:
+            raise WicError("Partition %s is not in the image")
+        part = self.partitions[pnum]
+        # check if fstype is supported
+        for fstype in self.fstypes:
+            if part.fstype.startswith(fstype):
+                break
+        else:
+            raise WicError("Not supported fstype: {}".format(part.fstype))
+        if pnum not in self._partimages:
+            tmpf = tempfile.NamedTemporaryFile(prefix="wic-part")
+            dst_fname = tmpf.name
+            tmpf.close()
+            sparse_copy(self.imagepath, dst_fname, skip=part.start, length=part.size)
+            self._partimages[pnum] = dst_fname
+
+        return self._partimages[pnum]
+
+    def _put_part_image(self, pnum):
+        """Put partition image into partitioned image."""
+        sparse_copy(self._partimages[pnum], self.imagepath,
+                    seek=self.partitions[pnum].start)
+
+    def dir(self, pnum, path):
+        if self.partitions[pnum].fstype.startswith('ext'):
+            return exec_cmd("{} {} -R 'ls -l {}'".format(self.debugfs,
+                                                         self._get_part_image(pnum),
+                                                         path), as_shell=True)
+        else: # fat
+            return exec_cmd("{} -i {} ::{}".format(self.mdir,
+                                                   self._get_part_image(pnum),
+                                                   path))
+
+    def copy(self, src, pnum, path):
+        """Copy partition image into wic image."""
+        if self.partitions[pnum].fstype.startswith('ext'):
+            cmd = "printf 'cd {}\nwrite {} {}' | {} -w {}".\
+                      format(path, src, os.path.basename(src),
+                             self.debugfs, self._get_part_image(pnum))
+        else: # fat
+            cmd = "{} -i {} -snop {} ::{}".format(self.mcopy,
+                                                  self._get_part_image(pnum),
+                                                  src, path)
+        exec_cmd(cmd, as_shell=True)
+        self._put_part_image(pnum)
+
+    def remove(self, pnum, path):
+        """Remove files/dirs from the partition."""
+        partimg = self._get_part_image(pnum)
+        if self.partitions[pnum].fstype.startswith('ext'):
+            cmd = "{} {} -wR 'rm {}'".format(self.debugfs,
+                                                self._get_part_image(pnum),
+                                                path)
+            out = exec_cmd(cmd , as_shell=True)
+            for line in out.splitlines():
+                if line.startswith("rm:"):
+                    if "file is a directory" in line:
+                        # Try rmdir to see if this is an empty directory. This won't delete
+                        # any non empty directory so let user know about any error that this might
+                        # generate.
+                        print(exec_cmd("{} {} -wR 'rmdir {}'".format(self.debugfs,
+                                                    self._get_part_image(pnum),
+                                                    path), as_shell=True))
+                    else:
+                        raise WicError("Could not complete operation: wic %s" % str(line))
+        else: # fat
+            cmd = "{} -i {} ::{}".format(self.mdel, partimg, path)
+            try:
+                exec_cmd(cmd)
+            except WicError as err:
+                if "not found" in str(err) or "non empty" in str(err):
+                    # mdel outputs 'File ... not found' or 'directory .. non empty"
+                    # try to use mdeltree as path could be a directory
+                    cmd = "{} -i {} ::{}".format(self.mdeltree,
+                                                 partimg, path)
+                    exec_cmd(cmd)
+                else:
+                    raise err
+        self._put_part_image(pnum)
+
+    def write(self, target, expand):
+        """Write disk image to the media or file."""
+        def write_sfdisk_script(outf, parts):
+            for key, val in parts['partitiontable'].items():
+                if key in ("partitions", "device", "firstlba", "lastlba"):
+                    continue
+                if key == "id":
+                    key = "label-id"
+                outf.write("{}: {}\n".format(key, val))
+            outf.write("\n")
+            for part in parts['partitiontable']['partitions']:
+                line = ''
+                for name in ('attrs', 'name', 'size', 'type', 'uuid'):
+                    if name == 'size' and part['type'] == 'f':
+                        # don't write size for extended partition
+                        continue
+                    val = part.get(name)
+                    if val:
+                        line += '{}={}, '.format(name, val)
+                if line:
+                    line = line[:-2] # strip ', '
+                if part.get('bootable'):
+                    line += ' ,bootable'
+                outf.write("{}\n".format(line))
+            outf.flush()
+
+        def read_ptable(path):
+            out = exec_cmd("{} -dJ {}".format(self.sfdisk, path))
+            return json.loads(out)
+
+        def write_ptable(parts, target):
+            with tempfile.NamedTemporaryFile(prefix="wic-sfdisk-", mode='w') as outf:
+                write_sfdisk_script(outf, parts)
+                cmd = "{} --no-reread {} < {} ".format(self.sfdisk, target, outf.name)
+                exec_cmd(cmd, as_shell=True)
+
+        if expand is None:
+            sparse_copy(self.imagepath, target)
+        else:
+            # copy first sectors that may contain bootloader
+            sparse_copy(self.imagepath, target, length=2048 * self._lsector_size)
+
+            # copy source partition table to the target
+            parts = read_ptable(self.imagepath)
+            write_ptable(parts, target)
+
+            # get size of unpartitioned space
+            free = None
+            for line in exec_cmd("{} -F {}".format(self.sfdisk, target)).splitlines():
+                if line.startswith("Unpartitioned space ") and line.endswith("sectors"):
+                    free = int(line.split()[-2])
+                    # Align free space to a 2048 sector boundary. YOCTO #12840.
+                    free = free - (free % 2048)
+            if free is None:
+                raise WicError("Can't get size of unpartitioned space")
+
+            # calculate expanded partitions sizes
+            sizes = {}
+            num_auto_resize = 0
+            for num, part in enumerate(parts['partitiontable']['partitions'], 1):
+                if num in expand:
+                    if expand[num] != 0: # don't resize partition if size is set to 0
+                        sectors = expand[num] // self._lsector_size
+                        free -= sectors - part['size']
+                        part['size'] = sectors
+                        sizes[num] = sectors
+                elif part['type'] != 'f':
+                    sizes[num] = -1
+                    num_auto_resize += 1
+
+            for num, part in enumerate(parts['partitiontable']['partitions'], 1):
+                if sizes.get(num) == -1:
+                    part['size'] += free // num_auto_resize
+
+            # write resized partition table to the target
+            write_ptable(parts, target)
+
+            # read resized partition table
+            parts = read_ptable(target)
+
+            # copy partitions content
+            for num, part in enumerate(parts['partitiontable']['partitions'], 1):
+                pnum = str(num)
+                fstype = self.partitions[pnum].fstype
+
+                # copy unchanged partition
+                if part['size'] == self.partitions[pnum].size // self._lsector_size:
+                    logger.info("copying unchanged partition {}".format(pnum))
+                    sparse_copy(self._get_part_image(pnum), target, seek=part['start'] * self._lsector_size)
+                    continue
+
+                # resize or re-create partitions
+                if fstype.startswith('ext') or fstype.startswith('fat') or \
+                   fstype.startswith('linux-swap'):
+
+                    partfname = None
+                    with tempfile.NamedTemporaryFile(prefix="wic-part{}-".format(pnum)) as partf:
+                        partfname = partf.name
+
+                    if fstype.startswith('ext'):
+                        logger.info("resizing ext partition {}".format(pnum))
+                        partimg = self._get_part_image(pnum)
+                        sparse_copy(partimg, partfname)
+                        exec_cmd("{} -pf {}".format(self.e2fsck, partfname))
+                        exec_cmd("{} {} {}s".format(\
+                                 self.resize2fs, partfname, part['size']))
+                    elif fstype.startswith('fat'):
+                        logger.info("copying content of the fat partition {}".format(pnum))
+                        with tempfile.TemporaryDirectory(prefix='wic-fatdir-') as tmpdir:
+                            # copy content to the temporary directory
+                            cmd = "{} -snompi {} :: {}".format(self.mcopy,
+                                                               self._get_part_image(pnum),
+                                                               tmpdir)
+                            exec_cmd(cmd)
+                            # create new msdos partition
+                            label = part.get("name")
+                            label_str = "-n {}".format(label) if label else ''
+
+                            cmd = "{} {} -C {} {}".format(self.mkdosfs, label_str, partfname,
+                                                          part['size'])
+                            exec_cmd(cmd)
+                            # copy content from the temporary directory to the new partition
+                            cmd = "{} -snompi {} {}/* ::".format(self.mcopy, partfname, tmpdir)
+                            exec_cmd(cmd, as_shell=True)
+                    elif fstype.startswith('linux-swap'):
+                        logger.info("creating swap partition {}".format(pnum))
+                        label = part.get("name")
+                        label_str = "-L {}".format(label) if label else ''
+                        uuid = part.get("uuid")
+                        uuid_str = "-U {}".format(uuid) if uuid else ''
+                        with open(partfname, 'w') as sparse:
+                            os.ftruncate(sparse.fileno(), part['size'] * self._lsector_size)
+                        exec_cmd("{} {} {} {}".format(self.mkswap, label_str, uuid_str, partfname))
+                    sparse_copy(partfname, target, seek=part['start'] * self._lsector_size)
+                    os.unlink(partfname)
+                elif part['type'] != 'f':
+                    logger.warning("skipping partition {}: unsupported fstype {}".format(pnum, fstype))
+
+def wic_ls(args, native_sysroot):
+    """List contents of partitioned image or vfat partition."""
+    disk = Disk(args.path.image, native_sysroot)
+    if not args.path.part:
+        if disk.partitions:
+            print('Num     Start        End          Size      Fstype')
+            for part in disk.partitions.values():
+                print("{:2d}  {:12d} {:12d} {:12d}  {}".format(\
+                          part.pnum, part.start, part.end,
+                          part.size, part.fstype))
+    else:
+        path = args.path.path or '/'
+        print(disk.dir(args.path.part, path))
+
+def wic_cp(args, native_sysroot):
+    """
+    Copy local file or directory to the vfat partition of
+    partitioned image.
+    """
+    disk = Disk(args.dest.image, native_sysroot)
+    disk.copy(args.src, args.dest.part, args.dest.path)
+
+def wic_rm(args, native_sysroot):
+    """
+    Remove files or directories from the vfat partition of
+    partitioned image.
+    """
+    disk = Disk(args.path.image, native_sysroot)
+    disk.remove(args.path.part, args.path.path)
+
+def wic_write(args, native_sysroot):
+    """
+    Write image to a target device.
+    """
+    disk = Disk(args.image, native_sysroot, ('fat', 'ext', 'swap'))
+    disk.write(args.target, args.expand)
+
+def find_canned(scripts_path, file_name):
+    """
+    Find a file either by its path or by name in the canned files dir.
+
+    Return None if not found
+    """
+    if os.path.exists(file_name):
+        return file_name
+
+    layers_canned_wks_dir = build_canned_image_list(scripts_path)
+    for canned_wks_dir in layers_canned_wks_dir:
+        for root, dirs, files in os.walk(canned_wks_dir):
+            for fname in files:
+                if fname == file_name:
+                    fullpath = os.path.join(canned_wks_dir, fname)
+                    return fullpath
+
+def get_custom_config(boot_file):
+    """
+    Get the custom configuration to be used for the bootloader.
+
+    Return None if the file can't be found.
+    """
+    # Get the scripts path of poky
+    scripts_path = os.path.abspath("%s/../.." % os.path.dirname(__file__))
+
+    cfg_file = find_canned(scripts_path, boot_file)
+    if cfg_file:
+        with open(cfg_file, "r") as f:
+            config = f.read()
+        return config
diff --git a/meta/poky/scripts/lib/wic/filemap.py b/meta/poky/scripts/lib/wic/filemap.py
new file mode 100644
index 0000000..abbf958
--- /dev/null
+++ b/meta/poky/scripts/lib/wic/filemap.py
@@ -0,0 +1,601 @@
+# Copyright (c) 2012 Intel, 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.
+
+"""
+This module implements python implements a way to get file block. Two methods
+are supported - the FIEMAP ioctl and the 'SEEK_HOLE / SEEK_DATA' features of
+the file seek syscall. The former is implemented by the 'FilemapFiemap' class,
+the latter is implemented by the 'FilemapSeek' class. Both classes provide the
+same API. The 'filemap' function automatically selects which class can be used
+and returns an instance of the class.
+"""
+
+# Disable the following pylint recommendations:
+#   * Too many instance attributes (R0902)
+# pylint: disable=R0902
+
+import errno
+import os
+import struct
+import array
+import fcntl
+import tempfile
+import logging
+
+def get_block_size(file_obj):
+    """
+    Returns block size for file object 'file_obj'. Errors are indicated by the
+    'IOError' exception.
+    """
+    # Get the block size of the host file-system for the image file by calling
+    # the FIGETBSZ ioctl (number 2).
+    binary_data = fcntl.ioctl(file_obj, 2, struct.pack('I', 0))
+    bsize = struct.unpack('I', binary_data)[0]
+    if not bsize:
+        import os
+        stat = os.fstat(file_obj.fileno())
+        if hasattr(stat, 'st_blksize'):
+            bsize = stat.st_blksize
+        else:
+            raise IOError("Unable to determine block size")
+    return bsize
+
+class ErrorNotSupp(Exception):
+    """
+    An exception of this type is raised when the 'FIEMAP' or 'SEEK_HOLE' feature
+    is not supported either by the kernel or the file-system.
+    """
+    pass
+
+class Error(Exception):
+    """A class for all the other exceptions raised by this module."""
+    pass
+
+
+class _FilemapBase(object):
+    """
+    This is a base class for a couple of other classes in this module. This
+    class simply performs the common parts of the initialization process: opens
+    the image file, gets its size, etc. The 'log' parameter is the logger object
+    to use for printing messages.
+    """
+
+    def __init__(self, image, log=None):
+        """
+        Initialize a class instance. The 'image' argument is full path to the
+        file or file object to operate on.
+        """
+
+        self._log = log
+        if self._log is None:
+            self._log = logging.getLogger(__name__)
+
+        self._f_image_needs_close = False
+
+        if hasattr(image, "fileno"):
+            self._f_image = image
+            self._image_path = image.name
+        else:
+            self._image_path = image
+            self._open_image_file()
+
+        try:
+            self.image_size = os.fstat(self._f_image.fileno()).st_size
+        except IOError as err:
+            raise Error("cannot get information about file '%s': %s"
+                        % (self._f_image.name, err))
+
+        try:
+            self.block_size = get_block_size(self._f_image)
+        except IOError as err:
+            raise Error("cannot get block size for '%s': %s"
+                        % (self._image_path, err))
+
+        self.blocks_cnt = self.image_size + self.block_size - 1
+        self.blocks_cnt //= self.block_size
+
+        try:
+            self._f_image.flush()
+        except IOError as err:
+            raise Error("cannot flush image file '%s': %s"
+                        % (self._image_path, err))
+
+        try:
+            os.fsync(self._f_image.fileno()),
+        except OSError as err:
+            raise Error("cannot synchronize image file '%s': %s "
+                        % (self._image_path, err.strerror))
+
+        self._log.debug("opened image \"%s\"" % self._image_path)
+        self._log.debug("block size %d, blocks count %d, image size %d"
+                        % (self.block_size, self.blocks_cnt, self.image_size))
+
+    def __del__(self):
+        """The class destructor which just closes the image file."""
+        if self._f_image_needs_close:
+            self._f_image.close()
+
+    def _open_image_file(self):
+        """Open the image file."""
+        try:
+            self._f_image = open(self._image_path, 'rb')
+        except IOError as err:
+            raise Error("cannot open image file '%s': %s"
+                        % (self._image_path, err))
+
+        self._f_image_needs_close = True
+
+    def block_is_mapped(self, block): # pylint: disable=W0613,R0201
+        """
+        This method has has to be implemented by child classes. It returns
+        'True' if block number 'block' of the image file is mapped and 'False'
+        otherwise.
+        """
+
+        raise Error("the method is not implemented")
+
+    def block_is_unmapped(self, block): # pylint: disable=W0613,R0201
+        """
+        This method has has to be implemented by child classes. It returns
+        'True' if block number 'block' of the image file is not mapped (hole)
+        and 'False' otherwise.
+        """
+
+        raise Error("the method is not implemented")
+
+    def get_mapped_ranges(self, start, count): # pylint: disable=W0613,R0201
+        """
+        This method has has to be implemented by child classes. This is a
+        generator which yields ranges of mapped blocks in the file. The ranges
+        are tuples of 2 elements: [first, last], where 'first' is the first
+        mapped block and 'last' is the last mapped block.
+
+        The ranges are yielded for the area of the file of size 'count' blocks,
+        starting from block 'start'.
+        """
+
+        raise Error("the method is not implemented")
+
+    def get_unmapped_ranges(self, start, count): # pylint: disable=W0613,R0201
+        """
+        This method has has to be implemented by child classes. Just like
+        'get_mapped_ranges()', but yields unmapped block ranges instead
+        (holes).
+        """
+
+        raise Error("the method is not implemented")
+
+
+# The 'SEEK_HOLE' and 'SEEK_DATA' options of the file seek system call
+_SEEK_DATA = 3
+_SEEK_HOLE = 4
+
+def _lseek(file_obj, offset, whence):
+    """This is a helper function which invokes 'os.lseek' for file object
+    'file_obj' and with specified 'offset' and 'whence'. The 'whence'
+    argument is supposed to be either '_SEEK_DATA' or '_SEEK_HOLE'. When
+    there is no more data or hole starting from 'offset', this function
+    returns '-1'.  Otherwise the data or hole position is returned."""
+
+    try:
+        return os.lseek(file_obj.fileno(), offset, whence)
+    except OSError as err:
+        # The 'lseek' system call returns the ENXIO if there is no data or
+        # hole starting from the specified offset.
+        if err.errno == errno.ENXIO:
+            return -1
+        elif err.errno == errno.EINVAL:
+            raise ErrorNotSupp("the kernel or file-system does not support "
+                               "\"SEEK_HOLE\" and \"SEEK_DATA\"")
+        else:
+            raise
+
+class FilemapSeek(_FilemapBase):
+    """
+    This class uses the 'SEEK_HOLE' and 'SEEK_DATA' to find file block mapping.
+    Unfortunately, the current implementation requires the caller to have write
+    access to the image file.
+    """
+
+    def __init__(self, image, log=None):
+        """Refer the '_FilemapBase' class for the documentation."""
+
+        # Call the base class constructor first
+        _FilemapBase.__init__(self, image, log)
+        self._log.debug("FilemapSeek: initializing")
+
+        self._probe_seek_hole()
+
+    def _probe_seek_hole(self):
+        """
+        Check whether the system implements 'SEEK_HOLE' and 'SEEK_DATA'.
+        Unfortunately, there seems to be no clean way for detecting this,
+        because often the system just fakes them by just assuming that all
+        files are fully mapped, so 'SEEK_HOLE' always returns EOF and
+        'SEEK_DATA' always returns the requested offset.
+
+        I could not invent a better way of detecting the fake 'SEEK_HOLE'
+        implementation than just to create a temporary file in the same
+        directory where the image file resides. It would be nice to change this
+        to something better.
+        """
+
+        directory = os.path.dirname(self._image_path)
+
+        try:
+            tmp_obj = tempfile.TemporaryFile("w+", dir=directory)
+        except IOError as err:
+            raise ErrorNotSupp("cannot create a temporary in \"%s\": %s" \
+                              % (directory, err))
+
+        try:
+            os.ftruncate(tmp_obj.fileno(), self.block_size)
+        except OSError as err:
+            raise ErrorNotSupp("cannot truncate temporary file in \"%s\": %s"
+                               % (directory, err))
+
+        offs = _lseek(tmp_obj, 0, _SEEK_HOLE)
+        if offs != 0:
+            # We are dealing with the stub 'SEEK_HOLE' implementation which
+            # always returns EOF.
+            self._log.debug("lseek(0, SEEK_HOLE) returned %d" % offs)
+            raise ErrorNotSupp("the file-system does not support "
+                               "\"SEEK_HOLE\" and \"SEEK_DATA\" but only "
+                               "provides a stub implementation")
+
+        tmp_obj.close()
+
+    def block_is_mapped(self, block):
+        """Refer the '_FilemapBase' class for the documentation."""
+        offs = _lseek(self._f_image, block * self.block_size, _SEEK_DATA)
+        if offs == -1:
+            result = False
+        else:
+            result = (offs // self.block_size == block)
+
+        self._log.debug("FilemapSeek: block_is_mapped(%d) returns %s"
+                        % (block, result))
+        return result
+
+    def block_is_unmapped(self, block):
+        """Refer the '_FilemapBase' class for the documentation."""
+        return not self.block_is_mapped(block)
+
+    def _get_ranges(self, start, count, whence1, whence2):
+        """
+        This function implements 'get_mapped_ranges()' and
+        'get_unmapped_ranges()' depending on what is passed in the 'whence1'
+        and 'whence2' arguments.
+        """
+
+        assert whence1 != whence2
+        end = start * self.block_size
+        limit = end + count * self.block_size
+
+        while True:
+            start = _lseek(self._f_image, end, whence1)
+            if start == -1 or start >= limit or start == self.image_size:
+                break
+
+            end = _lseek(self._f_image, start, whence2)
+            if end == -1 or end == self.image_size:
+                end = self.blocks_cnt * self.block_size
+            if end > limit:
+                end = limit
+
+            start_blk = start // self.block_size
+            end_blk = end // self.block_size - 1
+            self._log.debug("FilemapSeek: yielding range (%d, %d)"
+                            % (start_blk, end_blk))
+            yield (start_blk, end_blk)
+
+    def get_mapped_ranges(self, start, count):
+        """Refer the '_FilemapBase' class for the documentation."""
+        self._log.debug("FilemapSeek: get_mapped_ranges(%d,  %d(%d))"
+                        % (start, count, start + count - 1))
+        return self._get_ranges(start, count, _SEEK_DATA, _SEEK_HOLE)
+
+    def get_unmapped_ranges(self, start, count):
+        """Refer the '_FilemapBase' class for the documentation."""
+        self._log.debug("FilemapSeek: get_unmapped_ranges(%d,  %d(%d))"
+                        % (start, count, start + count - 1))
+        return self._get_ranges(start, count, _SEEK_HOLE, _SEEK_DATA)
+
+
+# Below goes the FIEMAP ioctl implementation, which is not very readable
+# because it deals with the rather complex FIEMAP ioctl. To understand the
+# code, you need to know the FIEMAP interface, which is documented in the
+# "Documentation/filesystems/fiemap.txt" file in the Linux kernel sources.
+
+# Format string for 'struct fiemap'
+_FIEMAP_FORMAT = "=QQLLLL"
+# sizeof(struct fiemap)
+_FIEMAP_SIZE = struct.calcsize(_FIEMAP_FORMAT)
+# Format string for 'struct fiemap_extent'
+_FIEMAP_EXTENT_FORMAT = "=QQQQQLLLL"
+# sizeof(struct fiemap_extent)
+_FIEMAP_EXTENT_SIZE = struct.calcsize(_FIEMAP_EXTENT_FORMAT)
+# The FIEMAP ioctl number
+_FIEMAP_IOCTL = 0xC020660B
+# This FIEMAP ioctl flag which instructs the kernel to sync the file before
+# reading the block map
+_FIEMAP_FLAG_SYNC = 0x00000001
+# Size of the buffer for 'struct fiemap_extent' elements which will be used
+# when invoking the FIEMAP ioctl. The larger is the buffer, the less times the
+# FIEMAP ioctl will be invoked.
+_FIEMAP_BUFFER_SIZE = 256 * 1024
+
+class FilemapFiemap(_FilemapBase):
+    """
+    This class provides API to the FIEMAP ioctl. Namely, it allows to iterate
+    over all mapped blocks and over all holes.
+
+    This class synchronizes the image file every time it invokes the FIEMAP
+    ioctl in order to work-around early FIEMAP implementation kernel bugs.
+    """
+
+    def __init__(self, image, log=None):
+        """
+        Initialize a class instance. The 'image' argument is full the file
+        object to operate on.
+        """
+
+        # Call the base class constructor first
+        _FilemapBase.__init__(self, image, log)
+        self._log.debug("FilemapFiemap: initializing")
+
+        self._buf_size = _FIEMAP_BUFFER_SIZE
+
+        # Calculate how many 'struct fiemap_extent' elements fit the buffer
+        self._buf_size -= _FIEMAP_SIZE
+        self._fiemap_extent_cnt = self._buf_size // _FIEMAP_EXTENT_SIZE
+        assert self._fiemap_extent_cnt > 0
+        self._buf_size = self._fiemap_extent_cnt * _FIEMAP_EXTENT_SIZE
+        self._buf_size += _FIEMAP_SIZE
+
+        # Allocate a mutable buffer for the FIEMAP ioctl
+        self._buf = array.array('B', [0] * self._buf_size)
+
+        # Check if the FIEMAP ioctl is supported
+        self.block_is_mapped(0)
+
+    def _invoke_fiemap(self, block, count):
+        """
+        Invoke the FIEMAP ioctl for 'count' blocks of the file starting from
+        block number 'block'.
+
+        The full result of the operation is stored in 'self._buf' on exit.
+        Returns the unpacked 'struct fiemap' data structure in form of a python
+        list (just like 'struct.upack()').
+        """
+
+        if self.blocks_cnt != 0 and (block < 0 or block >= self.blocks_cnt):
+            raise Error("bad block number %d, should be within [0, %d]"
+                        % (block, self.blocks_cnt))
+
+        # Initialize the 'struct fiemap' part of the buffer. We use the
+        # '_FIEMAP_FLAG_SYNC' flag in order to make sure the file is
+        # synchronized. The reason for this is that early FIEMAP
+        # implementations had many bugs related to cached dirty data, and
+        # synchronizing the file is a necessary work-around.
+        struct.pack_into(_FIEMAP_FORMAT, self._buf, 0, block * self.block_size,
+                         count * self.block_size, _FIEMAP_FLAG_SYNC, 0,
+                         self._fiemap_extent_cnt, 0)
+
+        try:
+            fcntl.ioctl(self._f_image, _FIEMAP_IOCTL, self._buf, 1)
+        except IOError as err:
+            # Note, the FIEMAP ioctl is supported by the Linux kernel starting
+            # from version 2.6.28 (year 2008).
+            if err.errno == errno.EOPNOTSUPP:
+                errstr = "FilemapFiemap: the FIEMAP ioctl is not supported " \
+                         "by the file-system"
+                self._log.debug(errstr)
+                raise ErrorNotSupp(errstr)
+            if err.errno == errno.ENOTTY:
+                errstr = "FilemapFiemap: the FIEMAP ioctl is not supported " \
+                         "by the kernel"
+                self._log.debug(errstr)
+                raise ErrorNotSupp(errstr)
+            raise Error("the FIEMAP ioctl failed for '%s': %s"
+                        % (self._image_path, err))
+
+        return struct.unpack(_FIEMAP_FORMAT, self._buf[:_FIEMAP_SIZE])
+
+    def block_is_mapped(self, block):
+        """Refer the '_FilemapBase' class for the documentation."""
+        struct_fiemap = self._invoke_fiemap(block, 1)
+
+        # The 3rd element of 'struct_fiemap' is the 'fm_mapped_extents' field.
+        # If it contains zero, the block is not mapped, otherwise it is
+        # mapped.
+        result = bool(struct_fiemap[3])
+        self._log.debug("FilemapFiemap: block_is_mapped(%d) returns %s"
+                        % (block, result))
+        return result
+
+    def block_is_unmapped(self, block):
+        """Refer the '_FilemapBase' class for the documentation."""
+        return not self.block_is_mapped(block)
+
+    def _unpack_fiemap_extent(self, index):
+        """
+        Unpack a 'struct fiemap_extent' structure object number 'index' from
+        the internal 'self._buf' buffer.
+        """
+
+        offset = _FIEMAP_SIZE + _FIEMAP_EXTENT_SIZE * index
+        return struct.unpack(_FIEMAP_EXTENT_FORMAT,
+                             self._buf[offset : offset + _FIEMAP_EXTENT_SIZE])
+
+    def _do_get_mapped_ranges(self, start, count):
+        """
+        Implements most the functionality for the  'get_mapped_ranges()'
+        generator: invokes the FIEMAP ioctl, walks through the mapped extents
+        and yields mapped block ranges. However, the ranges may be consecutive
+        (e.g., (1, 100), (100, 200)) and 'get_mapped_ranges()' simply merges
+        them.
+        """
+
+        block = start
+        while block < start + count:
+            struct_fiemap = self._invoke_fiemap(block, count)
+
+            mapped_extents = struct_fiemap[3]
+            if mapped_extents == 0:
+                # No more mapped blocks
+                return
+
+            extent = 0
+            while extent < mapped_extents:
+                fiemap_extent = self._unpack_fiemap_extent(extent)
+
+                # Start of the extent
+                extent_start = fiemap_extent[0]
+                # Starting block number of the extent
+                extent_block = extent_start // self.block_size
+                # Length of the extent
+                extent_len = fiemap_extent[2]
+                # Count of blocks in the extent
+                extent_count = extent_len // self.block_size
+
+                # Extent length and offset have to be block-aligned
+                assert extent_start % self.block_size == 0
+                assert extent_len % self.block_size == 0
+
+                if extent_block > start + count - 1:
+                    return
+
+                first = max(extent_block, block)
+                last = min(extent_block + extent_count, start + count) - 1
+                yield (first, last)
+
+                extent += 1
+
+            block = extent_block + extent_count
+
+    def get_mapped_ranges(self, start, count):
+        """Refer the '_FilemapBase' class for the documentation."""
+        self._log.debug("FilemapFiemap: get_mapped_ranges(%d,  %d(%d))"
+                        % (start, count, start + count - 1))
+        iterator = self._do_get_mapped_ranges(start, count)
+        first_prev, last_prev = next(iterator)
+
+        for first, last in iterator:
+            if last_prev == first - 1:
+                last_prev = last
+            else:
+                self._log.debug("FilemapFiemap: yielding range (%d, %d)"
+                                % (first_prev, last_prev))
+                yield (first_prev, last_prev)
+                first_prev, last_prev = first, last
+
+        self._log.debug("FilemapFiemap: yielding range (%d, %d)"
+                        % (first_prev, last_prev))
+        yield (first_prev, last_prev)
+
+    def get_unmapped_ranges(self, start, count):
+        """Refer the '_FilemapBase' class for the documentation."""
+        self._log.debug("FilemapFiemap: get_unmapped_ranges(%d,  %d(%d))"
+                        % (start, count, start + count - 1))
+        hole_first = start
+        for first, last in self._do_get_mapped_ranges(start, count):
+            if first > hole_first:
+                self._log.debug("FilemapFiemap: yielding range (%d, %d)"
+                                % (hole_first, first - 1))
+                yield (hole_first, first - 1)
+
+            hole_first = last + 1
+
+        if hole_first < start + count:
+            self._log.debug("FilemapFiemap: yielding range (%d, %d)"
+                            % (hole_first, start + count - 1))
+            yield (hole_first, start + count - 1)
+
+def filemap(image, log=None):
+    """
+    Create and return an instance of a Filemap class - 'FilemapFiemap' or
+    'FilemapSeek', depending on what the system we run on supports. If the
+    FIEMAP ioctl is supported, an instance of the 'FilemapFiemap' class is
+    returned. Otherwise, if 'SEEK_HOLE' is supported an instance of the
+    'FilemapSeek' class is returned. If none of these are supported, the
+    function generates an 'Error' type exception.
+    """
+
+    try:
+        return FilemapFiemap(image, log)
+    except ErrorNotSupp:
+        return FilemapSeek(image, log)
+
+def sparse_copy(src_fname, dst_fname, skip=0, seek=0,
+                length=0, api=None):
+    """
+    Efficiently copy sparse file to or into another file.
+
+    src_fname: path to source file
+    dst_fname: path to destination file
+    skip: skip N bytes at thestart of src
+    seek: seek N bytes from the start of dst
+    length: read N bytes from src and write them to dst
+    api: FilemapFiemap or FilemapSeek object
+    """
+    if not api:
+        api = filemap
+    fmap = api(src_fname)
+    try:
+        dst_file = open(dst_fname, 'r+b')
+    except IOError:
+        dst_file = open(dst_fname, 'wb')
+        if length:
+            dst_size = length + seek
+        else:
+            dst_size = os.path.getsize(src_fname) + seek - skip
+        dst_file.truncate(dst_size)
+
+    written = 0
+    for first, last in fmap.get_mapped_ranges(0, fmap.blocks_cnt):
+        start = first * fmap.block_size
+        end = (last + 1) * fmap.block_size
+
+        if skip >= end:
+            continue
+
+        if start < skip < end:
+            start = skip
+
+        fmap._f_image.seek(start, os.SEEK_SET)
+
+        written += start - skip - written
+        if length and written >= length:
+            dst_file.seek(seek + length, os.SEEK_SET)
+            dst_file.close()
+            return
+
+        dst_file.seek(seek + start - skip, os.SEEK_SET)
+
+        chunk_size = 1024 * 1024
+        to_read = end - start
+        read = 0
+
+        while read < to_read:
+            if read + chunk_size > to_read:
+                chunk_size = to_read - read
+            size = chunk_size
+            if length and written + size > length:
+                size = length - written
+            chunk = fmap._f_image.read(size)
+            dst_file.write(chunk)
+            read += size
+            written += size
+            if written == length:
+                dst_file.close()
+                return
+    dst_file.close()
diff --git a/meta/poky/scripts/lib/wic/help.py b/meta/poky/scripts/lib/wic/help.py
new file mode 100644
index 0000000..64f0805
--- /dev/null
+++ b/meta/poky/scripts/lib/wic/help.py
@@ -0,0 +1,1063 @@
+# ex:ts=4:sw=4:sts=4:et
+# -*- tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*-
+#
+# Copyright (c) 2013, Intel Corporation.
+# All rights reserved.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License 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.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# DESCRIPTION
+# This module implements some basic help invocation functions along
+# with the bulk of the help topic text for the OE Core Image Tools.
+#
+# AUTHORS
+# Tom Zanussi <tom.zanussi (at] linux.intel.com>
+#
+
+import subprocess
+import logging
+
+from wic.pluginbase import PluginMgr, PLUGIN_TYPES
+
+logger = logging.getLogger('wic')
+
+def subcommand_error(args):
+    logger.info("invalid subcommand %s", args[0])
+
+
+def display_help(subcommand, subcommands):
+    """
+    Display help for subcommand.
+    """
+    if subcommand not in subcommands:
+        return False
+
+    hlp = subcommands.get(subcommand, subcommand_error)[2]
+    if callable(hlp):
+        hlp = hlp()
+    pager = subprocess.Popen('less', stdin=subprocess.PIPE)
+    pager.communicate(hlp.encode('utf-8'))
+
+    return True
+
+
+def wic_help(args, usage_str, subcommands):
+    """
+    Subcommand help dispatcher.
+    """
+    if args.help_topic == None or not display_help(args.help_topic, subcommands):
+        print(usage_str)
+
+
+def get_wic_plugins_help():
+    """
+    Combine wic_plugins_help with the help for every known
+    source plugin.
+    """
+    result = wic_plugins_help
+    for plugin_type in PLUGIN_TYPES:
+        result += '\n\n%s PLUGINS\n\n' % plugin_type.upper()
+        for name, plugin in PluginMgr.get_plugins(plugin_type).items():
+            result += "\n %s plugin:\n" % name
+            if plugin.__doc__:
+                result += plugin.__doc__
+            else:
+                result += "\n    %s is missing docstring\n" % plugin
+    return result
+
+
+def invoke_subcommand(args, parser, main_command_usage, subcommands):
+    """
+    Dispatch to subcommand handler borrowed from combo-layer.
+    Should use argparse, but has to work in 2.6.
+    """
+    if not args.command:
+        logger.error("No subcommand specified, exiting")
+        parser.print_help()
+        return 1
+    elif args.command == "help":
+        wic_help(args, main_command_usage, subcommands)
+    elif args.command not in subcommands:
+        logger.error("Unsupported subcommand %s, exiting\n", args.command)
+        parser.print_help()
+        return 1
+    else:
+        subcmd = subcommands.get(args.command, subcommand_error)
+        usage = subcmd[1]
+        subcmd[0](args, usage)
+
+
+##
+# wic help and usage strings
+##
+
+wic_usage = """
+
+ Create a customized OpenEmbedded image
+
+ usage: wic [--version] | [--help] | [COMMAND [ARGS]]
+
+ Current 'wic' commands are:
+    help              Show help for command or one of the topics (see below)
+    create            Create a new OpenEmbedded image
+    list              List available canned images and source plugins
+
+ Help topics:
+    overview          wic overview - General overview of wic
+    plugins           wic plugins - Overview and API
+    kickstart         wic kickstart - wic kickstart reference
+"""
+
+wic_help_usage = """
+
+ usage: wic help <subcommand>
+
+ This command displays detailed help for the specified subcommand.
+"""
+
+wic_create_usage = """
+
+ Create a new OpenEmbedded image
+
+ usage: wic create <wks file or image name> [-o <DIRNAME> | --outdir <DIRNAME>]
+            [-e | --image-name] [-s, --skip-build-check] [-D, --debug]
+            [-r, --rootfs-dir] [-b, --bootimg-dir]
+            [-k, --kernel-dir] [-n, --native-sysroot] [-f, --build-rootfs]
+            [-c, --compress-with] [-m, --bmap]
+
+ This command creates an OpenEmbedded image based on the 'OE kickstart
+ commands' found in the <wks file>.
+
+ The -o option can be used to place the image in a directory with a
+ different name and location.
+
+ See 'wic help create' for more detailed instructions.
+"""
+
+wic_create_help = """
+
+NAME
+    wic create - Create a new OpenEmbedded image
+
+SYNOPSIS
+    wic create <wks file or image name> [-o <DIRNAME> | --outdir <DIRNAME>]
+        [-e | --image-name] [-s, --skip-build-check] [-D, --debug]
+        [-r, --rootfs-dir] [-b, --bootimg-dir]
+        [-k, --kernel-dir] [-n, --native-sysroot] [-f, --build-rootfs]
+        [-c, --compress-with] [-m, --bmap] [--no-fstab-update]
+
+DESCRIPTION
+    This command creates an OpenEmbedded image based on the 'OE
+    kickstart commands' found in the <wks file>.
+
+    In order to do this, wic needs to know the locations of the
+    various build artifacts required to build the image.
+
+    Users can explicitly specify the build artifact locations using
+    the -r, -b, -k, and -n options.  See below for details on where
+    the corresponding artifacts are typically found in a normal
+    OpenEmbedded build.
+
+    Alternatively, users can use the -e option to have 'wic' determine
+    those locations for a given image.  If the -e option is used, the
+    user needs to have set the appropriate MACHINE variable in
+    local.conf, and have sourced the build environment.
+
+    The -e option is used to specify the name of the image to use the
+    artifacts from e.g. core-image-sato.
+
+    The -r option is used to specify the path to the /rootfs dir to
+    use as the .wks rootfs source.
+
+    The -b option is used to specify the path to the dir containing
+    the boot artifacts (e.g. /EFI or /syslinux dirs) to use as the
+    .wks bootimg source.
+
+    The -k option is used to specify the path to the dir containing
+    the kernel to use in the .wks bootimg.
+
+    The -n option is used to specify the path to the native sysroot
+    containing the tools to use to build the image.
+
+    The -f option is used to build rootfs by running "bitbake <image>"
+
+    The -s option is used to skip the build check.  The build check is
+    a simple sanity check used to determine whether the user has
+    sourced the build environment so that the -e option can operate
+    correctly.  If the user has specified the build artifact locations
+    explicitly, 'wic' assumes the user knows what he or she is doing
+    and skips the build check.
+
+    The -D option is used to display debug information detailing
+    exactly what happens behind the scenes when a create request is
+    fulfilled (or not, as the case may be).  It enumerates and
+    displays the command sequence used, and should be included in any
+    bug report describing unexpected results.
+
+    When 'wic -e' is used, the locations for the build artifacts
+    values are determined by 'wic -e' from the output of the 'bitbake
+    -e' command given an image name e.g. 'core-image-minimal' and a
+    given machine set in local.conf.  In that case, the image is
+    created as if the following 'bitbake -e' variables were used:
+
+    -r:        IMAGE_ROOTFS
+    -k:        STAGING_KERNEL_DIR
+    -n:        STAGING_DIR_NATIVE
+    -b:        empty (plugin-specific handlers must determine this)
+
+    If 'wic -e' is not used, the user needs to select the appropriate
+    value for -b (as well as -r, -k, and -n).
+
+    The -o option can be used to place the image in a directory with a
+    different name and location.
+
+    The -c option is used to specify compressor utility to compress
+    an image. gzip, bzip2 and xz compressors are supported.
+
+    The -m option is used to produce .bmap file for the image. This file
+    can be used to flash image using bmaptool utility.
+
+    The --no-fstab-update option is used to doesn't change fstab file. When
+    using this option the final fstab file will be same that in rootfs and
+    wic doesn't update file, e.g adding a new mount point. User can control
+    the fstab file content in base-files recipe.
+"""
+
+wic_list_usage = """
+
+ List available OpenEmbedded images and source plugins
+
+ usage: wic list images
+        wic list <image> help
+        wic list source-plugins
+
+ This command enumerates the set of available canned images as well as
+ help for those images.  It also can be used to list of available source
+ plugins.
+
+ The first form enumerates all the available 'canned' images.
+
+ The second form lists the detailed help information for a specific
+ 'canned' image.
+
+ The third form enumerates all the available --sources (source
+ plugins).
+
+ See 'wic help list' for more details.
+"""
+
+wic_list_help = """
+
+NAME
+    wic list - List available OpenEmbedded images and source plugins
+
+SYNOPSIS
+    wic list images
+    wic list <image> help
+    wic list source-plugins
+
+DESCRIPTION
+    This command enumerates the set of available canned images as well
+    as help for those images.  It also can be used to list available
+    source plugins.
+
+    The first form enumerates all the available 'canned' images.
+    These are actually just the set of .wks files that have been moved
+    into the /scripts/lib/wic/canned-wks directory).
+
+    The second form lists the detailed help information for a specific
+    'canned' image.
+
+    The third form enumerates all the available --sources (source
+    plugins).  The contents of a given partition are driven by code
+    defined in 'source plugins'.  Users specify a specific plugin via
+    the --source parameter of the partition .wks command.  Normally
+    this is the 'rootfs' plugin but can be any of the more specialized
+    sources listed by the 'list source-plugins' command.  Users can
+    also add their own source plugins - see 'wic help plugins' for
+    details.
+"""
+
+wic_ls_usage = """
+
+ List content of a partitioned image
+
+ usage: wic ls <image>[:<partition>[<path>]] [--native-sysroot <path>]
+
+ This command  outputs either list of image partitions or directory contents
+ of vfat and ext* partitions.
+
+ See 'wic help ls' for more detailed instructions.
+
+"""
+
+wic_ls_help = """
+
+NAME
+    wic ls - List contents of partitioned image or partition
+
+SYNOPSIS
+    wic ls <image>
+    wic ls <image>:<vfat or ext* partition>
+    wic ls <image>:<vfat or ext* partition><path>
+    wic ls <image>:<vfat or ext* partition><path> --native-sysroot <path>
+
+DESCRIPTION
+    This command lists either partitions of the image or directory contents
+    of vfat or ext* partitions.
+
+    The first form it lists partitions of the image.
+    For example:
+        $ wic ls tmp/deploy/images/qemux86-64/core-image-minimal-qemux86-64.wic
+        Num     Start        End          Size      Fstype
+        1        1048576     24438783     23390208  fat16
+        2       25165824     50315263     25149440  ext4
+
+    Second and third form list directory content of the partition:
+        $ wic ls tmp/deploy/images/qemux86-64/core-image-minimal-qemux86-64.wic:1
+        Volume in drive : is boot
+         Volume Serial Number is 2DF2-5F02
+        Directory for ::/
+
+        efi          <DIR>     2017-05-11  10:54
+        startup  nsh        26 2017-05-11  10:54
+        vmlinuz        6922288 2017-05-11  10:54
+                3 files           6 922 314 bytes
+                                 15 818 752 bytes free
+
+
+        $ wic ls tmp/deploy/images/qemux86-64/core-image-minimal-qemux86-64.wic:1/EFI/boot/
+        Volume in drive : is boot
+         Volume Serial Number is 2DF2-5F02
+        Directory for ::/EFI/boot
+
+        .            <DIR>     2017-05-11  10:54
+        ..           <DIR>     2017-05-11  10:54
+        grub     cfg       679 2017-05-11  10:54
+        bootx64  efi    571392 2017-05-11  10:54
+                4 files             572 071 bytes
+                                 15 818 752 bytes free
+
+    The -n option is used to specify the path to the native sysroot
+    containing the tools(parted and mtools) to use.
+
+"""
+
+wic_cp_usage = """
+
+ Copy files and directories to the vfat or ext* partition
+
+ usage: wic cp <src> <image>:<partition>[<path>] [--native-sysroot <path>]
+
+ This command  copies local files or directories to the vfat or ext* partitions
+of partitioned  image.
+
+ See 'wic help cp' for more detailed instructions.
+
+"""
+
+wic_cp_help = """
+
+NAME
+    wic cp - copy files and directories to the vfat or ext* partitions
+
+SYNOPSIS
+    wic cp <src> <image>:<partition>
+    wic cp <src> <image>:<partition><path>
+    wic cp <src> <image>:<partition><path> --native-sysroot <path>
+
+DESCRIPTION
+    This command copies files and directories to the vfat or ext* partition of
+    the partitioned image.
+
+    The first form of it copies file or directory to the root directory of
+    the partition:
+        $ wic cp test.wks tmp/deploy/images/qemux86-64/core-image-minimal-qemux86-64.wic:1
+        $ wic ls tmp/deploy/images/qemux86-64/core-image-minimal-qemux86-64.wic:1
+        Volume in drive : is boot
+         Volume Serial Number is DB4C-FD4C
+        Directory for ::/
+
+        efi          <DIR>     2017-05-24  18:15
+        loader       <DIR>     2017-05-24  18:15
+        startup  nsh        26 2017-05-24  18:15
+        vmlinuz        6926384 2017-05-24  18:15
+        test     wks       628 2017-05-24  21:22
+                5 files           6 927 038 bytes
+                                 15 677 440 bytes free
+
+    The second form of the command copies file or directory to the specified directory
+    on the partition:
+       $ wic cp test tmp/deploy/images/qemux86-64/core-image-minimal-qemux86-64.wic:1/efi/
+       $ wic ls tmp/deploy/images/qemux86-64/core-image-minimal-qemux86-64.wic:1/efi/
+       Volume in drive : is boot
+        Volume Serial Number is DB4C-FD4C
+       Directory for ::/efi
+
+       .            <DIR>     2017-05-24  18:15
+       ..           <DIR>     2017-05-24  18:15
+       boot         <DIR>     2017-05-24  18:15
+       test         <DIR>     2017-05-24  21:27
+               4 files                   0 bytes
+                                15 675 392 bytes free
+
+    The -n option is used to specify the path to the native sysroot
+    containing the tools(parted and mtools) to use.
+"""
+
+wic_rm_usage = """
+
+ Remove files or directories from the vfat or ext* partitions
+
+ usage: wic rm <image>:<partition><path> [--native-sysroot <path>]
+
+ This command  removes files or directories from the vfat or ext* partitions of
+ the partitioned image.
+
+ See 'wic help rm' for more detailed instructions.
+
+"""
+
+wic_rm_help = """
+
+NAME
+    wic rm - remove files or directories from the vfat or ext* partitions
+
+SYNOPSIS
+    wic rm <src> <image>:<partition><path>
+    wic rm <src> <image>:<partition><path> --native-sysroot <path>
+
+DESCRIPTION
+    This command removes files or directories from the vfat or ext* partition of the
+    partitioned image:
+
+        $ wic ls ./tmp/deploy/images/qemux86-64/core-image-minimal-qemux86-64.wic:1
+        Volume in drive : is boot
+         Volume Serial Number is 11D0-DE21
+        Directory for ::/
+
+        libcom32 c32    186500 2017-06-02  15:15
+        libutil  c32     24148 2017-06-02  15:15
+        syslinux cfg       209 2017-06-02  15:15
+        vesamenu c32     27104 2017-06-02  15:15
+        vmlinuz        6926384 2017-06-02  15:15
+                5 files           7 164 345 bytes
+                                 16 582 656 bytes free
+
+        $ wic rm ./tmp/deploy/images/qemux86-64/core-image-minimal-qemux86-64.wic:1/libutil.c32
+
+        $ wic ls ./tmp/deploy/images/qemux86-64/core-image-minimal-qemux86-64.wic:1
+        Volume in drive : is boot
+         Volume Serial Number is 11D0-DE21
+        Directory for ::/
+
+        libcom32 c32    186500 2017-06-02  15:15
+        syslinux cfg       209 2017-06-02  15:15
+        vesamenu c32     27104 2017-06-02  15:15
+        vmlinuz        6926384 2017-06-02  15:15
+                4 files           7 140 197 bytes
+                                 16 607 232 bytes free
+
+    The -n option is used to specify the path to the native sysroot
+    containing the tools(parted and mtools) to use.
+"""
+
+wic_write_usage = """
+
+ Write image to a device
+
+ usage: wic write <image> <target device> [--expand [rules]] [--native-sysroot <path>]
+
+ This command writes partitioned image to a target device (USB stick, SD card etc).
+
+ See 'wic help write' for more detailed instructions.
+
+"""
+
+wic_write_help = """
+
+NAME
+    wic write - write an image to a device
+
+SYNOPSIS
+    wic write <image> <target>
+    wic write <image> <target> --expand auto
+    wic write <image> <target> --expand 1:100M-2:300M
+    wic write <image> <target> --native-sysroot <path>
+
+DESCRIPTION
+    This command writes an image to a target device (USB stick, SD card etc)
+
+        $ wic write ./tmp/deploy/images/qemux86-64/core-image-minimal-qemux86-64.wic /dev/sdb
+
+    The --expand option is used to resize image partitions.
+    --expand auto expands partitions to occupy all free space available on the target device.
+    It's also possible to specify expansion rules in a format
+    <partition>:<size>[-<partition>:<size>...] for one or more partitions.
+    Specifying size 0 will keep partition unmodified.
+    Note: Resizing boot partition can result in non-bootable image for non-EFI images. It is
+    recommended to use size 0 for boot partition to keep image bootable.
+
+    The --native-sysroot option is used to specify the path to the native sysroot
+    containing the tools(parted, resize2fs) to use.
+"""
+
+wic_plugins_help = """
+
+NAME
+    wic plugins - Overview and API
+
+DESCRIPTION
+    plugins allow wic functionality to be extended and specialized by
+    users.  This section documents the plugin interface, which is
+    currently restricted to 'source' plugins.
+
+    'Source' plugins provide a mechanism to customize various aspects
+    of the image generation process in wic, mainly the contents of
+    partitions.
+
+    Source plugins provide a mechanism for mapping values specified in
+    .wks files using the --source keyword to a particular plugin
+    implementation that populates a corresponding partition.
+
+    A source plugin is created as a subclass of SourcePlugin (see
+    scripts/lib/wic/pluginbase.py) and the plugin file containing it
+    is added to scripts/lib/wic/plugins/source/ to make the plugin
+    implementation available to the wic implementation.
+
+    Source plugins can also be implemented and added by external
+    layers - any plugins found in a scripts/lib/wic/plugins/source/
+    directory in an external layer will also be made available.
+
+    When the wic implementation needs to invoke a partition-specific
+    implementation, it looks for the plugin that has the same name as
+    the --source param given to that partition.  For example, if the
+    partition is set up like this:
+
+      part /boot --source bootimg-pcbios   ...
+
+    then the methods defined as class members of the plugin having the
+    matching bootimg-pcbios .name class member would be used.
+
+    To be more concrete, here's the plugin definition that would match
+    a '--source bootimg-pcbios' usage, along with an example method
+    that would be called by the wic implementation when it needed to
+    invoke an implementation-specific partition-preparation function:
+
+    class BootimgPcbiosPlugin(SourcePlugin):
+        name = 'bootimg-pcbios'
+
+    @classmethod
+        def do_prepare_partition(self, part, ...)
+
+    If the subclass itself doesn't implement a function, a 'default'
+    version in a superclass will be located and used, which is why all
+    plugins must be derived from SourcePlugin.
+
+    The SourcePlugin class defines the following methods, which is the
+    current set of methods that can be implemented/overridden by
+    --source plugins.  Any methods not implemented by a SourcePlugin
+    subclass inherit the implementations present in the SourcePlugin
+    class (see the SourcePlugin source for details):
+
+      do_prepare_partition()
+          Called to do the actual content population for a
+          partition. In other words, it 'prepares' the final partition
+          image which will be incorporated into the disk image.
+
+      do_post_partition()
+          Called after the partition is created. It is useful to add post
+          operations e.g. signing the partition.
+
+      do_configure_partition()
+          Called before do_prepare_partition(), typically used to
+          create custom configuration files for a partition, for
+          example syslinux or grub config files.
+
+      do_install_disk()
+          Called after all partitions have been prepared and assembled
+          into a disk image.  This provides a hook to allow
+          finalization of a disk image, for example to write an MBR to
+          it.
+
+      do_stage_partition()
+          Special content-staging hook called before
+          do_prepare_partition(), normally empty.
+
+          Typically, a partition will just use the passed-in
+          parameters, for example the unmodified value of bootimg_dir.
+          In some cases however, things may need to be more tailored.
+          As an example, certain files may additionally need to be
+          take from bootimg_dir + /boot.  This hook allows those files
+          to be staged in a customized fashion.  Note that
+          get_bitbake_var() allows you to access non-standard
+          variables that you might want to use for these types of
+          situations.
+
+    This scheme is extensible - adding more hooks is a simple matter
+    of adding more plugin methods to SourcePlugin and derived classes.
+    Please see the implementation for details.
+"""
+
+wic_overview_help = """
+
+NAME
+    wic overview - General overview of wic
+
+DESCRIPTION
+    The 'wic' command generates partitioned images from existing
+    OpenEmbedded build artifacts.  Image generation is driven by
+    partitioning commands contained in an 'Openembedded kickstart'
+    (.wks) file (see 'wic help kickstart') specified either directly
+    on the command-line or as one of a selection of canned .wks files
+    (see 'wic list images').  When applied to a given set of build
+    artifacts, the result is an image or set of images that can be
+    directly written onto media and used on a particular system.
+
+    The 'wic' command and the infrastructure it's based on is by
+    definition incomplete - its purpose is to allow the generation of
+    customized images, and as such was designed to be completely
+    extensible via a plugin interface (see 'wic help plugins').
+
+  Background and Motivation
+
+    wic is meant to be a completely independent standalone utility
+    that initially provides easier-to-use and more flexible
+    replacements for a couple bits of existing functionality in
+    oe-core: directdisk.bbclass and mkefidisk.sh.  The difference
+    between wic and those examples is that with wic the functionality
+    of those scripts is implemented by a general-purpose partitioning
+    'language' based on Redhat kickstart syntax).
+
+    The initial motivation and design considerations that lead to the
+    current tool are described exhaustively in Yocto Bug #3847
+    (https://bugzilla.yoctoproject.org/show_bug.cgi?id=3847).
+
+  Implementation and Examples
+
+    wic can be used in two different modes, depending on how much
+    control the user needs in specifying the Openembedded build
+    artifacts that will be used in creating the image: 'raw' and
+    'cooked'.
+
+    If used in 'raw' mode, artifacts are explicitly specified via
+    command-line arguments (see example below).
+
+    The more easily usable 'cooked' mode uses the current MACHINE
+    setting and a specified image name to automatically locate the
+    artifacts used to create the image.
+
+    OE kickstart files (.wks) can of course be specified directly on
+    the command-line, but the user can also choose from a set of
+    'canned' .wks files available via the 'wic list images' command
+    (example below).
+
+    In any case, the prerequisite for generating any image is to have
+    the build artifacts already available.  The below examples assume
+    the user has already build a 'core-image-minimal' for a specific
+    machine (future versions won't require this redundant step, but
+    for now that's typically how build artifacts get generated).
+
+    The other prerequisite is to source the build environment:
+
+      $ source oe-init-build-env
+
+    To start out with, we'll generate an image from one of the canned
+    .wks files.  The following generates a list of availailable
+    images:
+
+      $ wic list images
+        mkefidisk             Create an EFI disk image
+        directdisk            Create a 'pcbios' direct disk image
+
+    You can get more information about any of the available images by
+    typing 'wic list xxx help', where 'xxx' is one of the image names:
+
+      $ wic list mkefidisk help
+
+    Creates a partitioned EFI disk image that the user can directly dd
+    to boot media.
+
+    At any time, you can get help on the 'wic' command or any
+    subcommand (currently 'list' and 'create').  For instance, to get
+    the description of 'wic create' command and its parameters:
+
+      $ wic create
+
+       Usage:
+
+       Create a new OpenEmbedded image
+
+       usage: wic create <wks file or image name> [-o <DIRNAME> | ...]
+            [-i <JSON PROPERTY FILE> | --infile <JSON PROPERTY_FILE>]
+            [-e | --image-name] [-s, --skip-build-check] [-D, --debug]
+            [-r, --rootfs-dir] [-b, --bootimg-dir] [-k, --kernel-dir]
+            [-n, --native-sysroot] [-f, --build-rootfs]
+
+       This command creates an OpenEmbedded image based on the 'OE
+       kickstart commands' found in the <wks file>.
+
+       The -o option can be used to place the image in a directory
+       with a different name and location.
+
+       See 'wic help create' for more detailed instructions.
+       ...
+
+    As mentioned in the command, you can get even more detailed
+    information by adding 'help' to the above:
+
+      $ wic help create
+
+    So, the easiest way to create an image is to use the -e option
+    with a canned .wks file.  To use the -e option, you need to
+    specify the image used to generate the artifacts and you actually
+    need to have the MACHINE used to build them specified in your
+    local.conf (these requirements aren't necessary if you aren't
+    using the -e options.)  Below, we generate a directdisk image,
+    pointing the process at the core-image-minimal artifacts for the
+    current MACHINE:
+
+      $ wic create directdisk -e core-image-minimal
+
+      Checking basic build environment...
+      Done.
+
+      Creating image(s)...
+
+      Info: The new image(s) can be found here:
+      /var/tmp/wic/build/directdisk-201309252350-sda.direct
+
+      The following build artifacts were used to create the image(s):
+
+      ROOTFS_DIR:      ...
+      BOOTIMG_DIR:     ...
+      KERNEL_DIR:      ...
+      NATIVE_SYSROOT:  ...
+
+      The image(s) were created using OE kickstart file:
+        .../scripts/lib/wic/canned-wks/directdisk.wks
+
+    The output shows the name and location of the image created, and
+    so that you know exactly what was used to generate the image, each
+    of the artifacts and the kickstart file used.
+
+    Similarly, you can create a 'mkefidisk' image in the same way
+    (notice that this example uses a different machine - because it's
+    using the -e option, you need to change the MACHINE in your
+    local.conf):
+
+      $ wic create mkefidisk -e core-image-minimal
+      Checking basic build environment...
+      Done.
+
+      Creating image(s)...
+
+      Info: The new image(s) can be found here:
+         /var/tmp/wic/build/mkefidisk-201309260027-sda.direct
+
+      ...
+
+    Here's an example that doesn't take the easy way out and manually
+    specifies each build artifact, along with a non-canned .wks file,
+    and also uses the -o option to have wic create the output
+    somewhere other than the default /var/tmp/wic:
+
+      $ wic create ./test.wks -o ./out --rootfs-dir
+      tmp/work/qemux86_64-poky-linux/core-image-minimal/1.0-r0/rootfs
+      --bootimg-dir tmp/sysroots/qemux86-64/usr/share
+      --kernel-dir tmp/deploy/images/qemux86-64
+      --native-sysroot tmp/sysroots/x86_64-linux
+
+     Creating image(s)...
+
+     Info: The new image(s) can be found here:
+           out/build/test-201507211313-sda.direct
+
+     The following build artifacts were used to create the image(s):
+       ROOTFS_DIR:                   tmp/work/qemux86_64-poky-linux/core-image-minimal/1.0-r0/rootfs
+       BOOTIMG_DIR:                  tmp/sysroots/qemux86-64/usr/share
+       KERNEL_DIR:                   tmp/deploy/images/qemux86-64
+       NATIVE_SYSROOT:               tmp/sysroots/x86_64-linux
+
+     The image(s) were created using OE kickstart file:
+     ./test.wks
+
+     Here is a content of test.wks:
+
+     part /boot --source bootimg-pcbios --ondisk sda --label boot --active --align 1024
+     part / --source rootfs --ondisk sda --fstype=ext3 --label platform --align 1024
+
+     bootloader  --timeout=0  --append="rootwait rootfstype=ext3 video=vesafb vga=0x318 console=tty0"
+
+
+    Finally, here's an example of the actual partition language
+    commands used to generate the mkefidisk image i.e. these are the
+    contents of the mkefidisk.wks OE kickstart file:
+
+      # short-description: Create an EFI disk image
+      # long-description: Creates a partitioned EFI disk image that the user
+      # can directly dd to boot media.
+
+      part /boot --source bootimg-efi --ondisk sda --fstype=efi --active
+
+      part / --source rootfs --ondisk sda --fstype=ext3 --label platform
+
+      part swap --ondisk sda --size 44 --label swap1 --fstype=swap
+
+      bootloader  --timeout=10  --append="rootwait console=ttyPCH0,115200"
+
+    You can get a complete listing and description of all the
+    kickstart commands available for use in .wks files from 'wic help
+    kickstart'.
+"""
+
+wic_kickstart_help = """
+
+NAME
+    wic kickstart - wic kickstart reference
+
+DESCRIPTION
+    This section provides the definitive reference to the wic
+    kickstart language.  It also provides documentation on the list of
+    --source plugins available for use from the 'part' command (see
+    the 'Platform-specific Plugins' section below).
+
+    The current wic implementation supports only the basic kickstart
+    partitioning commands: partition (or part for short) and
+    bootloader.
+
+    The following is a listing of the commands, their syntax, and
+    meanings. The commands are based on the Fedora kickstart
+    documentation but with modifications to reflect wic capabilities.
+
+      http://fedoraproject.org/wiki/Anaconda/Kickstart#part_or_partition
+      http://fedoraproject.org/wiki/Anaconda/Kickstart#bootloader
+
+  Commands
+
+    * 'part' or 'partition'
+
+       This command creates a partition on the system and uses the
+       following syntax:
+
+         part [<mountpoint>]
+
+       The <mountpoint> is where the partition will be mounted and
+       must take of one of the following forms:
+
+         /<path>: For example: /, /usr, or /home
+
+         swap: The partition will be used as swap space.
+
+       If a <mountpoint> is not specified the partition will be created
+       but will not be mounted.
+
+       Partitions with a <mountpoint> specified will be automatically mounted.
+       This is achieved by wic adding entries to the fstab during image
+       generation. In order for a valid fstab to be generated one of the
+       --ondrive, --ondisk, --use-uuid or --use-label partition options must
+       be used for each partition that specifies a mountpoint.  Note that with
+       --use-{uuid,label} and non-root <mountpoint>, including swap, the mount
+       program must understand the PARTUUID or LABEL syntax.  This currently
+       excludes the busybox versions of these applications.
+
+
+       The following are supported 'part' options:
+
+         --size: The minimum partition size. Specify an integer value
+                 such as 500. Multipliers k, M ang G can be used. If
+                 not specified, the size is in MB.
+                 You do not need this option if you use --source.
+
+         --fixed-size: Exact partition size. Value format is the same
+                       as for --size option. This option cannot be
+                       specified along with --size. If partition data
+                       is larger than --fixed-size and error will be
+                       raised when assembling disk image.
+
+         --source: This option is a wic-specific option that names the
+                   source of the data that will populate the
+                   partition.  The most common value for this option
+                   is 'rootfs', but can be any value which maps to a
+                   valid 'source plugin' (see 'wic help plugins').
+
+                   If '--source rootfs' is used, it tells the wic
+                   command to create a partition as large as needed
+                   and to fill it with the contents of the root
+                   filesystem pointed to by the '-r' wic command-line
+                   option (or the equivalent rootfs derived from the
+                   '-e' command-line option).  The filesystem type
+                   that will be used to create the partition is driven
+                   by the value of the --fstype option specified for
+                   the partition (see --fstype below).
+
+                   If --source <plugin-name>' is used, it tells the
+                   wic command to create a partition as large as
+                   needed and to fill with the contents of the
+                   partition that will be generated by the specified
+                   plugin name using the data pointed to by the '-r'
+                   wic command-line option (or the equivalent rootfs
+                   derived from the '-e' command-line option).
+                   Exactly what those contents and filesystem type end
+                   up being are dependent on the given plugin
+                   implementation.
+
+                   If --source option is not used, the wic command
+                   will create empty partition. --size parameter has
+                   to be used to specify size of empty partition.
+
+         --ondisk or --ondrive: Forces the partition to be created on
+                                a particular disk.
+
+         --fstype: Sets the file system type for the partition.  These
+           apply to partitions created using '--source rootfs' (see
+           --source above).  Valid values are:
+
+             vfat
+             msdos
+             ext2
+             ext3
+             ext4
+             btrfs
+             squashfs
+             swap
+
+         --fsoptions: Specifies a free-form string of options to be
+                      used when mounting the filesystem. This string
+                      will be copied into the /etc/fstab file of the
+                      installed system and should be enclosed in
+                      quotes.  If not specified, the default string is
+                      "defaults".
+
+         --label label: Specifies the label to give to the filesystem
+                        to be made on the partition. If the given
+                        label is already in use by another filesystem,
+                        a new label is created for the partition.
+
+         --use-label: This option is specific to wic. It makes wic to use the
+                      label in /etc/fstab to specify a partition. If the
+                      --use-label and --use-uuid are used at the same time,
+                      we prefer the uuid because it is less likely to cause
+                      name confliction. We don't support using this parameter
+                      on the root partition since it requires an initramfs to
+                      parse this value and we do not currently support that.
+
+         --active: Marks the partition as active.
+
+         --align (in KBytes): This option is specific to wic and says
+                              to start a partition on an x KBytes
+                              boundary.
+
+         --no-table: This option is specific to wic. Space will be
+                     reserved for the partition and it will be
+                     populated but it will not be added to the
+                     partition table. It may be useful for
+                     bootloaders.
+
+         --exclude-path: This option is specific to wic. It excludes the given
+                         relative path from the resulting image. If the path
+                         ends with a slash, only the content of the directory
+                         is omitted, not the directory itself. This option only
+                         has an effect with the rootfs source plugin.
+
+         --extra-space: This option is specific to wic. It adds extra
+                        space after the space filled by the content
+                        of the partition. The final size can go
+                        beyond the size specified by --size.
+                        By default, 10MB. This option cannot be used
+                        with --fixed-size option.
+
+         --overhead-factor: This option is specific to wic. The
+                            size of the partition is multiplied by
+                            this factor. It has to be greater than or
+                            equal to 1. The default value is 1.3.
+                            This option cannot be used with --fixed-size
+                            option.
+
+         --part-name: This option is specific to wic. It specifies name for GPT partitions.
+
+         --part-type: This option is specific to wic. It specifies partition
+                      type GUID for GPT partitions.
+                      List of partition type GUIDS can be found here:
+                      http://en.wikipedia.org/wiki/GUID_Partition_Table#Partition_type_GUIDs
+
+         --use-uuid: This option is specific to wic. It makes wic to generate
+                     random globally unique identifier (GUID) for the partition
+                     and use it in bootloader configuration to specify root partition.
+
+         --uuid: This option is specific to wic. It specifies partition UUID.
+                 It's useful if preconfigured partition UUID is added to kernel command line
+                 in bootloader configuration before running wic. In this case .wks file can
+                 be generated or modified to set preconfigured parition UUID using this option.
+
+         --fsuuid: This option is specific to wic. It specifies filesystem UUID.
+                   It's useful if preconfigured filesystem UUID is added to kernel command line
+                   in bootloader configuration before running wic. In this case .wks file can
+                   be generated or modified to set preconfigured filesystem UUID using this option.
+
+         --system-id: This option is specific to wic. It specifies partition system id. It's useful
+                      for the harware that requires non-default partition system ids. The parameter
+                      in one byte long hex number either with 0x prefix or without it.
+
+         --mkfs-extraopts: This option specifies extra options to pass to mkfs utility.
+                           NOTE, that wic uses default options for some filesystems, for example
+                           '-S 512' for mkfs.fat or '-F -i 8192' for mkfs.ext. Those options will
+                           not take effect when --mkfs-extraopts is used. This should be taken into
+                           account when using --mkfs-extraopts.
+
+    * bootloader
+
+      This command allows the user to specify various bootloader
+      options.  The following are supported 'bootloader' options:
+
+        --timeout: Specifies the number of seconds before the
+                   bootloader times out and boots the default option.
+
+        --append: Specifies kernel parameters. These will be added to
+                  bootloader command-line - for example, the syslinux
+                  APPEND or grub kernel command line.
+
+        --configfile: Specifies a user defined configuration file for
+                      the bootloader. This file must be located in the
+                      canned-wks folder or could be the full path to the
+                      file. Using this option will override any other
+                      bootloader option.
+
+      Note that bootloader functionality and boot partitions are
+      implemented by the various --source plugins that implement
+      bootloader functionality; the bootloader command essentially
+      provides a means of modifying bootloader configuration.
+
+    * include
+
+      This command allows the user to include the content of .wks file
+      into original .wks file.
+
+      Command uses the following syntax:
+
+         include <file>
+
+      The <file> is either path to the file or its name. If name is
+      specified wic will try to find file in the directories with canned
+      .wks files.
+
+"""
+
+wic_help_help = """
+NAME
+    wic help - display a help topic
+
+DESCRIPTION
+    Specify a help topic to display it. Topics are shown above.
+"""
diff --git a/meta/poky/scripts/lib/wic/ksparser.py b/meta/poky/scripts/lib/wic/ksparser.py
new file mode 100644
index 0000000..7e5a9c5
--- /dev/null
+++ b/meta/poky/scripts/lib/wic/ksparser.py
@@ -0,0 +1,245 @@
+#!/usr/bin/env python -tt
+# ex:ts=4:sw=4:sts=4:et
+# -*- tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*-
+#
+# Copyright (c) 2016 Intel, Inc.
+#
+# This program is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by the Free
+# Software Foundation; version 2 of the License
+#
+# 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.
+#
+# DESCRIPTION
+# This module provides parser for kickstart format
+#
+# AUTHORS
+# Ed Bartosh <ed.bartosh> (at] linux.intel.com>
+
+"""Kickstart parser module."""
+
+import os
+import shlex
+import logging
+
+from argparse import ArgumentParser, ArgumentError, ArgumentTypeError
+
+from wic.engine import find_canned
+from wic.partition import Partition
+
+logger = logging.getLogger('wic')
+
+class KickStartError(Exception):
+    """Custom exception."""
+    pass
+
+class KickStartParser(ArgumentParser):
+    """
+    This class overwrites error method to throw exception
+    instead of producing usage message(default argparse behavior).
+    """
+    def error(self, message):
+        raise ArgumentError(None, message)
+
+def sizetype(arg):
+    """
+    Custom type for ArgumentParser
+    Converts size string in <num>[K|k|M|G] format into the integer value
+    """
+    if arg.isdigit():
+        return int(arg) * 1024
+
+    if not arg[:-1].isdigit():
+        raise ArgumentTypeError("Invalid size: %r" % arg)
+
+    size = int(arg[:-1])
+    if arg.endswith("k") or arg.endswith("K"):
+        return size
+    if arg.endswith("M"):
+        return size * 1024
+    if arg.endswith("G"):
+        return size * 1024 * 1024
+
+    raise ArgumentTypeError("Invalid size: %r" % arg)
+
+def overheadtype(arg):
+    """
+    Custom type for ArgumentParser
+    Converts overhead string to float and checks if it's bigger than 1.0
+    """
+    try:
+        result = float(arg)
+    except ValueError:
+        raise ArgumentTypeError("Invalid value: %r" % arg)
+
+    if result < 1.0:
+        raise ArgumentTypeError("Overhead factor should be > 1.0" % arg)
+
+    return result
+
+def cannedpathtype(arg):
+    """
+    Custom type for ArgumentParser
+    Tries to find file in the list of canned wks paths
+    """
+    scripts_path = os.path.abspath(os.path.dirname(__file__) + '../../..')
+    result = find_canned(scripts_path, arg)
+    if not result:
+        raise ArgumentTypeError("file not found: %s" % arg)
+    return result
+
+def systemidtype(arg):
+    """
+    Custom type for ArgumentParser
+    Checks if the argument sutisfies system id requirements,
+    i.e. if it's one byte long integer > 0
+    """
+    error = "Invalid system type: %s. must be hex "\
+            "between 0x1 and 0xFF" % arg
+    try:
+        result = int(arg, 16)
+    except ValueError:
+        raise ArgumentTypeError(error)
+
+    if result <= 0 or result > 0xff:
+        raise ArgumentTypeError(error)
+
+    return arg
+
+class KickStart():
+    """Kickstart parser implementation."""
+
+    DEFAULT_EXTRA_SPACE = 10*1024
+    DEFAULT_OVERHEAD_FACTOR = 1.3
+
+    def __init__(self, confpath):
+
+        self.partitions = []
+        self.bootloader = None
+        self.lineno = 0
+        self.partnum = 0
+
+        parser = KickStartParser()
+        subparsers = parser.add_subparsers()
+
+        part = subparsers.add_parser('part')
+        part.add_argument('mountpoint', nargs='?')
+        part.add_argument('--active', action='store_true')
+        part.add_argument('--align', type=int)
+        part.add_argument('--exclude-path', nargs='+')
+        part.add_argument("--extra-space", type=sizetype)
+        part.add_argument('--fsoptions', dest='fsopts')
+        part.add_argument('--fstype', default='vfat',
+                          choices=('ext2', 'ext3', 'ext4', 'btrfs',
+                                   'squashfs', 'vfat', 'msdos', 'swap'))
+        part.add_argument('--mkfs-extraopts', default='')
+        part.add_argument('--label')
+        part.add_argument('--use-label', action='store_true')
+        part.add_argument('--no-table', action='store_true')
+        part.add_argument('--ondisk', '--ondrive', dest='disk', default='sda')
+        part.add_argument("--overhead-factor", type=overheadtype)
+        part.add_argument('--part-name')
+        part.add_argument('--part-type')
+        part.add_argument('--rootfs-dir')
+
+        # --size and --fixed-size cannot be specified together; options
+        # ----extra-space and --overhead-factor should also raise a parser
+        # --error, but since nesting mutually exclusive groups does not work,
+        # ----extra-space/--overhead-factor are handled later
+        sizeexcl = part.add_mutually_exclusive_group()
+        sizeexcl.add_argument('--size', type=sizetype, default=0)
+        sizeexcl.add_argument('--fixed-size', type=sizetype, default=0)
+
+        part.add_argument('--source')
+        part.add_argument('--sourceparams')
+        part.add_argument('--system-id', type=systemidtype)
+        part.add_argument('--use-uuid', action='store_true')
+        part.add_argument('--uuid')
+        part.add_argument('--fsuuid')
+
+        bootloader = subparsers.add_parser('bootloader')
+        bootloader.add_argument('--append')
+        bootloader.add_argument('--configfile')
+        bootloader.add_argument('--ptable', choices=('msdos', 'gpt'),
+                                default='msdos')
+        bootloader.add_argument('--timeout', type=int)
+        bootloader.add_argument('--source')
+
+        include = subparsers.add_parser('include')
+        include.add_argument('path', type=cannedpathtype)
+
+        self._parse(parser, confpath)
+        if not self.bootloader:
+            logger.warning('bootloader config not specified, using defaults\n')
+            self.bootloader = bootloader.parse_args([])
+
+    def _parse(self, parser, confpath):
+        """
+        Parse file in .wks format using provided parser.
+        """
+        with open(confpath) as conf:
+            lineno = 0
+            for line in conf:
+                line = line.strip()
+                lineno += 1
+                if line and line[0] != '#':
+                    try:
+                        line_args = shlex.split(line)
+                        parsed = parser.parse_args(line_args)
+                    except ArgumentError as err:
+                        raise KickStartError('%s:%d: %s' % \
+                                             (confpath, lineno, err))
+                    if line.startswith('part'):
+                        # SquashFS does not support filesystem UUID
+                        if parsed.fstype == 'squashfs':
+                            if parsed.fsuuid:
+                                err = "%s:%d: SquashFS does not support UUID" \
+                                       % (confpath, lineno)
+                                raise KickStartError(err)
+                            if parsed.label:
+                                err = "%s:%d: SquashFS does not support LABEL" \
+                                       % (confpath, lineno)
+                                raise KickStartError(err)
+                        if parsed.use_label and not parsed.label:
+                            err = "%s:%d: Must set the label with --label" \
+                                  % (confpath, lineno)
+                            raise KickStartError(err)
+                        # using ArgumentParser one cannot easily tell if option
+                        # was passed as argument, if said option has a default
+                        # value; --overhead-factor/--extra-space cannot be used
+                        # with --fixed-size, so at least detect when these were
+                        # passed with non-0 values ...
+                        if parsed.fixed_size:
+                            if parsed.overhead_factor or parsed.extra_space:
+                                err = "%s:%d: arguments --overhead-factor and --extra-space not "\
+                                      "allowed with argument --fixed-size" \
+                                      % (confpath, lineno)
+                                raise KickStartError(err)
+                        else:
+                            # ... and provide defaults if not using
+                            # --fixed-size iff given option was not used
+                            # (again, one cannot tell if option was passed but
+                            # with value equal to 0)
+                            if '--overhead-factor' not in line_args:
+                                parsed.overhead_factor = self.DEFAULT_OVERHEAD_FACTOR
+                            if '--extra-space' not in line_args:
+                                parsed.extra_space = self.DEFAULT_EXTRA_SPACE
+
+                        self.partnum += 1
+                        self.partitions.append(Partition(parsed, self.partnum))
+                    elif line.startswith('include'):
+                        self._parse(parser, parsed.path)
+                    elif line.startswith('bootloader'):
+                        if not self.bootloader:
+                            self.bootloader = parsed
+                        else:
+                            err = "%s:%d: more than one bootloader specified" \
+                                      % (confpath, lineno)
+                            raise KickStartError(err)
diff --git a/meta/poky/scripts/lib/wic/misc.py b/meta/poky/scripts/lib/wic/misc.py
new file mode 100644
index 0000000..ee888b4
--- /dev/null
+++ b/meta/poky/scripts/lib/wic/misc.py
@@ -0,0 +1,263 @@
+# ex:ts=4:sw=4:sts=4:et
+# -*- tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*-
+#
+# Copyright (c) 2013, Intel Corporation.
+# All rights reserved.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License 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.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# DESCRIPTION
+# This module provides a place to collect various wic-related utils
+# for the OpenEmbedded Image Tools.
+#
+# AUTHORS
+# Tom Zanussi <tom.zanussi (at] linux.intel.com>
+#
+"""Miscellaneous functions."""
+
+import logging
+import os
+import re
+import subprocess
+
+from collections import defaultdict
+from distutils import spawn
+
+from wic import WicError
+
+logger = logging.getLogger('wic')
+
+# executable -> recipe pairs for exec_native_cmd
+NATIVE_RECIPES = {"bmaptool": "bmap-tools",
+                  "grub-mkimage": "grub-efi",
+                  "isohybrid": "syslinux",
+                  "mcopy": "mtools",
+                  "mdel" : "mtools",
+                  "mdeltree" : "mtools",
+                  "mdir" : "mtools",
+                  "mkdosfs": "dosfstools",
+                  "mkisofs": "cdrtools",
+                  "mkfs.btrfs": "btrfs-tools",
+                  "mkfs.ext2": "e2fsprogs",
+                  "mkfs.ext3": "e2fsprogs",
+                  "mkfs.ext4": "e2fsprogs",
+                  "mkfs.vfat": "dosfstools",
+                  "mksquashfs": "squashfs-tools",
+                  "mkswap": "util-linux",
+                  "mmd": "mtools",
+                  "parted": "parted",
+                  "sfdisk": "util-linux",
+                  "sgdisk": "gptfdisk",
+                  "syslinux": "syslinux"
+                 }
+
+def runtool(cmdln_or_args):
+    """ wrapper for most of the subprocess calls
+    input:
+        cmdln_or_args: can be both args and cmdln str (shell=True)
+    return:
+        rc, output
+    """
+    if isinstance(cmdln_or_args, list):
+        cmd = cmdln_or_args[0]
+        shell = False
+    else:
+        import shlex
+        cmd = shlex.split(cmdln_or_args)[0]
+        shell = True
+
+    sout = subprocess.PIPE
+    serr = subprocess.STDOUT
+
+    try:
+        process = subprocess.Popen(cmdln_or_args, stdout=sout,
+                                   stderr=serr, shell=shell)
+        sout, serr = process.communicate()
+        # combine stdout and stderr, filter None out and decode
+        out = ''.join([out.decode('utf-8') for out in [sout, serr] if out])
+    except OSError as err:
+        if err.errno == 2:
+            # [Errno 2] No such file or directory
+            raise WicError('Cannot run command: %s, lost dependency?' % cmd)
+        else:
+            raise # relay
+
+    return process.returncode, out
+
+def _exec_cmd(cmd_and_args, as_shell=False):
+    """
+    Execute command, catching stderr, stdout
+
+    Need to execute as_shell if the command uses wildcards
+    """
+    logger.debug("_exec_cmd: %s", cmd_and_args)
+    args = cmd_and_args.split()
+    logger.debug(args)
+
+    if as_shell:
+        ret, out = runtool(cmd_and_args)
+    else:
+        ret, out = runtool(args)
+    out = out.strip()
+    if ret != 0:
+        raise WicError("_exec_cmd: %s returned '%s' instead of 0\noutput: %s" % \
+                       (cmd_and_args, ret, out))
+
+    logger.debug("_exec_cmd: output for %s (rc = %d): %s",
+                 cmd_and_args, ret, out)
+
+    return ret, out
+
+
+def exec_cmd(cmd_and_args, as_shell=False):
+    """
+    Execute command, return output
+    """
+    return _exec_cmd(cmd_and_args, as_shell)[1]
+
+
+def exec_native_cmd(cmd_and_args, native_sysroot, pseudo=""):
+    """
+    Execute native command, catching stderr, stdout
+
+    Need to execute as_shell if the command uses wildcards
+
+    Always need to execute native commands as_shell
+    """
+    # The reason -1 is used is because there may be "export" commands.
+    args = cmd_and_args.split(';')[-1].split()
+    logger.debug(args)
+
+    if pseudo:
+        cmd_and_args = pseudo + cmd_and_args
+
+    native_paths = "%s/sbin:%s/usr/sbin:%s/usr/bin" % \
+                   (native_sysroot, native_sysroot, native_sysroot)
+
+    native_cmd_and_args = "export PATH=%s:$PATH;%s" % \
+                   (native_paths, cmd_and_args)
+    logger.debug("exec_native_cmd: %s", native_cmd_and_args)
+
+    # If the command isn't in the native sysroot say we failed.
+    if spawn.find_executable(args[0], native_paths):
+        ret, out = _exec_cmd(native_cmd_and_args, True)
+    else:
+        ret = 127
+        out = "can't find native executable %s in %s" % (args[0], native_paths)
+
+    prog = args[0]
+    # shell command-not-found
+    if ret == 127 \
+       or (pseudo and ret == 1 and out == "Can't find '%s' in $PATH." % prog):
+        msg = "A native program %s required to build the image "\
+              "was not found (see details above).\n\n" % prog
+        recipe = NATIVE_RECIPES.get(prog)
+        if recipe:
+            msg += "Please make sure wic-tools have %s-native in its DEPENDS, "\
+                   "build it with 'bitbake wic-tools' and try again.\n" % recipe
+        else:
+            msg += "Wic failed to find a recipe to build native %s. Please "\
+                   "file a bug against wic.\n" % prog
+        raise WicError(msg)
+
+    return ret, out
+
+BOOTDD_EXTRA_SPACE = 16384
+
+class BitbakeVars(defaultdict):
+    """
+    Container for Bitbake variables.
+    """
+    def __init__(self):
+        defaultdict.__init__(self, dict)
+
+        # default_image and vars_dir attributes should be set from outside
+        self.default_image = None
+        self.vars_dir = None
+
+    def _parse_line(self, line, image, matcher=re.compile(r"^([a-zA-Z0-9\-_+./~]+)=(.*)")):
+        """
+        Parse one line from bitbake -e output or from .env file.
+        Put result key-value pair into the storage.
+        """
+        if "=" not in line:
+            return
+        match = matcher.match(line)
+        if not match:
+            return
+        key, val = match.groups()
+        self[image][key] = val.strip('"')
+
+    def get_var(self, var, image=None, cache=True):
+        """
+        Get bitbake variable from 'bitbake -e' output or from .env file.
+        This is a lazy method, i.e. it runs bitbake or parses file only when
+        only when variable is requested. It also caches results.
+        """
+        if not image:
+            image = self.default_image
+
+        if image not in self:
+            if image and self.vars_dir:
+                fname = os.path.join(self.vars_dir, image + '.env')
+                if os.path.isfile(fname):
+                    # parse .env file
+                    with open(fname) as varsfile:
+                        for line in varsfile:
+                            self._parse_line(line, image)
+                else:
+                    print("Couldn't get bitbake variable from %s." % fname)
+                    print("File %s doesn't exist." % fname)
+                    return
+            else:
+                # Get bitbake -e output
+                cmd = "bitbake -e"
+                if image:
+                    cmd += " %s" % image
+
+                log_level = logger.getEffectiveLevel()
+                logger.setLevel(logging.INFO)
+                ret, lines = _exec_cmd(cmd)
+                logger.setLevel(log_level)
+
+                if ret:
+                    logger.error("Couldn't get '%s' output.", cmd)
+                    logger.error("Bitbake failed with error:\n%s\n", lines)
+                    return
+
+                # Parse bitbake -e output
+                for line in lines.split('\n'):
+                    self._parse_line(line, image)
+
+            # Make first image a default set of variables
+            if cache:
+                images = [key for key in self if key]
+                if len(images) == 1:
+                    self[None] = self[image]
+
+        result = self[image].get(var)
+        if not cache:
+            self.pop(image, None)
+
+        return result
+
+# Create BB_VARS singleton
+BB_VARS = BitbakeVars()
+
+def get_bitbake_var(var, image=None, cache=True):
+    """
+    Provide old get_bitbake_var API by wrapping
+    get_var method of BB_VARS singleton.
+    """
+    return BB_VARS.get_var(var, image, cache)
diff --git a/meta/poky/scripts/lib/wic/partition.py b/meta/poky/scripts/lib/wic/partition.py
new file mode 100644
index 0000000..3da7e23
--- /dev/null
+++ b/meta/poky/scripts/lib/wic/partition.py
@@ -0,0 +1,425 @@
+# ex:ts=4:sw=4:sts=4:et
+# -*- tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*-
+#
+# Copyright (c) 2013-2016 Intel Corporation.
+# All rights reserved.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License 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.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# DESCRIPTION
+# This module provides the OpenEmbedded partition object definitions.
+#
+# AUTHORS
+# Tom Zanussi <tom.zanussi (at] linux.intel.com>
+# Ed Bartosh <ed.bartosh> (at] linux.intel.com>
+
+import logging
+import os
+import uuid
+
+from wic import WicError
+from wic.misc import exec_cmd, exec_native_cmd, get_bitbake_var
+from wic.pluginbase import PluginMgr
+
+logger = logging.getLogger('wic')
+
+class Partition():
+
+    def __init__(self, args, lineno):
+        self.args = args
+        self.active = args.active
+        self.align = args.align
+        self.disk = args.disk
+        self.device = None
+        self.extra_space = args.extra_space
+        self.exclude_path = args.exclude_path
+        self.fsopts = args.fsopts
+        self.fstype = args.fstype
+        self.label = args.label
+        self.use_label = args.use_label
+        self.mkfs_extraopts = args.mkfs_extraopts
+        self.mountpoint = args.mountpoint
+        self.no_table = args.no_table
+        self.num = None
+        self.overhead_factor = args.overhead_factor
+        self.part_name = args.part_name
+        self.part_type = args.part_type
+        self.rootfs_dir = args.rootfs_dir
+        self.size = args.size
+        self.fixed_size = args.fixed_size
+        self.source = args.source
+        self.sourceparams = args.sourceparams
+        self.system_id = args.system_id
+        self.use_uuid = args.use_uuid
+        self.uuid = args.uuid
+        self.fsuuid = args.fsuuid
+
+        self.lineno = lineno
+        self.source_file = ""
+
+    def get_extra_block_count(self, current_blocks):
+        """
+        The --size param is reflected in self.size (in kB), and we already
+        have current_blocks (1k) blocks, calculate and return the
+        number of (1k) blocks we need to add to get to --size, 0 if
+        we're already there or beyond.
+        """
+        logger.debug("Requested partition size for %s: %d",
+                     self.mountpoint, self.size)
+
+        if not self.size:
+            return 0
+
+        requested_blocks = self.size
+
+        logger.debug("Requested blocks %d, current_blocks %d",
+                     requested_blocks, current_blocks)
+
+        if requested_blocks > current_blocks:
+            return requested_blocks - current_blocks
+        else:
+            return 0
+
+    def get_rootfs_size(self, actual_rootfs_size=0):
+        """
+        Calculate the required size of rootfs taking into consideration
+        --size/--fixed-size flags as well as overhead and extra space, as
+        specified in kickstart file. Raises an error if the
+        `actual_rootfs_size` is larger than fixed-size rootfs.
+
+        """
+        if self.fixed_size:
+            rootfs_size = self.fixed_size
+            if actual_rootfs_size > rootfs_size:
+                raise WicError("Actual rootfs size (%d kB) is larger than "
+                               "allowed size %d kB" %
+                               (actual_rootfs_size, rootfs_size))
+        else:
+            extra_blocks = self.get_extra_block_count(actual_rootfs_size)
+            if extra_blocks < self.extra_space:
+                extra_blocks = self.extra_space
+
+            rootfs_size = actual_rootfs_size + extra_blocks
+            rootfs_size *= self.overhead_factor
+
+            logger.debug("Added %d extra blocks to %s to get to %d total blocks",
+                         extra_blocks, self.mountpoint, rootfs_size)
+
+        return rootfs_size
+
+    @property
+    def disk_size(self):
+        """
+        Obtain on-disk size of partition taking into consideration
+        --size/--fixed-size options.
+
+        """
+        return self.fixed_size if self.fixed_size else self.size
+
+    def prepare(self, creator, cr_workdir, oe_builddir, rootfs_dir,
+                bootimg_dir, kernel_dir, native_sysroot):
+        """
+        Prepare content for individual partitions, depending on
+        partition command parameters.
+        """
+        if not self.source:
+            if not self.size and not self.fixed_size:
+                raise WicError("The %s partition has a size of zero. Please "
+                               "specify a non-zero --size/--fixed-size for that "
+                               "partition." % self.mountpoint)
+
+            if self.fstype == "swap":
+                self.prepare_swap_partition(cr_workdir, oe_builddir,
+                                            native_sysroot)
+                self.source_file = "%s/fs.%s" % (cr_workdir, self.fstype)
+            else:
+                if self.fstype == 'squashfs':
+                    raise WicError("It's not possible to create empty squashfs "
+                                   "partition '%s'" % (self.mountpoint))
+
+                rootfs = "%s/fs_%s.%s.%s" % (cr_workdir, self.label,
+                                             self.lineno, self.fstype)
+                if os.path.isfile(rootfs):
+                    os.remove(rootfs)
+
+                prefix = "ext" if self.fstype.startswith("ext") else self.fstype
+                method = getattr(self, "prepare_empty_partition_" + prefix)
+                method(rootfs, oe_builddir, native_sysroot)
+                self.source_file = rootfs
+            return
+
+        plugins = PluginMgr.get_plugins('source')
+
+        if self.source not in plugins:
+            raise WicError("The '%s' --source specified for %s doesn't exist.\n\t"
+                           "See 'wic list source-plugins' for a list of available"
+                           " --sources.\n\tSee 'wic help source-plugins' for "
+                           "details on adding a new source plugin." %
+                           (self.source, self.mountpoint))
+
+        srcparams_dict = {}
+        if self.sourceparams:
+            # Split sourceparams string of the form key1=val1[,key2=val2,...]
+            # into a dict.  Also accepts valueless keys i.e. without =
+            splitted = self.sourceparams.split(',')
+            srcparams_dict = dict(par.split('=') for par in splitted if par)
+
+        plugin = PluginMgr.get_plugins('source')[self.source]
+        plugin.do_configure_partition(self, srcparams_dict, creator,
+                                      cr_workdir, oe_builddir, bootimg_dir,
+                                      kernel_dir, native_sysroot)
+        plugin.do_stage_partition(self, srcparams_dict, creator,
+                                  cr_workdir, oe_builddir, bootimg_dir,
+                                  kernel_dir, native_sysroot)
+        plugin.do_prepare_partition(self, srcparams_dict, creator,
+                                    cr_workdir, oe_builddir, bootimg_dir,
+                                    kernel_dir, rootfs_dir, native_sysroot)
+        plugin.do_post_partition(self, srcparams_dict, creator,
+                                    cr_workdir, oe_builddir, bootimg_dir,
+                                    kernel_dir, rootfs_dir, native_sysroot)
+
+        # further processing required Partition.size to be an integer, make
+        # sure that it is one
+        if not isinstance(self.size, int):
+            raise WicError("Partition %s internal size is not an integer. "
+                           "This a bug in source plugin %s and needs to be fixed." %
+                           (self.mountpoint, self.source))
+
+        if self.fixed_size and self.size > self.fixed_size:
+            raise WicError("File system image of partition %s is "
+                           "larger (%d kB) than its allowed size %d kB" %
+                           (self.mountpoint, self.size, self.fixed_size))
+
+    def prepare_rootfs(self, cr_workdir, oe_builddir, rootfs_dir,
+                       native_sysroot, real_rootfs = True):
+        """
+        Prepare content for a rootfs partition i.e. create a partition
+        and fill it from a /rootfs dir.
+
+        Currently handles ext2/3/4, btrfs, vfat and squashfs.
+        """
+        p_prefix = os.environ.get("PSEUDO_PREFIX", "%s/usr" % native_sysroot)
+        p_localstatedir = os.environ.get("PSEUDO_LOCALSTATEDIR",
+                                         "%s/../pseudo" %  rootfs_dir)
+        p_passwd = os.environ.get("PSEUDO_PASSWD", rootfs_dir)
+        p_nosymlinkexp = os.environ.get("PSEUDO_NOSYMLINKEXP", "1")
+        pseudo = "export PSEUDO_PREFIX=%s;" % p_prefix
+        pseudo += "export PSEUDO_LOCALSTATEDIR=%s;" % p_localstatedir
+        pseudo += "export PSEUDO_PASSWD=%s;" % p_passwd
+        pseudo += "export PSEUDO_NOSYMLINKEXP=%s;" % p_nosymlinkexp
+        pseudo += "%s " % get_bitbake_var("FAKEROOTCMD")
+
+        rootfs = "%s/rootfs_%s.%s.%s" % (cr_workdir, self.label,
+                                         self.lineno, self.fstype)
+        if os.path.isfile(rootfs):
+            os.remove(rootfs)
+
+        # Get rootfs size from bitbake variable if it's not set in .ks file
+        if not self.size and real_rootfs:
+            # Bitbake variable ROOTFS_SIZE is calculated in
+            # Image._get_rootfs_size method from meta/lib/oe/image.py
+            # using IMAGE_ROOTFS_SIZE, IMAGE_ROOTFS_ALIGNMENT,
+            # IMAGE_OVERHEAD_FACTOR and IMAGE_ROOTFS_EXTRA_SPACE
+            rsize_bb = get_bitbake_var('ROOTFS_SIZE')
+            if rsize_bb:
+                logger.warning('overhead-factor was specified, but size was not,'
+                               ' so bitbake variables will be used for the size.'
+                               ' In this case both IMAGE_OVERHEAD_FACTOR and '
+                               '--overhead-factor will be applied')
+                self.size = int(round(float(rsize_bb)))
+
+        prefix = "ext" if self.fstype.startswith("ext") else self.fstype
+        method = getattr(self, "prepare_rootfs_" + prefix)
+        method(rootfs, oe_builddir, rootfs_dir, native_sysroot, pseudo)
+        self.source_file = rootfs
+
+        # get the rootfs size in the right units for kickstart (kB)
+        du_cmd = "du -Lbks %s" % rootfs
+        out = exec_cmd(du_cmd)
+        self.size = int(out.split()[0])
+
+    def prepare_rootfs_ext(self, rootfs, oe_builddir, rootfs_dir,
+                           native_sysroot, pseudo):
+        """
+        Prepare content for an ext2/3/4 rootfs partition.
+        """
+        du_cmd = "du -ks %s" % rootfs_dir
+        out = exec_cmd(du_cmd)
+        actual_rootfs_size = int(out.split()[0])
+
+        rootfs_size = self.get_rootfs_size(actual_rootfs_size)
+
+        with open(rootfs, 'w') as sparse:
+            os.ftruncate(sparse.fileno(), rootfs_size * 1024)
+
+        extraopts = self.mkfs_extraopts or "-F -i 8192"
+
+        label_str = ""
+        if self.label:
+            label_str = "-L %s" % self.label
+
+        mkfs_cmd = "mkfs.%s %s %s %s -U %s -d %s" % \
+            (self.fstype, extraopts, rootfs, label_str, self.fsuuid, rootfs_dir)
+        exec_native_cmd(mkfs_cmd, native_sysroot, pseudo=pseudo)
+
+        mkfs_cmd = "fsck.%s -pvfD %s" % (self.fstype, rootfs)
+        exec_native_cmd(mkfs_cmd, native_sysroot, pseudo=pseudo)
+
+    def prepare_rootfs_btrfs(self, rootfs, oe_builddir, rootfs_dir,
+                             native_sysroot, pseudo):
+        """
+        Prepare content for a btrfs rootfs partition.
+        """
+        du_cmd = "du -ks %s" % rootfs_dir
+        out = exec_cmd(du_cmd)
+        actual_rootfs_size = int(out.split()[0])
+
+        rootfs_size = self.get_rootfs_size(actual_rootfs_size)
+
+        with open(rootfs, 'w') as sparse:
+            os.ftruncate(sparse.fileno(), rootfs_size * 1024)
+
+        label_str = ""
+        if self.label:
+            label_str = "-L %s" % self.label
+
+        mkfs_cmd = "mkfs.%s -b %d -r %s %s %s -U %s %s" % \
+            (self.fstype, rootfs_size * 1024, rootfs_dir, label_str,
+             self.mkfs_extraopts, self.fsuuid, rootfs)
+        exec_native_cmd(mkfs_cmd, native_sysroot, pseudo=pseudo)
+
+    def prepare_rootfs_msdos(self, rootfs, oe_builddir, rootfs_dir,
+                             native_sysroot, pseudo):
+        """
+        Prepare content for a msdos/vfat rootfs partition.
+        """
+        du_cmd = "du -bks %s" % rootfs_dir
+        out = exec_cmd(du_cmd)
+        blocks = int(out.split()[0])
+
+        rootfs_size = self.get_rootfs_size(blocks)
+
+        label_str = "-n boot"
+        if self.label:
+            label_str = "-n %s" % self.label
+
+        size_str = ""
+        if self.fstype == 'msdos':
+            size_str = "-F 16" # FAT 16
+
+        extraopts = self.mkfs_extraopts or '-S 512'
+
+        dosfs_cmd = "mkdosfs %s -i %s %s %s -C %s %d" % \
+                    (label_str, self.fsuuid, size_str, extraopts, rootfs,
+                     max(8250, rootfs_size))
+        exec_native_cmd(dosfs_cmd, native_sysroot)
+
+        mcopy_cmd = "mcopy -i %s -s %s/* ::/" % (rootfs, rootfs_dir)
+        exec_native_cmd(mcopy_cmd, native_sysroot)
+
+        chmod_cmd = "chmod 644 %s" % rootfs
+        exec_cmd(chmod_cmd)
+
+    prepare_rootfs_vfat = prepare_rootfs_msdos
+
+    def prepare_rootfs_squashfs(self, rootfs, oe_builddir, rootfs_dir,
+                                native_sysroot, pseudo):
+        """
+        Prepare content for a squashfs rootfs partition.
+        """
+        extraopts = self.mkfs_extraopts or '-noappend'
+        squashfs_cmd = "mksquashfs %s %s %s" % \
+                       (rootfs_dir, rootfs, extraopts)
+        exec_native_cmd(squashfs_cmd, native_sysroot, pseudo=pseudo)
+
+    def prepare_empty_partition_ext(self, rootfs, oe_builddir,
+                                    native_sysroot):
+        """
+        Prepare an empty ext2/3/4 partition.
+        """
+        size = self.disk_size
+        with open(rootfs, 'w') as sparse:
+            os.ftruncate(sparse.fileno(), size * 1024)
+
+        extraopts = self.mkfs_extraopts or "-i 8192"
+
+        label_str = ""
+        if self.label:
+            label_str = "-L %s" % self.label
+
+        mkfs_cmd = "mkfs.%s -F %s %s -U %s %s" % \
+            (self.fstype, extraopts, label_str, self.fsuuid, rootfs)
+        exec_native_cmd(mkfs_cmd, native_sysroot)
+
+    def prepare_empty_partition_btrfs(self, rootfs, oe_builddir,
+                                      native_sysroot):
+        """
+        Prepare an empty btrfs partition.
+        """
+        size = self.disk_size
+        with open(rootfs, 'w') as sparse:
+            os.ftruncate(sparse.fileno(), size * 1024)
+
+        label_str = ""
+        if self.label:
+            label_str = "-L %s" % self.label
+
+        mkfs_cmd = "mkfs.%s -b %d %s -U %s %s %s" % \
+                   (self.fstype, self.size * 1024, label_str, self.fsuuid,
+                    self.mkfs_extraopts, rootfs)
+        exec_native_cmd(mkfs_cmd, native_sysroot)
+
+    def prepare_empty_partition_msdos(self, rootfs, oe_builddir,
+                                      native_sysroot):
+        """
+        Prepare an empty vfat partition.
+        """
+        blocks = self.disk_size
+
+        label_str = "-n boot"
+        if self.label:
+            label_str = "-n %s" % self.label
+
+        size_str = ""
+        if self.fstype == 'msdos':
+            size_str = "-F 16" # FAT 16
+
+        extraopts = self.mkfs_extraopts or '-S 512'
+
+        dosfs_cmd = "mkdosfs %s -i %s %s %s -C %s %d" % \
+                    (label_str, self.fsuuid, extraopts, size_str, rootfs,
+                     blocks)
+
+        exec_native_cmd(dosfs_cmd, native_sysroot)
+
+        chmod_cmd = "chmod 644 %s" % rootfs
+        exec_cmd(chmod_cmd)
+
+    prepare_empty_partition_vfat = prepare_empty_partition_msdos
+
+    def prepare_swap_partition(self, cr_workdir, oe_builddir, native_sysroot):
+        """
+        Prepare a swap partition.
+        """
+        path = "%s/fs.%s" % (cr_workdir, self.fstype)
+
+        with open(path, 'w') as sparse:
+            os.ftruncate(sparse.fileno(), self.size * 1024)
+
+        label_str = ""
+        if self.label:
+            label_str = "-L %s" % self.label
+
+        mkswap_cmd = "mkswap %s -U %s %s" % (label_str, self.fsuuid, path)
+        exec_native_cmd(mkswap_cmd, native_sysroot)
diff --git a/meta/poky/scripts/lib/wic/pluginbase.py b/meta/poky/scripts/lib/wic/pluginbase.py
new file mode 100644
index 0000000..686d2fe
--- /dev/null
+++ b/meta/poky/scripts/lib/wic/pluginbase.py
@@ -0,0 +1,149 @@
+#!/usr/bin/env python -tt
+#
+# Copyright (c) 2011 Intel, Inc.
+#
+# This program is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by the Free
+# Software Foundation; version 2 of the License
+#
+# 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.
+
+__all__ = ['ImagerPlugin', 'SourcePlugin']
+
+import os
+import logging
+
+from collections import defaultdict
+from importlib.machinery import SourceFileLoader
+
+from wic import WicError
+from wic.misc import get_bitbake_var
+
+PLUGIN_TYPES = ["imager", "source"]
+
+SCRIPTS_PLUGIN_DIR = "scripts/lib/wic/plugins"
+
+logger = logging.getLogger('wic')
+
+PLUGINS = defaultdict(dict)
+
+class PluginMgr:
+    _plugin_dirs = []
+
+    @classmethod
+    def get_plugins(cls, ptype):
+        """Get dictionary of <plugin_name>:<class> pairs."""
+        if ptype not in PLUGIN_TYPES:
+            raise WicError('%s is not valid plugin type' % ptype)
+
+        # collect plugin directories
+        if not cls._plugin_dirs:
+            cls._plugin_dirs = [os.path.join(os.path.dirname(__file__), 'plugins')]
+            layers = get_bitbake_var("BBLAYERS") or ''
+            for layer_path in layers.split():
+                path = os.path.join(layer_path, SCRIPTS_PLUGIN_DIR)
+                path = os.path.abspath(os.path.expanduser(path))
+                if path not in cls._plugin_dirs and os.path.isdir(path):
+                    cls._plugin_dirs.insert(0, path)
+
+        if ptype not in PLUGINS:
+            # load all ptype plugins
+            for pdir in cls._plugin_dirs:
+                ppath = os.path.join(pdir, ptype)
+                if os.path.isdir(ppath):
+                    for fname in os.listdir(ppath):
+                        if fname.endswith('.py'):
+                            mname = fname[:-3]
+                            mpath = os.path.join(ppath, fname)
+                            logger.debug("loading plugin module %s", mpath)
+                            SourceFileLoader(mname, mpath).load_module()
+
+        return PLUGINS.get(ptype)
+
+class PluginMeta(type):
+    def __new__(cls, name, bases, attrs):
+        class_type = type.__new__(cls, name, bases, attrs)
+        if 'name' in attrs:
+            PLUGINS[class_type.wic_plugin_type][attrs['name']] = class_type
+
+        return class_type
+
+class ImagerPlugin(metaclass=PluginMeta):
+    wic_plugin_type = "imager"
+
+    def do_create(self):
+        raise WicError("Method %s.do_create is not implemented" %
+                       self.__class__.__name__)
+
+class SourcePlugin(metaclass=PluginMeta):
+    wic_plugin_type = "source"
+    """
+    The methods that can be implemented by --source plugins.
+
+    Any methods not implemented in a subclass inherit these.
+    """
+
+    @classmethod
+    def do_install_disk(cls, disk, disk_name, creator, workdir, oe_builddir,
+                        bootimg_dir, kernel_dir, native_sysroot):
+        """
+        Called after all partitions have been prepared and assembled into a
+        disk image.  This provides a hook to allow finalization of a
+        disk image e.g. to write an MBR to it.
+        """
+        logger.debug("SourcePlugin: do_install_disk: disk: %s", disk_name)
+
+    @classmethod
+    def do_stage_partition(cls, part, source_params, creator, cr_workdir,
+                           oe_builddir, bootimg_dir, kernel_dir,
+                           native_sysroot):
+        """
+        Special content staging hook called before do_prepare_partition(),
+        normally empty.
+
+        Typically, a partition will just use the passed-in parame e.g
+        straight bootimg_dir, etc, but in some cases, things need to
+        be more tailored e.g. to use a deploy dir + /boot, etc.  This
+        hook allows those files to be staged in a customized fashion.
+        Not that get_bitbake_var() allows you to acces non-standard
+        variables that you might want to use for this.
+        """
+        logger.debug("SourcePlugin: do_stage_partition: part: %s", part)
+
+    @classmethod
+    def do_configure_partition(cls, part, source_params, creator, cr_workdir,
+                               oe_builddir, bootimg_dir, kernel_dir,
+                               native_sysroot):
+        """
+        Called before do_prepare_partition(), typically used to create
+        custom configuration files for a partition, for example
+        syslinux or grub config files.
+        """
+        logger.debug("SourcePlugin: do_configure_partition: part: %s", part)
+
+    @classmethod
+    def do_prepare_partition(cls, part, source_params, creator, cr_workdir,
+                             oe_builddir, bootimg_dir, kernel_dir, rootfs_dir,
+                             native_sysroot):
+        """
+        Called to do the actual content population for a partition i.e. it
+        'prepares' the partition to be incorporated into the image.
+        """
+        logger.debug("SourcePlugin: do_prepare_partition: part: %s", part)
+
+    @classmethod
+    def do_post_partition(cls, part, source_params, creator, cr_workdir,
+                             oe_builddir, bootimg_dir, kernel_dir, rootfs_dir,
+                             native_sysroot):
+        """
+        Called after the partition is created. It is useful to add post
+        operations e.g. security signing the partition.
+        """
+        logger.debug("SourcePlugin: do_post_partition: part: %s", part)
diff --git a/meta/poky/scripts/lib/wic/plugins/imager/direct.py b/meta/poky/scripts/lib/wic/plugins/imager/direct.py
new file mode 100644
index 0000000..bb14a33
--- /dev/null
+++ b/meta/poky/scripts/lib/wic/plugins/imager/direct.py
@@ -0,0 +1,613 @@
+# ex:ts=4:sw=4:sts=4:et
+# -*- tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*-
+#
+# Copyright (c) 2013, Intel Corporation.
+# All rights reserved.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License 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.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# DESCRIPTION
+# This implements the 'direct' imager plugin class for 'wic'
+#
+# AUTHORS
+# Tom Zanussi <tom.zanussi (at] linux.intel.com>
+#
+
+import logging
+import os
+import random
+import shutil
+import tempfile
+import uuid
+
+from time import strftime
+
+from oe.path import copyhardlinktree
+
+from wic import WicError
+from wic.filemap import sparse_copy
+from wic.ksparser import KickStart, KickStartError
+from wic.pluginbase import PluginMgr, ImagerPlugin
+from wic.misc import get_bitbake_var, exec_cmd, exec_native_cmd
+
+logger = logging.getLogger('wic')
+
+class DirectPlugin(ImagerPlugin):
+    """
+    Install a system into a file containing a partitioned disk image.
+
+    An image file is formatted with a partition table, each partition
+    created from a rootfs or other OpenEmbedded build artifact and dd'ed
+    into the virtual disk. The disk image can subsequently be dd'ed onto
+    media and used on actual hardware.
+    """
+    name = 'direct'
+
+    def __init__(self, wks_file, rootfs_dir, bootimg_dir, kernel_dir,
+                 native_sysroot, oe_builddir, options):
+        try:
+            self.ks = KickStart(wks_file)
+        except KickStartError as err:
+            raise WicError(str(err))
+
+        # parse possible 'rootfs=name' items
+        self.rootfs_dir = dict(rdir.split('=') for rdir in rootfs_dir.split(' '))
+        self.replaced_rootfs_paths = {}
+        self.bootimg_dir = bootimg_dir
+        self.kernel_dir = kernel_dir
+        self.native_sysroot = native_sysroot
+        self.oe_builddir = oe_builddir
+
+        self.outdir = options.outdir
+        self.compressor = options.compressor
+        self.bmap = options.bmap
+        self.no_fstab_update = options.no_fstab_update
+
+        self.name = "%s-%s" % (os.path.splitext(os.path.basename(wks_file))[0],
+                               strftime("%Y%m%d%H%M"))
+        self.workdir = tempfile.mkdtemp(dir=self.outdir, prefix='tmp.wic.')
+        self._image = None
+        self.ptable_format = self.ks.bootloader.ptable
+        self.parts = self.ks.partitions
+
+        # as a convenience, set source to the boot partition source
+        # instead of forcing it to be set via bootloader --source
+        for part in self.parts:
+            if not self.ks.bootloader.source and part.mountpoint == "/boot":
+                self.ks.bootloader.source = part.source
+                break
+
+        image_path = self._full_path(self.workdir, self.parts[0].disk, "direct")
+        self._image = PartitionedImage(image_path, self.ptable_format,
+                                       self.parts, self.native_sysroot)
+
+    def do_create(self):
+        """
+        Plugin entry point.
+        """
+        try:
+            self.create()
+            self.assemble()
+            self.finalize()
+            self.print_info()
+        finally:
+            self.cleanup()
+
+    def _write_fstab(self, image_rootfs):
+        """overriden to generate fstab (temporarily) in rootfs. This is called
+        from _create, make sure it doesn't get called from
+        BaseImage.create()
+        """
+        if not image_rootfs:
+            return
+
+        fstab_path = image_rootfs + "/etc/fstab"
+        if not os.path.isfile(fstab_path):
+            return
+
+        with open(fstab_path) as fstab:
+            fstab_lines = fstab.readlines()
+
+        if self._update_fstab(fstab_lines, self.parts):
+            # copy rootfs dir to workdir to update fstab
+            # as rootfs can be used by other tasks and can't be modified
+            new_pseudo = os.path.realpath(os.path.join(self.workdir, "pseudo"))
+            from_dir = os.path.join(os.path.join(image_rootfs, ".."), "pseudo")
+            from_dir = os.path.realpath(from_dir)
+            copyhardlinktree(from_dir, new_pseudo)
+            new_rootfs = os.path.realpath(os.path.join(self.workdir, "rootfs_copy"))
+            copyhardlinktree(image_rootfs, new_rootfs)
+            fstab_path = os.path.join(new_rootfs, 'etc/fstab')
+
+            os.unlink(fstab_path)
+
+            with open(fstab_path, "w") as fstab:
+                fstab.writelines(fstab_lines)
+
+            return new_rootfs
+
+    def _update_fstab(self, fstab_lines, parts):
+        """Assume partition order same as in wks"""
+        updated = False
+        for part in parts:
+            if not part.realnum or not part.mountpoint \
+               or part.mountpoint == "/":
+                continue
+
+            if part.use_uuid:
+                if part.fsuuid:
+                    # FAT UUID is different from others
+                    if len(part.fsuuid) == 10:
+                        device_name = "UUID=%s-%s" % \
+                                       (part.fsuuid[2:6], part.fsuuid[6:])
+                    else:
+                        device_name = "UUID=%s" % part.fsuuid
+                else:
+                    device_name = "PARTUUID=%s" % part.uuid
+            elif part.use_label:
+                device_name = "LABEL=%s" % part.label
+            else:
+                # mmc device partitions are named mmcblk0p1, mmcblk0p2..
+                prefix = 'p' if  part.disk.startswith('mmcblk') else ''
+                device_name = "/dev/%s%s%d" % (part.disk, prefix, part.realnum)
+
+            opts = part.fsopts if part.fsopts else "defaults"
+            line = "\t".join([device_name, part.mountpoint, part.fstype,
+                              opts, "0", "0"]) + "\n"
+
+            fstab_lines.append(line)
+            updated = True
+
+        return updated
+
+    def _full_path(self, path, name, extention):
+        """ Construct full file path to a file we generate. """
+        return os.path.join(path, "%s-%s.%s" % (self.name, name, extention))
+
+    #
+    # Actual implemention
+    #
+    def create(self):
+        """
+        For 'wic', we already have our build artifacts - we just create
+        filesystems from the artifacts directly and combine them into
+        a partitioned image.
+        """
+        if self.no_fstab_update:
+            new_rootfs = None
+        else:
+            new_rootfs = self._write_fstab(self.rootfs_dir.get("ROOTFS_DIR"))
+        if new_rootfs:
+            # rootfs was copied to update fstab
+            self.replaced_rootfs_paths[new_rootfs] = self.rootfs_dir['ROOTFS_DIR']
+            self.rootfs_dir['ROOTFS_DIR'] = new_rootfs
+
+        for part in self.parts:
+            # get rootfs size from bitbake variable if it's not set in .ks file
+            if not part.size:
+                # and if rootfs name is specified for the partition
+                image_name = self.rootfs_dir.get(part.rootfs_dir)
+                if image_name and os.path.sep not in image_name:
+                    # Bitbake variable ROOTFS_SIZE is calculated in
+                    # Image._get_rootfs_size method from meta/lib/oe/image.py
+                    # using IMAGE_ROOTFS_SIZE, IMAGE_ROOTFS_ALIGNMENT,
+                    # IMAGE_OVERHEAD_FACTOR and IMAGE_ROOTFS_EXTRA_SPACE
+                    rsize_bb = get_bitbake_var('ROOTFS_SIZE', image_name)
+                    if rsize_bb:
+                        part.size = int(round(float(rsize_bb)))
+
+        self._image.prepare(self)
+        self._image.layout_partitions()
+        self._image.create()
+
+    def assemble(self):
+        """
+        Assemble partitions into disk image
+        """
+        self._image.assemble()
+
+    def finalize(self):
+        """
+        Finalize the disk image.
+
+        For example, prepare the image to be bootable by e.g.
+        creating and installing a bootloader configuration.
+        """
+        source_plugin = self.ks.bootloader.source
+        disk_name = self.parts[0].disk
+        if source_plugin:
+            plugin = PluginMgr.get_plugins('source')[source_plugin]
+            plugin.do_install_disk(self._image, disk_name, self, self.workdir,
+                                   self.oe_builddir, self.bootimg_dir,
+                                   self.kernel_dir, self.native_sysroot)
+
+        full_path = self._image.path
+        # Generate .bmap
+        if self.bmap:
+            logger.debug("Generating bmap file for %s", disk_name)
+            python = os.path.join(self.native_sysroot, 'usr/bin/python3-native/python3')
+            bmaptool = os.path.join(self.native_sysroot, 'usr/bin/bmaptool')
+            exec_native_cmd("%s %s create %s -o %s.bmap" % \
+                            (python, bmaptool, full_path, full_path), self.native_sysroot)
+        # Compress the image
+        if self.compressor:
+            logger.debug("Compressing disk %s with %s", disk_name, self.compressor)
+            exec_cmd("%s %s" % (self.compressor, full_path))
+
+    def print_info(self):
+        """
+        Print the image(s) and artifacts used, for the user.
+        """
+        msg = "The new image(s) can be found here:\n"
+
+        extension = "direct" + {"gzip": ".gz",
+                                "bzip2": ".bz2",
+                                "xz": ".xz",
+                                None: ""}.get(self.compressor)
+        full_path = self._full_path(self.outdir, self.parts[0].disk, extension)
+        msg += '  %s\n\n' % full_path
+
+        msg += 'The following build artifacts were used to create the image(s):\n'
+        for part in self.parts:
+            if part.rootfs_dir is None:
+                continue
+            if part.mountpoint == '/':
+                suffix = ':'
+            else:
+                suffix = '["%s"]:' % (part.mountpoint or part.label)
+            rootdir = part.rootfs_dir
+            if rootdir in self.replaced_rootfs_paths:
+                rootdir = self.replaced_rootfs_paths[rootdir]
+            msg += '  ROOTFS_DIR%s%s\n' % (suffix.ljust(20), rootdir)
+
+        msg += '  BOOTIMG_DIR:                  %s\n' % self.bootimg_dir
+        msg += '  KERNEL_DIR:                   %s\n' % self.kernel_dir
+        msg += '  NATIVE_SYSROOT:               %s\n' % self.native_sysroot
+
+        logger.info(msg)
+
+    @property
+    def rootdev(self):
+        """
+        Get root device name to use as a 'root' parameter
+        in kernel command line.
+
+        Assume partition order same as in wks
+        """
+        for part in self.parts:
+            if part.mountpoint == "/":
+                if part.uuid:
+                    return "PARTUUID=%s" % part.uuid
+                else:
+                    suffix = 'p' if part.disk.startswith('mmcblk') else ''
+                    return "/dev/%s%s%-d" % (part.disk, suffix, part.realnum)
+
+    def cleanup(self):
+        if self._image:
+            self._image.cleanup()
+
+        # Move results to the output dir
+        if not os.path.exists(self.outdir):
+            os.makedirs(self.outdir)
+
+        for fname in os.listdir(self.workdir):
+            path = os.path.join(self.workdir, fname)
+            if os.path.isfile(path):
+                shutil.move(path, os.path.join(self.outdir, fname))
+
+        # remove work directory
+        shutil.rmtree(self.workdir, ignore_errors=True)
+
+# Overhead of the MBR partitioning scheme (just one sector)
+MBR_OVERHEAD = 1
+
+# Overhead of the GPT partitioning scheme
+GPT_OVERHEAD = 34
+
+# Size of a sector in bytes
+SECTOR_SIZE = 512
+
+class PartitionedImage():
+    """
+    Partitioned image in a file.
+    """
+
+    def __init__(self, path, ptable_format, partitions, native_sysroot=None):
+        self.path = path  # Path to the image file
+        self.numpart = 0  # Number of allocated partitions
+        self.realpart = 0 # Number of partitions in the partition table
+        self.offset = 0   # Offset of next partition (in sectors)
+        self.min_size = 0 # Minimum required disk size to fit
+                          # all partitions (in bytes)
+        self.ptable_format = ptable_format  # Partition table format
+        # Disk system identifier
+        self.identifier = random.SystemRandom().randint(1, 0xffffffff)
+
+        self.partitions = partitions
+        self.partimages = []
+        # Size of a sector used in calculations
+        self.sector_size = SECTOR_SIZE
+        self.native_sysroot = native_sysroot
+
+        # calculate the real partition number, accounting for partitions not
+        # in the partition table and logical partitions
+        realnum = 0
+        for part in self.partitions:
+            if part.no_table:
+                part.realnum = 0
+            else:
+                realnum += 1
+                if self.ptable_format == 'msdos' and realnum > 3 and len(partitions) > 4:
+                    part.realnum = realnum + 1
+                    continue
+                part.realnum = realnum
+
+        # generate parition and filesystem UUIDs
+        for part in self.partitions:
+            if not part.uuid and part.use_uuid:
+                if self.ptable_format == 'gpt':
+                    part.uuid = str(uuid.uuid4())
+                else: # msdos partition table
+                    part.uuid = '%08x-%02d' % (self.identifier, part.realnum)
+            if not part.fsuuid:
+                if part.fstype == 'vfat' or part.fstype == 'msdos':
+                    part.fsuuid = '0x' + str(uuid.uuid4())[:8].upper()
+                else:
+                    part.fsuuid = str(uuid.uuid4())
+
+    def prepare(self, imager):
+        """Prepare an image. Call prepare method of all image partitions."""
+        for part in self.partitions:
+            # need to create the filesystems in order to get their
+            # sizes before we can add them and do the layout.
+            part.prepare(imager, imager.workdir, imager.oe_builddir,
+                         imager.rootfs_dir, imager.bootimg_dir,
+                         imager.kernel_dir, imager.native_sysroot)
+
+            # Converting kB to sectors for parted
+            part.size_sec = part.disk_size * 1024 // self.sector_size
+
+    def layout_partitions(self):
+        """ Layout the partitions, meaning calculate the position of every
+        partition on the disk. The 'ptable_format' parameter defines the
+        partition table format and may be "msdos". """
+
+        logger.debug("Assigning %s partitions to disks", self.ptable_format)
+
+        # The number of primary and logical partitions. Extended partition and
+        # partitions not listed in the table are not included.
+        num_real_partitions = len([p for p in self.partitions if not p.no_table])
+
+        # Go through partitions in the order they are added in .ks file
+        for num in range(len(self.partitions)):
+            part = self.partitions[num]
+
+            if self.ptable_format == 'msdos' and part.part_name:
+                raise WicError("setting custom partition name is not " \
+                               "implemented for msdos partitions")
+
+            if self.ptable_format == 'msdos' and part.part_type:
+                # The --part-type can also be implemented for MBR partitions,
+                # in which case it would map to the 1-byte "partition type"
+                # filed at offset 3 of the partition entry.
+                raise WicError("setting custom partition type is not " \
+                               "implemented for msdos partitions")
+
+            # Get the disk where the partition is located
+            self.numpart += 1
+            if not part.no_table:
+                self.realpart += 1
+
+            if self.numpart == 1:
+                if self.ptable_format == "msdos":
+                    overhead = MBR_OVERHEAD
+                elif self.ptable_format == "gpt":
+                    overhead = GPT_OVERHEAD
+
+                # Skip one sector required for the partitioning scheme overhead
+                self.offset += overhead
+
+            if self.realpart > 3 and num_real_partitions > 4:
+                # Reserve a sector for EBR for every logical partition
+                # before alignment is performed.
+                if self.ptable_format == "msdos":
+                    self.offset += 1
+
+            if part.align:
+                # If not first partition and we do have alignment set we need
+                # to align the partition.
+                # FIXME: This leaves a empty spaces to the disk. To fill the
+                # gaps we could enlargea the previous partition?
+
+                # Calc how much the alignment is off.
+                align_sectors = self.offset % (part.align * 1024 // self.sector_size)
+
+                if align_sectors:
+                    # If partition is not aligned as required, we need
+                    # to move forward to the next alignment point
+                    align_sectors = (part.align * 1024 // self.sector_size) - align_sectors
+
+                    logger.debug("Realignment for %s%s with %s sectors, original"
+                                 " offset %s, target alignment is %sK.",
+                                 part.disk, self.numpart, align_sectors,
+                                 self.offset, part.align)
+
+                    # increase the offset so we actually start the partition on right alignment
+                    self.offset += align_sectors
+
+            part.start = self.offset
+            self.offset += part.size_sec
+
+            part.type = 'primary'
+            if not part.no_table:
+                part.num = self.realpart
+            else:
+                part.num = 0
+
+            if self.ptable_format == "msdos":
+                # only count the partitions that are in partition table
+                if num_real_partitions > 4:
+                    if self.realpart > 3:
+                        part.type = 'logical'
+                        part.num = self.realpart + 1
+
+            logger.debug("Assigned %s to %s%d, sectors range %d-%d size %d "
+                         "sectors (%d bytes).", part.mountpoint, part.disk,
+                         part.num, part.start, self.offset - 1, part.size_sec,
+                         part.size_sec * self.sector_size)
+
+        # Once all the partitions have been layed out, we can calculate the
+        # minumim disk size
+        self.min_size = self.offset
+        if self.ptable_format == "gpt":
+            self.min_size += GPT_OVERHEAD
+
+        self.min_size *= self.sector_size
+
+    def _create_partition(self, device, parttype, fstype, start, size):
+        """ Create a partition on an image described by the 'device' object. """
+
+        # Start is included to the size so we need to substract one from the end.
+        end = start + size - 1
+        logger.debug("Added '%s' partition, sectors %d-%d, size %d sectors",
+                     parttype, start, end, size)
+
+        cmd = "parted -s %s unit s mkpart %s" % (device, parttype)
+        if fstype:
+            cmd += " %s" % fstype
+        cmd += " %d %d" % (start, end)
+
+        return exec_native_cmd(cmd, self.native_sysroot)
+
+    def create(self):
+        logger.debug("Creating sparse file %s", self.path)
+        with open(self.path, 'w') as sparse:
+            os.ftruncate(sparse.fileno(), self.min_size)
+
+        logger.debug("Initializing partition table for %s", self.path)
+        exec_native_cmd("parted -s %s mklabel %s" %
+                        (self.path, self.ptable_format), self.native_sysroot)
+
+        logger.debug("Set disk identifier %x", self.identifier)
+        with open(self.path, 'r+b') as img:
+            img.seek(0x1B8)
+            img.write(self.identifier.to_bytes(4, 'little'))
+
+        logger.debug("Creating partitions")
+
+        for part in self.partitions:
+            if part.num == 0:
+                continue
+
+            if self.ptable_format == "msdos" and part.num == 5:
+                # Create an extended partition (note: extended
+                # partition is described in MBR and contains all
+                # logical partitions). The logical partitions save a
+                # sector for an EBR just before the start of a
+                # partition. The extended partition must start one
+                # sector before the start of the first logical
+                # partition. This way the first EBR is inside of the
+                # extended partition. Since the extended partitions
+                # starts a sector before the first logical partition,
+                # add a sector at the back, so that there is enough
+                # room for all logical partitions.
+                self._create_partition(self.path, "extended",
+                                       None, part.start - 1,
+                                       self.offset - part.start + 1)
+
+            if part.fstype == "swap":
+                parted_fs_type = "linux-swap"
+            elif part.fstype == "vfat":
+                parted_fs_type = "fat32"
+            elif part.fstype == "msdos":
+                parted_fs_type = "fat16"
+                if not part.system_id:
+                    part.system_id = '0x6' # FAT16
+            else:
+                # Type for ext2/ext3/ext4/btrfs
+                parted_fs_type = "ext2"
+
+            # Boot ROM of OMAP boards require vfat boot partition to have an
+            # even number of sectors.
+            if part.mountpoint == "/boot" and part.fstype in ["vfat", "msdos"] \
+               and part.size_sec % 2:
+                logger.debug("Subtracting one sector from '%s' partition to "
+                             "get even number of sectors for the partition",
+                             part.mountpoint)
+                part.size_sec -= 1
+
+            self._create_partition(self.path, part.type,
+                                   parted_fs_type, part.start, part.size_sec)
+
+            if part.part_name:
+                logger.debug("partition %d: set name to %s",
+                             part.num, part.part_name)
+                exec_native_cmd("sgdisk --change-name=%d:%s %s" % \
+                                         (part.num, part.part_name,
+                                          self.path), self.native_sysroot)
+
+            if part.part_type:
+                logger.debug("partition %d: set type UID to %s",
+                             part.num, part.part_type)
+                exec_native_cmd("sgdisk --typecode=%d:%s %s" % \
+                                         (part.num, part.part_type,
+                                          self.path), self.native_sysroot)
+
+            if part.uuid and self.ptable_format == "gpt":
+                logger.debug("partition %d: set UUID to %s",
+                             part.num, part.uuid)
+                exec_native_cmd("sgdisk --partition-guid=%d:%s %s" % \
+                                (part.num, part.uuid, self.path),
+                                self.native_sysroot)
+
+            if part.label and self.ptable_format == "gpt":
+                logger.debug("partition %d: set name to %s",
+                             part.num, part.label)
+                exec_native_cmd("parted -s %s name %d %s" % \
+                                (self.path, part.num, part.label),
+                                self.native_sysroot)
+
+            if part.active:
+                flag_name = "legacy_boot" if self.ptable_format == 'gpt' else "boot"
+                logger.debug("Set '%s' flag for partition '%s' on disk '%s'",
+                             flag_name, part.num, self.path)
+                exec_native_cmd("parted -s %s set %d %s on" % \
+                                (self.path, part.num, flag_name),
+                                self.native_sysroot)
+            if part.system_id:
+                exec_native_cmd("sfdisk --part-type %s %s %s" % \
+                                (self.path, part.num, part.system_id),
+                                self.native_sysroot)
+
+    def cleanup(self):
+        # remove partition images
+        for image in set(self.partimages):
+            os.remove(image)
+
+    def assemble(self):
+        logger.debug("Installing partitions")
+
+        for part in self.partitions:
+            source = part.source_file
+            if source:
+                # install source_file contents into a partition
+                sparse_copy(source, self.path, seek=part.start * self.sector_size)
+
+                logger.debug("Installed %s in partition %d, sectors %d-%d, "
+                             "size %d sectors", source, part.num, part.start,
+                             part.start + part.size_sec - 1, part.size_sec)
+
+                partimage = self.path + '.p%d' % part.num
+                os.rename(source, partimage)
+                self.partimages.append(partimage)
diff --git a/meta/poky/scripts/lib/wic/plugins/source/bootimg-efi.py b/meta/poky/scripts/lib/wic/plugins/source/bootimg-efi.py
new file mode 100644
index 0000000..1269818
--- /dev/null
+++ b/meta/poky/scripts/lib/wic/plugins/source/bootimg-efi.py
@@ -0,0 +1,276 @@
+# ex:ts=4:sw=4:sts=4:et
+# -*- tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*-
+#
+# Copyright (c) 2014, Intel Corporation.
+# All rights reserved.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License 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.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# DESCRIPTION
+# This implements the 'bootimg-efi' source plugin class for 'wic'
+#
+# AUTHORS
+# Tom Zanussi <tom.zanussi (at] linux.intel.com>
+#
+
+import logging
+import os
+import shutil
+
+from wic import WicError
+from wic.engine import get_custom_config
+from wic.pluginbase import SourcePlugin
+from wic.misc import (exec_cmd, exec_native_cmd,
+                      get_bitbake_var, BOOTDD_EXTRA_SPACE)
+
+logger = logging.getLogger('wic')
+
+class BootimgEFIPlugin(SourcePlugin):
+    """
+    Create EFI boot partition.
+    This plugin supports GRUB 2 and systemd-boot bootloaders.
+    """
+
+    name = 'bootimg-efi'
+
+    @classmethod
+    def do_configure_grubefi(cls, hdddir, creator, cr_workdir, source_params):
+        """
+        Create loader-specific (grub-efi) config
+        """
+        configfile = creator.ks.bootloader.configfile
+        custom_cfg = None
+        if configfile:
+            custom_cfg = get_custom_config(configfile)
+            if custom_cfg:
+                # Use a custom configuration for grub
+                grubefi_conf = custom_cfg
+                logger.debug("Using custom configuration file "
+                             "%s for grub.cfg", configfile)
+            else:
+                raise WicError("configfile is specified but failed to "
+                               "get it from %s." % configfile)
+
+        initrd = source_params.get('initrd')
+
+        if initrd:
+            bootimg_dir = get_bitbake_var("DEPLOY_DIR_IMAGE")
+            if not bootimg_dir:
+                raise WicError("Couldn't find DEPLOY_DIR_IMAGE, exiting")
+
+            cp_cmd = "cp %s/%s %s" % (bootimg_dir, initrd, hdddir)
+            exec_cmd(cp_cmd, True)
+        else:
+            logger.debug("Ignoring missing initrd")
+
+        if not custom_cfg:
+            # Create grub configuration using parameters from wks file
+            bootloader = creator.ks.bootloader
+
+            grubefi_conf = ""
+            grubefi_conf += "serial --unit=0 --speed=115200 --word=8 --parity=no --stop=1\n"
+            grubefi_conf += "default=boot\n"
+            grubefi_conf += "timeout=%s\n" % bootloader.timeout
+            grubefi_conf += "menuentry 'boot'{\n"
+
+            kernel = "/bzImage"
+
+            grubefi_conf += "linux %s root=%s rootwait %s\n" \
+                % (kernel, creator.rootdev, bootloader.append)
+
+            if initrd:
+               grubefi_conf += "initrd /%s\n" % initrd
+
+            grubefi_conf += "}\n"
+
+        logger.debug("Writing grubefi config %s/hdd/boot/EFI/BOOT/grub.cfg",
+                     cr_workdir)
+        cfg = open("%s/hdd/boot/EFI/BOOT/grub.cfg" % cr_workdir, "w")
+        cfg.write(grubefi_conf)
+        cfg.close()
+
+    @classmethod
+    def do_configure_systemdboot(cls, hdddir, creator, cr_workdir, source_params):
+        """
+        Create loader-specific systemd-boot/gummiboot config
+        """
+        install_cmd = "install -d %s/loader" % hdddir
+        exec_cmd(install_cmd)
+
+        install_cmd = "install -d %s/loader/entries" % hdddir
+        exec_cmd(install_cmd)
+
+        bootloader = creator.ks.bootloader
+
+        loader_conf = ""
+        loader_conf += "default boot\n"
+        loader_conf += "timeout %d\n" % bootloader.timeout
+
+        initrd = source_params.get('initrd')
+
+        if initrd:
+            # obviously we need to have a common common deploy var
+            bootimg_dir = get_bitbake_var("DEPLOY_DIR_IMAGE")
+            if not bootimg_dir:
+                raise WicError("Couldn't find DEPLOY_DIR_IMAGE, exiting")
+
+            cp_cmd = "cp %s/%s %s" % (bootimg_dir, initrd, hdddir)
+            exec_cmd(cp_cmd, True)
+        else:
+            logger.debug("Ignoring missing initrd")
+
+        logger.debug("Writing systemd-boot config "
+                     "%s/hdd/boot/loader/loader.conf", cr_workdir)
+        cfg = open("%s/hdd/boot/loader/loader.conf" % cr_workdir, "w")
+        cfg.write(loader_conf)
+        cfg.close()
+
+        configfile = creator.ks.bootloader.configfile
+        custom_cfg = None
+        if configfile:
+            custom_cfg = get_custom_config(configfile)
+            if custom_cfg:
+                # Use a custom configuration for systemd-boot
+                boot_conf = custom_cfg
+                logger.debug("Using custom configuration file "
+                             "%s for systemd-boots's boot.conf", configfile)
+            else:
+                raise WicError("configfile is specified but failed to "
+                               "get it from %s.", configfile)
+
+        if not custom_cfg:
+            # Create systemd-boot configuration using parameters from wks file
+            kernel = "/bzImage"
+
+            boot_conf = ""
+            boot_conf += "title boot\n"
+            boot_conf += "linux %s\n" % kernel
+            boot_conf += "options LABEL=Boot root=%s %s\n" % \
+                             (creator.rootdev, bootloader.append)
+
+            if initrd:
+                boot_conf += "initrd /%s\n" % initrd
+
+        logger.debug("Writing systemd-boot config "
+                     "%s/hdd/boot/loader/entries/boot.conf", cr_workdir)
+        cfg = open("%s/hdd/boot/loader/entries/boot.conf" % cr_workdir, "w")
+        cfg.write(boot_conf)
+        cfg.close()
+
+
+    @classmethod
+    def do_configure_partition(cls, part, source_params, creator, cr_workdir,
+                               oe_builddir, bootimg_dir, kernel_dir,
+                               native_sysroot):
+        """
+        Called before do_prepare_partition(), creates loader-specific config
+        """
+        hdddir = "%s/hdd/boot" % cr_workdir
+
+        install_cmd = "install -d %s/EFI/BOOT" % hdddir
+        exec_cmd(install_cmd)
+
+        try:
+            if source_params['loader'] == 'grub-efi':
+                cls.do_configure_grubefi(hdddir, creator, cr_workdir, source_params)
+            elif source_params['loader'] == 'systemd-boot':
+                cls.do_configure_systemdboot(hdddir, creator, cr_workdir, source_params)
+            else:
+                raise WicError("unrecognized bootimg-efi loader: %s" % source_params['loader'])
+        except KeyError:
+            raise WicError("bootimg-efi requires a loader, none specified")
+
+
+    @classmethod
+    def do_prepare_partition(cls, part, source_params, creator, cr_workdir,
+                             oe_builddir, bootimg_dir, kernel_dir,
+                             rootfs_dir, native_sysroot):
+        """
+        Called to do the actual content population for a partition i.e. it
+        'prepares' the partition to be incorporated into the image.
+        In this case, prepare content for an EFI (grub) boot partition.
+        """
+        if not kernel_dir:
+            kernel_dir = get_bitbake_var("DEPLOY_DIR_IMAGE")
+            if not kernel_dir:
+                raise WicError("Couldn't find DEPLOY_DIR_IMAGE, exiting")
+
+        staging_kernel_dir = kernel_dir
+
+        hdddir = "%s/hdd/boot" % cr_workdir
+
+        install_cmd = "install -m 0644 %s/bzImage %s/bzImage" % \
+            (staging_kernel_dir, hdddir)
+        exec_cmd(install_cmd)
+
+
+        try:
+            if source_params['loader'] == 'grub-efi':
+                shutil.copyfile("%s/hdd/boot/EFI/BOOT/grub.cfg" % cr_workdir,
+                                "%s/grub.cfg" % cr_workdir)
+                for mod in [x for x in os.listdir(kernel_dir) if x.startswith("grub-efi-")]:
+                    cp_cmd = "cp %s/%s %s/EFI/BOOT/%s" % (kernel_dir, mod, hdddir, mod[9:])
+                    exec_cmd(cp_cmd, True)
+                shutil.move("%s/grub.cfg" % cr_workdir,
+                            "%s/hdd/boot/EFI/BOOT/grub.cfg" % cr_workdir)
+            elif source_params['loader'] == 'systemd-boot':
+                for mod in [x for x in os.listdir(kernel_dir) if x.startswith("systemd-")]:
+                    cp_cmd = "cp %s/%s %s/EFI/BOOT/%s" % (kernel_dir, mod, hdddir, mod[8:])
+                    exec_cmd(cp_cmd, True)
+            else:
+                raise WicError("unrecognized bootimg-efi loader: %s" %
+                               source_params['loader'])
+        except KeyError:
+            raise WicError("bootimg-efi requires a loader, none specified")
+
+        startup = os.path.join(kernel_dir, "startup.nsh")
+        if os.path.exists(startup):
+            cp_cmd = "cp %s %s/" % (startup, hdddir)
+            exec_cmd(cp_cmd, True)
+
+        du_cmd = "du -bks %s" % hdddir
+        out = exec_cmd(du_cmd)
+        blocks = int(out.split()[0])
+
+        extra_blocks = part.get_extra_block_count(blocks)
+
+        if extra_blocks < BOOTDD_EXTRA_SPACE:
+            extra_blocks = BOOTDD_EXTRA_SPACE
+
+        blocks += extra_blocks
+
+        logger.debug("Added %d extra blocks to %s to get to %d total blocks",
+                     extra_blocks, part.mountpoint, blocks)
+
+        # dosfs image, created by mkdosfs
+        bootimg = "%s/boot.img" % cr_workdir
+
+        label = part.label if part.label else "ESP"
+
+        dosfs_cmd = "mkdosfs -n %s -i %s -C %s %d" % \
+                    (label, part.fsuuid, bootimg, blocks)
+        exec_native_cmd(dosfs_cmd, native_sysroot)
+
+        mcopy_cmd = "mcopy -i %s -s %s/* ::/" % (bootimg, hdddir)
+        exec_native_cmd(mcopy_cmd, native_sysroot)
+
+        chmod_cmd = "chmod 644 %s" % bootimg
+        exec_cmd(chmod_cmd)
+
+        du_cmd = "du -Lbks %s" % bootimg
+        out = exec_cmd(du_cmd)
+        bootimg_size = out.split()[0]
+
+        part.size = int(bootimg_size)
+        part.source_file = bootimg
diff --git a/meta/poky/scripts/lib/wic/plugins/source/bootimg-partition.py b/meta/poky/scripts/lib/wic/plugins/source/bootimg-partition.py
new file mode 100644
index 0000000..ddc880b
--- /dev/null
+++ b/meta/poky/scripts/lib/wic/plugins/source/bootimg-partition.py
@@ -0,0 +1,207 @@
+# ex:ts=4:sw=4:sts=4:et
+# -*- tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*-
+#
+# 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.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# DESCRIPTION
+# This implements the 'bootimg-partition' source plugin class for
+# 'wic'. The plugin creates an image of boot partition, copying over
+# files listed in IMAGE_BOOT_FILES bitbake variable.
+#
+# AUTHORS
+# Maciej Borzecki <maciej.borzecki (at] open-rnd.pl>
+#
+
+import logging
+import os
+import re
+
+from glob import glob
+
+from wic import WicError
+from wic.engine import get_custom_config
+from wic.pluginbase import SourcePlugin
+from wic.misc import exec_cmd, get_bitbake_var
+
+logger = logging.getLogger('wic')
+
+class BootimgPartitionPlugin(SourcePlugin):
+    """
+    Create an image of boot partition, copying over files
+    listed in IMAGE_BOOT_FILES bitbake variable.
+    """
+
+    name = 'bootimg-partition'
+
+    @classmethod
+    def do_configure_partition(cls, part, source_params, cr, cr_workdir,
+                             oe_builddir, bootimg_dir, kernel_dir,
+                             native_sysroot):
+        """
+        Called before do_prepare_partition(), create u-boot specific boot config
+        """
+        hdddir = "%s/boot.%d" % (cr_workdir, part.lineno)
+        install_cmd = "install -d %s" % hdddir
+        exec_cmd(install_cmd)
+
+        if not kernel_dir:
+            kernel_dir = get_bitbake_var("DEPLOY_DIR_IMAGE")
+            if not kernel_dir:
+                raise WicError("Couldn't find DEPLOY_DIR_IMAGE, exiting")
+
+        boot_files = None
+        for (fmt, id) in (("_uuid-%s", part.uuid), ("_label-%s", part.label), (None, None)):
+            if fmt:
+                var = fmt % id
+            else:
+                var = ""
+
+            boot_files = get_bitbake_var("IMAGE_BOOT_FILES" + var)
+            if boot_files is not None:
+                break
+
+        if boot_files is None:
+            raise WicError('No boot files defined, IMAGE_BOOT_FILES unset for entry #%d' % part.lineno)
+
+        logger.debug('Boot files: %s', boot_files)
+
+        # list of tuples (src_name, dst_name)
+        deploy_files = []
+        for src_entry in re.findall(r'[\w;\-\./\*]+', boot_files):
+            if ';' in src_entry:
+                dst_entry = tuple(src_entry.split(';'))
+                if not dst_entry[0] or not dst_entry[1]:
+                    raise WicError('Malformed boot file entry: %s' % src_entry)
+            else:
+                dst_entry = (src_entry, src_entry)
+
+            logger.debug('Destination entry: %r', dst_entry)
+            deploy_files.append(dst_entry)
+
+        cls.install_task = [];
+        for deploy_entry in deploy_files:
+            src, dst = deploy_entry
+            if '*' in src:
+                # by default install files under their basename
+                entry_name_fn = os.path.basename
+                if dst != src:
+                    # unless a target name was given, then treat name
+                    # as a directory and append a basename
+                    entry_name_fn = lambda name: \
+                                    os.path.join(dst,
+                                                 os.path.basename(name))
+
+                srcs = glob(os.path.join(kernel_dir, src))
+
+                logger.debug('Globbed sources: %s', ', '.join(srcs))
+                for entry in srcs:
+                    src = os.path.relpath(entry, kernel_dir)
+                    entry_dst_name = entry_name_fn(entry)
+                    cls.install_task.append((src, entry_dst_name))
+            else:
+                cls.install_task.append((src, dst))
+
+        if source_params.get('loader') != "u-boot":
+            return
+
+        configfile = cr.ks.bootloader.configfile
+        custom_cfg = None
+        if configfile:
+            custom_cfg = get_custom_config(configfile)
+            if custom_cfg:
+                # Use a custom configuration for extlinux.conf
+                extlinux_conf = custom_cfg
+                logger.debug("Using custom configuration file "
+                             "%s for extlinux.cfg", configfile)
+            else:
+                raise WicError("configfile is specified but failed to "
+                               "get it from %s." % configfile)
+
+        if not custom_cfg:
+            # The kernel types supported by the sysboot of u-boot
+            kernel_types = ["zImage", "Image", "fitImage", "uImage", "vmlinux"]
+            has_dtb = False
+            fdt_dir = '/'
+            kernel_name = None
+
+            # Find the kernel image name, from the highest precedence to lowest
+            for image in kernel_types:
+                for task in cls.install_task:
+                    src, dst = task
+                    if re.match(image, src):
+                        kernel_name = os.path.join('/', dst)
+                        break
+                if kernel_name:
+                    break
+
+            for task in cls.install_task:
+                src, dst = task
+                # We suppose that all the dtb are in the same directory
+                if re.search(r'\.dtb', src) and fdt_dir == '/':
+                    has_dtb = True
+                    fdt_dir = os.path.join(fdt_dir, os.path.dirname(dst))
+                    break
+
+            if not kernel_name:
+                raise WicError('No kernel file founded')
+
+            # Compose the extlinux.conf
+            extlinux_conf = "default Yocto\n"
+            extlinux_conf += "label Yocto\n"
+            extlinux_conf += "   kernel %s\n" % kernel_name
+            if has_dtb:
+                extlinux_conf += "   fdtdir %s\n" % fdt_dir
+            bootloader = cr.ks.bootloader
+            extlinux_conf += "append root=%s rootwait %s\n" \
+                             % (cr.rootdev, bootloader.append if bootloader.append else '')
+
+        install_cmd = "install -d %s/extlinux/" % hdddir
+        exec_cmd(install_cmd)
+        cfg = open("%s/extlinux/extlinux.conf" % hdddir, "w")
+        cfg.write(extlinux_conf)
+        cfg.close()
+
+
+    @classmethod
+    def do_prepare_partition(cls, part, source_params, cr, cr_workdir,
+                             oe_builddir, bootimg_dir, kernel_dir,
+                             rootfs_dir, native_sysroot):
+        """
+        Called to do the actual content population for a partition i.e. it
+        'prepares' the partition to be incorporated into the image.
+        In this case, does the following:
+        - sets up a vfat partition
+        - copies all files listed in IMAGE_BOOT_FILES variable
+        """
+        hdddir = "%s/boot.%d" % (cr_workdir, part.lineno)
+
+        if not kernel_dir:
+            kernel_dir = get_bitbake_var("DEPLOY_DIR_IMAGE")
+            if not kernel_dir:
+                raise WicError("Couldn't find DEPLOY_DIR_IMAGE, exiting")
+
+        logger.debug('Kernel dir: %s', bootimg_dir)
+
+
+        for task in cls.install_task:
+            src_path, dst_path = task
+            logger.debug('Install %s as %s', src_path, dst_path)
+            install_cmd = "install -m 0644 -D %s %s" \
+                          % (os.path.join(kernel_dir, src_path),
+                             os.path.join(hdddir, dst_path))
+            exec_cmd(install_cmd)
+
+        logger.debug('Prepare boot partition using rootfs in %s', hdddir)
+        part.prepare_rootfs(cr_workdir, oe_builddir, hdddir,
+                            native_sysroot, False)
diff --git a/meta/poky/scripts/lib/wic/plugins/source/bootimg-pcbios.py b/meta/poky/scripts/lib/wic/plugins/source/bootimg-pcbios.py
new file mode 100644
index 0000000..9347aa7
--- /dev/null
+++ b/meta/poky/scripts/lib/wic/plugins/source/bootimg-pcbios.py
@@ -0,0 +1,215 @@
+# ex:ts=4:sw=4:sts=4:et
+# -*- tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*-
+#
+# Copyright (c) 2014, Intel Corporation.
+# All rights reserved.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License 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.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# DESCRIPTION
+# This implements the 'bootimg-pcbios' source plugin class for 'wic'
+#
+# AUTHORS
+# Tom Zanussi <tom.zanussi (at] linux.intel.com>
+#
+
+import logging
+import os
+import re
+
+from wic import WicError
+from wic.engine import get_custom_config
+from wic.pluginbase import SourcePlugin
+from wic.misc import (exec_cmd, exec_native_cmd,
+                      get_bitbake_var, BOOTDD_EXTRA_SPACE)
+
+logger = logging.getLogger('wic')
+
+class BootimgPcbiosPlugin(SourcePlugin):
+    """
+    Create MBR boot partition and install syslinux on it.
+    """
+
+    name = 'bootimg-pcbios'
+
+    @classmethod
+    def _get_bootimg_dir(cls, bootimg_dir, dirname):
+        """
+        Check if dirname exists in default bootimg_dir or in STAGING_DIR.
+        """
+        staging_datadir = get_bitbake_var("STAGING_DATADIR")
+        for result in (bootimg_dir, staging_datadir):
+            if os.path.exists("%s/%s" % (result, dirname)):
+                return result
+
+        # STAGING_DATADIR is expanded with MLPREFIX if multilib is enabled
+        # but dependency syslinux is still populated to original STAGING_DATADIR
+        nonarch_datadir = re.sub('/[^/]*recipe-sysroot', '/recipe-sysroot', staging_datadir)
+        if os.path.exists(os.path.join(nonarch_datadir, dirname)):
+            return nonarch_datadir
+
+        raise WicError("Couldn't find correct bootimg_dir, exiting")
+
+    @classmethod
+    def do_install_disk(cls, disk, disk_name, creator, workdir, oe_builddir,
+                        bootimg_dir, kernel_dir, native_sysroot):
+        """
+        Called after all partitions have been prepared and assembled into a
+        disk image.  In this case, we install the MBR.
+        """
+        bootimg_dir = cls._get_bootimg_dir(bootimg_dir, 'syslinux')
+        mbrfile = "%s/syslinux/" % bootimg_dir
+        if creator.ptable_format == 'msdos':
+            mbrfile += "mbr.bin"
+        elif creator.ptable_format == 'gpt':
+            mbrfile += "gptmbr.bin"
+        else:
+            raise WicError("Unsupported partition table: %s" %
+                           creator.ptable_format)
+
+        if not os.path.exists(mbrfile):
+            raise WicError("Couldn't find %s.  If using the -e option, do you "
+                           "have the right MACHINE set in local.conf?  If not, "
+                           "is the bootimg_dir path correct?" % mbrfile)
+
+        full_path = creator._full_path(workdir, disk_name, "direct")
+        logger.debug("Installing MBR on disk %s as %s with size %s bytes",
+                     disk_name, full_path, disk.min_size)
+
+        dd_cmd = "dd if=%s of=%s conv=notrunc" % (mbrfile, full_path)
+        exec_cmd(dd_cmd, native_sysroot)
+
+    @classmethod
+    def do_configure_partition(cls, part, source_params, creator, cr_workdir,
+                               oe_builddir, bootimg_dir, kernel_dir,
+                               native_sysroot):
+        """
+        Called before do_prepare_partition(), creates syslinux config
+        """
+        hdddir = "%s/hdd/boot" % cr_workdir
+
+        install_cmd = "install -d %s" % hdddir
+        exec_cmd(install_cmd)
+
+        bootloader = creator.ks.bootloader
+
+        custom_cfg = None
+        if bootloader.configfile:
+            custom_cfg = get_custom_config(bootloader.configfile)
+            if custom_cfg:
+                # Use a custom configuration for grub
+                syslinux_conf = custom_cfg
+                logger.debug("Using custom configuration file %s "
+                             "for syslinux.cfg", bootloader.configfile)
+            else:
+                raise WicError("configfile is specified but failed to "
+                               "get it from %s." % bootloader.configfile)
+
+        if not custom_cfg:
+            # Create syslinux configuration using parameters from wks file
+            splash = os.path.join(cr_workdir, "/hdd/boot/splash.jpg")
+            if os.path.exists(splash):
+                splashline = "menu background splash.jpg"
+            else:
+                splashline = ""
+
+            syslinux_conf = ""
+            syslinux_conf += "PROMPT 0\n"
+            syslinux_conf += "TIMEOUT " + str(bootloader.timeout) + "\n"
+            syslinux_conf += "\n"
+            syslinux_conf += "ALLOWOPTIONS 1\n"
+            syslinux_conf += "SERIAL 0 115200\n"
+            syslinux_conf += "\n"
+            if splashline:
+                syslinux_conf += "%s\n" % splashline
+            syslinux_conf += "DEFAULT boot\n"
+            syslinux_conf += "LABEL boot\n"
+
+            kernel = "/vmlinuz"
+            syslinux_conf += "KERNEL " + kernel + "\n"
+
+            syslinux_conf += "APPEND label=boot root=%s %s\n" % \
+                             (creator.rootdev, bootloader.append)
+
+        logger.debug("Writing syslinux config %s/hdd/boot/syslinux.cfg",
+                     cr_workdir)
+        cfg = open("%s/hdd/boot/syslinux.cfg" % cr_workdir, "w")
+        cfg.write(syslinux_conf)
+        cfg.close()
+
+    @classmethod
+    def do_prepare_partition(cls, part, source_params, creator, cr_workdir,
+                             oe_builddir, bootimg_dir, kernel_dir,
+                             rootfs_dir, native_sysroot):
+        """
+        Called to do the actual content population for a partition i.e. it
+        'prepares' the partition to be incorporated into the image.
+        In this case, prepare content for legacy bios boot partition.
+        """
+        bootimg_dir = cls._get_bootimg_dir(bootimg_dir, 'syslinux')
+
+        staging_kernel_dir = kernel_dir
+
+        hdddir = "%s/hdd/boot" % cr_workdir
+
+        cmds = ("install -m 0644 %s/bzImage %s/vmlinuz" %
+                (staging_kernel_dir, hdddir),
+                "install -m 444 %s/syslinux/ldlinux.sys %s/ldlinux.sys" %
+                (bootimg_dir, hdddir),
+                "install -m 0644 %s/syslinux/vesamenu.c32 %s/vesamenu.c32" %
+                (bootimg_dir, hdddir),
+                "install -m 444 %s/syslinux/libcom32.c32 %s/libcom32.c32" %
+                (bootimg_dir, hdddir),
+                "install -m 444 %s/syslinux/libutil.c32 %s/libutil.c32" %
+                (bootimg_dir, hdddir))
+
+        for install_cmd in cmds:
+            exec_cmd(install_cmd)
+
+        du_cmd = "du -bks %s" % hdddir
+        out = exec_cmd(du_cmd)
+        blocks = int(out.split()[0])
+
+        extra_blocks = part.get_extra_block_count(blocks)
+
+        if extra_blocks < BOOTDD_EXTRA_SPACE:
+            extra_blocks = BOOTDD_EXTRA_SPACE
+
+        blocks += extra_blocks
+
+        logger.debug("Added %d extra blocks to %s to get to %d total blocks",
+                     extra_blocks, part.mountpoint, blocks)
+
+        # dosfs image, created by mkdosfs
+        bootimg = "%s/boot%s.img" % (cr_workdir, part.lineno)
+
+        dosfs_cmd = "mkdosfs -n boot -i %s -S 512 -C %s %d" % \
+                    (part.fsuuid, bootimg, blocks)
+        exec_native_cmd(dosfs_cmd, native_sysroot)
+
+        mcopy_cmd = "mcopy -i %s -s %s/* ::/" % (bootimg, hdddir)
+        exec_native_cmd(mcopy_cmd, native_sysroot)
+
+        syslinux_cmd = "syslinux %s" % bootimg
+        exec_native_cmd(syslinux_cmd, native_sysroot)
+
+        chmod_cmd = "chmod 644 %s" % bootimg
+        exec_cmd(chmod_cmd)
+
+        du_cmd = "du -Lbks %s" % bootimg
+        out = exec_cmd(du_cmd)
+        bootimg_size = out.split()[0]
+
+        part.size = int(bootimg_size)
+        part.source_file = bootimg
diff --git a/meta/poky/scripts/lib/wic/plugins/source/isoimage-isohybrid.py b/meta/poky/scripts/lib/wic/plugins/source/isoimage-isohybrid.py
new file mode 100644
index 0000000..170077c
--- /dev/null
+++ b/meta/poky/scripts/lib/wic/plugins/source/isoimage-isohybrid.py
@@ -0,0 +1,442 @@
+# ex:ts=4:sw=4:sts=4:et
+# -*- tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*-
+
+# 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.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# DESCRIPTION
+# This implements the 'isoimage-isohybrid' source plugin class for 'wic'
+#
+# AUTHORS
+# Mihaly Varga <mihaly.varga (at] ni.com>
+
+import glob
+import logging
+import os
+import re
+import shutil
+
+from wic import WicError
+from wic.engine import get_custom_config
+from wic.pluginbase import SourcePlugin
+from wic.misc import exec_cmd, exec_native_cmd, get_bitbake_var
+
+logger = logging.getLogger('wic')
+
+class IsoImagePlugin(SourcePlugin):
+    """
+    Create a bootable ISO image
+
+    This plugin creates a hybrid, legacy and EFI bootable ISO image. The
+    generated image can be used on optical media as well as USB media.
+
+    Legacy boot uses syslinux and EFI boot uses grub or gummiboot (not
+    implemented yet) as bootloader. The plugin creates the directories required
+    by bootloaders and populates them by creating and configuring the
+    bootloader files.
+
+    Example kickstart file:
+    part /boot --source isoimage-isohybrid --sourceparams="loader=grub-efi, \\
+    image_name= IsoImage" --ondisk cd --label LIVECD
+    bootloader  --timeout=10  --append=" "
+
+    In --sourceparams "loader" specifies the bootloader used for booting in EFI
+    mode, while "image_name" specifies the name of the generated image. In the
+    example above, wic creates an ISO image named IsoImage-cd.direct (default
+    extension added by direct imeger plugin) and a file named IsoImage-cd.iso
+    """
+
+    name = 'isoimage-isohybrid'
+
+    @classmethod
+    def do_configure_syslinux(cls, creator, cr_workdir):
+        """
+        Create loader-specific (syslinux) config
+        """
+        splash = os.path.join(cr_workdir, "ISO/boot/splash.jpg")
+        if os.path.exists(splash):
+            splashline = "menu background splash.jpg"
+        else:
+            splashline = ""
+
+        bootloader = creator.ks.bootloader
+
+        syslinux_conf = ""
+        syslinux_conf += "PROMPT 0\n"
+        syslinux_conf += "TIMEOUT %s \n" % (bootloader.timeout or 10)
+        syslinux_conf += "\n"
+        syslinux_conf += "ALLOWOPTIONS 1\n"
+        syslinux_conf += "SERIAL 0 115200\n"
+        syslinux_conf += "\n"
+        if splashline:
+            syslinux_conf += "%s\n" % splashline
+        syslinux_conf += "DEFAULT boot\n"
+        syslinux_conf += "LABEL boot\n"
+
+        kernel = "/bzImage"
+        syslinux_conf += "KERNEL " + kernel + "\n"
+        syslinux_conf += "APPEND initrd=/initrd LABEL=boot %s\n" \
+                             % bootloader.append
+
+        logger.debug("Writing syslinux config %s/ISO/isolinux/isolinux.cfg",
+                     cr_workdir)
+
+        with open("%s/ISO/isolinux/isolinux.cfg" % cr_workdir, "w") as cfg:
+            cfg.write(syslinux_conf)
+
+    @classmethod
+    def do_configure_grubefi(cls, part, creator, target_dir):
+        """
+        Create loader-specific (grub-efi) config
+        """
+        configfile = creator.ks.bootloader.configfile
+        if configfile:
+            grubefi_conf = get_custom_config(configfile)
+            if grubefi_conf:
+                logger.debug("Using custom configuration file %s for grub.cfg",
+                             configfile)
+            else:
+                raise WicError("configfile is specified "
+                               "but failed to get it from %s", configfile)
+        else:
+            splash = os.path.join(target_dir, "splash.jpg")
+            if os.path.exists(splash):
+                splashline = "menu background splash.jpg"
+            else:
+                splashline = ""
+
+            bootloader = creator.ks.bootloader
+
+            grubefi_conf = ""
+            grubefi_conf += "serial --unit=0 --speed=115200 --word=8 "
+            grubefi_conf += "--parity=no --stop=1\n"
+            grubefi_conf += "default=boot\n"
+            grubefi_conf += "timeout=%s\n" % (bootloader.timeout or 10)
+            grubefi_conf += "\n"
+            grubefi_conf += "search --set=root --label %s " % part.label
+            grubefi_conf += "\n"
+            grubefi_conf += "menuentry 'boot'{\n"
+
+            kernel = "/bzImage"
+
+            grubefi_conf += "linux %s rootwait %s\n" \
+                            % (kernel, bootloader.append)
+            grubefi_conf += "initrd /initrd \n"
+            grubefi_conf += "}\n"
+
+            if splashline:
+                grubefi_conf += "%s\n" % splashline
+
+        cfg_path = os.path.join(target_dir, "grub.cfg")
+        logger.debug("Writing grubefi config %s", cfg_path)
+
+        with open(cfg_path, "w") as cfg:
+            cfg.write(grubefi_conf)
+
+    @staticmethod
+    def _build_initramfs_path(rootfs_dir, cr_workdir):
+        """
+        Create path for initramfs image
+        """
+
+        initrd = get_bitbake_var("INITRD_LIVE") or get_bitbake_var("INITRD")
+        if not initrd:
+            initrd_dir = get_bitbake_var("DEPLOY_DIR_IMAGE")
+            if not initrd_dir:
+                raise WicError("Couldn't find DEPLOY_DIR_IMAGE, exiting.")
+
+            image_name = get_bitbake_var("IMAGE_BASENAME")
+            if not image_name:
+                raise WicError("Couldn't find IMAGE_BASENAME, exiting.")
+
+            image_type = get_bitbake_var("INITRAMFS_FSTYPES")
+            if not image_type:
+                raise WicError("Couldn't find INITRAMFS_FSTYPES, exiting.")
+
+            machine = os.path.basename(initrd_dir)
+
+            pattern = '%s/%s*%s.%s' % (initrd_dir, image_name, machine, image_type)
+            files = glob.glob(pattern)
+            if files:
+                initrd = files[0]
+
+        if not initrd or not os.path.exists(initrd):
+            # Create initrd from rootfs directory
+            initrd = "%s/initrd.cpio.gz" % cr_workdir
+            initrd_dir = "%s/INITRD" % cr_workdir
+            shutil.copytree("%s" % rootfs_dir, \
+                            "%s" % initrd_dir, symlinks=True)
+
+            if os.path.isfile("%s/init" % rootfs_dir):
+                shutil.copy2("%s/init" % rootfs_dir, "%s/init" % initrd_dir)
+            elif os.path.lexists("%s/init" % rootfs_dir):
+                os.symlink(os.readlink("%s/init" % rootfs_dir), \
+                            "%s/init" % initrd_dir)
+            elif os.path.isfile("%s/sbin/init" % rootfs_dir):
+                shutil.copy2("%s/sbin/init" % rootfs_dir, \
+                            "%s" % initrd_dir)
+            elif os.path.lexists("%s/sbin/init" % rootfs_dir):
+                os.symlink(os.readlink("%s/sbin/init" % rootfs_dir), \
+                            "%s/init" % initrd_dir)
+            else:
+                raise WicError("Couldn't find or build initrd, exiting.")
+
+            exec_cmd("cd %s && find . | cpio -o -H newc -R root:root >%s/initrd.cpio " \
+                     % (initrd_dir, cr_workdir), as_shell=True)
+            exec_cmd("gzip -f -9 %s/initrd.cpio" % cr_workdir, as_shell=True)
+            shutil.rmtree(initrd_dir)
+
+        return initrd
+
+    @classmethod
+    def do_configure_partition(cls, part, source_params, creator, cr_workdir,
+                               oe_builddir, bootimg_dir, kernel_dir,
+                               native_sysroot):
+        """
+        Called before do_prepare_partition(), creates loader-specific config
+        """
+        isodir = "%s/ISO/" % cr_workdir
+
+        if os.path.exists(isodir):
+            shutil.rmtree(isodir)
+
+        install_cmd = "install -d %s " % isodir
+        exec_cmd(install_cmd)
+
+        # Overwrite the name of the created image
+        logger.debug(source_params)
+        if 'image_name' in source_params and \
+                    source_params['image_name'].strip():
+            creator.name = source_params['image_name'].strip()
+            logger.debug("The name of the image is: %s", creator.name)
+
+    @classmethod
+    def do_prepare_partition(cls, part, source_params, creator, cr_workdir,
+                             oe_builddir, bootimg_dir, kernel_dir,
+                             rootfs_dir, native_sysroot):
+        """
+        Called to do the actual content population for a partition i.e. it
+        'prepares' the partition to be incorporated into the image.
+        In this case, prepare content for a bootable ISO image.
+        """
+
+        isodir = "%s/ISO" % cr_workdir
+
+        if part.rootfs_dir is None:
+            if not 'ROOTFS_DIR' in rootfs_dir:
+                raise WicError("Couldn't find --rootfs-dir, exiting.")
+            rootfs_dir = rootfs_dir['ROOTFS_DIR']
+        else:
+            if part.rootfs_dir in rootfs_dir:
+                rootfs_dir = rootfs_dir[part.rootfs_dir]
+            elif part.rootfs_dir:
+                rootfs_dir = part.rootfs_dir
+            else:
+                raise WicError("Couldn't find --rootfs-dir=%s connection "
+                               "or it is not a valid path, exiting." %
+                               part.rootfs_dir)
+
+        if not os.path.isdir(rootfs_dir):
+            rootfs_dir = get_bitbake_var("IMAGE_ROOTFS")
+        if not os.path.isdir(rootfs_dir):
+            raise WicError("Couldn't find IMAGE_ROOTFS, exiting.")
+
+        part.rootfs_dir = rootfs_dir
+        deploy_dir = get_bitbake_var("DEPLOY_DIR_IMAGE")
+        img_iso_dir = get_bitbake_var("ISODIR")
+
+        # Remove the temporary file created by part.prepare_rootfs()
+        if os.path.isfile(part.source_file):
+            os.remove(part.source_file)
+
+        # Support using a different initrd other than default
+        if source_params.get('initrd'):
+            initrd = source_params['initrd']
+            if not deploy_dir:
+                raise WicError("Couldn't find DEPLOY_DIR_IMAGE, exiting")
+            cp_cmd = "cp %s/%s %s" % (deploy_dir, initrd, cr_workdir)
+            exec_cmd(cp_cmd)
+        else:
+            # Prepare initial ramdisk
+            initrd = "%s/initrd" % deploy_dir
+            if not os.path.isfile(initrd):
+                initrd = "%s/initrd" % img_iso_dir
+            if not os.path.isfile(initrd):
+                initrd = cls._build_initramfs_path(rootfs_dir, cr_workdir)
+
+        install_cmd = "install -m 0644 %s %s/initrd" % (initrd, isodir)
+        exec_cmd(install_cmd)
+
+        # Remove the temporary file created by _build_initramfs_path function
+        if os.path.isfile("%s/initrd.cpio.gz" % cr_workdir):
+            os.remove("%s/initrd.cpio.gz" % cr_workdir)
+
+        # Install bzImage
+        install_cmd = "install -m 0644 %s/bzImage %s/bzImage" % \
+                      (kernel_dir, isodir)
+        exec_cmd(install_cmd)
+
+        #Create bootloader for efi boot
+        try:
+            target_dir = "%s/EFI/BOOT" % isodir
+            if os.path.exists(target_dir):
+                shutil.rmtree(target_dir)
+
+            os.makedirs(target_dir)
+
+            if source_params['loader'] == 'grub-efi':
+                # Builds bootx64.efi/bootia32.efi if ISODIR didn't exist or
+                # didn't contains it
+                target_arch = get_bitbake_var("TARGET_SYS")
+                if not target_arch:
+                    raise WicError("Coludn't find target architecture")
+
+                if re.match("x86_64", target_arch):
+                    grub_src_image = "grub-efi-bootx64.efi"
+                    grub_dest_image = "bootx64.efi"
+                elif re.match('i.86', target_arch):
+                    grub_src_image = "grub-efi-bootia32.efi"
+                    grub_dest_image = "bootia32.efi"
+                else:
+                    raise WicError("grub-efi is incompatible with target %s" %
+                                   target_arch)
+
+                grub_target = os.path.join(target_dir, grub_dest_image)
+                if not os.path.isfile(grub_target):
+                    grub_src = os.path.join(deploy_dir, grub_src_image)
+                    if not os.path.exists(grub_src):
+                        raise WicError("Grub loader %s is not found in %s. "
+                                       "Please build grub-efi first" % (grub_src_image, deploy_dir))
+                    shutil.copy(grub_src, grub_target)
+
+                if not os.path.isfile(os.path.join(target_dir, "boot.cfg")):
+                    cls.do_configure_grubefi(part, creator, target_dir)
+
+            else:
+                raise WicError("unrecognized bootimg-efi loader: %s" %
+                               source_params['loader'])
+        except KeyError:
+            raise WicError("bootimg-efi requires a loader, none specified")
+
+        # Create efi.img that contains bootloader files for EFI booting
+        # if ISODIR didn't exist or didn't contains it
+        if os.path.isfile("%s/efi.img" % img_iso_dir):
+            install_cmd = "install -m 0644 %s/efi.img %s/efi.img" % \
+                (img_iso_dir, isodir)
+            exec_cmd(install_cmd)
+        else:
+            du_cmd = "du -bks %s/EFI" % isodir
+            out = exec_cmd(du_cmd)
+            blocks = int(out.split()[0])
+            # Add some extra space for file system overhead
+            blocks += 100
+            logger.debug("Added 100 extra blocks to %s to get to %d "
+                         "total blocks", part.mountpoint, blocks)
+
+            # dosfs image for EFI boot
+            bootimg = "%s/efi.img" % isodir
+
+            dosfs_cmd = 'mkfs.vfat -n "EFIimg" -S 512 -C %s %d' \
+                        % (bootimg, blocks)
+            exec_native_cmd(dosfs_cmd, native_sysroot)
+
+            mmd_cmd = "mmd -i %s ::/EFI" % bootimg
+            exec_native_cmd(mmd_cmd, native_sysroot)
+
+            mcopy_cmd = "mcopy -i %s -s %s/EFI/* ::/EFI/" \
+                        % (bootimg, isodir)
+            exec_native_cmd(mcopy_cmd, native_sysroot)
+
+            chmod_cmd = "chmod 644 %s" % bootimg
+            exec_cmd(chmod_cmd)
+
+        # Prepare files for legacy boot
+        syslinux_dir = get_bitbake_var("STAGING_DATADIR")
+        if not syslinux_dir:
+            raise WicError("Couldn't find STAGING_DATADIR, exiting.")
+
+        if os.path.exists("%s/isolinux" % isodir):
+            shutil.rmtree("%s/isolinux" % isodir)
+
+        install_cmd = "install -d %s/isolinux" % isodir
+        exec_cmd(install_cmd)
+
+        cls.do_configure_syslinux(creator, cr_workdir)
+
+        install_cmd = "install -m 444 %s/syslinux/ldlinux.sys " % syslinux_dir
+        install_cmd += "%s/isolinux/ldlinux.sys" % isodir
+        exec_cmd(install_cmd)
+
+        install_cmd = "install -m 444 %s/syslinux/isohdpfx.bin " % syslinux_dir
+        install_cmd += "%s/isolinux/isohdpfx.bin" % isodir
+        exec_cmd(install_cmd)
+
+        install_cmd = "install -m 644 %s/syslinux/isolinux.bin " % syslinux_dir
+        install_cmd += "%s/isolinux/isolinux.bin" % isodir
+        exec_cmd(install_cmd)
+
+        install_cmd = "install -m 644 %s/syslinux/ldlinux.c32 " % syslinux_dir
+        install_cmd += "%s/isolinux/ldlinux.c32" % isodir
+        exec_cmd(install_cmd)
+
+        #create ISO image
+        iso_img = "%s/tempiso_img.iso" % cr_workdir
+        iso_bootimg = "isolinux/isolinux.bin"
+        iso_bootcat = "isolinux/boot.cat"
+        efi_img = "efi.img"
+
+        mkisofs_cmd = "mkisofs -V %s " % part.label
+        mkisofs_cmd += "-o %s -U " % iso_img
+        mkisofs_cmd += "-J -joliet-long -r -iso-level 2 -b %s " % iso_bootimg
+        mkisofs_cmd += "-c %s -no-emul-boot -boot-load-size 4 " % iso_bootcat
+        mkisofs_cmd += "-boot-info-table -eltorito-alt-boot "
+        mkisofs_cmd += "-eltorito-platform 0xEF -eltorito-boot %s " % efi_img
+        mkisofs_cmd += "-no-emul-boot %s " % isodir
+
+        logger.debug("running command: %s", mkisofs_cmd)
+        exec_native_cmd(mkisofs_cmd, native_sysroot)
+
+        shutil.rmtree(isodir)
+
+        du_cmd = "du -Lbks %s" % iso_img
+        out = exec_cmd(du_cmd)
+        isoimg_size = int(out.split()[0])
+
+        part.size = isoimg_size
+        part.source_file = iso_img
+
+    @classmethod
+    def do_install_disk(cls, disk, disk_name, creator, workdir, oe_builddir,
+                        bootimg_dir, kernel_dir, native_sysroot):
+        """
+        Called after all partitions have been prepared and assembled into a
+        disk image.  In this case, we insert/modify the MBR using isohybrid
+        utility for booting via BIOS from disk storage devices.
+        """
+
+        iso_img = "%s.p1" % disk.path
+        full_path = creator._full_path(workdir, disk_name, "direct")
+        full_path_iso = creator._full_path(workdir, disk_name, "iso")
+
+        isohybrid_cmd = "isohybrid -u %s" % iso_img
+        logger.debug("running command: %s", isohybrid_cmd)
+        exec_native_cmd(isohybrid_cmd, native_sysroot)
+
+        # Replace the image created by direct plugin with the one created by
+        # mkisofs command. This is necessary because the iso image created by
+        # mkisofs has a very specific MBR is system area of the ISO image, and
+        # direct plugin adds and configures an another MBR.
+        logger.debug("Replaceing the image created by direct plugin\n")
+        os.remove(disk.path)
+        shutil.copy2(iso_img, full_path_iso)
+        shutil.copy2(full_path_iso, full_path)
diff --git a/meta/poky/scripts/lib/wic/plugins/source/rawcopy.py b/meta/poky/scripts/lib/wic/plugins/source/rawcopy.py
new file mode 100644
index 0000000..e86398a
--- /dev/null
+++ b/meta/poky/scripts/lib/wic/plugins/source/rawcopy.py
@@ -0,0 +1,91 @@
+# ex:ts=4:sw=4:sts=4:et
+# -*- tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*-
+#
+# 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.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+
+import logging
+import os
+
+from wic import WicError
+from wic.pluginbase import SourcePlugin
+from wic.misc import exec_cmd, get_bitbake_var
+from wic.filemap import sparse_copy
+
+logger = logging.getLogger('wic')
+
+class RawCopyPlugin(SourcePlugin):
+    """
+    Populate partition content from raw image file.
+    """
+
+    name = 'rawcopy'
+
+    @staticmethod
+    def do_image_label(fstype, dst, label):
+        if fstype.startswith('ext'):
+            cmd = 'tune2fs -L %s %s' % (label, dst)
+        elif fstype in ('msdos', 'vfat'):
+            cmd = 'dosfslabel %s %s' % (dst, label)
+        elif fstype == 'btrfs':
+            cmd = 'btrfs filesystem label %s %s' % (dst, label)
+        elif fstype == 'swap':
+            cmd = 'mkswap -L %s %s' % (label, dst)
+        elif fstype == 'squashfs':
+            raise WicError("It's not possible to update a squashfs "
+                           "filesystem label '%s'" % (label))
+        else:
+            raise WicError("Cannot update filesystem label: "
+                           "Unknown fstype: '%s'" % (fstype))
+
+        exec_cmd(cmd)
+
+    @classmethod
+    def do_prepare_partition(cls, part, source_params, cr, cr_workdir,
+                             oe_builddir, bootimg_dir, kernel_dir,
+                             rootfs_dir, native_sysroot):
+        """
+        Called to do the actual content population for a partition i.e. it
+        'prepares' the partition to be incorporated into the image.
+        """
+        if not kernel_dir:
+            kernel_dir = get_bitbake_var("DEPLOY_DIR_IMAGE")
+            if not kernel_dir:
+                raise WicError("Couldn't find DEPLOY_DIR_IMAGE, exiting")
+
+        logger.debug('Kernel dir: %s', kernel_dir)
+
+        if 'file' not in source_params:
+            raise WicError("No file specified")
+
+        src = os.path.join(kernel_dir, source_params['file'])
+        dst = os.path.join(cr_workdir, "%s.%s" % (source_params['file'], part.lineno))
+
+        if 'skip' in source_params:
+            sparse_copy(src, dst, skip=int(source_params['skip']))
+        else:
+            sparse_copy(src, dst)
+
+        # get the size in the right units for kickstart (kB)
+        du_cmd = "du -Lbks %s" % dst
+        out = exec_cmd(du_cmd)
+        filesize = int(out.split()[0])
+
+        if filesize > part.size:
+            part.size = filesize
+
+        if part.label:
+            RawCopyPlugin.do_image_label(part.fstype, dst, part.label)
+
+        part.source_file = dst
diff --git a/meta/poky/scripts/lib/wic/plugins/source/rootfs.py b/meta/poky/scripts/lib/wic/plugins/source/rootfs.py
new file mode 100644
index 0000000..aec720f
--- /dev/null
+++ b/meta/poky/scripts/lib/wic/plugins/source/rootfs.py
@@ -0,0 +1,126 @@
+# ex:ts=4:sw=4:sts=4:et
+# -*- tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*-
+#
+# Copyright (c) 2014, Intel Corporation.
+# All rights reserved.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License 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.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# DESCRIPTION
+# This implements the 'rootfs' source plugin class for 'wic'
+#
+# AUTHORS
+# Tom Zanussi <tom.zanussi (at] linux.intel.com>
+# Joao Henrique Ferreira de Freitas <joaohf (at] gmail.com>
+#
+
+import logging
+import os
+import shutil
+import sys
+
+from oe.path import copyhardlinktree
+
+from wic import WicError
+from wic.pluginbase import SourcePlugin
+from wic.misc import get_bitbake_var
+
+logger = logging.getLogger('wic')
+
+class RootfsPlugin(SourcePlugin):
+    """
+    Populate partition content from a rootfs directory.
+    """
+
+    name = 'rootfs'
+
+    @staticmethod
+    def __get_rootfs_dir(rootfs_dir):
+        if os.path.isdir(rootfs_dir):
+            return os.path.realpath(rootfs_dir)
+
+        image_rootfs_dir = get_bitbake_var("IMAGE_ROOTFS", rootfs_dir)
+        if not os.path.isdir(image_rootfs_dir):
+            raise WicError("No valid artifact IMAGE_ROOTFS from image "
+                           "named %s has been found at %s, exiting." %
+                           (rootfs_dir, image_rootfs_dir))
+
+        return os.path.realpath(image_rootfs_dir)
+
+    @classmethod
+    def do_prepare_partition(cls, part, source_params, cr, cr_workdir,
+                             oe_builddir, bootimg_dir, kernel_dir,
+                             krootfs_dir, native_sysroot):
+        """
+        Called to do the actual content population for a partition i.e. it
+        'prepares' the partition to be incorporated into the image.
+        In this case, prepare content for legacy bios boot partition.
+        """
+        if part.rootfs_dir is None:
+            if not 'ROOTFS_DIR' in krootfs_dir:
+                raise WicError("Couldn't find --rootfs-dir, exiting")
+
+            rootfs_dir = krootfs_dir['ROOTFS_DIR']
+        else:
+            if part.rootfs_dir in krootfs_dir:
+                rootfs_dir = krootfs_dir[part.rootfs_dir]
+            elif part.rootfs_dir:
+                rootfs_dir = part.rootfs_dir
+            else:
+                raise WicError("Couldn't find --rootfs-dir=%s connection or "
+                               "it is not a valid path, exiting" % part.rootfs_dir)
+
+        part.rootfs_dir = cls.__get_rootfs_dir(rootfs_dir)
+
+        new_rootfs = None
+        # Handle excluded paths.
+        if part.exclude_path is not None:
+            # We need a new rootfs directory we can delete files from. Copy to
+            # workdir.
+            new_rootfs = os.path.realpath(os.path.join(cr_workdir, "rootfs%d" % part.lineno))
+
+            if os.path.lexists(new_rootfs):
+                shutil.rmtree(os.path.join(new_rootfs))
+
+            copyhardlinktree(part.rootfs_dir, new_rootfs)
+
+            for orig_path in part.exclude_path:
+                path = orig_path
+                if os.path.isabs(path):
+                    logger.error("Must be relative: --exclude-path=%s" % orig_path)
+                    sys.exit(1)
+
+                full_path = os.path.realpath(os.path.join(new_rootfs, path))
+
+                # Disallow climbing outside of parent directory using '..',
+                # because doing so could be quite disastrous (we will delete the
+                # directory).
+                if not full_path.startswith(new_rootfs):
+                    logger.error("'%s' points to a path outside the rootfs" % orig_path)
+                    sys.exit(1)
+
+                if path.endswith(os.sep):
+                    # Delete content only.
+                    for entry in os.listdir(full_path):
+                        full_entry = os.path.join(full_path, entry)
+                        if os.path.isdir(full_entry) and not os.path.islink(full_entry):
+                            shutil.rmtree(full_entry)
+                        else:
+                            os.remove(full_entry)
+                else:
+                    # Delete whole directory.
+                    shutil.rmtree(full_path)
+
+        part.prepare_rootfs(cr_workdir, oe_builddir,
+                            new_rootfs or part.rootfs_dir, native_sysroot)
