Squashed 'yocto-poky/' content from commit ea562de

git-subtree-dir: yocto-poky
git-subtree-split: ea562de57590c966cd5a75fda8defecd397e6436
diff --git a/scripts/lib/wic/3rdparty/pykickstart/__init__.py b/scripts/lib/wic/3rdparty/pykickstart/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/scripts/lib/wic/3rdparty/pykickstart/__init__.py
diff --git a/scripts/lib/wic/3rdparty/pykickstart/base.py b/scripts/lib/wic/3rdparty/pykickstart/base.py
new file mode 100644
index 0000000..e6c8f56
--- /dev/null
+++ b/scripts/lib/wic/3rdparty/pykickstart/base.py
@@ -0,0 +1,466 @@
+#
+# Chris Lumens <clumens@redhat.com>
+#
+# Copyright 2006, 2007, 2008 Red Hat, Inc.
+#
+# This copyrighted material is made available to anyone wishing to use, modify,
+# copy, or redistribute it subject to the terms and conditions of the GNU
+# General Public License v.2.  This program is distributed in the hope that it
+# will be useful, but WITHOUT ANY WARRANTY expressed or implied, including the
+# implied warranties 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.  Any Red Hat
+# trademarks that are incorporated in the source code or documentation are not
+# subject to the GNU General Public License and may only be used or replicated
+# with the express permission of Red Hat, Inc. 
+#
+"""
+Base classes for creating commands and syntax version object.
+
+This module exports several important base classes:
+
+    BaseData - The base abstract class for all data objects.  Data objects
+               are contained within a BaseHandler object.
+
+    BaseHandler - The base abstract class from which versioned kickstart
+                  handler are derived.  Subclasses of BaseHandler hold
+                  BaseData and KickstartCommand objects.
+
+    DeprecatedCommand - An abstract subclass of KickstartCommand that should
+                        be further subclassed by users of this module.  When
+                        a subclass is used, a warning message will be
+                        printed.
+
+    KickstartCommand - The base abstract class for all kickstart commands.
+                       Command objects are contained within a BaseHandler
+                       object.
+"""
+import gettext
+gettext.textdomain("pykickstart")
+_ = lambda x: gettext.ldgettext("pykickstart", x)
+
+import types
+import warnings
+from pykickstart.errors import *
+from pykickstart.ko import *
+from pykickstart.parser import Packages
+from pykickstart.version import versionToString
+
+###
+### COMMANDS
+###
+class KickstartCommand(KickstartObject):
+    """The base class for all kickstart commands.  This is an abstract class."""
+    removedKeywords = []
+    removedAttrs = []
+
+    def __init__(self, writePriority=0, *args, **kwargs):
+        """Create a new KickstartCommand instance.  This method must be
+           provided by all subclasses, but subclasses must call
+           KickstartCommand.__init__ first.  Instance attributes:
+
+           currentCmd    -- The name of the command in the input file that
+                            caused this handler to be run.
+           currentLine   -- The current unprocessed line from the input file
+                            that caused this handler to be run.
+           handler       -- A reference to the BaseHandler subclass this
+                            command is contained withing.  This is needed to
+                            allow referencing of Data objects.
+           lineno        -- The current line number in the input file.
+           writePriority -- An integer specifying when this command should be
+                            printed when iterating over all commands' __str__
+                            methods.  The higher the number, the later this
+                            command will be written.  All commands with the
+                            same priority will be written alphabetically.
+        """
+
+        # We don't want people using this class by itself.
+        if self.__class__ is KickstartCommand:
+            raise TypeError, "KickstartCommand is an abstract class."
+
+        KickstartObject.__init__(self, *args, **kwargs)
+
+        self.writePriority = writePriority
+
+        # These will be set by the dispatcher.
+        self.currentCmd = ""
+        self.currentLine = ""
+        self.handler = None
+        self.lineno = 0
+
+        # If a subclass provides a removedKeywords list, remove all the
+        # members from the kwargs list before we start processing it.  This
+        # ensures that subclasses don't continue to recognize arguments that
+        # were removed.
+        for arg in filter(kwargs.has_key, self.removedKeywords):
+            kwargs.pop(arg)
+
+    def __call__(self, *args, **kwargs):
+        """Set multiple attributes on a subclass of KickstartCommand at once
+           via keyword arguments.  Valid attributes are anything specified in
+           a subclass, but unknown attributes will be ignored.
+        """
+        for (key, val) in kwargs.items():
+            # Ignore setting attributes that were removed in a subclass, as
+            # if they were unknown attributes.
+            if key in self.removedAttrs:
+                continue
+
+            if hasattr(self, key):
+                setattr(self, key, val)
+
+    def __str__(self):
+        """Return a string formatted for output to a kickstart file.  This
+           method must be provided by all subclasses.
+        """
+        return KickstartObject.__str__(self)
+
+    def parse(self, args):
+        """Parse the list of args and set data on the KickstartCommand object.
+           This method must be provided by all subclasses.
+        """
+        raise TypeError, "parse() not implemented for KickstartCommand"
+
+    def apply(self, instroot="/"):
+        """Write out the configuration related to the KickstartCommand object.
+           Subclasses which do not provide this method will not have their
+           configuration written out.
+        """
+        return
+
+    def dataList(self):
+        """For commands that can occur multiple times in a single kickstart
+           file (like network, part, etc.), return the list that we should
+           append more data objects to.
+        """
+        return None
+
+    def deleteRemovedAttrs(self):
+        """Remove all attributes from self that are given in the removedAttrs
+           list.  This method should be called from __init__ in a subclass,
+           but only after the superclass's __init__ method has been called.
+        """
+        for attr in filter(lambda k: hasattr(self, k), self.removedAttrs):
+            delattr(self, attr)
+
+    # Set the contents of the opts object (an instance of optparse.Values
+    # returned by parse_args) as attributes on the KickstartCommand object.
+    # It's useful to call this from KickstartCommand subclasses after parsing
+    # the arguments.
+    def _setToSelf(self, optParser, opts):
+        self._setToObj(optParser, opts, self)
+
+    # Sets the contents of the opts object (an instance of optparse.Values
+    # returned by parse_args) as attributes on the provided object obj.  It's
+    # useful to call this from KickstartCommand subclasses that handle lists
+    # of objects (like partitions, network devices, etc.) and need to populate
+    # a Data object.
+    def _setToObj(self, optParser, opts, obj):
+        for key in filter (lambda k: getattr(opts, k) != None, optParser.keys()):
+            setattr(obj, key, getattr(opts, key))
+
+class DeprecatedCommand(KickstartCommand):
+    """Specify that a command is deprecated and no longer has any function.
+       Any command that is deprecated should be subclassed from this class,
+       only specifying an __init__ method that calls the superclass's __init__.
+       This is an abstract class.
+    """
+    def __init__(self, writePriority=None, *args, **kwargs):
+        # We don't want people using this class by itself.
+        if self.__class__ is KickstartCommand:
+            raise TypeError, "DeprecatedCommand is an abstract class."
+
+        # Create a new DeprecatedCommand instance.
+        KickstartCommand.__init__(self, writePriority, *args, **kwargs)
+
+    def __str__(self):
+        """Placeholder since DeprecatedCommands don't work anymore."""
+        return ""
+
+    def parse(self, args):
+        """Print a warning message if the command is seen in the input file."""
+        mapping = {"lineno": self.lineno, "cmd": self.currentCmd}
+        warnings.warn(_("Ignoring deprecated command on line %(lineno)s:  The %(cmd)s command has been deprecated and no longer has any effect.  It may be removed from future releases, which will result in a fatal error from kickstart.  Please modify your kickstart file to remove this command.") % mapping, DeprecationWarning)
+
+
+###
+### HANDLERS
+###
+class BaseHandler(KickstartObject):
+    """Each version of kickstart syntax is provided by a subclass of this
+       class.  These subclasses are what users will interact with for parsing,
+       extracting data, and writing out kickstart files.  This is an abstract
+       class.
+
+       version -- The version this syntax handler supports.  This is set by
+                  a class attribute of a BaseHandler subclass and is used to
+                  set up the command dict.  It is for read-only use.
+    """
+    version = None
+
+    def __init__(self, mapping=None, dataMapping=None, commandUpdates=None,
+                 dataUpdates=None, *args, **kwargs):
+        """Create a new BaseHandler instance.  This method must be provided by
+           all subclasses, but subclasses must call BaseHandler.__init__ first.
+
+           mapping          -- A custom map from command strings to classes,
+                               useful when creating your own handler with
+                               special command objects.  It is otherwise unused
+                               and rarely needed.  If you give this argument,
+                               the mapping takes the place of the default one
+                               and so must include all commands you want
+                               recognized.
+           dataMapping      -- This is the same as mapping, but for data
+                               objects.  All the same comments apply.
+           commandUpdates   -- This is similar to mapping, but does not take
+                               the place of the defaults entirely.  Instead,
+                               this mapping is applied after the defaults and
+                               updates it with just the commands you want to
+                               modify.
+           dataUpdates      -- This is the same as commandUpdates, but for
+                               data objects.
+
+
+           Instance attributes:
+
+           commands -- A mapping from a string command to a KickstartCommand
+                       subclass object that handles it.  Multiple strings can
+                       map to the same object, but only one instance of the
+                       command object should ever exist.  Most users should
+                       never have to deal with this directly, as it is
+                       manipulated internally and called through dispatcher.
+           currentLine -- The current unprocessed line from the input file
+                          that caused this handler to be run.
+           packages -- An instance of pykickstart.parser.Packages which
+                       describes the packages section of the input file.
+           platform -- A string describing the hardware platform, which is
+                       needed only by system-config-kickstart.
+           scripts  -- A list of pykickstart.parser.Script instances, which is
+                       populated by KickstartParser.addScript and describes the
+                       %pre/%post/%traceback script section of the input file.
+        """
+
+        # We don't want people using this class by itself.
+        if self.__class__ is BaseHandler:
+            raise TypeError, "BaseHandler is an abstract class."
+
+        KickstartObject.__init__(self, *args, **kwargs)
+
+        # This isn't really a good place for these, but it's better than
+        # everything else I can think of.
+        self.scripts = []
+        self.packages = Packages()
+        self.platform = ""
+
+        # These will be set by the dispatcher.
+        self.commands = {}
+        self.currentLine = 0
+
+        # A dict keyed by an integer priority number, with each value being a
+        # list of KickstartCommand subclasses.  This dict is maintained by
+        # registerCommand and used in __str__.  No one else should be touching
+        # it.
+        self._writeOrder = {}
+
+        self._registerCommands(mapping, dataMapping, commandUpdates, dataUpdates)
+
+    def __str__(self):
+        """Return a string formatted for output to a kickstart file."""
+        retval = ""
+
+        if self.platform != "":
+            retval += "#platform=%s\n" % self.platform
+
+        retval += "#version=%s\n" % versionToString(self.version)
+
+        lst = self._writeOrder.keys()
+        lst.sort()
+
+        for prio in lst:
+            for obj in self._writeOrder[prio]:
+                retval += obj.__str__()
+
+        for script in self.scripts:
+            retval += script.__str__()
+
+        retval += self.packages.__str__()
+
+        return retval
+
+    def _insertSorted(self, lst, obj):
+        length = len(lst)
+        i = 0
+
+        while i < length:
+            # If the two classes have the same name, it's because we are
+            # overriding an existing class with one from a later kickstart
+            # version, so remove the old one in favor of the new one.
+            if obj.__class__.__name__ > lst[i].__class__.__name__:
+                i += 1
+            elif obj.__class__.__name__ == lst[i].__class__.__name__:
+                lst[i] = obj
+                return
+            elif obj.__class__.__name__ < lst[i].__class__.__name__:
+                break
+
+        if i >= length:
+            lst.append(obj)
+        else:
+            lst.insert(i, obj)
+
+    def _setCommand(self, cmdObj):
+        # Add an attribute on this version object.  We need this to provide a
+        # way for clients to access the command objects.  We also need to strip
+        # off the version part from the front of the name.
+        if cmdObj.__class__.__name__.find("_") != -1:
+            name = unicode(cmdObj.__class__.__name__.split("_", 1)[1])
+        else:
+            name = unicode(cmdObj.__class__.__name__).lower()
+
+        setattr(self, name.lower(), cmdObj)
+
+        # Also, add the object into the _writeOrder dict in the right place.
+        if cmdObj.writePriority is not None:
+            if self._writeOrder.has_key(cmdObj.writePriority):
+                self._insertSorted(self._writeOrder[cmdObj.writePriority], cmdObj)
+            else:
+                self._writeOrder[cmdObj.writePriority] = [cmdObj]
+
+    def _registerCommands(self, mapping=None, dataMapping=None, commandUpdates=None,
+                          dataUpdates=None):
+        if mapping == {} or mapping == None:
+            from pykickstart.handlers.control import commandMap
+            cMap = commandMap[self.version]
+        else:
+            cMap = mapping
+
+        if dataMapping == {} or dataMapping == None:
+            from pykickstart.handlers.control import dataMap
+            dMap = dataMap[self.version]
+        else:
+            dMap = dataMapping
+
+        if type(commandUpdates) == types.DictType:
+            cMap.update(commandUpdates)
+
+        if type(dataUpdates) == types.DictType:
+            dMap.update(dataUpdates)
+
+        for (cmdName, cmdClass) in cMap.iteritems():
+            # First make sure we haven't instantiated this command handler
+            # already.  If we have, we just need to make another mapping to
+            # it in self.commands.
+            cmdObj = None
+
+            for (key, val) in self.commands.iteritems():
+                if val.__class__.__name__ == cmdClass.__name__:
+                    cmdObj = val
+                    break
+
+            # If we didn't find an instance in self.commands, create one now.
+            if cmdObj == None:
+                cmdObj = cmdClass()
+                self._setCommand(cmdObj)
+
+            # Finally, add the mapping to the commands dict.
+            self.commands[cmdName] = cmdObj
+            self.commands[cmdName].handler = self
+
+        # We also need to create attributes for the various data objects.
+        # No checks here because dMap is a bijection.  At least, that's what
+        # the comment says.  Hope no one screws that up.
+        for (dataName, dataClass) in dMap.iteritems():
+            setattr(self, dataName, dataClass)
+
+    def dispatcher(self, args, lineno):
+        """Call the appropriate KickstartCommand handler for the current line
+           in the kickstart file.  A handler for the current command should
+           be registered, though a handler of None is not an error.  Returns
+           the data object returned by KickstartCommand.parse.
+
+           args    -- A list of arguments to the current command
+           lineno  -- The line number in the file, for error reporting
+        """
+        cmd = args[0]
+
+        if not self.commands.has_key(cmd):
+            raise KickstartParseError, formatErrorMsg(lineno, msg=_("Unknown command: %s" % cmd))
+        elif self.commands[cmd] != None:
+            self.commands[cmd].currentCmd = cmd
+            self.commands[cmd].currentLine = self.currentLine
+            self.commands[cmd].lineno = lineno
+
+            # The parser returns the data object that was modified.  This could
+            # be a BaseData subclass that should be put into a list, or it
+            # could be the command handler object itself.
+            obj = self.commands[cmd].parse(args[1:])
+            lst = self.commands[cmd].dataList()
+            if lst is not None:
+                lst.append(obj)
+
+            return obj
+
+    def maskAllExcept(self, lst):
+        """Set all entries in the commands dict to None, except the ones in
+           the lst.  All other commands will not be processed.
+        """
+        self._writeOrder = {}
+
+        for (key, val) in self.commands.iteritems():
+            if not key in lst:
+                self.commands[key] = None
+
+    def hasCommand(self, cmd):
+        """Return true if there is a handler for the string cmd."""
+        return hasattr(self, cmd)
+
+
+###
+### DATA
+###
+class BaseData(KickstartObject):
+    """The base class for all data objects.  This is an abstract class."""
+    removedKeywords = []
+    removedAttrs = []
+
+    def __init__(self, *args, **kwargs):
+        """Create a new BaseData instance.
+        
+           lineno -- Line number in the ks-file where this object was defined
+        """
+
+        # We don't want people using this class by itself.
+        if self.__class__ is BaseData:
+            raise TypeError, "BaseData is an abstract class."
+
+        KickstartObject.__init__(self, *args, **kwargs)
+        self.lineno = 0
+
+    def __str__(self):
+        """Return a string formatted for output to a kickstart file."""
+        return ""
+
+    def __call__(self, *args, **kwargs):
+        """Set multiple attributes on a subclass of BaseData at once via
+           keyword arguments.  Valid attributes are anything specified in a
+           subclass, but unknown attributes will be ignored.
+        """
+        for (key, val) in kwargs.items():
+            # Ignore setting attributes that were removed in a subclass, as
+            # if they were unknown attributes.
+            if key in self.removedAttrs:
+                continue
+
+            if hasattr(self, key):
+                setattr(self, key, val)
+
+    def deleteRemovedAttrs(self):
+        """Remove all attributes from self that are given in the removedAttrs
+           list.  This method should be called from __init__ in a subclass,
+           but only after the superclass's __init__ method has been called.
+        """
+        for attr in filter(lambda k: hasattr(self, k), self.removedAttrs):
+            delattr(self, attr)
diff --git a/scripts/lib/wic/3rdparty/pykickstart/commands/__init__.py b/scripts/lib/wic/3rdparty/pykickstart/commands/__init__.py
new file mode 100644
index 0000000..2d94550
--- /dev/null
+++ b/scripts/lib/wic/3rdparty/pykickstart/commands/__init__.py
@@ -0,0 +1,20 @@
+#
+# Chris Lumens <clumens@redhat.com>
+#
+# Copyright 2009 Red Hat, Inc.
+#
+# This copyrighted material is made available to anyone wishing to use, modify,
+# copy, or redistribute it subject to the terms and conditions of the GNU
+# General Public License v.2.  This program is distributed in the hope that it
+# will be useful, but WITHOUT ANY WARRANTY expressed or implied, including the
+# implied warranties 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.  Any Red Hat
+# trademarks that are incorporated in the source code or documentation are not
+# subject to the GNU General Public License and may only be used or replicated
+# with the express permission of Red Hat, Inc. 
+#
+import bootloader, partition
diff --git a/scripts/lib/wic/3rdparty/pykickstart/commands/bootloader.py b/scripts/lib/wic/3rdparty/pykickstart/commands/bootloader.py
new file mode 100644
index 0000000..c2b552f
--- /dev/null
+++ b/scripts/lib/wic/3rdparty/pykickstart/commands/bootloader.py
@@ -0,0 +1,216 @@
+#
+# Chris Lumens <clumens@redhat.com>
+#
+# Copyright 2007 Red Hat, Inc.
+#
+# This copyrighted material is made available to anyone wishing to use, modify,
+# copy, or redistribute it subject to the terms and conditions of the GNU
+# General Public License v.2.  This program is distributed in the hope that it
+# will be useful, but WITHOUT ANY WARRANTY expressed or implied, including the
+# implied warranties 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.  Any Red Hat
+# trademarks that are incorporated in the source code or documentation are not
+# subject to the GNU General Public License and may only be used or replicated
+# with the express permission of Red Hat, Inc. 
+#
+from pykickstart.base import *
+from pykickstart.options import *
+
+class FC3_Bootloader(KickstartCommand):
+    removedKeywords = KickstartCommand.removedKeywords
+    removedAttrs = KickstartCommand.removedAttrs
+
+    def __init__(self, writePriority=10, *args, **kwargs):
+        KickstartCommand.__init__(self, writePriority, *args, **kwargs)
+        self.op = self._getParser()
+
+        self.driveorder = kwargs.get("driveorder", [])
+        self.appendLine = kwargs.get("appendLine", "")
+        self.forceLBA = kwargs.get("forceLBA", False)
+        self.linear = kwargs.get("linear", True)
+        self.location = kwargs.get("location", "")
+        self.md5pass = kwargs.get("md5pass", "")
+        self.password = kwargs.get("password", "")
+        self.upgrade = kwargs.get("upgrade", False)
+        self.useLilo = kwargs.get("useLilo", False)
+
+        self.deleteRemovedAttrs()
+
+    def _getArgsAsStr(self):
+        retval = ""
+
+        if self.appendLine != "":
+            retval += " --append=\"%s\"" % self.appendLine
+        if self.linear:
+            retval += " --linear"
+        if self.location:
+            retval += " --location=%s" % self.location
+        if hasattr(self, "forceLBA") and self.forceLBA:
+            retval += " --lba32"
+        if self.password != "":
+            retval += " --password=\"%s\"" % self.password
+        if self.md5pass != "":
+            retval += " --md5pass=\"%s\"" % self.md5pass
+        if self.upgrade:
+            retval += " --upgrade"
+        if self.useLilo:
+            retval += " --useLilo"
+        if len(self.driveorder) > 0:
+            retval += " --driveorder=\"%s\"" % ",".join(self.driveorder)
+
+        return retval
+
+    def __str__(self):
+        retval = KickstartCommand.__str__(self)
+
+        if self.location != "":
+            retval += "# System bootloader configuration\nbootloader"
+            retval += self._getArgsAsStr() + "\n"
+
+        return retval
+
+    def _getParser(self):
+        def driveorder_cb (option, opt_str, value, parser):
+            for d in value.split(','):
+                parser.values.ensure_value(option.dest, []).append(d)
+
+        op = KSOptionParser()
+        op.add_option("--append", dest="appendLine")
+        op.add_option("--linear", dest="linear", action="store_true",
+                      default=True)
+        op.add_option("--nolinear", dest="linear", action="store_false")
+        op.add_option("--location", dest="location", type="choice",
+                      default="mbr",
+                      choices=["mbr", "partition", "none", "boot"])
+        op.add_option("--lba32", dest="forceLBA", action="store_true",
+                      default=False)
+        op.add_option("--password", dest="password", default="")
+        op.add_option("--md5pass", dest="md5pass", default="")
+        op.add_option("--upgrade", dest="upgrade", action="store_true",
+                      default=False)
+        op.add_option("--useLilo", dest="useLilo", action="store_true",
+                      default=False)
+        op.add_option("--driveorder", dest="driveorder", action="callback",
+                      callback=driveorder_cb, nargs=1, type="string")
+        return op
+
+    def parse(self, args):
+        (opts, extra) = self.op.parse_args(args=args, lineno=self.lineno)
+        self._setToSelf(self.op, opts)
+
+        if self.currentCmd == "lilo":
+            self.useLilo = True
+
+        return self
+
+class FC4_Bootloader(FC3_Bootloader):
+    removedKeywords = FC3_Bootloader.removedKeywords + ["linear", "useLilo"]
+    removedAttrs = FC3_Bootloader.removedAttrs + ["linear", "useLilo"]
+
+    def __init__(self, writePriority=10, *args, **kwargs):
+        FC3_Bootloader.__init__(self, writePriority, *args, **kwargs)
+
+    def _getArgsAsStr(self):
+        retval = ""
+        if self.appendLine != "":
+            retval += " --append=\"%s\"" % self.appendLine
+        if self.location:
+            retval += " --location=%s" % self.location
+        if hasattr(self, "forceLBA") and self.forceLBA:
+            retval += " --lba32"
+        if self.password != "":
+            retval += " --password=\"%s\"" % self.password
+        if self.md5pass != "":
+            retval += " --md5pass=\"%s\"" % self.md5pass
+        if self.upgrade:
+            retval += " --upgrade"
+        if len(self.driveorder) > 0:
+            retval += " --driveorder=\"%s\"" % ",".join(self.driveorder)
+        return retval
+
+    def _getParser(self):
+        op = FC3_Bootloader._getParser(self)
+        op.remove_option("--linear")
+        op.remove_option("--nolinear")
+        op.remove_option("--useLilo")
+        return op
+
+    def parse(self, args):
+        (opts, extra) = self.op.parse_args(args=args, lineno=self.lineno)
+        self._setToSelf(self.op, opts)
+        return self
+
+class F8_Bootloader(FC4_Bootloader):
+    removedKeywords = FC4_Bootloader.removedKeywords
+    removedAttrs = FC4_Bootloader.removedAttrs
+
+    def __init__(self, writePriority=10, *args, **kwargs):
+        FC4_Bootloader.__init__(self, writePriority, *args, **kwargs)
+
+        self.timeout = kwargs.get("timeout", None)
+        self.default = kwargs.get("default", "")
+
+    def _getArgsAsStr(self):
+        ret = FC4_Bootloader._getArgsAsStr(self)
+
+        if self.timeout is not None:
+            ret += " --timeout=%d" %(self.timeout,)
+        if self.default:
+            ret += " --default=%s" %(self.default,)
+
+        return ret
+
+    def _getParser(self):
+        op = FC4_Bootloader._getParser(self)
+        op.add_option("--timeout", dest="timeout", type="int")
+        op.add_option("--default", dest="default")
+        return op
+
+class F12_Bootloader(F8_Bootloader):
+    removedKeywords = F8_Bootloader.removedKeywords
+    removedAttrs = F8_Bootloader.removedAttrs
+
+    def _getParser(self):
+        op = F8_Bootloader._getParser(self)
+        op.add_option("--lba32", dest="forceLBA", deprecated=1, action="store_true")
+        return op
+
+class F14_Bootloader(F12_Bootloader):
+    removedKeywords = F12_Bootloader.removedKeywords + ["forceLBA"]
+    removedAttrs = F12_Bootloader.removedKeywords + ["forceLBA"]
+
+    def _getParser(self):
+        op = F12_Bootloader._getParser(self)
+        op.remove_option("--lba32")
+        return op
+
+class F15_Bootloader(F14_Bootloader):
+    removedKeywords = F14_Bootloader.removedKeywords
+    removedAttrs = F14_Bootloader.removedAttrs
+
+    def __init__(self, writePriority=10, *args, **kwargs):
+        F14_Bootloader.__init__(self, writePriority, *args, **kwargs)
+
+        self.isCrypted = kwargs.get("isCrypted", False)
+
+    def _getArgsAsStr(self):
+        ret = F14_Bootloader._getArgsAsStr(self)
+
+        if self.isCrypted:
+            ret += " --iscrypted"
+
+        return ret
+
+    def _getParser(self):
+        def password_cb(option, opt_str, value, parser):
+            parser.values.isCrypted = True
+            parser.values.password = value
+
+        op = F14_Bootloader._getParser(self)
+        op.add_option("--iscrypted", dest="isCrypted", action="store_true", default=False)
+        op.add_option("--md5pass", action="callback", callback=password_cb, nargs=1, type="string")
+        return op
diff --git a/scripts/lib/wic/3rdparty/pykickstart/commands/partition.py b/scripts/lib/wic/3rdparty/pykickstart/commands/partition.py
new file mode 100644
index 0000000..b564b1a
--- /dev/null
+++ b/scripts/lib/wic/3rdparty/pykickstart/commands/partition.py
@@ -0,0 +1,314 @@
+#
+# Chris Lumens <clumens@redhat.com>
+#
+# Copyright 2005, 2006, 2007, 2008 Red Hat, Inc.
+#
+# This copyrighted material is made available to anyone wishing to use, modify,
+# copy, or redistribute it subject to the terms and conditions of the GNU
+# General Public License v.2.  This program is distributed in the hope that it
+# will be useful, but WITHOUT ANY WARRANTY expressed or implied, including the
+# implied warranties 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.  Any Red Hat
+# trademarks that are incorporated in the source code or documentation are not
+# subject to the GNU General Public License and may only be used or replicated
+# with the express permission of Red Hat, Inc. 
+#
+from pykickstart.base import *
+from pykickstart.errors import *
+from pykickstart.options import *
+
+import gettext
+import warnings
+_ = lambda x: gettext.ldgettext("pykickstart", x)
+
+class FC3_PartData(BaseData):
+    removedKeywords = BaseData.removedKeywords
+    removedAttrs = BaseData.removedAttrs
+
+    def __init__(self, *args, **kwargs):
+        BaseData.__init__(self, *args, **kwargs)
+        self.active = kwargs.get("active", False)
+        self.primOnly = kwargs.get("primOnly", False)
+        self.end = kwargs.get("end", 0)
+        self.fstype = kwargs.get("fstype", "")
+        self.grow = kwargs.get("grow", False)
+        self.maxSizeMB = kwargs.get("maxSizeMB", 0)
+        self.format = kwargs.get("format", True)
+        self.onbiosdisk = kwargs.get("onbiosdisk", "")
+        self.disk = kwargs.get("disk", "")
+        self.onPart = kwargs.get("onPart", "")
+        self.recommended = kwargs.get("recommended", False)
+        self.size = kwargs.get("size", None)
+        self.start = kwargs.get("start", 0)
+        self.mountpoint = kwargs.get("mountpoint", "")
+
+    def __eq__(self, y):
+        if self.mountpoint:
+            return self.mountpoint == y.mountpoint
+        else:
+            return False
+
+    def _getArgsAsStr(self):
+        retval = ""
+
+        if self.active:
+            retval += " --active"
+        if self.primOnly:
+            retval += " --asprimary"
+        if hasattr(self, "end") and self.end != 0:
+            retval += " --end=%s" % self.end
+        if self.fstype != "":
+            retval += " --fstype=\"%s\"" % self.fstype
+        if self.grow:
+            retval += " --grow"
+        if self.maxSizeMB > 0:
+            retval += " --maxsize=%d" % self.maxSizeMB
+        if not self.format:
+            retval += " --noformat"
+        if self.onbiosdisk != "":
+            retval += " --onbiosdisk=%s" % self.onbiosdisk
+        if self.disk != "":
+            retval += " --ondisk=%s" % self.disk
+        if self.onPart != "":
+            retval += " --onpart=%s" % self.onPart
+        if self.recommended:
+            retval += " --recommended"
+        if self.size and self.size != 0:
+            retval += " --size=%sk" % self.size
+        if hasattr(self, "start") and self.start != 0:
+            retval += " --start=%s" % self.start
+
+        return retval
+
+    def __str__(self):
+        retval = BaseData.__str__(self)
+        if self.mountpoint:
+            mountpoint_str = "%s" % self.mountpoint
+        else:
+            mountpoint_str = "(No mount point)"
+        retval += "part %s%s\n" % (mountpoint_str, self._getArgsAsStr())
+        return retval
+
+class FC4_PartData(FC3_PartData):
+    removedKeywords = FC3_PartData.removedKeywords
+    removedAttrs = FC3_PartData.removedAttrs
+
+    def __init__(self, *args, **kwargs):
+        FC3_PartData.__init__(self, *args, **kwargs)
+        self.bytesPerInode = kwargs.get("bytesPerInode", 4096)
+        self.fsopts = kwargs.get("fsopts", "")
+        self.label = kwargs.get("label", "")
+
+    def _getArgsAsStr(self):
+        retval = FC3_PartData._getArgsAsStr(self)
+
+        if hasattr(self, "bytesPerInode") and self.bytesPerInode != 0:
+            retval += " --bytes-per-inode=%d" % self.bytesPerInode
+        if self.fsopts != "":
+            retval += " --fsoptions=\"%s\"" % self.fsopts
+        if self.label != "":
+            retval += " --label=%s" % self.label
+
+        return retval
+
+class F9_PartData(FC4_PartData):
+    removedKeywords = FC4_PartData.removedKeywords + ["bytesPerInode"]
+    removedAttrs = FC4_PartData.removedAttrs + ["bytesPerInode"]
+
+    def __init__(self, *args, **kwargs):
+        FC4_PartData.__init__(self, *args, **kwargs)
+        self.deleteRemovedAttrs()
+
+        self.fsopts = kwargs.get("fsopts", "")
+        self.label = kwargs.get("label", "")
+        self.fsprofile = kwargs.get("fsprofile", "")
+        self.encrypted = kwargs.get("encrypted", False)
+        self.passphrase = kwargs.get("passphrase", "")
+
+    def _getArgsAsStr(self):
+        retval = FC4_PartData._getArgsAsStr(self)
+
+        if self.fsprofile != "":
+            retval += " --fsprofile=\"%s\"" % self.fsprofile
+        if self.encrypted:
+            retval += " --encrypted"
+
+            if self.passphrase != "":
+                retval += " --passphrase=\"%s\"" % self.passphrase
+
+        return retval
+
+class F11_PartData(F9_PartData):
+    removedKeywords = F9_PartData.removedKeywords + ["start", "end"]
+    removedAttrs = F9_PartData.removedAttrs + ["start", "end"]
+
+class F12_PartData(F11_PartData):
+    removedKeywords = F11_PartData.removedKeywords
+    removedAttrs = F11_PartData.removedAttrs
+
+    def __init__(self, *args, **kwargs):
+        F11_PartData.__init__(self, *args, **kwargs)
+
+        self.escrowcert = kwargs.get("escrowcert", "")
+        self.backuppassphrase = kwargs.get("backuppassphrase", False)
+
+    def _getArgsAsStr(self):
+        retval = F11_PartData._getArgsAsStr(self)
+
+        if self.encrypted and self.escrowcert != "":
+            retval += " --escrowcert=\"%s\"" % self.escrowcert
+
+            if self.backuppassphrase:
+                retval += " --backuppassphrase"
+
+        return retval
+
+F14_PartData = F12_PartData
+
+class FC3_Partition(KickstartCommand):
+    removedKeywords = KickstartCommand.removedKeywords
+    removedAttrs = KickstartCommand.removedAttrs
+
+    def __init__(self, writePriority=130, *args, **kwargs):
+        KickstartCommand.__init__(self, writePriority, *args, **kwargs)
+        self.op = self._getParser()
+
+        self.partitions = kwargs.get("partitions", [])
+
+    def __str__(self):
+        retval = ""
+
+        for part in self.partitions:
+            retval += part.__str__()
+
+        if retval != "":
+            return "# Disk partitioning information\n" + retval
+        else:
+            return ""
+
+    def _getParser(self):
+        def part_cb (option, opt_str, value, parser):
+            if value.startswith("/dev/"):
+                parser.values.ensure_value(option.dest, value[5:])
+            else:
+                parser.values.ensure_value(option.dest, value)
+
+        op = KSOptionParser()
+        op.add_option("--active", dest="active", action="store_true",
+                      default=False)
+        op.add_option("--asprimary", dest="primOnly", action="store_true",
+                      default=False)
+        op.add_option("--end", dest="end", action="store", type="int",
+                      nargs=1)
+        op.add_option("--fstype", "--type", dest="fstype")
+        op.add_option("--grow", dest="grow", action="store_true", default=False)
+        op.add_option("--maxsize", dest="maxSizeMB", action="store", type="int",
+                      nargs=1)
+        op.add_option("--noformat", dest="format", action="store_false",
+                      default=True)
+        op.add_option("--onbiosdisk", dest="onbiosdisk")
+        op.add_option("--ondisk", "--ondrive", dest="disk")
+        op.add_option("--onpart", "--usepart", dest="onPart", action="callback",
+                      callback=part_cb, nargs=1, type="string")
+        op.add_option("--recommended", dest="recommended", action="store_true",
+                      default=False)
+        op.add_option("--size", dest="size", action="store", type="size",
+                      nargs=1)
+        op.add_option("--start", dest="start", action="store", type="int",
+                      nargs=1)
+        return op
+
+    def parse(self, args):
+        (opts, extra) = self.op.parse_args(args=args, lineno=self.lineno)
+
+        pd = self.handler.PartData()
+        self._setToObj(self.op, opts, pd)
+        pd.lineno = self.lineno
+        if extra:
+            pd.mountpoint = extra[0]
+            if pd in self.dataList():
+                warnings.warn(_("A partition with the mountpoint %s has already been defined.") % pd.mountpoint)
+        else:
+            pd.mountpoint = None
+
+        return pd
+
+    def dataList(self):
+        return self.partitions
+
+class FC4_Partition(FC3_Partition):
+    removedKeywords = FC3_Partition.removedKeywords
+    removedAttrs = FC3_Partition.removedAttrs
+
+    def __init__(self, writePriority=130, *args, **kwargs):
+        FC3_Partition.__init__(self, writePriority, *args, **kwargs)
+
+        def part_cb (option, opt_str, value, parser):
+            if value.startswith("/dev/"):
+                parser.values.ensure_value(option.dest, value[5:])
+            else:
+                parser.values.ensure_value(option.dest, value)
+
+    def _getParser(self):
+        op = FC3_Partition._getParser(self)
+        op.add_option("--bytes-per-inode", dest="bytesPerInode", action="store",
+                      type="int", nargs=1)
+        op.add_option("--fsoptions", dest="fsopts")
+        op.add_option("--label", dest="label")
+        return op
+
+class F9_Partition(FC4_Partition):
+    removedKeywords = FC4_Partition.removedKeywords
+    removedAttrs = FC4_Partition.removedAttrs
+
+    def __init__(self, writePriority=130, *args, **kwargs):
+        FC4_Partition.__init__(self, writePriority, *args, **kwargs)
+
+        def part_cb (option, opt_str, value, parser):
+            if value.startswith("/dev/"):
+                parser.values.ensure_value(option.dest, value[5:])
+            else:
+                parser.values.ensure_value(option.dest, value)
+
+    def _getParser(self):
+        op = FC4_Partition._getParser(self)
+        op.add_option("--bytes-per-inode", deprecated=1)
+        op.add_option("--fsprofile")
+        op.add_option("--encrypted", action="store_true", default=False)
+        op.add_option("--passphrase")
+        return op
+
+class F11_Partition(F9_Partition):
+    removedKeywords = F9_Partition.removedKeywords
+    removedAttrs = F9_Partition.removedAttrs
+
+    def _getParser(self):
+        op = F9_Partition._getParser(self)
+        op.add_option("--start", deprecated=1)
+        op.add_option("--end", deprecated=1)
+        return op
+
+class F12_Partition(F11_Partition):
+    removedKeywords = F11_Partition.removedKeywords
+    removedAttrs = F11_Partition.removedAttrs
+
+    def _getParser(self):
+        op = F11_Partition._getParser(self)
+        op.add_option("--escrowcert")
+        op.add_option("--backuppassphrase", action="store_true", default=False)
+        return op
+
+class F14_Partition(F12_Partition):
+    removedKeywords = F12_Partition.removedKeywords
+    removedAttrs = F12_Partition.removedAttrs
+
+    def _getParser(self):
+        op = F12_Partition._getParser(self)
+        op.remove_option("--bytes-per-inode")
+        op.remove_option("--start")
+        op.remove_option("--end")
+        return op
diff --git a/scripts/lib/wic/3rdparty/pykickstart/constants.py b/scripts/lib/wic/3rdparty/pykickstart/constants.py
new file mode 100644
index 0000000..5e12fc8
--- /dev/null
+++ b/scripts/lib/wic/3rdparty/pykickstart/constants.py
@@ -0,0 +1,57 @@
+#
+# Chris Lumens <clumens@redhat.com>
+#
+# Copyright 2005-2007 Red Hat, Inc.
+#
+# This copyrighted material is made available to anyone wishing to use, modify,
+# copy, or redistribute it subject to the terms and conditions of the GNU
+# General Public License v.2.  This program is distributed in the hope that it
+# will be useful, but WITHOUT ANY WARRANTY expressed or implied, including the
+# implied warranties 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.  Any Red Hat
+# trademarks that are incorporated in the source code or documentation are not
+# subject to the GNU General Public License and may only be used or replicated
+# with the express permission of Red Hat, Inc. 
+#
+CLEARPART_TYPE_LINUX = 0
+CLEARPART_TYPE_ALL = 1
+CLEARPART_TYPE_NONE = 2
+
+DISPLAY_MODE_CMDLINE = 0
+DISPLAY_MODE_GRAPHICAL = 1
+DISPLAY_MODE_TEXT = 2
+
+FIRSTBOOT_DEFAULT = 0
+FIRSTBOOT_SKIP = 1
+FIRSTBOOT_RECONFIG = 2
+
+KS_MISSING_PROMPT = 0
+KS_MISSING_IGNORE = 1
+
+SELINUX_DISABLED = 0
+SELINUX_ENFORCING = 1
+SELINUX_PERMISSIVE = 2
+
+KS_SCRIPT_PRE = 0
+KS_SCRIPT_POST = 1
+KS_SCRIPT_TRACEBACK = 2
+
+KS_WAIT = 0
+KS_REBOOT = 1
+KS_SHUTDOWN = 2
+
+KS_INSTKEY_SKIP = -99
+
+BOOTPROTO_DHCP = "dhcp"
+BOOTPROTO_BOOTP = "bootp"
+BOOTPROTO_STATIC = "static"
+BOOTPROTO_QUERY = "query"
+BOOTPROTO_IBFT = "ibft"
+
+GROUP_REQUIRED = 0
+GROUP_DEFAULT = 1
+GROUP_ALL = 2
diff --git a/scripts/lib/wic/3rdparty/pykickstart/errors.py b/scripts/lib/wic/3rdparty/pykickstart/errors.py
new file mode 100644
index 0000000..a234d99
--- /dev/null
+++ b/scripts/lib/wic/3rdparty/pykickstart/errors.py
@@ -0,0 +1,103 @@
+#
+# errors.py:  Kickstart error handling.
+#
+# Chris Lumens <clumens@redhat.com>
+#
+# This copyrighted material is made available to anyone wishing to use, modify,
+# copy, or redistribute it subject to the terms and conditions of the GNU
+# General Public License v.2.  This program is distributed in the hope that it
+# will be useful, but WITHOUT ANY WARRANTY expressed or implied, including the
+# implied warranties 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.  Any Red Hat
+# trademarks that are incorporated in the source code or documentation are not
+# subject to the GNU General Public License and may only be used or replicated
+# with the express permission of Red Hat, Inc. 
+#
+"""
+Error handling classes and functions.
+
+This module exports a single function:
+
+    formatErrorMsg - Properly formats an error message.
+
+It also exports several exception classes:
+
+    KickstartError - A generic exception class.
+
+    KickstartParseError - An exception for errors relating to parsing.
+
+    KickstartValueError - An exception for errors relating to option
+                          processing.
+
+    KickstartVersionError - An exception for errors relating to unsupported
+                            syntax versions.
+"""
+import gettext
+_ = lambda x: gettext.ldgettext("pykickstart", x)
+
+def formatErrorMsg(lineno, msg=""):
+    """Properly format the error message msg for inclusion in an exception."""
+    if msg != "":
+        mapping = {"lineno": lineno, "msg": msg}
+        return _("The following problem occurred on line %(lineno)s of the kickstart file:\n\n%(msg)s\n") % mapping
+    else:
+        return _("There was a problem reading from line %s of the kickstart file") % lineno
+
+class KickstartError(Exception):
+    """A generic exception class for unspecific error conditions."""
+    def __init__(self, val = ""):
+        """Create a new KickstartError exception instance with the descriptive
+           message val.  val should be the return value of formatErrorMsg.
+        """
+        Exception.__init__(self)
+        self.value = val
+
+    def __str__ (self):
+        return self.value
+
+class KickstartParseError(KickstartError):
+    """An exception class for errors when processing the input file, such as
+       unknown options, commands, or sections.
+    """
+    def __init__(self, msg):
+        """Create a new KickstartParseError exception instance with the
+           descriptive message val.  val should be the return value of
+           formatErrorMsg.
+        """
+        KickstartError.__init__(self, msg)
+
+    def __str__(self):
+        return self.value
+
+class KickstartValueError(KickstartError):
+    """An exception class for errors when processing arguments to commands,
+       such as too many arguments, too few arguments, or missing required
+       arguments.
+    """
+    def __init__(self, msg):
+        """Create a new KickstartValueError exception instance with the
+           descriptive message val.  val should be the return value of
+           formatErrorMsg.
+        """
+        KickstartError.__init__(self, msg)
+
+    def __str__ (self):
+        return self.value
+
+class KickstartVersionError(KickstartError):
+    """An exception class for errors related to using an incorrect version of
+       kickstart syntax.
+    """
+    def __init__(self, msg):
+        """Create a new KickstartVersionError exception instance with the
+           descriptive message val.  val should be the return value of
+           formatErrorMsg.
+        """
+        KickstartError.__init__(self, msg)
+
+    def __str__ (self):
+        return self.value
diff --git a/scripts/lib/wic/3rdparty/pykickstart/handlers/__init__.py b/scripts/lib/wic/3rdparty/pykickstart/handlers/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/scripts/lib/wic/3rdparty/pykickstart/handlers/__init__.py
diff --git a/scripts/lib/wic/3rdparty/pykickstart/handlers/control.py b/scripts/lib/wic/3rdparty/pykickstart/handlers/control.py
new file mode 100644
index 0000000..8dc80d1
--- /dev/null
+++ b/scripts/lib/wic/3rdparty/pykickstart/handlers/control.py
@@ -0,0 +1,46 @@
+#
+# Chris Lumens <clumens@redhat.com>
+#
+# Copyright 2007, 2008, 2009, 2010 Red Hat, Inc.
+#
+# This copyrighted material is made available to anyone wishing to use, modify,
+# copy, or redistribute it subject to the terms and conditions of the GNU
+# General Public License v.2.  This program is distributed in the hope that it
+# will be useful, but WITHOUT ANY WARRANTY expressed or implied, including the
+# implied warranties 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.  Any Red Hat
+# trademarks that are incorporated in the source code or documentation are not
+# subject to the GNU General Public License and may only be used or replicated
+# with the express permission of Red Hat, Inc. 
+#
+from pykickstart.version import *
+from pykickstart.commands import *
+
+# This map is keyed on kickstart syntax version as provided by
+# pykickstart.version.  Within each sub-dict is a mapping from command name
+# to the class that handles it.  This is an onto mapping - that is, multiple
+# command names can map to the same class.  However, the Handler will ensure
+# that only one instance of each class ever exists.
+commandMap = {
+    # based on f15
+    F16: {
+        "bootloader": bootloader.F15_Bootloader,
+        "part": partition.F14_Partition,
+        "partition": partition.F14_Partition,
+    },
+}
+
+# This map is keyed on kickstart syntax version as provided by
+# pykickstart.version.  Within each sub-dict is a mapping from a data object
+# name to the class that provides it.  This is a bijective mapping - that is,
+# each name maps to exactly one data class and all data classes have a name.
+# More than one instance of each class is allowed to exist, however.
+dataMap = {
+    F16: {
+        "PartData": partition.F14_PartData,
+    },
+}
diff --git a/scripts/lib/wic/3rdparty/pykickstart/handlers/f16.py b/scripts/lib/wic/3rdparty/pykickstart/handlers/f16.py
new file mode 100644
index 0000000..3c52f8d
--- /dev/null
+++ b/scripts/lib/wic/3rdparty/pykickstart/handlers/f16.py
@@ -0,0 +1,24 @@
+#
+# Chris Lumens <clumens@redhat.com>
+#
+# Copyright 2011 Red Hat, Inc.
+#
+# This copyrighted material is made available to anyone wishing to use, modify,
+# copy, or redistribute it subject to the terms and conditions of the GNU
+# General Public License v.2.  This program is distributed in the hope that it
+# will be useful, but WITHOUT ANY WARRANTY expressed or implied, including the
+# implied warranties 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.  Any Red Hat
+# trademarks that are incorporated in the source code or documentation are not
+# subject to the GNU General Public License and may only be used or replicated
+# with the express permission of Red Hat, Inc. 
+#
+from pykickstart.base import *
+from pykickstart.version import *
+
+class F16Handler(BaseHandler):
+    version = F16
diff --git a/scripts/lib/wic/3rdparty/pykickstart/ko.py b/scripts/lib/wic/3rdparty/pykickstart/ko.py
new file mode 100644
index 0000000..1350d19
--- /dev/null
+++ b/scripts/lib/wic/3rdparty/pykickstart/ko.py
@@ -0,0 +1,37 @@
+#
+# Chris Lumens <clumens@redhat.com>
+#
+# Copyright 2009 Red Hat, Inc.
+#
+# This copyrighted material is made available to anyone wishing to use, modify,
+# copy, or redistribute it subject to the terms and conditions of the GNU
+# General Public License v.2.  This program is distributed in the hope that it
+# will be useful, but WITHOUT ANY WARRANTY expressed or implied, including the
+# implied warranties 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.  Any Red Hat
+# trademarks that are incorporated in the source code or documentation are not
+# subject to the GNU General Public License and may only be used or replicated
+# with the express permission of Red Hat, Inc. 
+#
+"""
+Base classes for internal pykickstart use.
+
+The module exports the following important classes:
+
+    KickstartObject - The base class for all classes in pykickstart
+"""
+
+class KickstartObject(object):
+    """The base class for all other classes in pykickstart."""
+    def __init__(self, *args, **kwargs):
+        """Create a new KickstartObject instance.  All other classes in
+           pykickstart should be derived from this one.  Instance attributes:
+        """
+        pass
+
+    def __str__(self):
+        return ""
diff --git a/scripts/lib/wic/3rdparty/pykickstart/options.py b/scripts/lib/wic/3rdparty/pykickstart/options.py
new file mode 100644
index 0000000..ebc23ed
--- /dev/null
+++ b/scripts/lib/wic/3rdparty/pykickstart/options.py
@@ -0,0 +1,223 @@
+#
+# Chris Lumens <clumens@redhat.com>
+#
+# Copyright 2005, 2006, 2007 Red Hat, Inc.
+#
+# This copyrighted material is made available to anyone wishing to use, modify,
+# copy, or redistribute it subject to the terms and conditions of the GNU
+# General Public License v.2.  This program is distributed in the hope that it
+# will be useful, but WITHOUT ANY WARRANTY expressed or implied, including the
+# implied warranties 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.  Any Red Hat
+# trademarks that are incorporated in the source code or documentation are not
+# subject to the GNU General Public License and may only be used or replicated
+# with the express permission of Red Hat, Inc. 
+#
+"""
+Specialized option handling.
+
+This module exports two classes:
+
+    KSOptionParser - A specialized subclass of OptionParser to be used
+                     in BaseHandler subclasses.
+
+    KSOption - A specialized subclass of Option.
+"""
+import warnings
+from copy import copy
+from optparse import *
+
+from constants import *
+from errors import *
+from version import *
+
+import gettext
+_ = lambda x: gettext.ldgettext("pykickstart", x)
+
+class KSOptionParser(OptionParser):
+    """A specialized subclass of optparse.OptionParser to handle extra option
+       attribute checking, work error reporting into the KickstartParseError
+       framework, and to turn off the default help.
+    """
+    def exit(self, status=0, msg=None):
+        pass
+
+    def error(self, msg):
+        if self.lineno != None:
+            raise KickstartParseError, formatErrorMsg(self.lineno, msg=msg)
+        else:
+            raise KickstartParseError, msg
+
+    def keys(self):
+        retval = []
+
+        for opt in self.option_list:
+            if opt not in retval:
+                retval.append(opt.dest)
+
+        return retval
+
+    def _init_parsing_state (self):
+        OptionParser._init_parsing_state(self)
+        self.option_seen = {}
+
+    def check_values (self, values, args):
+        def seen(self, option):
+            return self.option_seen.has_key(option)
+
+        def usedTooNew(self, option):
+            return option.introduced and option.introduced > self.version
+
+        def usedDeprecated(self, option):
+            return option.deprecated
+
+        def usedRemoved(self, option):
+            return option.removed and option.removed <= self.version
+
+        for option in filter(lambda o: isinstance(o, Option), self.option_list):
+            if option.required and not seen(self, option):
+                raise KickstartValueError, formatErrorMsg(self.lineno, _("Option %s is required") % option)
+            elif seen(self, option) and usedTooNew(self, option):
+                mapping = {"option": option, "intro": versionToString(option.introduced),
+                           "version": versionToString(self.version)}
+                self.error(_("The %(option)s option was introduced in version %(intro)s, but you are using kickstart syntax version %(version)s.") % mapping)
+            elif seen(self, option) and usedRemoved(self, option):
+                mapping = {"option": option, "removed": versionToString(option.removed),
+                           "version": versionToString(self.version)}
+
+                if option.removed == self.version:
+                    self.error(_("The %(option)s option is no longer supported.") % mapping)
+                else:
+                    self.error(_("The %(option)s option was removed in version %(removed)s, but you are using kickstart syntax version %(version)s.") % mapping)
+            elif seen(self, option) and usedDeprecated(self, option):
+                mapping = {"lineno": self.lineno, "option": option}
+                warnings.warn(_("Ignoring deprecated option on line %(lineno)s:  The %(option)s option has been deprecated and no longer has any effect.  It may be removed from future releases, which will result in a fatal error from kickstart.  Please modify your kickstart file to remove this option.") % mapping, DeprecationWarning)
+
+        return (values, args)
+
+    def parse_args(self, *args, **kwargs):
+        if kwargs.has_key("lineno"):
+            self.lineno = kwargs.pop("lineno")
+
+        return OptionParser.parse_args(self, **kwargs)
+
+    def __init__(self, mapping=None, version=None):
+        """Create a new KSOptionParser instance.  Each KickstartCommand
+           subclass should create one instance of KSOptionParser, providing
+           at least the lineno attribute.  mapping and version are not required.
+           Instance attributes:
+
+           mapping -- A mapping from option strings to different values.
+           version -- The version of the kickstart syntax we are checking
+                      against.
+        """
+        OptionParser.__init__(self, option_class=KSOption,
+                              add_help_option=False,
+                              conflict_handler="resolve")
+        if mapping is None:
+            self.map = {}
+        else:
+            self.map = mapping
+
+        self.lineno = None
+        self.option_seen = {}
+        self.version = version
+
+def _check_ksboolean(option, opt, value):
+    if value.lower() in ("on", "yes", "true", "1"):
+        return True
+    elif value.lower() in ("off", "no", "false", "0"):
+        return False
+    else:
+        mapping = {"opt": opt, "value": value}
+        raise OptionValueError(_("Option %(opt)s: invalid boolean value: %(value)r") % mapping)
+
+def _check_string(option, opt, value):
+    if len(value) > 2 and value.startswith("--"):
+        mapping = {"opt": opt, "value": value}
+        raise OptionValueError(_("Option %(opt)s: invalid string value: %(value)r") % mapping)
+    else:
+        return value
+
+def _check_size(option, opt, value):
+    # Former default was MB
+    if value.isdigit():
+        return int(value) * 1024L
+
+    mapping = {"opt": opt, "value": value}
+    if not value[:-1].isdigit():
+        raise OptionValueError(_("Option %(opt)s: invalid size value: %(value)r") % mapping)
+
+    size = int(value[:-1])
+    if value.endswith("k") or value.endswith("K"):
+        return size
+    if value.endswith("M"):
+        return size * 1024L
+    if value.endswith("G"):
+        return size * 1024L * 1024L
+    raise OptionValueError(_("Option %(opt)s: invalid size value: %(value)r") % mapping)
+
+# Creates a new Option class that supports several new attributes:
+# - required:  any option with this attribute must be supplied or an exception
+#              is thrown
+# - introduced:  the kickstart syntax version that this option first appeared
+#                in - an exception will be raised if the option is used and
+#                the specified syntax version is less than the value of this
+#                attribute
+# - deprecated:  the kickstart syntax version that this option was deprecated
+#                in - a DeprecationWarning will be thrown if the option is
+#                used and the specified syntax version is greater than the
+#                value of this attribute
+# - removed:  the kickstart syntax version that this option was removed in - an
+#             exception will be raised if the option is used and the specified
+#             syntax version is greated than the value of this attribute
+# Also creates a new type:
+# - ksboolean:  support various kinds of boolean values on an option
+# And two new actions:
+# - map :  allows you to define an opt -> val mapping such that dest gets val
+#          when opt is seen
+# - map_extend:  allows you to define an opt -> [val1, ... valn] mapping such
+#                that dest gets a list of vals built up when opt is seen
+class KSOption (Option):
+    ATTRS = Option.ATTRS + ['introduced', 'deprecated', 'removed', 'required']
+    ACTIONS = Option.ACTIONS + ("map", "map_extend",)
+    STORE_ACTIONS = Option.STORE_ACTIONS + ("map", "map_extend",)
+
+    TYPES = Option.TYPES + ("ksboolean", "string", "size")
+    TYPE_CHECKER = copy(Option.TYPE_CHECKER)
+    TYPE_CHECKER["ksboolean"] = _check_ksboolean
+    TYPE_CHECKER["string"] = _check_string
+    TYPE_CHECKER["size"] = _check_size
+
+    def _check_required(self):
+        if self.required and not self.takes_value():
+            raise OptionError(_("Required flag set for option that doesn't take a value"), self)
+
+    # Make sure _check_required() is called from the constructor!
+    CHECK_METHODS = Option.CHECK_METHODS + [_check_required]
+
+    def process (self, opt, value, values, parser):
+        Option.process(self, opt, value, values, parser)
+        parser.option_seen[self] = 1
+
+    # Override default take_action method to handle our custom actions.
+    def take_action(self, action, dest, opt, value, values, parser):
+        if action == "map":
+            values.ensure_value(dest, parser.map[opt.lstrip('-')])
+        elif action == "map_extend":
+            values.ensure_value(dest, []).extend(parser.map[opt.lstrip('-')])
+        else:
+            Option.take_action(self, action, dest, opt, value, values, parser)
+
+    def takes_value(self):
+        # Deprecated options don't take a value.
+        return Option.takes_value(self) and not self.deprecated
+
+    def __init__(self, *args, **kwargs):
+        self.deprecated = False
+        self.required = False
+        Option.__init__(self, *args, **kwargs)
diff --git a/scripts/lib/wic/3rdparty/pykickstart/parser.py b/scripts/lib/wic/3rdparty/pykickstart/parser.py
new file mode 100644
index 0000000..9c9674b
--- /dev/null
+++ b/scripts/lib/wic/3rdparty/pykickstart/parser.py
@@ -0,0 +1,619 @@
+#
+# parser.py:  Kickstart file parser.
+#
+# Chris Lumens <clumens@redhat.com>
+#
+# Copyright 2005, 2006, 2007, 2008, 2011 Red Hat, Inc.
+#
+# This copyrighted material is made available to anyone wishing to use, modify,
+# copy, or redistribute it subject to the terms and conditions of the GNU
+# General Public License v.2.  This program is distributed in the hope that it
+# will be useful, but WITHOUT ANY WARRANTY expressed or implied, including the
+# implied warranties 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.  Any Red Hat
+# trademarks that are incorporated in the source code or documentation are not
+# subject to the GNU General Public License and may only be used or replicated
+# with the express permission of Red Hat, Inc. 
+#
+"""
+Main kickstart file processing module.
+
+This module exports several important classes:
+
+    Script - Representation of a single %pre, %post, or %traceback script.
+
+    Packages - Representation of the %packages section.
+
+    KickstartParser - The kickstart file parser state machine.
+"""
+
+from collections import Iterator
+import os
+import shlex
+import sys
+import tempfile
+from copy import copy
+from optparse import *
+
+import constants
+from errors import KickstartError, KickstartParseError, KickstartValueError, formatErrorMsg
+from ko import KickstartObject
+from sections import *
+import version
+
+import gettext
+_ = lambda x: gettext.ldgettext("pykickstart", x)
+
+STATE_END = "end"
+STATE_COMMANDS = "commands"
+
+ver = version.DEVEL
+
+
+class PutBackIterator(Iterator):
+    def __init__(self, iterable):
+        self._iterable = iter(iterable)
+        self._buf = None
+
+    def __iter__(self):
+        return self
+
+    def put(self, s):
+        self._buf = s
+
+    def next(self):
+        if self._buf:
+            retval = self._buf
+            self._buf = None
+            return retval
+        else:
+            return self._iterable.next()
+
+###
+### SCRIPT HANDLING
+###
+class Script(KickstartObject):
+    """A class representing a single kickstart script.  If functionality beyond
+       just a data representation is needed (for example, a run method in
+       anaconda), Script may be subclassed.  Although a run method is not
+       provided, most of the attributes of Script have to do with running the
+       script.  Instances of Script are held in a list by the Version object.
+    """
+    def __init__(self, script, *args , **kwargs):
+        """Create a new Script instance.  Instance attributes:
+
+           errorOnFail -- If execution of the script fails, should anaconda
+                          stop, display an error, and then reboot without
+                          running any other scripts?
+           inChroot    -- Does the script execute in anaconda's chroot
+                          environment or not?
+           interp      -- The program that should be used to interpret this
+                          script.
+           lineno      -- The line number this script starts on.
+           logfile     -- Where all messages from the script should be logged.
+           script      -- A string containing all the lines of the script.
+           type        -- The type of the script, which can be KS_SCRIPT_* from
+                          pykickstart.constants.
+        """
+        KickstartObject.__init__(self, *args, **kwargs)
+        self.script = "".join(script)
+
+        self.interp = kwargs.get("interp", "/bin/sh")
+        self.inChroot = kwargs.get("inChroot", False)
+        self.lineno = kwargs.get("lineno", None)
+        self.logfile = kwargs.get("logfile", None)
+        self.errorOnFail = kwargs.get("errorOnFail", False)
+        self.type = kwargs.get("type", constants.KS_SCRIPT_PRE)
+
+    def __str__(self):
+        """Return a string formatted for output to a kickstart file."""
+        retval = ""
+
+        if self.type == constants.KS_SCRIPT_PRE:
+            retval += '\n%pre'
+        elif self.type == constants.KS_SCRIPT_POST:
+            retval += '\n%post'
+        elif self.type == constants.KS_SCRIPT_TRACEBACK:
+            retval += '\n%traceback'
+
+        if self.interp != "/bin/sh" and self.interp != "":
+            retval += " --interpreter=%s" % self.interp
+        if self.type == constants.KS_SCRIPT_POST and not self.inChroot:
+            retval += " --nochroot"
+        if self.logfile != None:
+            retval += " --logfile %s" % self.logfile
+        if self.errorOnFail:
+            retval += " --erroronfail"
+
+        if self.script.endswith("\n"):
+            if ver >= version.F8:
+                return retval + "\n%s%%end\n" % self.script
+            else:
+                return retval + "\n%s\n" % self.script
+        else:
+            if ver >= version.F8:
+                return retval + "\n%s\n%%end\n" % self.script
+            else:
+                return retval + "\n%s\n" % self.script
+
+
+##
+## PACKAGE HANDLING
+##
+class Group:
+    """A class representing a single group in the %packages section."""
+    def __init__(self, name="", include=constants.GROUP_DEFAULT):
+        """Create a new Group instance.  Instance attributes:
+
+           name    -- The group's identifier
+           include -- The level of how much of the group should be included.
+                      Values can be GROUP_* from pykickstart.constants.
+        """
+        self.name = name
+        self.include = include
+
+    def __str__(self):
+        """Return a string formatted for output to a kickstart file."""
+        if self.include == constants.GROUP_REQUIRED:
+            return "@%s --nodefaults" % self.name
+        elif self.include == constants.GROUP_ALL:
+            return "@%s --optional" % self.name
+        else:
+            return "@%s" % self.name
+
+    def __cmp__(self, other):
+        if self.name < other.name:
+            return -1
+        elif self.name > other.name:
+            return 1
+        return 0
+
+class Packages(KickstartObject):
+    """A class representing the %packages section of the kickstart file."""
+    def __init__(self, *args, **kwargs):
+        """Create a new Packages instance.  Instance attributes:
+
+           addBase       -- Should the Base group be installed even if it is
+                            not specified?
+           default       -- Should the default package set be selected?
+           excludedList  -- A list of all the packages marked for exclusion in
+                            the %packages section, without the leading minus
+                            symbol.
+           excludeDocs   -- Should documentation in each package be excluded?
+           groupList     -- A list of Group objects representing all the groups
+                            specified in the %packages section.  Names will be
+                            stripped of the leading @ symbol.
+           excludedGroupList -- A list of Group objects representing all the
+                                groups specified for removal in the %packages
+                                section.  Names will be stripped of the leading
+                                -@ symbols.
+           handleMissing -- If unknown packages are specified in the %packages
+                            section, should it be ignored or not?  Values can
+                            be KS_MISSING_* from pykickstart.constants.
+           packageList   -- A list of all the packages specified in the
+                            %packages section.
+           instLangs     -- A list of languages to install.
+        """
+        KickstartObject.__init__(self, *args, **kwargs)
+
+        self.addBase = True
+        self.default = False
+        self.excludedList = []
+        self.excludedGroupList = []
+        self.excludeDocs = False
+        self.groupList = []
+        self.handleMissing = constants.KS_MISSING_PROMPT
+        self.packageList = []
+        self.instLangs = None
+
+    def __str__(self):
+        """Return a string formatted for output to a kickstart file."""
+        pkgs = ""
+
+        if not self.default:
+            grps = self.groupList
+            grps.sort()
+            for grp in grps:
+                pkgs += "%s\n" % grp.__str__()
+
+            p = self.packageList
+            p.sort()
+            for pkg in p:
+                pkgs += "%s\n" % pkg
+
+            grps = self.excludedGroupList
+            grps.sort()
+            for grp in grps:
+                pkgs += "-%s\n" % grp.__str__()
+
+            p = self.excludedList
+            p.sort()
+            for pkg in p:
+                pkgs += "-%s\n" % pkg
+
+            if pkgs == "":
+                return ""
+
+        retval = "\n%packages"
+
+        if self.default:
+            retval += " --default"
+        if self.excludeDocs:
+            retval += " --excludedocs"
+        if not self.addBase:
+            retval += " --nobase"
+        if self.handleMissing == constants.KS_MISSING_IGNORE:
+            retval += " --ignoremissing"
+        if self.instLangs:
+            retval += " --instLangs=%s" % self.instLangs
+
+        if ver >= version.F8:
+            return retval + "\n" + pkgs + "\n%end\n"
+        else:
+            return retval + "\n" + pkgs + "\n"
+
+    def _processGroup (self, line):
+        op = OptionParser()
+        op.add_option("--nodefaults", action="store_true", default=False)
+        op.add_option("--optional", action="store_true", default=False)
+
+        (opts, extra) = op.parse_args(args=line.split())
+
+        if opts.nodefaults and opts.optional:
+            raise KickstartValueError, _("Group cannot specify both --nodefaults and --optional")
+
+        # If the group name has spaces in it, we have to put it back together
+        # now.
+        grp = " ".join(extra)
+
+        if opts.nodefaults:
+            self.groupList.append(Group(name=grp, include=constants.GROUP_REQUIRED))
+        elif opts.optional:
+            self.groupList.append(Group(name=grp, include=constants.GROUP_ALL))
+        else:
+            self.groupList.append(Group(name=grp, include=constants.GROUP_DEFAULT))
+
+    def add (self, pkgList):
+        """Given a list of lines from the input file, strip off any leading
+           symbols and add the result to the appropriate list.
+        """
+        existingExcludedSet = set(self.excludedList)
+        existingPackageSet = set(self.packageList)
+        newExcludedSet = set()
+        newPackageSet = set()
+
+        excludedGroupList = []
+
+        for pkg in pkgList:
+            stripped = pkg.strip()
+
+            if stripped[0] == "@":
+                self._processGroup(stripped[1:])
+            elif stripped[0] == "-":
+                if stripped[1] == "@":
+                    excludedGroupList.append(Group(name=stripped[2:]))
+                else:
+                    newExcludedSet.add(stripped[1:])
+            else:
+                newPackageSet.add(stripped)
+
+        # Groups have to be excluded in two different ways (note: can't use
+        # sets here because we have to store objects):
+        excludedGroupNames = map(lambda g: g.name, excludedGroupList)
+
+        # First, an excluded group may be cancelling out a previously given
+        # one.  This is often the case when using %include.  So there we should
+        # just remove the group from the list.
+        self.groupList = filter(lambda g: g.name not in excludedGroupNames, self.groupList)
+
+        # Second, the package list could have included globs which are not
+        # processed by pykickstart.  In that case we need to preserve a list of
+        # excluded groups so whatever tool doing package/group installation can
+        # take appropriate action.
+        self.excludedGroupList.extend(excludedGroupList)
+
+        existingPackageSet = (existingPackageSet - newExcludedSet) | newPackageSet
+        existingExcludedSet = (existingExcludedSet - existingPackageSet) | newExcludedSet
+
+        self.packageList = list(existingPackageSet)
+        self.excludedList = list(existingExcludedSet)
+
+
+###
+### PARSER
+###
+class KickstartParser:
+    """The kickstart file parser class as represented by a basic state
+       machine.  To create a specialized parser, make a subclass and override
+       any of the methods you care about.  Methods that don't need to do
+       anything may just pass.  However, _stateMachine should never be
+       overridden.
+    """
+    def __init__ (self, handler, followIncludes=True, errorsAreFatal=True,
+                  missingIncludeIsFatal=True):
+        """Create a new KickstartParser instance.  Instance attributes:
+
+           errorsAreFatal        -- Should errors cause processing to halt, or
+                                    just print a message to the screen?  This
+                                    is most useful for writing syntax checkers
+                                    that may want to continue after an error is
+                                    encountered.
+           followIncludes        -- If %include is seen, should the included
+                                    file be checked as well or skipped?
+           handler               -- An instance of a BaseHandler subclass.  If
+                                    None, the input file will still be parsed
+                                    but no data will be saved and no commands
+                                    will be executed.
+           missingIncludeIsFatal -- Should missing include files be fatal, even
+                                    if errorsAreFatal is False?
+        """
+        self.errorsAreFatal = errorsAreFatal
+        self.followIncludes = followIncludes
+        self.handler = handler
+        self.currentdir = {}
+        self.missingIncludeIsFatal = missingIncludeIsFatal
+
+        self._state = STATE_COMMANDS
+        self._includeDepth = 0
+        self._line = ""
+
+        self.version = self.handler.version
+
+        global ver
+        ver = self.version
+
+        self._sections = {}
+        self.setupSections()
+
+    def _reset(self):
+        """Reset the internal variables of the state machine for a new kickstart file."""
+        self._state = STATE_COMMANDS
+        self._includeDepth = 0
+
+    def getSection(self, s):
+        """Return a reference to the requested section (s must start with '%'s),
+           or raise KeyError if not found.
+        """
+        return self._sections[s]
+
+    def handleCommand (self, lineno, args):
+        """Given the list of command and arguments, call the Version's
+           dispatcher method to handle the command.  Returns the command or
+           data object returned by the dispatcher.  This method may be
+           overridden in a subclass if necessary.
+        """
+        if self.handler:
+            self.handler.currentCmd = args[0]
+            self.handler.currentLine = self._line
+            retval = self.handler.dispatcher(args, lineno)
+
+            return retval
+
+    def registerSection(self, obj):
+        """Given an instance of a Section subclass, register the new section
+           with the parser.  Calling this method means the parser will
+           recognize your new section and dispatch into the given object to
+           handle it.
+        """
+        if not obj.sectionOpen:
+            raise TypeError, "no sectionOpen given for section %s" % obj
+
+        if not obj.sectionOpen.startswith("%"):
+            raise TypeError, "section %s tag does not start with a %%" % obj.sectionOpen
+
+        self._sections[obj.sectionOpen] = obj
+
+    def _finalize(self, obj):
+        """Called at the close of a kickstart section to take any required
+           actions.  Internally, this is used to add scripts once we have the
+           whole body read.
+        """
+        obj.finalize()
+        self._state = STATE_COMMANDS
+
+    def _handleSpecialComments(self, line):
+        """Kickstart recognizes a couple special comments."""
+        if self._state != STATE_COMMANDS:
+            return
+
+        # Save the platform for s-c-kickstart.
+        if line[:10] == "#platform=":
+            self.handler.platform = self._line[11:]
+
+    def _readSection(self, lineIter, lineno):
+        obj = self._sections[self._state]
+
+        while True:
+            try:
+                line = lineIter.next()
+                if line == "":
+                    # This section ends at the end of the file.
+                    if self.version >= version.F8:
+                        raise KickstartParseError, formatErrorMsg(lineno, msg=_("Section does not end with %%end."))
+
+                    self._finalize(obj)
+            except StopIteration:
+                break
+
+            lineno += 1
+
+            # Throw away blank lines and comments, unless the section wants all
+            # lines.
+            if self._isBlankOrComment(line) and not obj.allLines:
+                continue
+
+            if line.startswith("%"):
+                args = shlex.split(line)
+
+                if args and args[0] == "%end":
+                    # This is a properly terminated section.
+                    self._finalize(obj)
+                    break
+                elif args and args[0] == "%ksappend":
+                    continue
+                elif args and (self._validState(args[0]) or args[0] in ["%include", "%ksappend"]):
+                    # This is an unterminated section.
+                    if self.version >= version.F8:
+                        raise KickstartParseError, formatErrorMsg(lineno, msg=_("Section does not end with %%end."))
+
+                    # Finish up.  We do not process the header here because
+                    # kicking back out to STATE_COMMANDS will ensure that happens.
+                    lineIter.put(line)
+                    lineno -= 1
+                    self._finalize(obj)
+                    break
+            else:
+                # This is just a line within a section.  Pass it off to whatever
+                # section handles it.
+                obj.handleLine(line)
+
+        return lineno
+
+    def _validState(self, st):
+        """Is the given section tag one that has been registered with the parser?"""
+        return st in self._sections.keys()
+
+    def _tryFunc(self, fn):
+        """Call the provided function (which doesn't take any arguments) and
+           do the appropriate error handling.  If errorsAreFatal is False, this
+           function will just print the exception and keep going.
+        """
+        try:
+            fn()
+        except Exception, msg:
+            if self.errorsAreFatal:
+                raise
+            else:
+                print msg
+
+    def _isBlankOrComment(self, line):
+        return line.isspace() or line == "" or line.lstrip()[0] == '#'
+
+    def _stateMachine(self, lineIter):
+        # For error reporting.
+        lineno = 0
+
+        while True:
+            # Get the next line out of the file, quitting if this is the last line.
+            try:
+                self._line = lineIter.next()
+                if self._line == "":
+                    break
+            except StopIteration:
+                break
+
+            lineno += 1
+
+            # Eliminate blank lines, whitespace-only lines, and comments.
+            if self._isBlankOrComment(self._line):
+                self._handleSpecialComments(self._line)
+                continue
+
+            # Remove any end-of-line comments.
+            sanitized = self._line.split("#")[0]
+
+            # Then split the line.
+            args = shlex.split(sanitized.rstrip())
+
+            if args[0] == "%include":
+                # This case comes up primarily in ksvalidator.
+                if not self.followIncludes:
+                    continue
+
+                if len(args) == 1 or not args[1]:
+                    raise KickstartParseError, formatErrorMsg(lineno)
+
+                self._includeDepth += 1
+
+                try:
+                    self.readKickstart(args[1], reset=False)
+                except KickstartError:
+                    # Handle the include file being provided over the
+                    # network in a %pre script.  This case comes up in the
+                    # early parsing in anaconda.
+                    if self.missingIncludeIsFatal:
+                        raise
+
+                self._includeDepth -= 1
+                continue
+
+            # Now on to the main event.
+            if self._state == STATE_COMMANDS:
+                if args[0] == "%ksappend":
+                    # This is handled by the preprocess* functions, so continue.
+                    continue
+                elif args[0][0] == '%':
+                    # This is the beginning of a new section.  Handle its header
+                    # here.
+                    newSection = args[0]
+                    if not self._validState(newSection):
+                        raise KickstartParseError, formatErrorMsg(lineno, msg=_("Unknown kickstart section: %s" % newSection))
+
+                    self._state = newSection
+                    obj = self._sections[self._state]
+                    self._tryFunc(lambda: obj.handleHeader(lineno, args))
+
+                    # This will handle all section processing, kicking us back
+                    # out to STATE_COMMANDS at the end with the current line
+                    # being the next section header, etc.
+                    lineno = self._readSection(lineIter, lineno)
+                else:
+                    # This is a command in the command section.  Dispatch to it.
+                    self._tryFunc(lambda: self.handleCommand(lineno, args))
+            elif self._state == STATE_END:
+                break
+
+    def readKickstartFromString (self, s, reset=True):
+        """Process a kickstart file, provided as the string str."""
+        if reset:
+            self._reset()
+
+        # Add a "" to the end of the list so the string reader acts like the
+        # file reader and we only get StopIteration when we're after the final
+        # line of input.
+        i = PutBackIterator(s.splitlines(True) + [""])
+        self._stateMachine (i)
+
+    def readKickstart(self, f, reset=True):
+        """Process a kickstart file, given by the filename f."""
+        if reset:
+            self._reset()
+
+        # an %include might not specify a full path.  if we don't try to figure
+        # out what the path should have been, then we're unable to find it
+        # requiring full path specification, though, sucks.  so let's make
+        # the reading "smart" by keeping track of what the path is at each
+        # include depth.
+        if not os.path.exists(f):
+            if self.currentdir.has_key(self._includeDepth - 1):
+                if os.path.exists(os.path.join(self.currentdir[self._includeDepth - 1], f)):
+                    f = os.path.join(self.currentdir[self._includeDepth - 1], f)
+
+        cd = os.path.dirname(f)
+        if not cd.startswith("/"):
+            cd = os.path.abspath(cd)
+        self.currentdir[self._includeDepth] = cd
+
+        try:
+            s = file(f).read()
+        except IOError, e:
+            raise KickstartError, formatErrorMsg(0, msg=_("Unable to open input kickstart file: %s") % e.strerror)
+
+        self.readKickstartFromString(s, reset=False)
+
+    def setupSections(self):
+        """Install the sections all kickstart files support.  You may override
+           this method in a subclass, but should avoid doing so unless you know
+           what you're doing.
+        """
+        self._sections = {}
+
+        # Install the sections all kickstart files support.
+        self.registerSection(PreScriptSection(self.handler, dataObj=Script))
+        self.registerSection(PostScriptSection(self.handler, dataObj=Script))
+        self.registerSection(TracebackScriptSection(self.handler, dataObj=Script))
+        self.registerSection(PackageSection(self.handler))
diff --git a/scripts/lib/wic/3rdparty/pykickstart/sections.py b/scripts/lib/wic/3rdparty/pykickstart/sections.py
new file mode 100644
index 0000000..44df856
--- /dev/null
+++ b/scripts/lib/wic/3rdparty/pykickstart/sections.py
@@ -0,0 +1,244 @@
+#
+# sections.py:  Kickstart file sections.
+#
+# Chris Lumens <clumens@redhat.com>
+#
+# Copyright 2011 Red Hat, Inc.
+#
+# This copyrighted material is made available to anyone wishing to use, modify,
+# copy, or redistribute it subject to the terms and conditions of the GNU
+# General Public License v.2.  This program is distributed in the hope that it
+# will be useful, but WITHOUT ANY WARRANTY expressed or implied, including the
+# implied warranties 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.  Any Red Hat
+# trademarks that are incorporated in the source code or documentation are not
+# subject to the GNU General Public License and may only be used or replicated
+# with the express permission of Red Hat, Inc. 
+#
+"""
+This module exports the classes that define a section of a kickstart file.  A
+section is a chunk of the file starting with a %tag and ending with a %end.
+Examples of sections include %packages, %pre, and %post.
+
+You may use this module to define your own custom sections which will be
+treated just the same as a predefined one by the kickstart parser.  All that
+is necessary is to create a new subclass of Section and call
+parser.registerSection with an instance of your new class.
+"""
+from constants import *
+from options import KSOptionParser
+from version import *
+
+class Section(object):
+    """The base class for defining kickstart sections.  You are free to
+       subclass this as appropriate.
+
+       Class attributes:
+
+       allLines    -- Does this section require the parser to call handleLine
+                      for every line in the section, even blanks and comments?
+       sectionOpen -- The string that denotes the start of this section.  You
+                      must start your tag with a percent sign.
+       timesSeen   -- This attribute is for informational purposes only.  It is
+                      incremented every time handleHeader is called to keep
+                      track of the number of times a section of this type is
+                      seen.
+    """
+    allLines = False
+    sectionOpen = ""
+    timesSeen = 0
+
+    def __init__(self, handler, **kwargs):
+        """Create a new Script instance.  At the least, you must pass in an
+           instance of a baseHandler subclass.
+
+           Valid kwargs:
+
+           dataObj --
+        """
+        self.handler = handler
+
+        self.version = self.handler.version
+
+        self.dataObj = kwargs.get("dataObj", None)
+
+    def finalize(self):
+        """This method is called when the %end tag for a section is seen.  It
+           is not required to be provided.
+        """
+        pass
+
+    def handleLine(self, line):
+        """This method is called for every line of a section.  Take whatever
+           action is appropriate.  While this method is not required to be
+           provided, not providing it does not make a whole lot of sense.
+
+           Arguments:
+
+           line -- The complete line, with any trailing newline.
+        """
+        pass
+
+    def handleHeader(self, lineno, args):
+        """This method is called when the opening tag for a section is seen.
+           Not all sections will need this method, though all provided with
+           kickstart include one.
+
+           Arguments:
+
+           args -- A list of all strings passed as arguments to the section
+                   opening tag.
+        """
+        self.timesSeen += 1
+
+class NullSection(Section):
+    """This defines a section that pykickstart will recognize but do nothing
+       with.  If the parser runs across a %section that has no object registered,
+       it will raise an error.  Sometimes, you may want to simply ignore those
+       sections instead.  This class is useful for that purpose.
+    """
+    def __init__(self, *args, **kwargs):
+        """Create a new NullSection instance.  You must pass a sectionOpen
+           parameter (including a leading '%') for the section you wish to
+           ignore.
+        """
+        Section.__init__(self, *args, **kwargs)
+        self.sectionOpen = kwargs.get("sectionOpen")
+
+class ScriptSection(Section):
+    allLines = True
+
+    def __init__(self, *args, **kwargs):
+        Section.__init__(self, *args, **kwargs)
+        self._script = {}
+        self._resetScript()
+
+    def _getParser(self):
+        op = KSOptionParser(self.version)
+        op.add_option("--erroronfail", dest="errorOnFail", action="store_true",
+                      default=False)
+        op.add_option("--interpreter", dest="interpreter", default="/bin/sh")
+        op.add_option("--log", "--logfile", dest="log")
+        return op
+
+    def _resetScript(self):
+        self._script = {"interp": "/bin/sh", "log": None, "errorOnFail": False,
+                        "lineno": None, "chroot": False, "body": []}
+
+    def handleLine(self, line):
+        self._script["body"].append(line)
+
+    def finalize(self):
+        if " ".join(self._script["body"]).strip() == "":
+            return
+
+        kwargs = {"interp": self._script["interp"],
+                  "inChroot": self._script["chroot"],
+                  "lineno": self._script["lineno"],
+                  "logfile": self._script["log"],
+                  "errorOnFail": self._script["errorOnFail"],
+                  "type": self._script["type"]}
+
+        s = self.dataObj (self._script["body"], **kwargs)
+        self._resetScript()
+
+        if self.handler:
+            self.handler.scripts.append(s)
+
+    def handleHeader(self, lineno, args):
+        """Process the arguments to a %pre/%post/%traceback header for later
+           setting on a Script instance once the end of the script is found.
+           This method may be overridden in a subclass if necessary.
+        """
+        Section.handleHeader(self, lineno, args)
+        op = self._getParser()
+
+        (opts, extra) = op.parse_args(args=args[1:], lineno=lineno)
+
+        self._script["interp"] = opts.interpreter
+        self._script["lineno"] = lineno
+        self._script["log"] = opts.log
+        self._script["errorOnFail"] = opts.errorOnFail
+        if hasattr(opts, "nochroot"):
+            self._script["chroot"] = not opts.nochroot
+
+class PreScriptSection(ScriptSection):
+    sectionOpen = "%pre"
+
+    def _resetScript(self):
+        ScriptSection._resetScript(self)
+        self._script["type"] = KS_SCRIPT_PRE
+
+class PostScriptSection(ScriptSection):
+    sectionOpen = "%post"
+
+    def _getParser(self):
+        op = ScriptSection._getParser(self)
+        op.add_option("--nochroot", dest="nochroot", action="store_true",
+                      default=False)
+        return op
+
+    def _resetScript(self):
+        ScriptSection._resetScript(self)
+        self._script["chroot"] = True
+        self._script["type"] = KS_SCRIPT_POST
+
+class TracebackScriptSection(ScriptSection):
+    sectionOpen = "%traceback"
+
+    def _resetScript(self):
+        ScriptSection._resetScript(self)
+        self._script["type"] = KS_SCRIPT_TRACEBACK
+
+class PackageSection(Section):
+    sectionOpen = "%packages"
+
+    def handleLine(self, line):
+        if not self.handler:
+            return
+
+        (h, s, t) = line.partition('#')
+        line = h.rstrip()
+
+        self.handler.packages.add([line])
+
+    def handleHeader(self, lineno, args):
+        """Process the arguments to the %packages header and set attributes
+           on the Version's Packages instance appropriate.  This method may be
+           overridden in a subclass if necessary.
+        """
+        Section.handleHeader(self, lineno, args)
+        op = KSOptionParser(version=self.version)
+        op.add_option("--excludedocs", dest="excludedocs", action="store_true",
+                      default=False)
+        op.add_option("--ignoremissing", dest="ignoremissing",
+                      action="store_true", default=False)
+        op.add_option("--nobase", dest="nobase", action="store_true",
+                      default=False)
+        op.add_option("--ignoredeps", dest="resolveDeps", action="store_false",
+                      deprecated=FC4, removed=F9)
+        op.add_option("--resolvedeps", dest="resolveDeps", action="store_true",
+                      deprecated=FC4, removed=F9)
+        op.add_option("--default", dest="defaultPackages", action="store_true",
+                      default=False, introduced=F7)
+        op.add_option("--instLangs", dest="instLangs", type="string",
+                      default="", introduced=F9)
+
+        (opts, extra) = op.parse_args(args=args[1:], lineno=lineno)
+
+        self.handler.packages.excludeDocs = opts.excludedocs
+        self.handler.packages.addBase = not opts.nobase
+        if opts.ignoremissing:
+            self.handler.packages.handleMissing = KS_MISSING_IGNORE
+        else:
+            self.handler.packages.handleMissing = KS_MISSING_PROMPT
+
+        if opts.defaultPackages:
+            self.handler.packages.default = True
+
+        if opts.instLangs:
+            self.handler.packages.instLangs = opts.instLangs
diff --git a/scripts/lib/wic/3rdparty/pykickstart/version.py b/scripts/lib/wic/3rdparty/pykickstart/version.py
new file mode 100644
index 0000000..8a8e6aa
--- /dev/null
+++ b/scripts/lib/wic/3rdparty/pykickstart/version.py
@@ -0,0 +1,168 @@
+#
+# Chris Lumens <clumens@redhat.com>
+#
+# Copyright 2006, 2007, 2008, 2009, 2010 Red Hat, Inc.
+#
+# This copyrighted material is made available to anyone wishing to use, modify,
+# copy, or redistribute it subject to the terms and conditions of the GNU
+# General Public License v.2.  This program is distributed in the hope that it
+# will be useful, but WITHOUT ANY WARRANTY expressed or implied, including the
+# implied warranties 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.  Any Red Hat
+# trademarks that are incorporated in the source code or documentation are not
+# subject to the GNU General Public License and may only be used or replicated
+# with the express permission of Red Hat, Inc. 
+#
+"""
+Methods for working with kickstart versions.
+
+This module defines several symbolic constants that specify kickstart syntax
+versions.  Each version corresponds roughly to one release of Red Hat Linux,
+Red Hat Enterprise Linux, or Fedora Core as these are where most syntax
+changes take place.
+
+This module also exports several functions:
+
+    makeVersion - Given a version number, return an instance of the
+                  matching handler class.
+
+    returnClassForVersion - Given a version number, return the matching
+                            handler class.  This does not return an
+                            instance of that class, however.
+
+    stringToVersion - Convert a string representation of a version number
+                      into the symbolic constant.
+
+    versionToString - Perform the reverse mapping.
+
+    versionFromFile - Read a kickstart file and determine the version of
+                      syntax it uses.  This requires the kickstart file to
+                      have a version= comment in it.
+"""
+import imputil, re, sys
+
+import gettext
+_ = lambda x: gettext.ldgettext("pykickstart", x)
+
+from pykickstart.errors import KickstartVersionError
+
+# Symbolic names for internal version numbers.
+RHEL3 = 900
+FC3 = 1000
+RHEL4 = 1100
+FC4 = 2000
+FC5 = 3000
+FC6 = 4000
+RHEL5 = 4100
+F7  = 5000
+F8 = 6000
+F9 = 7000
+F10 = 8000
+F11 = 9000
+F12 = 10000
+F13 = 11000
+RHEL6 = 11100
+F14 = 12000
+F15 = 13000
+F16 = 14000
+
+# This always points at the latest version and is the default.
+DEVEL = F16
+
+# A one-to-one mapping from string representations to version numbers.
+versionMap = {
+        "DEVEL": DEVEL,
+        "FC3": FC3, "FC4": FC4, "FC5": FC5, "FC6": FC6, "F7": F7, "F8": F8,
+        "F9": F9, "F10": F10, "F11": F11, "F12": F12, "F13": F13,
+        "F14": F14, "F15": F15, "F16": F16,
+        "RHEL3": RHEL3, "RHEL4": RHEL4, "RHEL5": RHEL5, "RHEL6": RHEL6
+}
+
+def stringToVersion(s):
+    """Convert string into one of the provided version constants.  Raises
+       KickstartVersionError if string does not match anything.
+    """
+    # First try these short forms.
+    try:
+        return versionMap[s.upper()]
+    except KeyError:
+        pass
+
+    # Now try the Fedora versions.
+    m = re.match("^fedora.* (\d+)$", s, re.I)
+
+    if m and m.group(1):
+        if versionMap.has_key("FC" + m.group(1)):
+            return versionMap["FC" + m.group(1)]
+        elif versionMap.has_key("F" + m.group(1)):
+            return versionMap["F" + m.group(1)]
+        else:
+            raise KickstartVersionError(_("Unsupported version specified: %s") % s)
+
+    # Now try the RHEL versions.
+    m = re.match("^red hat enterprise linux.* (\d+)([\.\d]*)$", s, re.I)
+
+    if m and m.group(1):
+        if versionMap.has_key("RHEL" + m.group(1)):
+            return versionMap["RHEL" + m.group(1)]
+        else:
+            raise KickstartVersionError(_("Unsupported version specified: %s") % s)
+
+    # If nothing else worked, we're out of options.
+    raise KickstartVersionError(_("Unsupported version specified: %s") % s)
+
+def versionToString(version, skipDevel=False):
+    """Convert version into a string representation of the version number.
+       This is the reverse operation of stringToVersion.  Raises
+       KickstartVersionError if version does not match anything.
+    """
+    if not skipDevel and version == versionMap["DEVEL"]:
+        return "DEVEL"
+
+    for (key, val) in versionMap.iteritems():
+        if key == "DEVEL":
+            continue
+        elif val == version:
+            return key
+
+    raise KickstartVersionError(_("Unsupported version specified: %s") % version)
+
+def returnClassForVersion(version=DEVEL):
+    """Return the class of the syntax handler for version.  version can be
+       either a string or the matching constant.  Raises KickstartValueError
+       if version does not match anything.
+    """
+    try:
+        version = int(version)
+        module = "%s" % versionToString(version, skipDevel=True)
+    except ValueError:
+        module = "%s" % version
+        version = stringToVersion(version)
+
+    module = module.lower()
+
+    try:
+        import pykickstart.handlers
+        sys.path.extend(pykickstart.handlers.__path__)
+        found = imputil.imp.find_module(module)
+        loaded = imputil.imp.load_module(module, found[0], found[1], found[2])
+
+        for (k, v) in loaded.__dict__.iteritems():
+            if k.lower().endswith("%shandler" % module):
+                return v
+    except:
+        raise KickstartVersionError(_("Unsupported version specified: %s") % version)
+
+def makeVersion(version=DEVEL):
+    """Return a new instance of the syntax handler for version.  version can be
+       either a string or the matching constant.  This function is useful for
+       standalone programs which just need to handle a specific version of
+       kickstart syntax (as provided by a command line argument, for example)
+       and need to instantiate the correct object.
+    """
+    cl = returnClassForVersion(version)
+    return cl()
diff --git a/scripts/lib/wic/__init__.py b/scripts/lib/wic/__init__.py
new file mode 100644
index 0000000..63c1d9c
--- /dev/null
+++ b/scripts/lib/wic/__init__.py
@@ -0,0 +1,4 @@
+import os, sys
+
+cur_path = os.path.dirname(__file__) or '.'
+sys.path.insert(0, cur_path + '/3rdparty')
diff --git a/scripts/lib/wic/__version__.py b/scripts/lib/wic/__version__.py
new file mode 100644
index 0000000..5452a46
--- /dev/null
+++ b/scripts/lib/wic/__version__.py
@@ -0,0 +1 @@
+VERSION = "2.00"
diff --git a/scripts/lib/wic/canned-wks/directdisk-gpt.wks b/scripts/lib/wic/canned-wks/directdisk-gpt.wks
new file mode 100644
index 0000000..ea01cf3
--- /dev/null
+++ b/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"
+
diff --git a/scripts/lib/wic/canned-wks/directdisk-multi-rootfs.wks b/scripts/lib/wic/canned-wks/directdisk-multi-rootfs.wks
new file mode 100644
index 0000000..8a81f8f
--- /dev/null
+++ b/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"
+
diff --git a/scripts/lib/wic/canned-wks/directdisk.wks b/scripts/lib/wic/canned-wks/directdisk.wks
new file mode 100644
index 0000000..af4c9ea
--- /dev/null
+++ b/scripts/lib/wic/canned-wks/directdisk.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
+
+bootloader  --timeout=0  --append="rootwait rootfstype=ext4 video=vesafb vga=0x318 console=tty0"
+
diff --git a/scripts/lib/wic/canned-wks/mkefidisk.wks b/scripts/lib/wic/canned-wks/mkefidisk.wks
new file mode 100644
index 0000000..696e94e
--- /dev/null
+++ b/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
+
+part swap --ondisk sda --size 44 --label swap1 --fstype=swap
+
+bootloader  --timeout=10  --append="rootwait rootfstype=ext4 console=ttyPCH0,115200 console=tty0 vmalloc=256MB snd-hda-intel.enable_msi=0"
diff --git a/scripts/lib/wic/canned-wks/mkgummidisk.wks b/scripts/lib/wic/canned-wks/mkgummidisk.wks
new file mode 100644
index 0000000..66a22f6
--- /dev/null
+++ b/scripts/lib/wic/canned-wks/mkgummidisk.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=gummiboot" --ondisk sda --label msdos --active --align 1024
+
+part / --source rootfs --ondisk sda --fstype=ext4 --label platform --align 1024
+
+part swap --ondisk sda --size 44 --label swap1 --fstype=swap
+
+bootloader  --timeout=10  --append="rootwait rootfstype=ext4 console=ttyPCH0,115200 console=tty0 vmalloc=256MB snd-hda-intel.enable_msi=0"
diff --git a/scripts/lib/wic/canned-wks/mkhybridiso.wks b/scripts/lib/wic/canned-wks/mkhybridiso.wks
new file mode 100644
index 0000000..9d34e9b
--- /dev/null
+++ b/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 --fstype=ext4
+
+bootloader  --timeout=15  --append=""
diff --git a/scripts/lib/wic/canned-wks/qemux86-directdisk.wks b/scripts/lib/wic/canned-wks/qemux86-directdisk.wks
new file mode 100644
index 0000000..8fc38b5
--- /dev/null
+++ b/scripts/lib/wic/canned-wks/qemux86-directdisk.wks
@@ -0,0 +1,10 @@
+# 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.
+
+
+part /boot --source bootimg-pcbios --ondisk sda --label boot --active --align 1024
+part / --source rootfs --ondisk sda --fstype=ext4 --label platform --align 1024
+
+bootloader  --timeout=0  --append="vga=0 uvesafb.mode_option=640x480-32 root=/dev/vda2 rw mem=256M ip=192.168.7.2::192.168.7.1:255.255.255.0 oprofile.timer=1 rootfstype=ext4 "
+
diff --git a/scripts/lib/wic/canned-wks/sdimage-bootpart.wks b/scripts/lib/wic/canned-wks/sdimage-bootpart.wks
new file mode 100644
index 0000000..7ffd632
--- /dev/null
+++ b/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 mmcblk --fstype=vfat --label boot --active --align 4 --size 16
+part / --source rootfs --ondisk mmcblk --fstype=ext4 --label root --align 4
diff --git a/scripts/lib/wic/conf.py b/scripts/lib/wic/conf.py
new file mode 100644
index 0000000..1d4363a
--- /dev/null
+++ b/scripts/lib/wic/conf.py
@@ -0,0 +1,100 @@
+#!/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.
+
+import os
+
+from wic import msger
+from wic import kickstart
+from wic.utils import misc
+
+
+def get_siteconf():
+    wic_path = os.path.dirname(__file__)
+    eos = wic_path.find('scripts') + len('scripts')
+    scripts_path = wic_path[:eos]
+
+    return scripts_path + "/lib/image/config/wic.conf"
+
+class ConfigMgr(object):
+    DEFAULTS = {
+        'common': {
+            "distro_name": "Default Distribution",
+            "plugin_dir": "/usr/lib/wic/plugins"}, # TODO use prefix also?
+        'create': {
+            "tmpdir": '/var/tmp/wic',
+            "outdir": './wic-output',
+            "release": None,
+            "logfile": None,
+            "name_prefix": None,
+            "name_suffix": None}
+        }
+
+    # make the manager class as singleton
+    _instance = None
+    def __new__(cls, *args, **kwargs):
+        if not cls._instance:
+            cls._instance = super(ConfigMgr, cls).__new__(cls, *args, **kwargs)
+
+        return cls._instance
+
+    def __init__(self, ksconf=None, siteconf=None):
+        # reset config options
+        self.reset()
+
+        if not siteconf:
+            siteconf = get_siteconf()
+
+        # initial options from siteconf
+        self._siteconf = siteconf
+
+        if ksconf:
+            self._ksconf = ksconf
+
+    def reset(self):
+        self.__ksconf = None
+        self.__siteconf = None
+        self.create = {}
+
+        # initialize the values with defaults
+        for sec, vals in self.DEFAULTS.iteritems():
+            setattr(self, sec, vals)
+
+    def __set_ksconf(self, ksconf):
+        if not os.path.isfile(ksconf):
+            msger.error('Cannot find ks file: %s' % ksconf)
+
+        self.__ksconf = ksconf
+        self._parse_kickstart(ksconf)
+    def __get_ksconf(self):
+        return self.__ksconf
+    _ksconf = property(__get_ksconf, __set_ksconf)
+
+    def _parse_kickstart(self, ksconf=None):
+        if not ksconf:
+            return
+
+        ksobj = kickstart.read_kickstart(ksconf)
+
+        self.create['ks'] = ksobj
+        self.create['name'] = os.path.splitext(os.path.basename(ksconf))[0]
+
+        self.create['name'] = misc.build_name(ksconf,
+                                              self.create['release'],
+                                              self.create['name_prefix'],
+                                              self.create['name_suffix'])
+
+configmgr = ConfigMgr()
diff --git a/scripts/lib/wic/config/wic.conf b/scripts/lib/wic/config/wic.conf
new file mode 100644
index 0000000..a51bcb5
--- /dev/null
+++ b/scripts/lib/wic/config/wic.conf
@@ -0,0 +1,6 @@
+[common]
+; general settings
+distro_name = OpenEmbedded
+
+[create]
+; settings for create subcommand
diff --git a/scripts/lib/wic/creator.py b/scripts/lib/wic/creator.py
new file mode 100644
index 0000000..5231297
--- /dev/null
+++ b/scripts/lib/wic/creator.py
@@ -0,0 +1,124 @@
+#!/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.
+
+import os, sys
+from optparse import OptionParser, SUPPRESS_HELP
+
+from wic import msger
+from wic.utils import errors
+from wic.conf import configmgr
+from wic.plugin import pluginmgr
+
+
+class Creator(object):
+    """${name}: create an image
+
+    Usage:
+        ${name} SUBCOMMAND <ksfile> [OPTS]
+
+    ${command_list}
+    ${option_list}
+    """
+
+    name = 'wic create(cr)'
+
+    def __init__(self, *args, **kwargs):
+        self._subcmds = {}
+
+        # get cmds from pluginmgr
+        # mix-in do_subcmd interface
+        for subcmd, klass in pluginmgr.get_plugins('imager').iteritems():
+            if not hasattr(klass, 'do_create'):
+                msger.warning("Unsupported subcmd: %s" % subcmd)
+                continue
+
+            func = getattr(klass, 'do_create')
+            self._subcmds[subcmd] = func
+
+    def get_optparser(self):
+        optparser = OptionParser()
+        optparser.add_option('-d', '--debug', action='store_true',
+                             dest='debug',
+                             help=SUPPRESS_HELP)
+        optparser.add_option('-v', '--verbose', action='store_true',
+                             dest='verbose',
+                             help=SUPPRESS_HELP)
+        optparser.add_option('', '--logfile', type='string', dest='logfile',
+                             default=None,
+                             help='Path of logfile')
+        optparser.add_option('-c', '--config', type='string', dest='config',
+                             default=None,
+                             help='Specify config file for wic')
+        optparser.add_option('-o', '--outdir', type='string', action='store',
+                             dest='outdir', default=None,
+                             help='Output directory')
+        optparser.add_option('', '--tmpfs', action='store_true', dest='enabletmpfs',
+                             help='Setup tmpdir as tmpfs to accelerate, experimental'
+                                  ' feature, use it if you have more than 4G memory')
+        return optparser
+
+    def postoptparse(self, options):
+        abspath = lambda pth: os.path.abspath(os.path.expanduser(pth))
+
+        if options.verbose:
+            msger.set_loglevel('verbose')
+        if options.debug:
+            msger.set_loglevel('debug')
+
+        if options.logfile:
+            logfile_abs_path = abspath(options.logfile)
+            if os.path.isdir(logfile_abs_path):
+                raise errors.Usage("logfile's path %s should be file"
+                                   % options.logfile)
+            if not os.path.exists(os.path.dirname(logfile_abs_path)):
+                os.makedirs(os.path.dirname(logfile_abs_path))
+            msger.set_interactive(False)
+            msger.set_logfile(logfile_abs_path)
+            configmgr.create['logfile'] = options.logfile
+
+        if options.config:
+            configmgr.reset()
+            configmgr._siteconf = options.config
+
+        if options.outdir is not None:
+            configmgr.create['outdir'] = abspath(options.outdir)
+
+        cdir = 'outdir'
+        if os.path.exists(configmgr.create[cdir]) \
+           and not os.path.isdir(configmgr.create[cdir]):
+            msger.error('Invalid directory specified: %s' \
+                        % configmgr.create[cdir])
+
+        if options.enabletmpfs:
+            configmgr.create['enabletmpfs'] = options.enabletmpfs
+
+    def main(self, argv=None):
+        if argv is None:
+            argv = sys.argv
+        else:
+            argv = argv[:] # don't modify caller's list
+
+        pname = argv[0]
+        if pname not in self._subcmds:
+            msger.error('Unknown plugin: %s' % pname)
+
+        optparser = self.get_optparser()
+        options, args = optparser.parse_args(argv)
+
+        self.postoptparse(options)
+
+        return self._subcmds[pname](options, *args[1:])
diff --git a/scripts/lib/wic/engine.py b/scripts/lib/wic/engine.py
new file mode 100644
index 0000000..76b93e8
--- /dev/null
+++ b/scripts/lib/wic/engine.py
@@ -0,0 +1,220 @@
+# 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 os
+import sys
+
+from wic import msger, creator
+from wic.utils import misc
+from wic.plugin import pluginmgr
+from wic.utils.oe import misc
+
+
+def verify_build_env():
+    """
+    Verify that the build environment is sane.
+
+    Returns True if it is, false otherwise
+    """
+    if not os.environ.get("BUILDDIR"):
+        print "BUILDDIR not found, exiting. (Did you forget to source oe-init-build-env?)"
+        sys.exit(1)
+
+    return True
+
+
+CANNED_IMAGE_DIR = "lib/wic/canned-wks" # relative to scripts
+SCRIPTS_CANNED_IMAGE_DIR = "scripts/" + CANNED_IMAGE_DIR
+
+def build_canned_image_list(path):
+    layers_path = misc.get_bitbake_var("BBLAYERS")
+    canned_wks_layer_dirs = []
+
+    if layers_path is not None:
+        for layer_path in layers_path.split():
+            cpath = os.path.join(layer_path, SCRIPTS_CANNED_IMAGE_DIR)
+            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_source_plugins()
+
+    for plugin in plugins:
+        print "  %s" % plugin
+
+
+def wic_create(wks_file, rootfs_dir, bootimg_dir, kernel_dir,
+               native_sysroot, scripts_path, image_output_dir,
+               compressor, debug):
+    """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
+    scripts_path - absolute path to /scripts dir
+    image_output_dir - dirname to create for image
+    compressor - compressor utility to compress the image
+
+    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:
+        print "BUILDDIR not found, exiting. (Did you forget to source oe-init-build-env?)"
+        sys.exit(1)
+
+    if debug:
+        msger.set_loglevel('debug')
+
+    crobj = creator.Creator()
+
+    crobj.main(["direct", native_sysroot, kernel_dir, bootimg_dir, rootfs_dir,
+                wks_file, image_output_dir, oe_builddir, compressor or ""])
+
+    print "\nThe 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 len(args) < 1:
+        return False
+
+    if args == ["images"]:
+        list_canned_images(scripts_path)
+        return True
+    elif args == ["source-plugins"]:
+        list_source_plugins()
+        return True
+    elif len(args) == 2 and args[1] == "help":
+        wks_file = args[0]
+        fullpath = find_canned_image(scripts_path, wks_file)
+        if not fullpath:
+            print "No image named %s found, exiting. "\
+                  "(Use 'wic list images' to list available images, or "\
+                  "specify a fully-qualified OE kickstart (.wks) "\
+                  "filename)\n" % wks_file
+            sys.exit(1)
+        list_canned_image_help(scripts_path, fullpath)
+        return True
+
+    return False
diff --git a/scripts/lib/wic/help.py b/scripts/lib/wic/help.py
new file mode 100644
index 0000000..9a778b6
--- /dev/null
+++ b/scripts/lib/wic/help.py
@@ -0,0 +1,747 @@
+# 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.plugin import pluginmgr, PLUGIN_TYPES
+
+def subcommand_error(args):
+    logging.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)
+
+    return True
+
+
+def wic_help(args, usage_str, subcommands):
+    """
+    Subcommand help dispatcher.
+    """
+    if len(args) == 1 or not display_help(args[1], 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).iteritems():
+            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:
+        logging.error("No subcommand specified, exiting")
+        parser.print_help()
+        return 1
+    elif args[0] == "help":
+        wic_help(args, main_command_usage, subcommands)
+    elif args[0] not in subcommands:
+        logging.error("Unsupported subcommand %s, exiting\n" % (args[0]))
+        parser.print_help()
+        return 1
+    else:
+        usage = subcommands.get(args[0], subcommand_error)[1]
+        subcommands.get(args[0], subcommand_error)[0](args[1:], 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>]
+            [-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.
+"""
+
+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]
+
+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.
+"""
+
+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_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_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.
+    The code that then needs to call the plugin methods uses
+    plugin.get_source_plugin_methods() to find the method(s) needed by
+    the call; this is done by filling up a dict with keys containing
+    the method names of interest - on success, these will be filled in
+    with the actual methods. Please see the implementation for
+    examples and 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.
+
+       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.
+
+         --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:
+
+             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.
+
+         --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.
+
+         --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.
+
+         --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.
+
+         --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.
+
+    * 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.
+
+      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.
+"""
diff --git a/scripts/lib/wic/imager/__init__.py b/scripts/lib/wic/imager/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/scripts/lib/wic/imager/__init__.py
diff --git a/scripts/lib/wic/imager/baseimager.py b/scripts/lib/wic/imager/baseimager.py
new file mode 100644
index 0000000..acbe948
--- /dev/null
+++ b/scripts/lib/wic/imager/baseimager.py
@@ -0,0 +1,192 @@
+#!/usr/bin/env python -tt
+#
+# Copyright (c) 2007 Red Hat  Inc.
+# Copyright (c) 2009, 2010, 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.
+
+from __future__ import with_statement
+import os
+import tempfile
+import shutil
+
+from wic import msger
+from wic.utils.errors import CreatorError
+from wic.utils import runner
+
+class BaseImageCreator(object):
+    """Base class for image creation.
+
+    BaseImageCreator is the simplest creator class available; it will
+    create a system image according to the supplied kickstart file.
+
+    e.g.
+
+      import wic.imgcreate as imgcreate
+      ks = imgcreate.read_kickstart("foo.ks")
+      imgcreate.ImageCreator(ks, "foo").create()
+    """
+
+    def __del__(self):
+        self.cleanup()
+
+    def __init__(self, createopts=None):
+        """Initialize an ImageCreator instance.
+
+        ks -- a pykickstart.KickstartParser instance; this instance will be
+              used to drive the install by e.g. providing the list of packages
+              to be installed, the system configuration and %post scripts
+
+        name -- a name for the image; used for e.g. image filenames or
+                filesystem labels
+        """
+
+        self.__builddir = None
+
+        self.ks = None
+        self.name = "target"
+        self.tmpdir = "/var/tmp/wic"
+        self.workdir = "/var/tmp/wic/build"
+
+        # setup tmpfs tmpdir when enabletmpfs is True
+        self.enabletmpfs = False
+
+        if createopts:
+            # Mapping table for variables that have different names.
+            optmap = {"outdir" : "destdir",
+                     }
+
+            # update setting from createopts
+            for key in createopts.keys():
+                if key in optmap:
+                    option = optmap[key]
+                else:
+                    option = key
+                setattr(self, option, createopts[key])
+
+            self.destdir = os.path.abspath(os.path.expanduser(self.destdir))
+
+        self._dep_checks = ["ls", "bash", "cp", "echo"]
+
+        # Output image file names
+        self.outimage = []
+
+        # No ks provided when called by convertor, so skip the dependency check
+        if self.ks:
+            # If we have btrfs partition we need to check necessary tools
+            for part in self.ks.handler.partition.partitions:
+                if part.fstype and part.fstype == "btrfs":
+                    self._dep_checks.append("mkfs.btrfs")
+                    break
+
+        # make sure the specified tmpdir and cachedir exist
+        if not os.path.exists(self.tmpdir):
+            os.makedirs(self.tmpdir)
+
+
+    #
+    # Hooks for subclasses
+    #
+    def _create(self):
+        """Create partitions for the disk image(s)
+
+        This is the hook where subclasses may create the partitions
+        that will be assembled into disk image(s).
+
+        There is no default implementation.
+        """
+        pass
+
+    def _cleanup(self):
+        """Undo anything performed in _create().
+
+        This is the hook where subclasses must undo anything which was
+        done in _create().
+
+        There is no default implementation.
+
+        """
+        pass
+
+    #
+    # Actual implementation
+    #
+    def __ensure_builddir(self):
+        if not self.__builddir is None:
+            return
+
+        try:
+            self.workdir = os.path.join(self.tmpdir, "build")
+            if not os.path.exists(self.workdir):
+                os.makedirs(self.workdir)
+            self.__builddir = tempfile.mkdtemp(dir=self.workdir,
+                                               prefix="imgcreate-")
+        except OSError as err:
+            raise CreatorError("Failed create build directory in %s: %s" %
+                               (self.tmpdir, err))
+
+    def __setup_tmpdir(self):
+        if not self.enabletmpfs:
+            return
+
+        runner.show('mount -t tmpfs -o size=4G tmpfs %s' % self.workdir)
+
+    def __clean_tmpdir(self):
+        if not self.enabletmpfs:
+            return
+
+        runner.show('umount -l %s' % self.workdir)
+
+    def create(self):
+        """Create partitions for the disk image(s)
+
+        Create the partitions that will be assembled into disk
+        image(s).
+        """
+        self.__setup_tmpdir()
+        self.__ensure_builddir()
+
+        self._create()
+
+    def cleanup(self):
+        """Undo anything performed in create().
+
+        Note, make sure to call this method once finished with the creator
+        instance in order to ensure no stale files are left on the host e.g.:
+
+          creator = ImageCreator(ks, name)
+          try:
+              creator.create()
+          finally:
+              creator.cleanup()
+
+        """
+        if not self.__builddir:
+            return
+
+        self._cleanup()
+
+        shutil.rmtree(self.__builddir, ignore_errors=True)
+        self.__builddir = None
+
+        self.__clean_tmpdir()
+
+
+    def print_outimage_info(self):
+        msg = "The new image can be found here:\n"
+        self.outimage.sort()
+        for path in self.outimage:
+            msg += '  %s\n' % os.path.abspath(path)
+
+        msger.info(msg)
diff --git a/scripts/lib/wic/imager/direct.py b/scripts/lib/wic/imager/direct.py
new file mode 100644
index 0000000..146a0d1
--- /dev/null
+++ b/scripts/lib/wic/imager/direct.py
@@ -0,0 +1,378 @@
+# 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' image creator class for 'wic'
+#
+# AUTHORS
+# Tom Zanussi <tom.zanussi (at] linux.intel.com>
+#
+
+import os
+import shutil
+
+from wic import kickstart, msger
+from wic.utils import fs_related
+from wic.utils.oe.misc import get_bitbake_var
+from wic.utils.partitionedfs import Image
+from wic.utils.errors import CreatorError, ImageError
+from wic.imager.baseimager import BaseImageCreator
+from wic.plugin import pluginmgr
+from wic.utils.oe.misc import exec_cmd
+
+disk_methods = {
+    "do_install_disk":None,
+}
+
+class DirectImageCreator(BaseImageCreator):
+    """
+    Installs a system into a file containing a partitioned disk image.
+
+    DirectImageCreator is an advanced ImageCreator subclass; 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.
+    """
+
+    def __init__(self, oe_builddir, image_output_dir, rootfs_dir, bootimg_dir,
+                 kernel_dir, native_sysroot, compressor, creatoropts=None):
+        """
+        Initialize a DirectImageCreator instance.
+
+        This method takes the same arguments as ImageCreator.__init__()
+        """
+        BaseImageCreator.__init__(self, creatoropts)
+
+        self.__image = None
+        self.__disks = {}
+        self.__disk_format = "direct"
+        self._disk_names = []
+        self.ptable_format = self.ks.handler.bootloader.ptable
+
+        self.oe_builddir = oe_builddir
+        if image_output_dir:
+            self.tmpdir = image_output_dir
+        self.rootfs_dir = rootfs_dir
+        self.bootimg_dir = bootimg_dir
+        self.kernel_dir = kernel_dir
+        self.native_sysroot = native_sysroot
+        self.compressor = compressor
+
+    def __get_part_num(self, num, parts):
+        """calculate the real partition number, accounting for partitions not
+        in the partition table and logical partitions
+        """
+        realnum = 0
+        for pnum, part in enumerate(parts, 1):
+            if not part.no_table:
+                realnum += 1
+            if pnum == num:
+                if  part.no_table:
+                    return 0
+                if self.ptable_format == 'msdos' and realnum > 3:
+                    # account for logical partition numbering, ex. sda5..
+                    return realnum + 1
+                return realnum
+
+    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._get_parts()):
+            shutil.copyfile(fstab_path, fstab_path + ".orig")
+
+            with open(fstab_path, "w") as fstab:
+                fstab.writelines(fstab_lines)
+
+            return fstab_path
+
+    def _update_fstab(self, fstab_lines, parts):
+        """Assume partition order same as in wks"""
+        updated = False
+        for num, part in enumerate(parts, 1):
+            pnum = self.__get_part_num(num, parts)
+            if not pnum or not part.mountpoint \
+               or part.mountpoint in ("/", "/boot"):
+                continue
+
+            # mmc device partitions are named mmcblk0p1, mmcblk0p2..
+            prefix = 'p' if  part.disk.startswith('mmcblk') else ''
+            device_name = "/dev/%s%s%d" % (part.disk, prefix, pnum)
+
+            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 set_bootimg_dir(self, bootimg_dir):
+        """
+        Accessor for bootimg_dir, the actual location used for the source
+        of the bootimg.  Should be set by source plugins (only if they
+        change the default bootimg source) so the correct info gets
+        displayed for print_outimage_info().
+        """
+        self.bootimg_dir = bootimg_dir
+
+    def _get_parts(self):
+        if not self.ks:
+            raise CreatorError("Failed to get partition info, "
+                               "please check your kickstart setting.")
+
+        # Set a default partition if no partition is given out
+        if not self.ks.handler.partition.partitions:
+            partstr = "part / --size 1900 --ondisk sda --fstype=ext3"
+            args = partstr.split()
+            part = self.ks.handler.partition.parse(args[1:])
+            if part not in self.ks.handler.partition.partitions:
+                self.ks.handler.partition.partitions.append(part)
+
+        # partitions list from kickstart file
+        return kickstart.get_partitions(self.ks)
+
+    def get_disk_names(self):
+        """ Returns a list of physical target disk names (e.g., 'sdb') which
+        will be created. """
+
+        if self._disk_names:
+            return self._disk_names
+
+        #get partition info from ks handler
+        parts = self._get_parts()
+
+        for i in range(len(parts)):
+            if parts[i].disk:
+                disk_name = parts[i].disk
+            else:
+                raise CreatorError("Failed to create disks, no --ondisk "
+                                   "specified in partition line of ks file")
+
+            if parts[i].mountpoint and not parts[i].fstype:
+                raise CreatorError("Failed to create disks, no --fstype "
+                                   "specified for partition with mountpoint "
+                                   "'%s' in the ks file")
+
+            self._disk_names.append(disk_name)
+
+        return self._disk_names
+
+    def _full_name(self, name, extention):
+        """ Construct full file name for a file we generate. """
+        return "%s-%s.%s" % (self.name, name, extention)
+
+    def _full_path(self, path, name, extention):
+        """ Construct full file path to a file we generate. """
+        return os.path.join(path, self._full_name(name, extention))
+
+    def get_default_source_plugin(self):
+        """
+        The default source plugin i.e. the plugin that's consulted for
+        overall image generation tasks outside of any particular
+        partition.  For convenience, we just hang it off the
+        bootloader handler since it's the one non-partition object in
+        any setup.  By default the default plugin is set to the same
+        plugin as the /boot partition; since we hang it off the
+        bootloader object, the default can be explicitly set using the
+        --source bootloader param.
+        """
+        return self.ks.handler.bootloader.source
+
+    #
+    # 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.
+        """
+        parts = self._get_parts()
+
+        self.__image = Image(self.native_sysroot)
+
+        for part in parts:
+            # as a convenience, set source to the boot partition source
+            # instead of forcing it to be set via bootloader --source
+            if not self.ks.handler.bootloader.source and part.mountpoint == "/boot":
+                self.ks.handler.bootloader.source = part.source
+
+        fstab_path = self._write_fstab(self.rootfs_dir.get("ROOTFS_DIR"))
+
+        for part in 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 = part.get_rootfs()
+                if 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:
+                        # convert from Kb to Mb
+                        part.size = int(round(float(rsize_bb) / 1024.))
+            # need to create the filesystems in order to get their
+            # sizes before we can add them and do the layout.
+            # Image.create() actually calls __format_disks() to create
+            # the disk images and carve out the partitions, then
+            # self.assemble() calls Image.assemble() which calls
+            # __write_partitition() for each partition to dd the fs
+            # into the partitions.
+            part.prepare(self, self.workdir, self.oe_builddir, self.rootfs_dir,
+                         self.bootimg_dir, self.kernel_dir, self.native_sysroot)
+
+
+            self.__image.add_partition(int(part.size),
+                                       part.disk,
+                                       part.mountpoint,
+                                       part.source_file,
+                                       part.fstype,
+                                       part.label,
+                                       fsopts=part.fsopts,
+                                       boot=part.active,
+                                       align=part.align,
+                                       no_table=part.no_table,
+                                       part_type=part.part_type,
+                                       uuid=part.uuid)
+
+        if fstab_path:
+            shutil.move(fstab_path + ".orig", fstab_path)
+
+        self.__image.layout_partitions(self.ptable_format)
+
+        self.__imgdir = self.workdir
+        for disk_name, disk in self.__image.disks.items():
+            full_path = self._full_path(self.__imgdir, disk_name, "direct")
+            msger.debug("Adding disk %s as %s with size %s bytes" \
+                        % (disk_name, full_path, disk['min_size']))
+            disk_obj = fs_related.DiskImage(full_path, disk['min_size'])
+            self.__disks[disk_name] = disk_obj
+            self.__image.add_disk(disk_name, disk_obj)
+
+        self.__image.create()
+
+    def assemble(self):
+        """
+        Assemble partitions into disk image(s)
+        """
+        for disk_name, disk in self.__image.disks.items():
+            full_path = self._full_path(self.__imgdir, disk_name, "direct")
+            msger.debug("Assembling disk %s as %s with size %s bytes" \
+                        % (disk_name, full_path, disk['min_size']))
+            self.__image.assemble(full_path)
+
+    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.get_default_source_plugin()
+        if source_plugin:
+            self._source_methods = pluginmgr.get_source_plugin_methods(source_plugin, disk_methods)
+            for disk_name, disk in self.__image.disks.items():
+                self._source_methods["do_install_disk"](disk, disk_name, self,
+                                                        self.workdir,
+                                                        self.oe_builddir,
+                                                        self.bootimg_dir,
+                                                        self.kernel_dir,
+                                                        self.native_sysroot)
+        # Compress the image
+        if self.compressor:
+            for disk_name, disk in self.__image.disks.items():
+                full_path = self._full_path(self.__imgdir, disk_name, "direct")
+                msger.debug("Compressing disk %s with %s" % \
+                            (disk_name, self.compressor))
+                exec_cmd("%s %s" % (self.compressor, full_path))
+
+    def print_outimage_info(self):
+        """
+        Print the image(s) and artifacts used, for the user.
+        """
+        msg = "The new image(s) can be found here:\n"
+
+        parts = self._get_parts()
+
+        for disk_name in self.__image.disks:
+            extension = "direct" + {"gzip": ".gz",
+                                    "bzip2": ".bz2",
+                                    "xz": ".xz",
+                                    "": ""}.get(self.compressor)
+            full_path = self._full_path(self.__imgdir, disk_name, extension)
+            msg += '  %s\n\n' % full_path
+
+        msg += 'The following build artifacts were used to create the image(s):\n'
+        for part in parts:
+            if part.get_rootfs() is None:
+                continue
+            if part.mountpoint == '/':
+                suffix = ':'
+            else:
+                suffix = '["%s"]:' % (part.mountpoint or part.label)
+            msg += '  ROOTFS_DIR%s%s\n' % (suffix.ljust(20), part.get_rootfs())
+
+        msg += '  BOOTIMG_DIR:                  %s\n' % self.bootimg_dir
+        msg += '  KERNEL_DIR:                   %s\n' % self.kernel_dir
+        msg += '  NATIVE_SYSROOT:               %s\n' % self.native_sysroot
+
+        msger.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
+        """
+        parts = self._get_parts()
+        for num, part in enumerate(parts, 1):
+            if part.mountpoint == "/":
+                if part.uuid:
+                    return "PARTUUID=%s" % part.uuid
+                else:
+                    suffix = 'p' if part.disk.startswith('mmcblk') else ''
+                    pnum = self.__get_part_num(num, parts)
+                    return "/dev/%s%s%-d" % (part.disk, suffix, pnum)
+
+    def _cleanup(self):
+        if not self.__image is None:
+            try:
+                self.__image.cleanup()
+            except ImageError, err:
+                msger.warning("%s" % err)
+
diff --git a/scripts/lib/wic/kickstart/__init__.py b/scripts/lib/wic/kickstart/__init__.py
new file mode 100644
index 0000000..c9b0e51
--- /dev/null
+++ b/scripts/lib/wic/kickstart/__init__.py
@@ -0,0 +1,122 @@
+#!/usr/bin/env python -tt
+#
+# Copyright (c) 2007 Red Hat, Inc.
+# Copyright (c) 2009, 2010, 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.
+
+import os, sys, re
+import shutil
+import subprocess
+import string
+
+import pykickstart.sections as kssections
+import pykickstart.commands as kscommands
+import pykickstart.constants as ksconstants
+import pykickstart.errors as kserrors
+import pykickstart.parser as ksparser
+import pykickstart.version as ksversion
+from pykickstart.handlers.control import commandMap
+from pykickstart.handlers.control import dataMap
+
+from wic import msger
+from wic.utils import errors, misc, runner, fs_related as fs
+from custom_commands import wicboot, partition
+
+def read_kickstart(path):
+    """Parse a kickstart file and return a KickstartParser instance.
+
+    This is a simple utility function which takes a path to a kickstart file,
+    parses it and returns a pykickstart KickstartParser instance which can
+    be then passed to an ImageCreator constructor.
+
+    If an error occurs, a CreatorError exception is thrown.
+    """
+
+    #version = ksversion.makeVersion()
+    #ks = ksparser.KickstartParser(version)
+
+    using_version = ksversion.DEVEL
+    commandMap[using_version]["bootloader"] = wicboot.Wic_Bootloader
+    commandMap[using_version]["part"] = partition.Wic_Partition
+    commandMap[using_version]["partition"] = partition.Wic_Partition
+    dataMap[using_version]["PartData"] = partition.Wic_PartData
+    superclass = ksversion.returnClassForVersion(version=using_version)
+
+    class KSHandlers(superclass):
+        def __init__(self):
+            superclass.__init__(self, mapping=commandMap[using_version])
+
+    kickstart = ksparser.KickstartParser(KSHandlers(), errorsAreFatal=True)
+
+    try:
+        kickstart.readKickstart(path)
+    except (kserrors.KickstartParseError, kserrors.KickstartError), err:
+        msger.warning("Errors occurred when parsing kickstart file: %s\n" % path)
+        msger.error("%s" % err)
+
+    return kickstart
+
+def get_image_size(kickstart, default=None):
+    __size = 0
+    for part in kickstart.handler.partition.partitions:
+        if part.mountpoint == "/" and part.size:
+            __size = part.size
+    if __size > 0:
+        return int(__size) * 1024L
+    else:
+        return default
+
+def get_image_fstype(kickstart, default=None):
+    for part in kickstart.handler.partition.partitions:
+        if part.mountpoint == "/" and part.fstype:
+            return part.fstype
+    return default
+
+def get_image_fsopts(kickstart, default=None):
+    for part in kickstart.handler.partition.partitions:
+        if part.mountpoint == "/" and part.fsopts:
+            return part.fsopts
+    return default
+
+def get_timeout(kickstart, default=None):
+    if not hasattr(kickstart.handler.bootloader, "timeout"):
+        return default
+    if kickstart.handler.bootloader.timeout is None:
+        return default
+    return int(kickstart.handler.bootloader.timeout)
+
+def get_kernel_args(kickstart, default="ro rd.live.image"):
+    if not hasattr(kickstart.handler.bootloader, "appendLine"):
+        return default
+    if kickstart.handler.bootloader.appendLine is None:
+        return default
+    return "%s %s" %(default, kickstart.handler.bootloader.appendLine)
+
+def get_menu_args(kickstart, default=""):
+    if not hasattr(kickstart.handler.bootloader, "menus"):
+        return default
+    if kickstart.handler.bootloader.menus in (None, ""):
+        return default
+    return "%s" % kickstart.handler.bootloader.menus
+
+def get_default_kernel(kickstart, default=None):
+    if not hasattr(kickstart.handler.bootloader, "default"):
+        return default
+    if not kickstart.handler.bootloader.default:
+        return default
+    return kickstart.handler.bootloader.default
+
+def get_partitions(kickstart):
+    return kickstart.handler.partition.partitions
diff --git a/scripts/lib/wic/kickstart/custom_commands/__init__.py b/scripts/lib/wic/kickstart/custom_commands/__init__.py
new file mode 100644
index 0000000..e4ae406
--- /dev/null
+++ b/scripts/lib/wic/kickstart/custom_commands/__init__.py
@@ -0,0 +1,7 @@
+from partition import Wic_Partition
+from partition import Wic_PartData
+
+__all__ = (
+    "Wic_Partition",
+    "Wic_PartData",
+)
diff --git a/scripts/lib/wic/kickstart/custom_commands/partition.py b/scripts/lib/wic/kickstart/custom_commands/partition.py
new file mode 100644
index 0000000..eee25a4
--- /dev/null
+++ b/scripts/lib/wic/kickstart/custom_commands/partition.py
@@ -0,0 +1,526 @@
+# 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 the OpenEmbedded partition object definitions.
+#
+# AUTHORS
+# Tom Zanussi <tom.zanussi (at] linux.intel.com>
+#
+
+import os
+import tempfile
+import uuid
+from optparse import OptionValueError
+
+from pykickstart.commands.partition import FC4_PartData, FC4_Partition
+from wic.utils.oe.misc import msger, parse_sourceparams
+from wic.utils.oe.misc import exec_cmd, exec_native_cmd
+from wic.plugin import pluginmgr
+
+partition_methods = {
+    "do_stage_partition":None,
+    "do_prepare_partition":None,
+    "do_configure_partition":None,
+}
+
+class Wic_PartData(FC4_PartData):
+    removedKeywords = FC4_PartData.removedKeywords
+    removedAttrs = FC4_PartData.removedAttrs
+
+    def __init__(self, *args, **kwargs):
+        FC4_PartData.__init__(self, *args, **kwargs)
+        self.deleteRemovedAttrs()
+        self.align = kwargs.get("align", None)
+        self.extopts = kwargs.get("extopts", None)
+        self.part_type = kwargs.get("part_type", None)
+        self.source = kwargs.get("source", None)
+        self.sourceparams = kwargs.get("sourceparams", None)
+        self.rootfs = kwargs.get("rootfs-dir", None)
+        self.no_table = kwargs.get("no-table", False)
+        self.extra_space = kwargs.get("extra-space", "10M")
+        self.overhead_factor = kwargs.get("overhead-factor", 1.3)
+        self._use_uuid = False
+        self.uuid = kwargs.get("uuid", None)
+        self.use_uuid = kwargs.get("use-uuid", False)
+        self.source_file = ""
+        self.size = 0
+
+    def _getArgsAsStr(self):
+        retval = FC4_PartData._getArgsAsStr(self)
+
+        if self.align:
+            retval += " --align=%d" % self.align
+        if self.extopts:
+            retval += " --extoptions=%s" % self.extopts
+        if self.part_type:
+            retval += " --part-type=%s" % self.part_type
+        if self.source:
+            retval += " --source=%s" % self.source
+            if self.sourceparams:
+                retval += " --sourceparams=%s" % self.sourceparams
+            if self.rootfs:
+                retval += " --rootfs-dir=%s" % self.rootfs
+        if self.no_table:
+            retval += " --no-table"
+        if self.use_uuid:
+            retval += " --use-uuid"
+        if self.uuid:
+            retval += " --uuid=%s" % self.uuid
+        retval += " --extra-space=%s" % self.extra_space
+        retval += " --overhead-factor=%f" % self.overhead_factor
+
+        return retval
+
+    @property
+    def use_uuid(self):
+        return self._use_uuid
+
+    @use_uuid.setter
+    def use_uuid(self, value):
+        self._use_uuid = value
+        if value and not self.uuid:
+            self.uuid = str(uuid.uuid4())
+
+    def get_rootfs(self):
+        """
+        Acessor for rootfs dir
+        """
+        return self.rootfs
+
+    def set_rootfs(self, rootfs):
+        """
+        Acessor for actual rootfs dir, which must be set by source
+        plugins.
+        """
+        self.rootfs = rootfs
+
+    def get_size(self):
+        """
+        Accessor for partition size, 0 or --size before set_size().
+        """
+        return self.size
+
+    def set_size(self, size):
+        """
+        Accessor for actual partition size, which must be set by source
+        plugins.
+        """
+        self.size = size
+
+    def set_source_file(self, source_file):
+        """
+        Accessor for source_file, the location of the generated partition
+        image, which must be set by source plugins.
+        """
+        self.source_file = 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.
+        """
+        msger.debug("Requested partition size for %s: %d" % \
+                    (self.mountpoint, self.size))
+
+        if not self.size:
+            return 0
+
+        requested_blocks = self.size
+
+        msger.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 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.
+        """
+        self.sourceparams_dict = {}
+
+        if self.sourceparams:
+            self.sourceparams_dict = parse_sourceparams(self.sourceparams)
+
+        if not self.source:
+            if not self.size:
+                msger.error("The %s partition has a size of zero.  Please "
+                            "specify a non-zero --size for that partition." % \
+                            self.mountpoint)
+            if self.fstype and self.fstype == "swap":
+                self.prepare_swap_partition(cr_workdir, oe_builddir,
+                                            native_sysroot)
+            elif self.fstype:
+                rootfs = "%s/fs_%s.%s.%s" % (cr_workdir, self.label,
+                                             self.lineno, self.fstype)
+                if os.path.isfile(rootfs):
+                    os.remove(rootfs)
+                for prefix in ("ext", "btrfs", "vfat", "squashfs"):
+                    if self.fstype.startswith(prefix):
+                        method = getattr(self,
+                                         "prepare_empty_partition_" + prefix)
+                        method(rootfs, oe_builddir, native_sysroot)
+                        self.source_file = rootfs
+                        break
+            return
+
+        plugins = pluginmgr.get_source_plugins()
+
+        if self.source not in plugins:
+            msger.error("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))
+
+        self._source_methods = pluginmgr.get_source_plugin_methods(\
+                                   self.source, partition_methods)
+        self._source_methods["do_configure_partition"](self, self.sourceparams_dict,
+                                                       creator, cr_workdir,
+                                                       oe_builddir,
+                                                       bootimg_dir,
+                                                       kernel_dir,
+                                                       native_sysroot)
+        self._source_methods["do_stage_partition"](self, self.sourceparams_dict,
+                                                   creator, cr_workdir,
+                                                   oe_builddir,
+                                                   bootimg_dir, kernel_dir,
+                                                   native_sysroot)
+        self._source_methods["do_prepare_partition"](self, self.sourceparams_dict,
+                                                     creator, cr_workdir,
+                                                     oe_builddir,
+                                                     bootimg_dir, kernel_dir, rootfs_dir,
+                                                     native_sysroot)
+
+    def prepare_rootfs_from_fs_image(self, cr_workdir, oe_builddir,
+                                     rootfs_dir):
+        """
+        Handle an already-created partition e.g. xxx.ext3
+        """
+        rootfs = oe_builddir
+        du_cmd = "du -Lbks %s" % rootfs
+        out = exec_cmd(du_cmd)
+        rootfs_size = out.split()[0]
+
+        self.size = rootfs_size
+        self.source_file = rootfs
+
+    def prepare_rootfs(self, cr_workdir, oe_builddir, rootfs_dir,
+                       native_sysroot):
+        """
+        Prepare content for a rootfs partition i.e. create a partition
+        and fill it from a /rootfs dir.
+
+        Currently handles ext2/3/4, btrfs and vfat.
+        """
+        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/usr/bin/pseudo " % native_sysroot
+
+        rootfs = "%s/rootfs_%s.%s.%s" % (cr_workdir, self.label,
+                                         self.lineno, self.fstype)
+        if os.path.isfile(rootfs):
+            os.remove(rootfs)
+
+        for prefix in ("ext", "btrfs", "vfat", "squashfs"):
+            if self.fstype.startswith(prefix):
+                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 = out.split()[0]
+
+                break
+
+    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])
+
+        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
+
+        msger.debug("Added %d extra blocks to %s to get to %d total blocks" % \
+                    (extra_blocks, self.mountpoint, rootfs_size))
+
+        dd_cmd = "dd if=/dev/zero of=%s bs=1024 seek=%d count=0 bs=1k" % \
+            (rootfs, rootfs_size)
+        exec_cmd(dd_cmd)
+
+        extra_imagecmd = "-i 8192"
+
+        label_str = ""
+        if self.label:
+            label_str = "-L %s" % self.label
+
+        mkfs_cmd = "mkfs.%s -F %s %s %s -d %s" % \
+            (self.fstype, extra_imagecmd, rootfs, label_str, rootfs_dir)
+        exec_native_cmd(pseudo + mkfs_cmd, native_sysroot)
+
+    def prepare_rootfs_btrfs(self, rootfs, oe_builddir, rootfs_dir,
+                             native_sysroot, pseudo):
+        """
+        Prepare content for a btrfs rootfs partition.
+
+        Currently handles ext2/3/4 and btrfs.
+        """
+        du_cmd = "du -ks %s" % rootfs_dir
+        out = exec_cmd(du_cmd)
+        actual_rootfs_size = int(out.split()[0])
+
+        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
+
+        msger.debug("Added %d extra blocks to %s to get to %d total blocks" % \
+                    (extra_blocks, self.mountpoint, rootfs_size))
+
+        dd_cmd = "dd if=/dev/zero of=%s bs=1024 seek=%d count=0 bs=1k" % \
+            (rootfs, rootfs_size)
+        exec_cmd(dd_cmd)
+
+        label_str = ""
+        if self.label:
+            label_str = "-L %s" % self.label
+
+        mkfs_cmd = "mkfs.%s -b %d -r %s %s %s" % \
+            (self.fstype, rootfs_size * 1024, rootfs_dir, label_str, rootfs)
+        exec_native_cmd(pseudo + mkfs_cmd, native_sysroot)
+
+    def prepare_rootfs_vfat(self, rootfs, oe_builddir, rootfs_dir,
+                            native_sysroot, pseudo):
+        """
+        Prepare content for a vfat rootfs partition.
+        """
+        du_cmd = "du -bks %s" % rootfs_dir
+        out = exec_cmd(du_cmd)
+        blocks = int(out.split()[0])
+
+        extra_blocks = self.get_extra_block_count(blocks)
+        if extra_blocks < self.extra_space:
+            extra_blocks = self.extra_space
+
+        blocks += extra_blocks
+
+        msger.debug("Added %d extra blocks to %s to get to %d total blocks" % \
+                    (extra_blocks, self.mountpoint, blocks))
+
+        # Ensure total sectors is an integral number of sectors per
+        # track or mcopy will complain. Sectors are 512 bytes, and we
+        # generate images with 32 sectors per track. This calculation
+        # is done in blocks, thus the mod by 16 instead of 32. Apply
+        # sector count fix only when needed.
+        if blocks % 16 != 0:
+            blocks += (16 - (blocks % 16))
+
+        label_str = "-n boot"
+        if self.label:
+            label_str = "-n %s" % self.label
+
+        dosfs_cmd = "mkdosfs %s -S 512 -C %s %d" % (label_str, rootfs, blocks)
+        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)
+
+    def prepare_rootfs_squashfs(self, rootfs, oe_builddir, rootfs_dir,
+                                native_sysroot, pseudo):
+        """
+        Prepare content for a squashfs rootfs partition.
+        """
+        squashfs_cmd = "mksquashfs %s %s -noappend" % \
+                       (rootfs_dir, rootfs)
+        exec_native_cmd(pseudo + squashfs_cmd, native_sysroot)
+
+    def prepare_empty_partition_ext(self, rootfs, oe_builddir,
+                                    native_sysroot):
+        """
+        Prepare an empty ext2/3/4 partition.
+        """
+        dd_cmd = "dd if=/dev/zero of=%s bs=1k seek=%d count=0" % \
+            (rootfs, self.size)
+        exec_cmd(dd_cmd)
+
+        extra_imagecmd = "-i 8192"
+
+        label_str = ""
+        if self.label:
+            label_str = "-L %s" % self.label
+
+        mkfs_cmd = "mkfs.%s -F %s %s %s" % \
+            (self.fstype, extra_imagecmd, label_str, rootfs)
+        exec_native_cmd(mkfs_cmd, native_sysroot)
+
+    def prepare_empty_partition_btrfs(self, rootfs, oe_builddir,
+                                      native_sysroot):
+        """
+        Prepare an empty btrfs partition.
+        """
+        dd_cmd = "dd if=/dev/zero of=%s bs=1k seek=%d count=0" % \
+            (rootfs, self.size)
+        exec_cmd(dd_cmd)
+
+        label_str = ""
+        if self.label:
+            label_str = "-L %s" % self.label
+
+        mkfs_cmd = "mkfs.%s -b %d %s %s" % \
+            (self.fstype, self.size * 1024, label_str, rootfs)
+        exec_native_cmd(mkfs_cmd, native_sysroot)
+
+    def prepare_empty_partition_vfat(self, rootfs, oe_builddir,
+                                     native_sysroot):
+        """
+        Prepare an empty vfat partition.
+        """
+        blocks = self.size
+
+        label_str = "-n boot"
+        if self.label:
+            label_str = "-n %s" % self.label
+
+        dosfs_cmd = "mkdosfs %s -S 512 -C %s %d" % (label_str, rootfs, blocks)
+        exec_native_cmd(dosfs_cmd, native_sysroot)
+
+        chmod_cmd = "chmod 644 %s" % rootfs
+        exec_cmd(chmod_cmd)
+
+    def prepare_empty_partition_squashfs(self, cr_workdir, oe_builddir,
+                                         native_sysroot):
+        """
+        Prepare an empty squashfs partition.
+        """
+        msger.warning("Creating of an empty squashfs %s partition was attempted. " \
+                      "Proceeding as requested." % self.mountpoint)
+
+        path = "%s/fs_%s.%s" % (cr_workdir, self.label, self.fstype)
+        os.path.isfile(path) and os.remove(path)
+
+        # it is not possible to create a squashfs without source data,
+        # thus prepare an empty temp dir that is used as source
+        tmpdir = tempfile.mkdtemp()
+
+        squashfs_cmd = "mksquashfs %s %s -noappend" % \
+                       (tmpdir, path)
+        exec_native_cmd(squashfs_cmd, native_sysroot)
+
+        os.rmdir(tmpdir)
+
+        # get the rootfs size in the right units for kickstart (kB)
+        du_cmd = "du -Lbks %s" % path
+        out = exec_cmd(du_cmd)
+        fs_size = out.split()[0]
+
+        self.size = fs_size
+
+    def prepare_swap_partition(self, cr_workdir, oe_builddir, native_sysroot):
+        """
+        Prepare a swap partition.
+        """
+        path = "%s/fs.%s" % (cr_workdir, self.fstype)
+
+        dd_cmd = "dd if=/dev/zero of=%s bs=1k seek=%d count=0" % \
+            (path, self.size)
+        exec_cmd(dd_cmd)
+
+        import uuid
+        label_str = ""
+        if self.label:
+            label_str = "-L %s" % self.label
+        mkswap_cmd = "mkswap %s -U %s %s" % (label_str, str(uuid.uuid1()), path)
+        exec_native_cmd(mkswap_cmd, native_sysroot)
+
+
+class Wic_Partition(FC4_Partition):
+    removedKeywords = FC4_Partition.removedKeywords
+    removedAttrs = FC4_Partition.removedAttrs
+
+    def _getParser(self):
+        def overhead_cb(option, opt_str, value, parser):
+            if value < 1:
+                raise OptionValueError("Option %s: invalid value: %r" % \
+                                       (option, value))
+            setattr(parser.values, option.dest, value)
+
+        parser = FC4_Partition._getParser(self)
+
+        # The alignment value is given in kBytes. e.g., value 8 means that
+        # the partition is aligned to start from 8096 byte boundary.
+        parser.add_option("--align", type="int", action="store", dest="align",
+                          default=None)
+        parser.add_option("--extoptions", type="string", action="store", dest="extopts",
+                          default=None)
+        parser.add_option("--part-type", type="string", action="store", dest="part_type",
+                          default=None)
+        # use specified source file to fill the partition
+        # and calculate partition size
+        parser.add_option("--source", type="string", action="store",
+                          dest="source", default=None)
+        # comma-separated list of param=value pairs
+        parser.add_option("--sourceparams", type="string", action="store",
+                          dest="sourceparams", default=None)
+        # use specified rootfs path to fill the partition
+        parser.add_option("--rootfs-dir", type="string", action="store",
+                          dest="rootfs", default=None)
+        # wether to add the partition in the partition table
+        parser.add_option("--no-table", dest="no_table", action="store_true",
+                          default=False)
+        # extra space beyond the partition size
+        parser.add_option("--extra-space", dest="extra_space", action="store",
+                          type="size", nargs=1, default="10M")
+        parser.add_option("--overhead-factor", dest="overhead_factor",
+                          action="callback", callback=overhead_cb, type="float",
+                          nargs=1, default=1.3)
+        parser.add_option("--use-uuid", dest="use_uuid", action="store_true",
+                          default=False)
+        parser.add_option("--uuid")
+
+        return parser
diff --git a/scripts/lib/wic/kickstart/custom_commands/wicboot.py b/scripts/lib/wic/kickstart/custom_commands/wicboot.py
new file mode 100644
index 0000000..a3e1852
--- /dev/null
+++ b/scripts/lib/wic/kickstart/custom_commands/wicboot.py
@@ -0,0 +1,60 @@
+# 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 module provides the OpenEmbedded bootloader object definitions.
+#
+# AUTHORS
+# Tom Zanussi <tom.zanussi (at] linux.intel.com>
+#
+from pykickstart.commands.bootloader import F8_Bootloader
+
+class Wic_Bootloader(F8_Bootloader):
+    def __init__(self, writePriority=10, appendLine="", driveorder=None,
+                 forceLBA=False, location="", md5pass="", password="",
+                 upgrade=False, menus=""):
+        F8_Bootloader.__init__(self, writePriority, appendLine, driveorder,
+                               forceLBA, location, md5pass, password, upgrade)
+
+        self.menus = ""
+        self.ptable = "msdos"
+        self.source = ""
+
+    def _getArgsAsStr(self):
+        retval = F8_Bootloader._getArgsAsStr(self)
+
+        if self.menus == "":
+            retval += " --menus=%s" %(self.menus,)
+        if self.ptable:
+            retval += " --ptable=\"%s\"" %(self.ptable,)
+        if self.source:
+            retval += " --source=%s" % self.source
+
+        return retval
+
+    def _getParser(self):
+        parser = F8_Bootloader._getParser(self)
+        parser.add_option("--menus", dest="menus")
+        parser.add_option("--ptable", dest="ptable", choices=("msdos", "gpt"),
+                          default="msdos")
+        # use specified source plugin to implement bootloader-specific methods
+        parser.add_option("--source", type="string", action="store",
+                      dest="source", default=None)
+        return parser
+
diff --git a/scripts/lib/wic/msger.py b/scripts/lib/wic/msger.py
new file mode 100644
index 0000000..b737554
--- /dev/null
+++ b/scripts/lib/wic/msger.py
@@ -0,0 +1,309 @@
+#!/usr/bin/env python -tt
+# vim: ai ts=4 sts=4 et sw=4
+#
+# Copyright (c) 2009, 2010, 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.
+
+import os
+import sys
+import re
+import time
+
+__ALL__ = ['set_mode',
+           'get_loglevel',
+           'set_loglevel',
+           'set_logfile',
+           'raw',
+           'debug',
+           'verbose',
+           'info',
+           'warning',
+           'error',
+           'ask',
+           'pause',
+          ]
+
+# COLORs in ANSI
+INFO_COLOR = 32 # green
+WARN_COLOR = 33 # yellow
+ERR_COLOR = 31 # red
+ASK_COLOR = 34 # blue
+NO_COLOR = 0
+
+PREFIX_RE = re.compile('^<(.*?)>\s*(.*)', re.S)
+
+INTERACTIVE = True
+
+LOG_LEVEL = 1
+LOG_LEVELS = {
+    'quiet': 0,
+    'normal': 1,
+    'verbose': 2,
+    'debug': 3,
+    'never': 4,
+}
+
+LOG_FILE_FP = None
+LOG_CONTENT = ''
+CATCHERR_BUFFILE_FD = -1
+CATCHERR_BUFFILE_PATH = None
+CATCHERR_SAVED_2 = -1
+
+def _general_print(head, color, msg=None, stream=None, level='normal'):
+    global LOG_CONTENT
+    if not stream:
+        stream = sys.stdout
+
+    if LOG_LEVELS[level] > LOG_LEVEL:
+        # skip
+        return
+
+    # encode raw 'unicode' str to utf8 encoded str
+    if msg and isinstance(msg, unicode):
+        msg = msg.encode('utf-8', 'ignore')
+
+    errormsg = ''
+    if CATCHERR_BUFFILE_FD > 0:
+        size = os.lseek(CATCHERR_BUFFILE_FD, 0, os.SEEK_END)
+        os.lseek(CATCHERR_BUFFILE_FD, 0, os.SEEK_SET)
+        errormsg = os.read(CATCHERR_BUFFILE_FD, size)
+        os.ftruncate(CATCHERR_BUFFILE_FD, 0)
+
+    # append error msg to LOG
+    if errormsg:
+        LOG_CONTENT += errormsg
+
+    # append normal msg to LOG
+    save_msg = msg.strip() if msg else None
+    if save_msg:
+        timestr = time.strftime("[%m/%d %H:%M:%S %Z] ", time.localtime())
+        LOG_CONTENT += timestr + save_msg + '\n'
+
+    if errormsg:
+        _color_print('', NO_COLOR, errormsg, stream, level)
+
+    _color_print(head, color, msg, stream, level)
+
+def _color_print(head, color, msg, stream, level):
+    colored = True
+    if color == NO_COLOR or \
+       not stream.isatty() or \
+       os.getenv('ANSI_COLORS_DISABLED') is not None:
+        colored = False
+
+    if head.startswith('\r'):
+        # need not \n at last
+        newline = False
+    else:
+        newline = True
+
+    if colored:
+        head = '\033[%dm%s:\033[0m ' %(color, head)
+        if not newline:
+            # ESC cmd to clear line
+            head = '\033[2K' + head
+    else:
+        if head:
+            head += ': '
+            if head.startswith('\r'):
+                head = head.lstrip()
+                newline = True
+
+    if msg is not None:
+        if isinstance(msg, unicode):
+            msg = msg.encode('utf8', 'ignore')
+
+        stream.write('%s%s' % (head, msg))
+        if newline:
+            stream.write('\n')
+
+    stream.flush()
+
+def _color_perror(head, color, msg, level='normal'):
+    if CATCHERR_BUFFILE_FD > 0:
+        _general_print(head, color, msg, sys.stdout, level)
+    else:
+        _general_print(head, color, msg, sys.stderr, level)
+
+def _split_msg(head, msg):
+    if isinstance(msg, list):
+        msg = '\n'.join(map(str, msg))
+
+    if msg.startswith('\n'):
+        # means print \n at first
+        msg = msg.lstrip()
+        head = '\n' + head
+
+    elif msg.startswith('\r'):
+        # means print \r at first
+        msg = msg.lstrip()
+        head = '\r' + head
+
+    match = PREFIX_RE.match(msg)
+    if match:
+        head += ' <%s>' % match.group(1)
+        msg = match.group(2)
+
+    return head, msg
+
+def get_loglevel():
+    return (k for k, v in LOG_LEVELS.items() if v == LOG_LEVEL).next()
+
+def set_loglevel(level):
+    global LOG_LEVEL
+    if level not in LOG_LEVELS:
+        # no effect
+        return
+
+    LOG_LEVEL = LOG_LEVELS[level]
+
+def set_interactive(mode=True):
+    global INTERACTIVE
+    if mode:
+        INTERACTIVE = True
+    else:
+        INTERACTIVE = False
+
+def log(msg=''):
+    # log msg to LOG_CONTENT then save to logfile
+    global LOG_CONTENT
+    if msg:
+        LOG_CONTENT += msg
+
+def raw(msg=''):
+    _general_print('', NO_COLOR, msg)
+
+def info(msg):
+    head, msg = _split_msg('Info', msg)
+    _general_print(head, INFO_COLOR, msg)
+
+def verbose(msg):
+    head, msg = _split_msg('Verbose', msg)
+    _general_print(head, INFO_COLOR, msg, level='verbose')
+
+def warning(msg):
+    head, msg = _split_msg('Warning', msg)
+    _color_perror(head, WARN_COLOR, msg)
+
+def debug(msg):
+    head, msg = _split_msg('Debug', msg)
+    _color_perror(head, ERR_COLOR, msg, level='debug')
+
+def error(msg):
+    head, msg = _split_msg('Error', msg)
+    _color_perror(head, ERR_COLOR, msg)
+    sys.exit(1)
+
+def ask(msg, default=True):
+    _general_print('\rQ', ASK_COLOR, '')
+    try:
+        if default:
+            msg += '(Y/n) '
+        else:
+            msg += '(y/N) '
+        if INTERACTIVE:
+            while True:
+                repl = raw_input(msg)
+                if repl.lower() == 'y':
+                    return True
+                elif repl.lower() == 'n':
+                    return False
+                elif not repl.strip():
+                    # <Enter>
+                    return default
+
+                # else loop
+        else:
+            if default:
+                msg += ' Y'
+            else:
+                msg += ' N'
+            _general_print('', NO_COLOR, msg)
+
+            return default
+    except KeyboardInterrupt:
+        sys.stdout.write('\n')
+        sys.exit(2)
+
+def choice(msg, choices, default=0):
+    if default >= len(choices):
+        return None
+    _general_print('\rQ', ASK_COLOR, '')
+    try:
+        msg += " [%s] " % '/'.join(choices)
+        if INTERACTIVE:
+            while True:
+                repl = raw_input(msg)
+                if repl in choices:
+                    return repl
+                elif not repl.strip():
+                    return choices[default]
+        else:
+            msg += choices[default]
+            _general_print('', NO_COLOR, msg)
+
+            return choices[default]
+    except KeyboardInterrupt:
+        sys.stdout.write('\n')
+        sys.exit(2)
+
+def pause(msg=None):
+    if INTERACTIVE:
+        _general_print('\rQ', ASK_COLOR, '')
+        if msg is None:
+            msg = 'press <ENTER> to continue ...'
+        raw_input(msg)
+
+def set_logfile(fpath):
+    global LOG_FILE_FP
+
+    def _savelogf():
+        if LOG_FILE_FP:
+            with open(LOG_FILE_FP, 'w') as log:
+                log.write(LOG_CONTENT)
+
+    if LOG_FILE_FP is not None:
+        warning('duplicate log file configuration')
+
+    LOG_FILE_FP = fpath
+
+    import atexit
+    atexit.register(_savelogf)
+
+def enable_logstderr(fpath):
+    global CATCHERR_BUFFILE_FD
+    global CATCHERR_BUFFILE_PATH
+    global CATCHERR_SAVED_2
+
+    if os.path.exists(fpath):
+        os.remove(fpath)
+    CATCHERR_BUFFILE_PATH = fpath
+    CATCHERR_BUFFILE_FD = os.open(CATCHERR_BUFFILE_PATH, os.O_RDWR|os.O_CREAT)
+    CATCHERR_SAVED_2 = os.dup(2)
+    os.dup2(CATCHERR_BUFFILE_FD, 2)
+
+def disable_logstderr():
+    global CATCHERR_BUFFILE_FD
+    global CATCHERR_BUFFILE_PATH
+    global CATCHERR_SAVED_2
+
+    raw(msg=None) # flush message buffer and print it.
+    os.dup2(CATCHERR_SAVED_2, 2)
+    os.close(CATCHERR_SAVED_2)
+    os.close(CATCHERR_BUFFILE_FD)
+    os.unlink(CATCHERR_BUFFILE_PATH)
+    CATCHERR_BUFFILE_FD = -1
+    CATCHERR_BUFFILE_PATH = None
+    CATCHERR_SAVED_2 = -1
diff --git a/scripts/lib/wic/plugin.py b/scripts/lib/wic/plugin.py
new file mode 100644
index 0000000..ccfdfcb
--- /dev/null
+++ b/scripts/lib/wic/plugin.py
@@ -0,0 +1,150 @@
+#!/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.
+
+import os, sys
+
+from wic import msger
+from wic import pluginbase
+from wic.utils import errors
+from wic.utils.oe.misc import get_bitbake_var
+
+__ALL__ = ['PluginMgr', 'pluginmgr']
+
+PLUGIN_TYPES = ["imager", "source"]
+
+PLUGIN_DIR = "/lib/wic/plugins" # relative to scripts
+SCRIPTS_PLUGIN_DIR = "scripts" + PLUGIN_DIR
+
+class PluginMgr(object):
+    plugin_dirs = {}
+
+    # make the manager class as singleton
+    _instance = None
+    def __new__(cls, *args, **kwargs):
+        if not cls._instance:
+            cls._instance = super(PluginMgr, cls).__new__(cls, *args, **kwargs)
+
+        return cls._instance
+
+    def __init__(self):
+        wic_path = os.path.dirname(__file__)
+        eos = wic_path.find('scripts') + len('scripts')
+        scripts_path = wic_path[:eos]
+        self.scripts_path = scripts_path
+        self.plugin_dir = scripts_path + PLUGIN_DIR
+        self.layers_path = None
+
+    def _build_plugin_dir_list(self, plugin_dir, ptype):
+        if self.layers_path is None:
+            self.layers_path = get_bitbake_var("BBLAYERS")
+        layer_dirs = []
+
+        if self.layers_path is not None:
+            for layer_path in self.layers_path.split():
+                path = os.path.join(layer_path, SCRIPTS_PLUGIN_DIR, ptype)
+                layer_dirs.append(path)
+
+        path = os.path.join(plugin_dir, ptype)
+        layer_dirs.append(path)
+
+        return layer_dirs
+
+    def append_dirs(self, dirs):
+        for path in dirs:
+            self._add_plugindir(path)
+
+        # load all the plugins AGAIN
+        self._load_all()
+
+    def _add_plugindir(self, path):
+        path = os.path.abspath(os.path.expanduser(path))
+
+        if not os.path.isdir(path):
+            return
+
+        if path not in self.plugin_dirs:
+            self.plugin_dirs[path] = False
+            # the value True/False means "loaded"
+
+    def _load_all(self):
+        for (pdir, loaded) in self.plugin_dirs.iteritems():
+            if loaded:
+                continue
+
+            sys.path.insert(0, pdir)
+            for mod in [x[:-3] for x in os.listdir(pdir) if x.endswith(".py")]:
+                if mod and mod != '__init__':
+                    if mod in sys.modules:
+                        #self.plugin_dirs[pdir] = True
+                        msger.warning("Module %s already exists, skip" % mod)
+                    else:
+                        try:
+                            pymod = __import__(mod)
+                            self.plugin_dirs[pdir] = True
+                            msger.debug("Plugin module %s:%s imported"\
+                                        % (mod, pymod.__file__))
+                        except ImportError, err:
+                            msg = 'Failed to load plugin %s/%s: %s' \
+                                % (os.path.basename(pdir), mod, err)
+                            msger.warning(msg)
+
+            del sys.path[0]
+
+    def get_plugins(self, ptype):
+        """ the return value is dict of name:class pairs """
+
+        if ptype not in PLUGIN_TYPES:
+            raise errors.CreatorError('%s is not valid plugin type' % ptype)
+
+        plugins_dir = self._build_plugin_dir_list(self.plugin_dir, ptype)
+
+        self.append_dirs(plugins_dir)
+
+        return pluginbase.get_plugins(ptype)
+
+    def get_source_plugins(self):
+        """
+        Return list of available source plugins.
+        """
+        plugins_dir = self._build_plugin_dir_list(self.plugin_dir, 'source')
+
+        self.append_dirs(plugins_dir)
+
+        return self.get_plugins('source')
+
+
+    def get_source_plugin_methods(self, source_name, methods):
+        """
+        The methods param is a dict with the method names to find.  On
+        return, the dict values will be filled in with pointers to the
+        corresponding methods.  If one or more methods are not found,
+        None is returned.
+        """
+        return_methods = None
+        for _source_name, klass in self.get_plugins('source').iteritems():
+            if _source_name == source_name:
+                for _method_name in methods.keys():
+                    if not hasattr(klass, _method_name):
+                        msger.warning("Unimplemented %s source interface for: %s"\
+                                      % (_method_name, _source_name))
+                        return None
+                    func = getattr(klass, _method_name)
+                    methods[_method_name] = func
+                    return_methods = methods
+        return return_methods
+
+pluginmgr = PluginMgr()
diff --git a/scripts/lib/wic/pluginbase.py b/scripts/lib/wic/pluginbase.py
new file mode 100644
index 0000000..ee8fe95
--- /dev/null
+++ b/scripts/lib/wic/pluginbase.py
@@ -0,0 +1,108 @@
+#!/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.
+
+from wic import msger
+
+class _Plugin(object):
+    class __metaclass__(type):
+        def __init__(cls, name, bases, attrs):
+            if not hasattr(cls, 'plugins'):
+                cls.plugins = {}
+
+            elif 'wic_plugin_type' in attrs:
+                if attrs['wic_plugin_type'] not in cls.plugins:
+                    cls.plugins[attrs['wic_plugin_type']] = {}
+
+            elif hasattr(cls, 'wic_plugin_type') and 'name' in attrs:
+                cls.plugins[cls.wic_plugin_type][attrs['name']] = cls
+
+        def show_plugins(cls):
+            for cls in cls.plugins[cls.wic_plugin_type]:
+                print cls
+
+        def get_plugins(cls):
+            return cls.plugins
+
+
+class ImagerPlugin(_Plugin):
+    wic_plugin_type = "imager"
+
+
+class SourcePlugin(_Plugin):
+    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.
+        """
+        msger.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.
+        """
+        msger.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.
+        """
+        msger.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.
+        """
+        msger.debug("SourcePlugin: do_prepare_partition: part: %s" % part)
+
+def get_plugins(typen):
+    plugins = ImagerPlugin.get_plugins()
+    if typen in plugins:
+        return plugins[typen]
+    else:
+        return None
+
+__all__ = ['ImagerPlugin', 'SourcePlugin', 'get_plugins']
diff --git a/scripts/lib/wic/plugins/imager/direct_plugin.py b/scripts/lib/wic/plugins/imager/direct_plugin.py
new file mode 100644
index 0000000..6d3f46c
--- /dev/null
+++ b/scripts/lib/wic/plugins/imager/direct_plugin.py
@@ -0,0 +1,102 @@
+# 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>
+#
+
+from wic.utils import errors
+from wic.conf import configmgr
+
+import wic.imager.direct as direct
+from wic.pluginbase import ImagerPlugin
+
+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'
+
+    @classmethod
+    def __rootfs_dir_to_dict(cls, rootfs_dirs):
+        """
+        Gets a string that contain 'connection=dir' splitted by
+        space and return a dict
+        """
+        krootfs_dir = {}
+        for rootfs_dir in rootfs_dirs.split(' '):
+            key, val = rootfs_dir.split('=')
+            krootfs_dir[key] = val
+
+        return krootfs_dir
+
+    @classmethod
+    def do_create(cls, opts, *args):
+        """
+        Create direct image, called from creator as 'direct' cmd
+        """
+        if len(args) != 8:
+            raise errors.Usage("Extra arguments given")
+
+        native_sysroot = args[0]
+        kernel_dir = args[1]
+        bootimg_dir = args[2]
+        rootfs_dir = args[3]
+
+        creatoropts = configmgr.create
+        ksconf = args[4]
+
+        image_output_dir = args[5]
+        oe_builddir = args[6]
+        compressor = args[7]
+
+        krootfs_dir = cls.__rootfs_dir_to_dict(rootfs_dir)
+
+        configmgr._ksconf = ksconf
+
+        creator = direct.DirectImageCreator(oe_builddir,
+                                            image_output_dir,
+                                            krootfs_dir,
+                                            bootimg_dir,
+                                            kernel_dir,
+                                            native_sysroot,
+                                            compressor,
+                                            creatoropts)
+
+        try:
+            creator.create()
+            creator.assemble()
+            creator.finalize()
+            creator.print_outimage_info()
+
+        except errors.CreatorError:
+            raise
+        finally:
+            creator.cleanup()
+
+        return 0
diff --git a/scripts/lib/wic/plugins/source/bootimg-efi.py b/scripts/lib/wic/plugins/source/bootimg-efi.py
new file mode 100644
index 0000000..fa63c6a
--- /dev/null
+++ b/scripts/lib/wic/plugins/source/bootimg-efi.py
@@ -0,0 +1,214 @@
+# 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 os
+import shutil
+
+from wic import kickstart, msger
+from wic.pluginbase import SourcePlugin
+from wic.utils.oe.misc import exec_cmd, exec_native_cmd, get_bitbake_var, \
+                              BOOTDD_EXTRA_SPACE
+
+class BootimgEFIPlugin(SourcePlugin):
+    """
+    Create EFI boot partition.
+    This plugin supports GRUB 2 and gummiboot bootloaders.
+    """
+
+    name = 'bootimg-efi'
+
+    @classmethod
+    def do_configure_grubefi(cls, hdddir, creator, cr_workdir):
+        """
+        Create loader-specific (grub-efi) config
+        """
+        options = creator.ks.handler.bootloader.appendLine
+
+        grubefi_conf = ""
+        grubefi_conf += "serial --unit=0 --speed=115200 --word=8 --parity=no --stop=1\n"
+        grubefi_conf += "default=boot\n"
+        timeout = kickstart.get_timeout(creator.ks)
+        if not timeout:
+            timeout = 0
+        grubefi_conf += "timeout=%s\n" % timeout
+        grubefi_conf += "menuentry 'boot'{\n"
+
+        kernel = "/bzImage"
+
+        grubefi_conf += "linux %s root=%s rootwait %s\n" \
+            % (kernel, creator.rootdev, options)
+        grubefi_conf += "}\n"
+
+        msger.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_gummiboot(cls, hdddir, creator, cr_workdir):
+        """
+        Create loader-specific (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)
+
+        options = creator.ks.handler.bootloader.appendLine
+
+        timeout = kickstart.get_timeout(creator.ks)
+        if not timeout:
+            timeout = 0
+
+        loader_conf = ""
+        loader_conf += "default boot\n"
+        loader_conf += "timeout %d\n" % timeout
+
+        msger.debug("Writing gummiboot 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()
+
+        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, options)
+
+        msger.debug("Writing gummiboot 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
+        rm_cmd = "rm -rf %s" % cr_workdir
+        exec_cmd(rm_cmd)
+
+        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)
+            elif source_params['loader'] == 'gummiboot':
+                cls.do_configure_gummiboot(hdddir, creator, cr_workdir)
+            else:
+                msger.error("unrecognized bootimg-efi loader: %s" % source_params['loader'])
+        except KeyError:
+            msger.error("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 bootimg_dir:
+            bootimg_dir = get_bitbake_var("HDDDIR")
+            if not bootimg_dir:
+                msger.error("Couldn't find HDDDIR, exiting\n")
+            # just so the result notes display it
+            creator.set_bootimg_dir(bootimg_dir)
+
+        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)
+                cp_cmd = "cp %s/EFI/BOOT/* %s/EFI/BOOT" % (bootimg_dir, hdddir)
+                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'] == 'gummiboot':
+                cp_cmd = "cp %s/EFI/BOOT/* %s/EFI/BOOT" % (bootimg_dir, hdddir)
+                exec_cmd(cp_cmd, True)
+            else:
+                msger.error("unrecognized bootimg-efi loader: %s" % source_params['loader'])
+        except KeyError:
+            msger.error("bootimg-efi requires a loader, none specified")
+
+        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
+
+        msger.debug("Added %d extra blocks to %s to get to %d total blocks" % \
+                    (extra_blocks, part.mountpoint, blocks))
+
+        # Ensure total sectors is an integral number of sectors per
+        # track or mcopy will complain. Sectors are 512 bytes, and we
+        # generate images with 32 sectors per track. This calculation is
+        # done in blocks, thus the mod by 16 instead of 32.
+        blocks += (16 - (blocks % 16))
+
+        # dosfs image, created by mkdosfs
+        bootimg = "%s/boot.img" % cr_workdir
+
+        dosfs_cmd = "mkdosfs -n efi -C %s %d" % (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.set_size(bootimg_size)
+        part.set_source_file(bootimg)
diff --git a/scripts/lib/wic/plugins/source/bootimg-partition.py b/scripts/lib/wic/plugins/source/bootimg-partition.py
new file mode 100644
index 0000000..bc2ca0f
--- /dev/null
+++ b/scripts/lib/wic/plugins/source/bootimg-partition.py
@@ -0,0 +1,143 @@
+# 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 os
+import re
+
+from wic import msger
+from wic.pluginbase import SourcePlugin
+from wic.utils.oe.misc import exec_cmd, get_bitbake_var
+from glob import glob
+
+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_install_disk(cls, disk, disk_name, cr, workdir, oe_builddir,
+                        bootimg_dir, kernel_dir, native_sysroot):
+        """
+        Called after all partitions have been prepared and assembled into a
+        disk image. Do nothing.
+        """
+        pass
+
+    @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(). Possibly prepare
+        configuration files of some sort.
+
+        """
+        pass
+
+    @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" % cr_workdir
+        rm_cmd = "rm -rf %s/boot" % cr_workdir
+        exec_cmd(rm_cmd)
+
+        install_cmd = "install -d %s" % hdddir
+        exec_cmd(install_cmd)
+
+        if not bootimg_dir:
+            bootimg_dir = get_bitbake_var("DEPLOY_DIR_IMAGE")
+            if not bootimg_dir:
+                msger.error("Couldn't find DEPLOY_DIR_IMAGE, exiting\n")
+
+        msger.debug('Bootimg dir: %s' % bootimg_dir)
+
+        boot_files = get_bitbake_var("IMAGE_BOOT_FILES")
+
+        if not boot_files:
+            msger.error('No boot files defined, IMAGE_BOOT_FILES unset')
+
+        msger.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]:
+                    msger.error('Malformed boot file entry: %s' % (src_entry))
+            else:
+                dst_entry = (src_entry, src_entry)
+
+            msger.debug('Destination entry: %r' % (dst_entry,))
+            deploy_files.append(dst_entry)
+
+        for deploy_entry in deploy_files:
+            src, dst = deploy_entry
+            install_task = []
+            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(bootimg_dir, src))
+
+                msger.debug('Globbed sources: %s' % (', '.join(srcs)))
+                for entry in srcs:
+                    entry_dst_name = entry_name_fn(entry)
+                    install_task.append((entry,
+                                         os.path.join(hdddir,
+                                                      entry_dst_name)))
+            else:
+                install_task = [(os.path.join(bootimg_dir, src),
+                                 os.path.join(hdddir, dst))]
+
+            for task in install_task:
+                src_path, dst_path = task
+                msger.debug('Install %s as %s' % (os.path.basename(src_path),
+                                                  dst_path))
+                install_cmd = "install -m 0644 -D %s %s" \
+                              % (src_path, dst_path)
+                exec_cmd(install_cmd)
+
+        msger.debug('Prepare boot partition using rootfs in %s' % (hdddir))
+        part.prepare_rootfs(cr_workdir, oe_builddir, hdddir,
+                            native_sysroot)
+
diff --git a/scripts/lib/wic/plugins/source/bootimg-pcbios.py b/scripts/lib/wic/plugins/source/bootimg-pcbios.py
new file mode 100644
index 0000000..96ed54d
--- /dev/null
+++ b/scripts/lib/wic/plugins/source/bootimg-pcbios.py
@@ -0,0 +1,200 @@
+# 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 os
+
+from wic.utils.errors import ImageError
+from wic import kickstart, msger
+from wic.utils import runner
+from wic.pluginbase import SourcePlugin
+from wic.utils.oe.misc import exec_cmd, exec_native_cmd, \
+                              get_bitbake_var, BOOTDD_EXTRA_SPACE
+
+class BootimgPcbiosPlugin(SourcePlugin):
+    """
+    Create MBR boot partition and install syslinux on it.
+    """
+
+    name = 'bootimg-pcbios'
+
+    @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.
+        """
+        mbrfile = "%s/syslinux/" % bootimg_dir
+        if creator.ptable_format == 'msdos':
+            mbrfile += "mbr.bin"
+        elif creator.ptable_format == 'gpt':
+            mbrfile += "gptmbr.bin"
+        else:
+            msger.error("Unsupported partition table: %s" % creator.ptable_format)
+
+        if not os.path.exists(mbrfile):
+            msger.error("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")
+        msger.debug("Installing MBR on disk %s as %s with size %s bytes" \
+                    % (disk_name, full_path, disk['min_size']))
+
+        rcode = runner.show(['dd', 'if=%s' % mbrfile,
+                             'of=%s' % full_path, 'conv=notrunc'])
+        if rcode != 0:
+            raise ImageError("Unable to set MBR to %s" % full_path)
+
+    @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
+        rm_cmd = "rm -rf " + cr_workdir
+        exec_cmd(rm_cmd)
+
+        install_cmd = "install -d %s" % hdddir
+        exec_cmd(install_cmd)
+
+        splash = os.path.join(cr_workdir, "/hdd/boot/splash.jpg")
+        if os.path.exists(splash):
+            splashline = "menu background splash.jpg"
+        else:
+            splashline = ""
+
+        options = creator.ks.handler.bootloader.appendLine
+
+        syslinux_conf = ""
+        syslinux_conf += "PROMPT 0\n"
+        timeout = kickstart.get_timeout(creator.ks)
+        if not timeout:
+            timeout = 0
+        syslinux_conf += "TIMEOUT " + str(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, options)
+
+        msger.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.
+        """
+        def _has_syslinux(dirname):
+            if dirname:
+                syslinux = "%s/syslinux" % dirname
+                if os.path.exists(syslinux):
+                    return True
+            return False
+
+        if not _has_syslinux(bootimg_dir):
+            bootimg_dir = get_bitbake_var("STAGING_DATADIR")
+            if not bootimg_dir:
+                msger.error("Couldn't find STAGING_DATADIR, exiting\n")
+            if not _has_syslinux(bootimg_dir):
+                msger.error("Please build syslinux first\n")
+            # just so the result notes display it
+            creator.set_bootimg_dir(bootimg_dir)
+
+        staging_kernel_dir = kernel_dir
+
+        hdddir = "%s/hdd/boot" % cr_workdir
+
+        install_cmd = "install -m 0644 %s/bzImage %s/vmlinuz" \
+            % (staging_kernel_dir, hdddir)
+        exec_cmd(install_cmd)
+
+        install_cmd = "install -m 444 %s/syslinux/ldlinux.sys %s/ldlinux.sys" \
+            % (bootimg_dir, hdddir)
+        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
+
+        msger.debug("Added %d extra blocks to %s to get to %d total blocks" % \
+                    (extra_blocks, part.mountpoint, blocks))
+
+        # Ensure total sectors is an integral number of sectors per
+        # track or mcopy will complain. Sectors are 512 bytes, and we
+        # generate images with 32 sectors per track. This calculation is
+        # done in blocks, thus the mod by 16 instead of 32.
+        blocks += (16 - (blocks % 16))
+
+        # dosfs image, created by mkdosfs
+        bootimg = "%s/boot.img" % cr_workdir
+
+        dosfs_cmd = "mkdosfs -n boot -S 512 -C %s %d" % (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.set_size(bootimg_size)
+        part.set_source_file(bootimg)
+
+
diff --git a/scripts/lib/wic/plugins/source/fsimage.py b/scripts/lib/wic/plugins/source/fsimage.py
new file mode 100644
index 0000000..f894e89
--- /dev/null
+++ b/scripts/lib/wic/plugins/source/fsimage.py
@@ -0,0 +1,73 @@
+# 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 os
+
+from wic import msger
+from wic.pluginbase import SourcePlugin
+from wic.utils.oe.misc import get_bitbake_var
+
+class FSImagePlugin(SourcePlugin):
+    """
+    Add an already existing filesystem image to the partition layout.
+    """
+
+    name = 'fsimage'
+
+    @classmethod
+    def do_install_disk(cls, disk, disk_name, cr, workdir, oe_builddir,
+                        bootimg_dir, kernel_dir, native_sysroot):
+        """
+        Called after all partitions have been prepared and assembled into a
+        disk image. Do nothing.
+        """
+        pass
+
+    @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(). Possibly prepare
+        configuration files of some sort.
+        """
+        pass
+
+    @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 bootimg_dir:
+            bootimg_dir = get_bitbake_var("DEPLOY_DIR_IMAGE")
+            if not bootimg_dir:
+                msger.error("Couldn't find DEPLOY_DIR_IMAGE, exiting\n")
+
+        msger.debug('Bootimg dir: %s' % bootimg_dir)
+
+        if 'file' not in source_params:
+            msger.error("No file specified\n")
+            return
+
+        src = os.path.join(bootimg_dir, source_params['file'])
+
+
+        msger.debug('Preparing partition using image %s' % (src))
+        part.prepare_rootfs_from_fs_image(cr_workdir, src, "")
diff --git a/scripts/lib/wic/plugins/source/isoimage-isohybrid.py b/scripts/lib/wic/plugins/source/isoimage-isohybrid.py
new file mode 100644
index 0000000..9472d8a
--- /dev/null
+++ b/scripts/lib/wic/plugins/source/isoimage-isohybrid.py
@@ -0,0 +1,538 @@
+# 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 os
+import re
+import shutil
+
+from wic import kickstart, msger
+from wic.pluginbase import SourcePlugin
+from wic.utils.oe.misc import exec_cmd, exec_native_cmd, get_bitbake_var
+
+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 --fstype=ext2
+    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 = ""
+
+        options = creator.ks.handler.bootloader.appendLine
+
+        timeout = kickstart.get_timeout(creator.ks, 10)
+
+        syslinux_conf = ""
+        syslinux_conf += "PROMPT 0\n"
+        syslinux_conf += "TIMEOUT %s \n" % timeout
+        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" % options
+
+        msger.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, cr_workdir):
+        """
+        Create loader-specific (grub-efi) config
+        """
+        splash = os.path.join(cr_workdir, "/EFI/boot/splash.jpg")
+        if os.path.exists(splash):
+            splashline = "menu background splash.jpg"
+        else:
+            splashline = ""
+
+        options = creator.ks.handler.bootloader.appendLine
+
+        grubefi_conf = ""
+        grubefi_conf += "serial --unit=0 --speed=115200 --word=8 "
+        grubefi_conf += "--parity=no --stop=1\n"
+        grubefi_conf += "default=boot\n"
+        timeout = kickstart.get_timeout(creator.ks, 10)
+        grubefi_conf += "timeout=%s\n" % timeout
+        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, options)
+        grubefi_conf += "initrd /initrd \n"
+        grubefi_conf += "}\n"
+
+        if splashline:
+            grubefi_conf += "%s\n" % splashline
+
+        msger.debug("Writing grubefi config %s/EFI/BOOT/grub.cfg" \
+                        % cr_workdir)
+        with open("%s/EFI/BOOT/grub.cfg" % cr_workdir, "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")
+        if not initrd:
+            initrd_dir = get_bitbake_var("DEPLOY_DIR_IMAGE")
+            if not initrd_dir:
+                msger.error("Couldn't find DEPLOY_DIR_IMAGE, exiting.\n")
+
+            image_name = get_bitbake_var("IMAGE_BASENAME")
+            if not image_name:
+                msger.error("Couldn't find IMAGE_BASENAME, exiting.\n")
+
+            image_type = get_bitbake_var("INITRAMFS_FSTYPES")
+            if not image_type:
+                msger.error("Couldn't find INITRAMFS_FSTYPES, exiting.\n")
+
+            machine_arch = get_bitbake_var("MACHINE_ARCH")
+            if not machine_arch:
+                msger.error("Couldn't find MACHINE_ARCH, exiting.\n")
+
+            initrd = "%s/%s-initramfs-%s.%s" \
+                    % (initrd_dir, image_name, machine_arch, image_type)
+
+        if 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:
+                msger.error("Couldn't find or build initrd, exiting.\n")
+
+            exec_cmd("cd %s && find . | cpio -o -H newc >%s/initrd.cpio " \
+                    % (initrd_dir, cr_workdir), as_shell=True)
+            exec_cmd("gzip -f -9 -c %s/initrd.cpio > %s" \
+                    % (cr_workdir, initrd), as_shell=True)
+            shutil.rmtree(initrd_dir)
+
+        return initrd
+
+    @classmethod
+    def do_stage_partition(cls, part, source_params, creator, cr_workdir,
+                           oe_builddir, bootimg_dir, kernel_dir,
+                           native_sysroot):
+        """
+        Special content staging called before do_prepare_partition().
+        It cheks if all necessary tools are available, if not
+        tries to instal them.
+        """
+        # Make sure parted is available in native sysroot
+        if not os.path.isfile("%s/usr/sbin/parted" % native_sysroot):
+            msger.info("Building parted-native...\n")
+            exec_cmd("bitbake parted-native")
+
+        # Make sure mkfs.ext2/3/4 is available in native sysroot
+        if not os.path.isfile("%s/sbin/mkfs.ext2" % native_sysroot):
+            msger.info("Building e2fsprogs-native...\n")
+            exec_cmd("bitbake e2fsprogs-native")
+
+        # Make sure syslinux is available in sysroot and in native sysroot
+        syslinux_dir = get_bitbake_var("STAGING_DATADIR")
+        if not syslinux_dir:
+            msger.error("Couldn't find STAGING_DATADIR, exiting.\n")
+        if not os.path.exists("%s/syslinux" % syslinux_dir):
+            msger.info("Building syslinux...\n")
+            exec_cmd("bitbake syslinux")
+            msger.info("Building syslinux-native...\n")
+            exec_cmd("bitbake syslinux-native")
+        if not os.path.exists("%s/syslinux" % syslinux_dir):
+            msger.error("Please build syslinux first\n")
+
+        #Make sure mkisofs is available in native sysroot
+        if not os.path.isfile("%s/usr/bin/mkisofs" % native_sysroot):
+            msger.info("Building cdrtools-native...\n")
+            exec_cmd("bitbake cdrtools-native")
+
+        # Make sure mkfs.vfat is available in native sysroot
+        if not os.path.isfile("%s/sbin/mkfs.vfat" % native_sysroot):
+            msger.info("Building dosfstools-native...\n")
+            exec_cmd("bitbake dosfstools-native")
+
+        # Make sure mtools is available in native sysroot
+        if not os.path.isfile("%s/usr/bin/mcopy" % native_sysroot):
+            msger.info("Building mtools-native...\n")
+            exec_cmd("bitbake mtools-native")
+
+    @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(cr_workdir):
+            shutil.rmtree(cr_workdir)
+
+        install_cmd = "install -d %s " % isodir
+        exec_cmd(install_cmd)
+
+        # Overwrite the name of the created image
+        msger.debug("%s" % source_params)
+        if 'image_name' in source_params and \
+                    source_params['image_name'].strip():
+            creator.name = source_params['image_name'].strip()
+            msger.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 is None:
+            if not 'ROOTFS_DIR' in rootfs_dir:
+                msger.error("Couldn't find --rootfs-dir, exiting.\n")
+            rootfs_dir = rootfs_dir['ROOTFS_DIR']
+        else:
+            if part.rootfs in rootfs_dir:
+                rootfs_dir = rootfs_dir[part.rootfs]
+            elif part.rootfs:
+                rootfs_dir = part.rootfs
+            else:
+                msg = "Couldn't find --rootfs-dir=%s connection "
+                msg += "or it is not a valid path, exiting.\n"
+                msger.error(msg % part.rootfs)
+
+        if not os.path.isdir(rootfs_dir):
+            rootfs_dir = get_bitbake_var("IMAGE_ROOTFS")
+        if not os.path.isdir(rootfs_dir):
+            msger.error("Couldn't find IMAGE_ROOTFS, exiting.\n")
+
+        part.set_rootfs(rootfs_dir)
+
+        # Prepare rootfs.img
+        hdd_dir = get_bitbake_var("HDDDIR")
+        img_iso_dir = get_bitbake_var("ISODIR")
+
+        rootfs_img = "%s/rootfs.img" % hdd_dir
+        if not os.path.isfile(rootfs_img):
+            rootfs_img = "%s/rootfs.img" % img_iso_dir
+        if not os.path.isfile(rootfs_img):
+            # check if rootfs.img is in deploydir
+            deploy_dir = get_bitbake_var("DEPLOY_DIR_IMAGE")
+            image_name = get_bitbake_var("IMAGE_LINK_NAME")
+            rootfs_img = "%s/%s.%s" \
+                % (deploy_dir, image_name, part.fstype)
+
+        if not os.path.isfile(rootfs_img):
+            # create image file with type specified by --fstype
+            # which contains rootfs
+            du_cmd = "du -bks %s" % rootfs_dir
+            out = exec_cmd(du_cmd)
+            part.set_size(int(out.split()[0]))
+            part.extra_space = 0
+            part.overhead_factor = 1.2
+            part.prepare_rootfs(cr_workdir, oe_builddir, rootfs_dir, \
+                                native_sysroot)
+            rootfs_img = part.source_file
+
+        install_cmd = "install -m 0644 %s %s/rootfs.img" \
+            % (rootfs_img, isodir)
+        exec_cmd(install_cmd)
+
+        # Remove the temporary file created by part.prepare_rootfs()
+        if os.path.isfile(part.source_file):
+            os.remove(part.source_file)
+
+        # Prepare initial ramdisk
+        initrd = "%s/initrd" % hdd_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:
+            if source_params['loader'] == 'grub-efi':
+                # Builds grub.cfg if ISODIR didn't exist or
+                # didn't contains grub.cfg
+                bootimg_dir = img_iso_dir
+                if not os.path.exists("%s/EFI/BOOT" % bootimg_dir):
+                    bootimg_dir = "%s/bootimg" % cr_workdir
+                    if os.path.exists(bootimg_dir):
+                        shutil.rmtree(bootimg_dir)
+                    install_cmd = "install -d %s/EFI/BOOT" % bootimg_dir
+                    exec_cmd(install_cmd)
+
+                if not os.path.isfile("%s/EFI/BOOT/boot.cfg" % bootimg_dir):
+                    cls.do_configure_grubefi(part, creator, bootimg_dir)
+
+                # 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:
+                    msger.error("Coludn't find target architecture\n")
+
+                if re.match("x86_64", target_arch):
+                    grub_target = 'x86_64-efi'
+                    grub_image = "bootx64.efi"
+                elif re.match('i.86', target_arch):
+                    grub_target = 'i386-efi'
+                    grub_image = "bootia32.efi"
+                else:
+                    msger.error("grub-efi is incompatible with target %s\n" \
+                                % target_arch)
+
+                if not os.path.isfile("%s/EFI/BOOT/%s" \
+                                % (bootimg_dir, grub_image)):
+                    grub_path = get_bitbake_var("STAGING_LIBDIR")
+                    if not grub_path:
+                        msger.error("Couldn't find STAGING_LIBDIR, exiting.\n")
+
+                    grub_core = "%s/grub/%s" % (grub_path, grub_target)
+                    if not os.path.exists(grub_core):
+                        msger.info("Building grub-efi...\n")
+                        exec_cmd("bitbake grub-efi")
+                    if not os.path.exists(grub_core):
+                        msger.error("Please build grub-efi first\n")
+
+                    grub_cmd = "grub-mkimage -p '/EFI/BOOT' "
+                    grub_cmd += "-d %s "  % grub_core
+                    grub_cmd += "-O %s -o %s/EFI/BOOT/%s " \
+                                % (grub_target, bootimg_dir, grub_image)
+                    grub_cmd += "part_gpt part_msdos ntfs ntfscomp fat ext2 "
+                    grub_cmd += "normal chain boot configfile linux multiboot "
+                    grub_cmd += "search efi_gop efi_uga font gfxterm gfxmenu "
+                    grub_cmd += "terminal minicmd test iorw loadenv echo help "
+                    grub_cmd += "reboot serial terminfo iso9660 loopback tar "
+                    grub_cmd += "memdisk ls search_fs_uuid udf btrfs xfs lvm "
+                    grub_cmd += "reiserfs ata "
+                    exec_native_cmd(grub_cmd, native_sysroot)
+
+            else:
+                # TODO: insert gummiboot stuff
+                msger.error("unrecognized bootimg-efi loader: %s" \
+                            % source_params['loader'])
+        except KeyError:
+            msger.error("bootimg-efi requires a loader, none specified")
+
+        if os.path.exists("%s/EFI/BOOT" % isodir):
+            shutil.rmtree("%s/EFI/BOOT" % isodir)
+
+        shutil.copytree(bootimg_dir+"/EFI/BOOT", isodir+"/EFI/BOOT")
+
+        # If exists, remove cr_workdir/bootimg temporary folder
+        if os.path.exists("%s/bootimg" % cr_workdir):
+            shutil.rmtree("%s/bootimg" % cr_workdir)
+
+        # 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
+            msg = "Added 100 extra blocks to %s to get to %d total blocks" \
+                    % (part.mountpoint, blocks)
+            msger.debug(msg)
+
+            # Ensure total sectors is an integral number of sectors per
+            # track or mcopy will complain. Sectors are 512 bytes, and we
+            # generate images with 32 sectors per track. This calculation is
+            # done in blocks, thus the mod by 16 instead of 32.
+            blocks += (16 - (blocks % 16))
+
+            # 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:
+            msger.error("Couldn't find STAGING_DATADIR, exiting.\n")
+
+        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
+
+        msger.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.set_size(isoimg_size)
+        part.set_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.
+        """
+
+        full_path = creator._full_path(workdir, disk_name, "direct")
+        iso_img = "%s.p1" % full_path
+        full_path_iso = creator._full_path(workdir, disk_name, "iso")
+
+        isohybrid_cmd = "isohybrid -u %s" % iso_img
+        msger.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.
+        msger.debug("Replaceing the image created by direct plugin\n")
+        os.remove(full_path)
+        shutil.copy2(iso_img, full_path_iso)
+        shutil.copy2(full_path_iso, full_path)
+
+        # Remove temporary ISO file
+        os.remove(iso_img)
diff --git a/scripts/lib/wic/plugins/source/rawcopy.py b/scripts/lib/wic/plugins/source/rawcopy.py
new file mode 100644
index 0000000..f0691ba
--- /dev/null
+++ b/scripts/lib/wic/plugins/source/rawcopy.py
@@ -0,0 +1,87 @@
+# 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 os
+
+from wic import msger
+from wic.pluginbase import SourcePlugin
+from wic.utils.oe.misc import exec_cmd, get_bitbake_var
+
+class RawCopyPlugin(SourcePlugin):
+    """
+    Populate partition content from raw image file.
+    """
+
+    name = 'rawcopy'
+
+    @classmethod
+    def do_install_disk(cls, disk, disk_name, cr, workdir, oe_builddir,
+                        bootimg_dir, kernel_dir, native_sysroot):
+        """
+        Called after all partitions have been prepared and assembled into a
+        disk image. Do nothing.
+        """
+        pass
+
+    @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(). Possibly prepare
+        configuration files of some sort.
+        """
+        pass
+
+    @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 bootimg_dir:
+            bootimg_dir = get_bitbake_var("DEPLOY_DIR_IMAGE")
+            if not bootimg_dir:
+                msger.error("Couldn't find DEPLOY_DIR_IMAGE, exiting\n")
+
+        msger.debug('Bootimg dir: %s' % bootimg_dir)
+
+        if 'file' not in source_params:
+            msger.error("No file specified\n")
+            return
+
+        src = os.path.join(bootimg_dir, source_params['file'])
+        dst = src
+
+        if 'skip' in source_params:
+            dst = os.path.join(cr_workdir, source_params['file'])
+            dd_cmd = "dd if=%s of=%s ibs=%s skip=1 conv=notrunc" % \
+                    (src, dst, source_params['skip'])
+            exec_cmd(dd_cmd)
+
+        # get the size in the right units for kickstart (kB)
+        du_cmd = "du -Lbks %s" % dst
+        out = exec_cmd(du_cmd)
+        filesize = out.split()[0]
+
+        if int(filesize) > int(part.size):
+            part.size = filesize
+
+        part.source_file = dst
+
diff --git a/scripts/lib/wic/plugins/source/rootfs.py b/scripts/lib/wic/plugins/source/rootfs.py
new file mode 100644
index 0000000..a90712b
--- /dev/null
+++ b/scripts/lib/wic/plugins/source/rootfs.py
@@ -0,0 +1,83 @@
+# 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 os
+
+from wic import msger
+from wic.pluginbase import SourcePlugin
+from wic.utils.oe.misc import get_bitbake_var
+
+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 rootfs_dir
+
+        image_rootfs_dir = get_bitbake_var("IMAGE_ROOTFS", rootfs_dir)
+        if not os.path.isdir(image_rootfs_dir):
+            msg = "No valid artifact IMAGE_ROOTFS from image named"
+            msg += " %s has been found at %s, exiting.\n" % \
+                (rootfs_dir, image_rootfs_dir)
+            msger.error(msg)
+
+        return 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 is None:
+            if not 'ROOTFS_DIR' in krootfs_dir:
+                msg = "Couldn't find --rootfs-dir, exiting"
+                msger.error(msg)
+            rootfs_dir = krootfs_dir['ROOTFS_DIR']
+        else:
+            if part.rootfs in krootfs_dir:
+                rootfs_dir = krootfs_dir[part.rootfs]
+            elif part.rootfs:
+                rootfs_dir = part.rootfs
+            else:
+                msg = "Couldn't find --rootfs-dir=%s connection"
+                msg += " or it is not a valid path, exiting"
+                msger.error(msg % part.rootfs)
+
+        real_rootfs_dir = cls.__get_rootfs_dir(rootfs_dir)
+
+        part.set_rootfs(real_rootfs_dir)
+        part.prepare_rootfs(cr_workdir, oe_builddir, real_rootfs_dir, native_sysroot)
+
diff --git a/scripts/lib/wic/plugins/source/rootfs_pcbios_ext.py b/scripts/lib/wic/plugins/source/rootfs_pcbios_ext.py
new file mode 100644
index 0000000..76e7b03
--- /dev/null
+++ b/scripts/lib/wic/plugins/source/rootfs_pcbios_ext.py
@@ -0,0 +1,181 @@
+# 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 distribute 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 mo 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.
+#
+# AUTHOR
+# Adrian Freihofer <adrian.freihofer (at] neratec.com>
+#
+
+import os
+from wic import kickstart
+from wic import msger
+from wic.utils import syslinux
+from wic.utils import runner
+from wic.utils.oe import misc
+from wic.utils.errors import ImageError
+from wic.pluginbase import SourcePlugin
+
+
+# pylint: disable=no-init
+class RootfsPlugin(SourcePlugin):
+    """
+    Create root partition and install syslinux bootloader
+
+    This plugin creates a disk image containing a bootable root partition with
+    syslinux installed. The filesystem is ext2/3/4, no extra boot partition is
+    required.
+
+    Example kickstart file:
+    part / --source rootfs-pcbios-ext --ondisk sda --fstype=ext4 --label rootfs --align 1024
+    bootloader --source rootfs-pcbios-ext --timeout=0 --append="rootwait rootfstype=ext4"
+
+    The first line generates a root file system including a syslinux.cfg file
+    The "--source rootfs-pcbios-ext" in the second line triggers the installation
+    of ldlinux.sys into the image.
+    """
+
+    name = 'rootfs-pcbios-ext'
+
+    @staticmethod
+    def _get_rootfs_dir(rootfs_dir):
+        """
+        Find rootfs pseudo dir
+
+        If rootfs_dir is a directory consider it as rootfs directory.
+        Otherwise ask bitbake about the IMAGE_ROOTFS directory.
+        """
+        if os.path.isdir(rootfs_dir):
+            return rootfs_dir
+
+        image_rootfs_dir = misc.get_bitbake_var("IMAGE_ROOTFS", rootfs_dir)
+        if not os.path.isdir(image_rootfs_dir):
+            msg = "No valid artifact IMAGE_ROOTFS from image named"
+            msg += " %s has been found at %s, exiting.\n" % \
+                (rootfs_dir, image_rootfs_dir)
+            msger.error(msg)
+
+        return image_rootfs_dir
+
+    # pylint: disable=unused-argument
+    @classmethod
+    def do_configure_partition(cls, part, source_params, image_creator,
+                               image_creator_workdir, oe_builddir, bootimg_dir,
+                               kernel_dir, native_sysroot):
+        """
+        Creates syslinux config in rootfs directory
+
+        Called before do_prepare_partition()
+        """
+        options = image_creator.ks.handler.bootloader.appendLine
+
+        syslinux_conf = ""
+        syslinux_conf += "PROMPT 0\n"
+
+        timeout = kickstart.get_timeout(image_creator.ks)
+        if not timeout:
+            timeout = 0
+        syslinux_conf += "TIMEOUT " + str(timeout) + "\n"
+        syslinux_conf += "ALLOWOPTIONS 1\n"
+
+        # Derive SERIAL... line from from kernel boot parameters
+        syslinux_conf += syslinux.serial_console_form_kargs(options) + "\n"
+
+        syslinux_conf += "DEFAULT linux\n"
+        syslinux_conf += "LABEL linux\n"
+        syslinux_conf += "  KERNEL /boot/bzImage\n"
+
+        syslinux_conf += "  APPEND label=boot root=%s %s\n" % \
+                             (image_creator.rootdev, options)
+
+        syslinux_cfg = os.path.join(image_creator.rootfs_dir['ROOTFS_DIR'], "boot", "syslinux.cfg")
+        msger.debug("Writing syslinux config %s" % syslinux_cfg)
+        with open(syslinux_cfg, "w") as cfg:
+            cfg.write(syslinux_conf)
+
+    @classmethod
+    def do_prepare_partition(cls, part, source_params, image_creator,
+                             image_creator_workdir, oe_builddir, bootimg_dir,
+                             kernel_dir, krootfs_dir, native_sysroot):
+        """
+        Creates partition out of rootfs directory
+
+        Prepare content for a rootfs partition i.e. create a partition
+        and fill it from a /rootfs dir.
+        Install syslinux bootloader into root partition image file
+        """
+        def is_exe(exepath):
+            """Verify exepath is an executable file"""
+            return os.path.isfile(exepath) and os.access(exepath, os.X_OK)
+
+        # Make sure syslinux-nomtools is available in native sysroot or fail
+        native_syslinux_nomtools = os.path.join(native_sysroot, "usr/bin/syslinux-nomtools")
+        if not is_exe(native_syslinux_nomtools):
+            msger.info("building syslinux-native...")
+            misc.exec_cmd("bitbake syslinux-native")
+        if not is_exe(native_syslinux_nomtools):
+            msger.error("Couldn't find syslinux-nomtools (%s), exiting\n" %
+                        native_syslinux_nomtools)
+
+        if part.rootfs is None:
+            if 'ROOTFS_DIR' not in krootfs_dir:
+                msger.error("Couldn't find --rootfs-dir, exiting")
+            rootfs_dir = krootfs_dir['ROOTFS_DIR']
+        else:
+            if part.rootfs in krootfs_dir:
+                rootfs_dir = krootfs_dir[part.rootfs]
+            elif part.rootfs:
+                rootfs_dir = part.rootfs
+            else:
+                msg = "Couldn't find --rootfs-dir=%s connection"
+                msg += " or it is not a valid path, exiting"
+                msger.error(msg % part.rootfs)
+
+        real_rootfs_dir = cls._get_rootfs_dir(rootfs_dir)
+
+        part.set_rootfs(real_rootfs_dir)
+        part.prepare_rootfs(image_creator_workdir, oe_builddir, real_rootfs_dir, native_sysroot)
+
+        # install syslinux into rootfs partition
+        syslinux_cmd = "syslinux-nomtools -d /boot -i %s" % part.source_file
+        misc.exec_native_cmd(syslinux_cmd, native_sysroot)
+
+    @classmethod
+    def do_install_disk(cls, disk, disk_name, image_creator, workdir, oe_builddir,
+                        bootimg_dir, kernel_dir, native_sysroot):
+        """
+        Assemble partitions to disk image
+
+        Called after all partitions have been prepared and assembled into a
+        disk image. In this case, we install the MBR.
+        """
+        mbrfile = os.path.join(native_sysroot, "usr/share/syslinux/")
+        if image_creator.ptable_format == 'msdos':
+            mbrfile += "mbr.bin"
+        elif image_creator.ptable_format == 'gpt':
+            mbrfile += "gptmbr.bin"
+        else:
+            msger.error("Unsupported partition table: %s" % \
+                        image_creator.ptable_format)
+
+        if not os.path.exists(mbrfile):
+            msger.error("Couldn't find %s. Has syslinux-native been baked?" % mbrfile)
+
+        full_path = disk['disk'].device
+        msger.debug("Installing MBR on disk %s as %s with size %s bytes" \
+                    % (disk_name, full_path, disk['min_size']))
+
+        ret_code = runner.show(['dd', 'if=%s' % mbrfile, 'of=%s' % full_path, 'conv=notrunc'])
+        if ret_code != 0:
+            raise ImageError("Unable to set MBR to %s" % full_path)
diff --git a/scripts/lib/wic/test b/scripts/lib/wic/test
new file mode 100644
index 0000000..9daeafb
--- /dev/null
+++ b/scripts/lib/wic/test
@@ -0,0 +1 @@
+test
diff --git a/scripts/lib/wic/utils/__init__.py b/scripts/lib/wic/utils/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/scripts/lib/wic/utils/__init__.py
diff --git a/scripts/lib/wic/utils/errors.py b/scripts/lib/wic/utils/errors.py
new file mode 100644
index 0000000..d1b514d
--- /dev/null
+++ b/scripts/lib/wic/utils/errors.py
@@ -0,0 +1,29 @@
+#!/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
+
+class CreatorError(WicError):
+    pass
+
+class Usage(WicError):
+    pass
+
+class ImageError(WicError):
+    pass
diff --git a/scripts/lib/wic/utils/fs_related.py b/scripts/lib/wic/utils/fs_related.py
new file mode 100644
index 0000000..2e74461
--- /dev/null
+++ b/scripts/lib/wic/utils/fs_related.py
@@ -0,0 +1,84 @@
+#!/usr/bin/env python -tt
+#
+# Copyright (c) 2007, Red Hat, Inc.
+# Copyright (c) 2009, 2010, 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.
+
+from __future__ import with_statement
+import os
+import errno
+
+from wic.utils.oe.misc import exec_cmd
+
+def makedirs(dirname):
+    """A version of os.makedirs() that doesn't throw an
+    exception if the leaf directory already exists.
+    """
+    try:
+        os.makedirs(dirname)
+    except OSError, err:
+        if err.errno != errno.EEXIST:
+            raise
+
+class Disk:
+    """
+    Generic base object for a disk.
+    """
+    def __init__(self, size, device=None):
+        self._device = device
+        self._size = size
+
+    def create(self):
+        pass
+
+    def cleanup(self):
+        pass
+
+    def get_device(self):
+        return self._device
+    def set_device(self, path):
+        self._device = path
+    device = property(get_device, set_device)
+
+    def get_size(self):
+        return self._size
+    size = property(get_size)
+
+
+class DiskImage(Disk):
+    """
+    A Disk backed by a file.
+    """
+    def __init__(self, image_file, size):
+        Disk.__init__(self, size)
+        self.image_file = image_file
+
+    def exists(self):
+        return os.path.exists(self.image_file)
+
+    def create(self):
+        if self.device is not None:
+            return
+
+        blocks = self.size / 1024
+        if self.size - blocks * 1024:
+            blocks += 1
+
+        # create disk image
+        dd_cmd = "dd if=/dev/zero of=%s bs=1024 seek=%d count=1" % \
+            (self.image_file, blocks)
+        exec_cmd(dd_cmd)
+
+        self.device = self.image_file
diff --git a/scripts/lib/wic/utils/misc.py b/scripts/lib/wic/utils/misc.py
new file mode 100644
index 0000000..9d75069
--- /dev/null
+++ b/scripts/lib/wic/utils/misc.py
@@ -0,0 +1,58 @@
+#!/usr/bin/env python -tt
+#
+# Copyright (c) 2010, 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.
+
+import os
+import time
+
+def build_name(kscfg, release=None, prefix=None, suffix=None):
+    """Construct and return an image name string.
+
+    This is a utility function to help create sensible name and fslabel
+    strings. The name is constructed using the sans-prefix-and-extension
+    kickstart filename and the supplied prefix and suffix.
+
+    kscfg -- a path to a kickstart file
+    release --  a replacement to suffix for image release
+    prefix -- a prefix to prepend to the name; defaults to None, which causes
+              no prefix to be used
+    suffix -- a suffix to append to the name; defaults to None, which causes
+              a YYYYMMDDHHMM suffix to be used
+
+    Note, if maxlen is less then the len(suffix), you get to keep both pieces.
+
+    """
+    name = os.path.basename(kscfg)
+    idx = name.rfind('.')
+    if idx >= 0:
+        name = name[:idx]
+
+    if release is not None:
+        suffix = ""
+    if prefix is None:
+        prefix = ""
+    if suffix is None:
+        suffix = time.strftime("%Y%m%d%H%M")
+
+    if name.startswith(prefix):
+        name = name[len(prefix):]
+
+    prefix = "%s-" % prefix if prefix else ""
+    suffix = "-%s" % suffix if suffix else ""
+
+    ret = prefix + name + suffix
+
+    return ret
diff --git a/scripts/lib/wic/utils/oe/__init__.py b/scripts/lib/wic/utils/oe/__init__.py
new file mode 100644
index 0000000..0a81575
--- /dev/null
+++ b/scripts/lib/wic/utils/oe/__init__.py
@@ -0,0 +1,22 @@
+#
+# OpenEmbedded wic utils library
+#
+# 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.
+#
+# AUTHORS
+# Tom Zanussi <tom.zanussi (at] linux.intel.com>
+#
diff --git a/scripts/lib/wic/utils/oe/misc.py b/scripts/lib/wic/utils/oe/misc.py
new file mode 100644
index 0000000..7370d93
--- /dev/null
+++ b/scripts/lib/wic/utils/oe/misc.py
@@ -0,0 +1,234 @@
+# 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 os
+from collections import defaultdict
+
+from wic import msger
+from wic.utils import runner
+
+# executable -> recipe pairs for exec_native_cmd
+NATIVE_RECIPES = {"mcopy": "mtools",
+                  "mkdosfs": "dosfstools",
+                  "mkfs.btrfs": "btrfs-tools",
+                  "mkfs.ext2": "e2fsprogs",
+                  "mkfs.ext3": "e2fsprogs",
+                  "mkfs.ext4": "e2fsprogs",
+                  "mkfs.vfat": "dosfstools",
+                  "mksquashfs": "squashfs-tools",
+                  "mkswap": "util-linux",
+                  "parted": "parted",
+                  "sgdisk": "gptfdisk",
+                  "syslinux": "syslinux"
+                 }
+
+def _exec_cmd(cmd_and_args, as_shell=False, catch=3):
+    """
+    Execute command, catching stderr, stdout
+
+    Need to execute as_shell if the command uses wildcards
+    """
+    msger.debug("_exec_cmd: %s" % cmd_and_args)
+    args = cmd_and_args.split()
+    msger.debug(args)
+
+    if as_shell:
+        ret, out = runner.runtool(cmd_and_args, catch)
+    else:
+        ret, out = runner.runtool(args, catch)
+    out = out.strip()
+    msger.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, catch=3):
+    """
+    Execute command, catching stderr, stdout
+
+    Exits if rc non-zero
+    """
+    ret, out = _exec_cmd(cmd_and_args, as_shell, catch)
+
+    if ret != 0:
+        msger.error("exec_cmd: %s returned '%s' instead of 0" % \
+                    (cmd_and_args, ret))
+
+    return out
+
+
+def exec_native_cmd(cmd_and_args, native_sysroot, catch=3):
+    """
+    Execute native command, catching stderr, stdout
+
+    Need to execute as_shell if the command uses wildcards
+
+    Always need to execute native commands as_shell
+    """
+    native_paths = \
+        "export PATH=%s/sbin:%s/usr/sbin:%s/usr/bin" % \
+        (native_sysroot, native_sysroot, native_sysroot)
+    native_cmd_and_args = "%s;%s" % (native_paths, cmd_and_args)
+    msger.debug("exec_native_cmd: %s" % cmd_and_args)
+
+    args = cmd_and_args.split()
+    msger.debug(args)
+
+    ret, out = _exec_cmd(native_cmd_and_args, True, catch)
+
+    if ret == 127: # shell command-not-found
+        prog = args[0]
+        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 bake it with 'bitbake %s-native' "\
+                   "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
+        msger.error(msg)
+    if out:
+        msger.debug('"%s" output: %s' % (args[0], out))
+
+    if ret != 0:
+        msger.error("exec_cmd: '%s' returned '%s' instead of 0" % \
+                    (cmd_and_args, ret))
+
+    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):
+        """
+        Parse one line from bitbake -e output or from .env file.
+        Put result key-value pair into the storage.
+        """
+        if "=" not in line:
+            return
+        try:
+            key, val = line.split("=")
+        except ValueError:
+            return
+        key = key.strip()
+        val = val.strip()
+        if key.replace('_', '').isalnum():
+            self[image][key] = val.strip('"')
+
+    def get_var(self, var, image=None):
+        """
+        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 = msger.get_loglevel()
+                msger.set_loglevel('normal')
+                ret, lines = _exec_cmd(cmd)
+                msger.set_loglevel(log_level)
+
+                if ret:
+                    print "Couldn't get '%s' output." % cmd
+                    print "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
+            images = [key for key in self if key]
+            if len(images) == 1:
+                self[None] = self[image]
+
+        return self[image].get(var)
+
+# Create BB_VARS singleton
+BB_VARS = BitbakeVars()
+
+def get_bitbake_var(var, image=None):
+    """
+    Provide old get_bitbake_var API by wrapping
+    get_var method of BB_VARS singleton.
+    """
+    return BB_VARS.get_var(var, image)
+
+def parse_sourceparams(sourceparams):
+    """
+    Split sourceparams string of the form key1=val1[,key2=val2,...]
+    into a dict.  Also accepts valueless keys i.e. without =.
+
+    Returns dict of param key/val pairs (note that val may be None).
+    """
+    params_dict = {}
+
+    params = sourceparams.split(',')
+    if params:
+        for par in params:
+            if not par:
+                continue
+            if not '=' in par:
+                key = par
+                val = None
+            else:
+                key, val = par.split('=')
+            params_dict[key] = val
+
+    return params_dict
diff --git a/scripts/lib/wic/utils/partitionedfs.py b/scripts/lib/wic/utils/partitionedfs.py
new file mode 100644
index 0000000..5a103bb
--- /dev/null
+++ b/scripts/lib/wic/utils/partitionedfs.py
@@ -0,0 +1,362 @@
+#!/usr/bin/env python -tt
+#
+# Copyright (c) 2009, 2010, 2011 Intel, Inc.
+# Copyright (c) 2007, 2008 Red Hat, Inc.
+# Copyright (c) 2008 Daniel P. Berrange
+# Copyright (c) 2008 David P. Huff
+#
+# 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.
+
+import os
+from wic import msger
+from wic.utils.errors import ImageError
+from wic.utils.oe.misc import exec_cmd, exec_native_cmd
+
+# 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 Image(object):
+    """
+    Generic base object for an image.
+
+    An Image is a container for a set of DiskImages and associated
+    partitions.
+    """
+    def __init__(self, native_sysroot=None):
+        self.disks = {}
+        self.partitions = []
+        # Size of a sector used in calculations
+        self.sector_size = SECTOR_SIZE
+        self._partitions_layed_out = False
+        self.native_sysroot = native_sysroot
+
+    def __add_disk(self, disk_name):
+        """ Add a disk 'disk_name' to the internal list of disks. Note,
+        'disk_name' is the name of the disk in the target system
+        (e.g., sdb). """
+
+        if disk_name in self.disks:
+            # We already have this disk
+            return
+
+        assert not self._partitions_layed_out
+
+        self.disks[disk_name] = \
+                {'disk': None,     # Disk object
+                 'numpart': 0,     # Number of allocate partitions
+                 'realpart': 0,    # Number of partitions in the partition table
+                 'partitions': [], # Indexes to self.partitions
+                 'offset': 0,      # Offset of next partition (in sectors)
+                 # Minimum required disk size to fit all partitions (in bytes)
+                 'min_size': 0,
+                 'ptable_format': "msdos"} # Partition table format
+
+    def add_disk(self, disk_name, disk_obj):
+        """ Add a disk object which have to be partitioned. More than one disk
+        can be added. In case of multiple disks, disk partitions have to be
+        added for each disk separately with 'add_partition()". """
+
+        self.__add_disk(disk_name)
+        self.disks[disk_name]['disk'] = disk_obj
+
+    def __add_partition(self, part):
+        """ This is a helper function for 'add_partition()' which adds a
+        partition to the internal list of partitions. """
+
+        assert not self._partitions_layed_out
+
+        self.partitions.append(part)
+        self.__add_disk(part['disk_name'])
+
+    def add_partition(self, size, disk_name, mountpoint, source_file=None, fstype=None,
+                      label=None, fsopts=None, boot=False, align=None, no_table=False,
+                      part_type=None, uuid=None):
+        """ Add the next partition. Prtitions have to be added in the
+        first-to-last order. """
+
+        ks_pnum = len(self.partitions)
+
+        # Converting kB to sectors for parted
+        size = size * 1024 / self.sector_size
+
+        # We still need partition for "/" or non-subvolume
+        if mountpoint == "/" or not fsopts:
+            part = {'ks_pnum': ks_pnum, # Partition number in the KS file
+                    'size': size, # In sectors
+                    'mountpoint': mountpoint, # Mount relative to chroot
+                    'source_file': source_file, # partition contents
+                    'fstype': fstype, # Filesystem type
+                    'fsopts': fsopts, # Filesystem mount options
+                    'label': label, # Partition label
+                    'disk_name': disk_name, # physical disk name holding partition
+                    'device': None, # kpartx device node for partition
+                    'num': None, # Partition number
+                    'boot': boot, # Bootable flag
+                    'align': align, # Partition alignment
+                    'no_table' : no_table, # Partition does not appear in partition table
+                    'part_type' : part_type, # Partition type
+                    'uuid': uuid} # Partition UUID
+
+            self.__add_partition(part)
+
+    def layout_partitions(self, ptable_format="msdos"):
+        """ 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". """
+
+        msger.debug("Assigning %s partitions to disks" % ptable_format)
+
+        if self._partitions_layed_out:
+            return
+
+        self._partitions_layed_out = True
+
+        # Go through partitions in the order they are added in .ks file
+        for num in range(len(self.partitions)):
+            part = self.partitions[num]
+
+            if not self.disks.has_key(part['disk_name']):
+                raise ImageError("No disk %s for partition %s" \
+                                 % (part['disk_name'], part['mountpoint']))
+
+            if 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 ImageError("setting custom partition type is not " \
+                                 "implemented for msdos partitions")
+
+            # Get the disk where the partition is located
+            disk = self.disks[part['disk_name']]
+            disk['numpart'] += 1
+            if not part['no_table']:
+                disk['realpart'] += 1
+            disk['ptable_format'] = ptable_format
+
+            if disk['numpart'] == 1:
+                if ptable_format == "msdos":
+                    overhead = MBR_OVERHEAD
+                elif ptable_format == "gpt":
+                    overhead = GPT_OVERHEAD
+
+                # Skip one sector required for the partitioning scheme overhead
+                disk['offset'] += overhead
+
+            if disk['realpart'] > 3:
+                # Reserve a sector for EBR for every logical partition
+                # before alignment is performed.
+                if ptable_format == "msdos":
+                    disk['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 = disk['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
+
+                    msger.debug("Realignment for %s%s with %s sectors, original"
+                                " offset %s, target alignment is %sK." %
+                                (part['disk_name'], disk['numpart'], align_sectors,
+                                 disk['offset'], part['align']))
+
+                    # increase the offset so we actually start the partition on right alignment
+                    disk['offset'] += align_sectors
+
+            part['start'] = disk['offset']
+            disk['offset'] += part['size']
+
+            part['type'] = 'primary'
+            if not part['no_table']:
+                part['num'] = disk['realpart']
+            else:
+                part['num'] = 0
+
+            if disk['ptable_format'] == "msdos":
+                if disk['realpart'] > 3:
+                    part['type'] = 'logical'
+                    part['num'] = disk['realpart'] + 1
+
+            disk['partitions'].append(num)
+            msger.debug("Assigned %s to %s%d, sectors range %d-%d size %d "
+                        "sectors (%d bytes)." \
+                            % (part['mountpoint'], part['disk_name'], part['num'],
+                               part['start'], part['start'] + part['size'] - 1,
+                               part['size'], part['size'] * self.sector_size))
+
+        # Once all the partitions have been layed out, we can calculate the
+        # minumim disk sizes.
+        for disk in self.disks.values():
+            disk['min_size'] = disk['offset']
+            if disk['ptable_format'] == "gpt":
+                disk['min_size'] += GPT_OVERHEAD
+
+            disk['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
+        msger.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 __format_disks(self):
+        self.layout_partitions()
+
+        for dev in self.disks.keys():
+            disk = self.disks[dev]
+            msger.debug("Initializing partition table for %s" % \
+                        (disk['disk'].device))
+            exec_native_cmd("parted -s %s mklabel %s" % \
+                            (disk['disk'].device, disk['ptable_format']),
+                            self.native_sysroot)
+
+        msger.debug("Creating partitions")
+
+        for part in self.partitions:
+            if part['num'] == 0:
+                continue
+
+            disk = self.disks[part['disk_name']]
+            if disk['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(disk['disk'].device, "extended",
+                                        None, part['start'] - 1,
+                                        disk['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"
+            elif part['fstype'] == "ontrackdm6aux3":
+                parted_fs_type = "ontrackdm6aux3"
+            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'] % 2:
+                msger.debug("Substracting one sector from '%s' partition to " \
+                            "get even number of sectors for the partition" % \
+                            part['mountpoint'])
+                part['size'] -= 1
+
+            self.__create_partition(disk['disk'].device, part['type'],
+                                    parted_fs_type, part['start'], part['size'])
+
+            if part['part_type']:
+                msger.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'],
+                                          disk['disk'].device), self.native_sysroot)
+
+            if part['uuid']:
+                msger.debug("partition %d: set UUID to %s" % \
+                            (part['num'], part['uuid']))
+                exec_native_cmd("sgdisk --partition-guid=%d:%s %s" % \
+                                (part['num'], part['uuid'], disk['disk'].device),
+                                self.native_sysroot)
+
+            if part['boot']:
+                flag_name = "legacy_boot" if disk['ptable_format'] == 'gpt' else "boot"
+                msger.debug("Set '%s' flag for partition '%s' on disk '%s'" % \
+                            (flag_name, part['num'], disk['disk'].device))
+                exec_native_cmd("parted -s %s set %d %s on" % \
+                                (disk['disk'].device, part['num'], flag_name),
+                                self.native_sysroot)
+
+            # Parted defaults to enabling the lba flag for fat16 partitions,
+            # which causes compatibility issues with some firmware (and really
+            # isn't necessary).
+            if parted_fs_type == "fat16":
+                if disk['ptable_format'] == 'msdos':
+                    msger.debug("Disable 'lba' flag for partition '%s' on disk '%s'" % \
+                                (part['num'], disk['disk'].device))
+                    exec_native_cmd("parted -s %s set %d lba off" % \
+                                    (disk['disk'].device, part['num']),
+                                    self.native_sysroot)
+
+    def cleanup(self):
+        if self.disks:
+            for dev in self.disks:
+                disk = self.disks[dev]
+                try:
+                    disk['disk'].cleanup()
+                except:
+                    pass
+
+    def assemble(self, image_file):
+        msger.debug("Installing partitions")
+
+        for part in self.partitions:
+            source = part['source_file']
+            if source:
+                # install source_file contents into a partition
+                cmd = "dd if=%s of=%s bs=%d seek=%d count=%d conv=notrunc" % \
+                      (source, image_file, self.sector_size,
+                       part['start'], part['size'])
+                exec_cmd(cmd)
+
+                msger.debug("Installed %s in partition %d, sectors %d-%d, "
+                            "size %d sectors" % \
+                            (source, part['num'], part['start'],
+                             part['start'] + part['size'] - 1, part['size']))
+
+                os.rename(source, image_file + '.p%d' % part['num'])
+
+    def create(self):
+        for dev in self.disks.keys():
+            disk = self.disks[dev]
+            disk['disk'].create()
+
+        self.__format_disks()
+
+        return
diff --git a/scripts/lib/wic/utils/runner.py b/scripts/lib/wic/utils/runner.py
new file mode 100644
index 0000000..7431917
--- /dev/null
+++ b/scripts/lib/wic/utils/runner.py
@@ -0,0 +1,110 @@
+#!/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.
+
+import os
+import subprocess
+
+from wic import msger
+
+def runtool(cmdln_or_args, catch=1):
+    """ wrapper for most of the subprocess calls
+    input:
+        cmdln_or_args: can be both args and cmdln str (shell=True)
+        catch: 0, quitely run
+               1, only STDOUT
+               2, only STDERR
+               3, both STDOUT and STDERR
+    return:
+        (rc, output)
+        if catch==0: the output will always None
+    """
+
+    if catch not in (0, 1, 2, 3):
+        # invalid catch selection, will cause exception, that's good
+        return None
+
+    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
+
+    if catch != 3:
+        dev_null = os.open("/dev/null", os.O_WRONLY)
+
+    if catch == 0:
+        sout = dev_null
+        serr = dev_null
+    elif catch == 1:
+        sout = subprocess.PIPE
+        serr = dev_null
+    elif catch == 2:
+        sout = dev_null
+        serr = subprocess.PIPE
+    elif catch == 3:
+        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
+        out = ''.join(filter(None, [sout, serr]))
+    except OSError, err:
+        if err.errno == 2:
+            # [Errno 2] No such file or directory
+            msger.error('Cannot run command: %s, lost dependency?' % cmd)
+        else:
+            raise # relay
+    finally:
+        if catch != 3:
+            os.close(dev_null)
+
+    return (process.returncode, out)
+
+def show(cmdln_or_args):
+    # show all the message using msger.verbose
+
+    rcode, out = runtool(cmdln_or_args, catch=3)
+
+    if isinstance(cmdln_or_args, list):
+        cmd = ' '.join(cmdln_or_args)
+    else:
+        cmd = cmdln_or_args
+
+    msg = 'running command: "%s"' % cmd
+    if out:
+        out = out.strip()
+    if out:
+        msg += ', with output::'
+        msg += '\n  +----------------'
+        for line in out.splitlines():
+            msg += '\n  | %s' % line
+        msg += '\n  +----------------'
+
+    msger.verbose(msg)
+    return rcode
+
+def outs(cmdln_or_args, catch=1):
+    # get the outputs of tools
+    return runtool(cmdln_or_args, catch)[1].strip()
+
+def quiet(cmdln_or_args):
+    return runtool(cmdln_or_args, catch=0)[0]
diff --git a/scripts/lib/wic/utils/syslinux.py b/scripts/lib/wic/utils/syslinux.py
new file mode 100644
index 0000000..aace286
--- /dev/null
+++ b/scripts/lib/wic/utils/syslinux.py
@@ -0,0 +1,58 @@
+# 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 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.
+#
+# AUTHOR
+# Adrian Freihofer <adrian.freihofer (at] neratec.com>
+
+
+import re
+from wic import msger
+
+
+def serial_console_form_kargs(kernel_args):
+    """
+    Create SERIAL... line from kernel parameters
+
+    syslinux needs a line SERIAL port [baudrate [flowcontrol]]
+    in the syslinux.cfg file. The config line is generated based
+    on kernel boot parameters. The the parameters of the first
+    ttyS console are considered for syslinux config.
+    @param kernel_args kernel command line
+    @return line for syslinux config file e.g. "SERIAL 0 115200"
+    """
+    syslinux_conf = ""
+    for param in kernel_args.split():
+        param_match = re.match("console=ttyS([0-9]+),?([0-9]*)([noe]?)([0-9]?)(r?)", param)
+        if param_match:
+            syslinux_conf += "SERIAL " + param_match.group(1)
+            # baudrate
+            if param_match.group(2):
+                syslinux_conf += " " + param_match.group(2)
+            # parity
+            if param_match.group(3) and param_match.group(3) != 'n':
+                msger.warning("syslinux does not support parity for console. {} is ignored."
+                              .format(param_match.group(3)))
+            # number of bits
+            if param_match.group(4) and param_match.group(4) != '8':
+                msger.warning("syslinux supports 8 bit console configuration only. {} is ignored."
+                              .format(param_match.group(4)))
+            # flow control
+            if param_match.group(5) and param_match.group(5) != '':
+                msger.warning("syslinux console flowcontrol configuration. {} is ignored."
+                              .format(param_match.group(5)))
+            break
+
+    return syslinux_conf