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)
+
