diff --git a/blivet/__init__.py b/blivet/__init__.py
index 5f898a5..998a989 100644
--- a/blivet/__init__.py
+++ b/blivet/__init__.py
@@ -1838,24 +1838,19 @@ class Blivet(object):
 
         """
         log_method_call(self, device_type, size, **kwargs)
-        mountpoint = kwargs.get("mountpoint")
-        fstype = kwargs.get("fstype")
-        label = kwargs.get("label")
-        name = kwargs.get("name")
-        container_name = kwargs.get("container_name")
-        device = kwargs.get("device")
 
         # we can't do anything with existing devices
-        if device and device.exists:
-            log.info("factoryDevice refusing to change device %s" % device)
-            return
+        #if device and device.exists:
+        #    log.info("factoryDevice refusing to change device %s" % device)
+        #    return
 
-        if not fstype:
-            fstype = self.getFSType(mountpoint=mountpoint)
-            if fstype == "swap":
-                mountpoint = None
+        if not kwargs.get("fstype"):
+            kwargs["fstype"] = self.getFSType(mountpoint=kwargs.get("mountpoint"))
+            if kwargs["fstype"] == "swap":
+                kwargs["mountpoint"] = None
 
-        if fstype == "swap" and device_type == devicefactory.DEVICE_TYPE_BTRFS:
+        if kwargs["fstype"] == "swap" and \
+           device_type == devicefactory.DEVICE_TYPE_BTRFS:
             device_type = devicefactory.DEVICE_TYPE_PARTITION
 
         factory = devicefactory.get_device_factory(self, device_type, size,
@@ -1865,9 +1860,7 @@ class Blivet(object):
             raise StorageError("no disks specified for new device")
 
         self.size_sets = [] # clear this since there are no growable reqs now
-        factory.configure_device(device=device, container_name=container_name,
-                                 name=name, fstype=fstype,
-                                 mountpoint=mountpoint, label=label)
+        factory.configure()
 
     def copy(self):
         new = copy.deepcopy(self)
diff --git a/blivet/devicefactory.py b/blivet/devicefactory.py
index d16068f..aedd286 100644
--- a/blivet/devicefactory.py
+++ b/blivet/devicefactory.py
@@ -80,9 +80,7 @@ def get_raid_level(device):
 
 def get_device_factory(blivet, device_type, size, **kwargs):
     """ Return a suitable DeviceFactory instance for device_type. """
-    disks = kwargs.get("disks", [])
-    raid_level = kwargs.get("raid_level")
-    encrypted = kwargs.get("encrypted", False)
+    disks = kwargs.pop("disks", [])
 
     class_table = {DEVICE_TYPE_LVM: LVMFactory,
                    DEVICE_TYPE_BTRFS: BTRFSFactory,
@@ -91,10 +89,71 @@ def get_device_factory(blivet, device_type, size, **kwargs):
                    DEVICE_TYPE_DISK: DiskFactory}
 
     factory_class = class_table[device_type]
-    log.debug("instantiating %s: %r, %s, %s, %s" % (factory_class,
-                blivet, size, [d.name for d in disks], raid_level))
-    return factory_class(blivet, size, disks, raid_level, encrypted)
-
+    log.debug("instantiating %s: %s, %s, %s, %s" % (factory_class,
+                blivet, size, [d.name for d in disks], kwargs))
+    return factory_class(blivet, size, disks, **kwargs)
+
+""" Limitations:
+
+        - boundaries of support for preexisting devices are rigid/arbitrary
+            - can use a preexisting container, but cannot modify it
+                - this is only in the current member/container/device model
+        - stacks are limited to partition[/luks]/container/device[/luks]
+            - what about lvm on md, lvm thin provisioning?
+            - factory as an arbitrary recipe that can include other factories?
+                - examples
+                    - PartitionSet
+                        - set of partitions managed by a SizeSet
+                    - MDFactory
+                        - members use a PartitionSet
+                    - LVMFactory
+                        - members use a PartitionSet or an MDFactory
+                    - ThinProvisioningFactory
+                        - members use a PartitionSet or an MDFactory
+                        - container uses a variation on LVMFactory
+
+
+                    - partition
+                    - md/partitionset/partition
+                    - lvm/partitionset/partition
+                    - lvm/md/partitionset/partition
+                    - thinp/lvm/partitionset/partition
+                    - thinp/lvm/md/partitionset/partition
+                        - thinp
+                            - container is thin pool
+                            - device is thin lv
+                        - lvm
+                            - container is vg
+                            - device is lv
+                        - md
+                            - no container
+                            - device is md
+                        - partition set
+                            - container is whatever container we're members of
+                            - device is a list of partitions
+                    - btrfs/partitionset/partition
+                        - btrfs
+                            - container is volume
+                            - device is subvolume
+
+                    - md/diskset/disk
+                    - lvm/diskset/disk
+                    - lvm/md/diskset/disk
+
+
+                - factory
+                    - parent factory governs whatever the parent device is
+                        - a PartitionFactory has no parent factory
+                        - an LVMFactory has a parent factory of either
+                          PartitionSetFactory or MDFactory
+                    - configure
+                        - configures the device, including the parent factory
+
+                - encryption
+                    - LUKSFactory?
+                    - as-is except only set encrypted at the levels you want it
+
+"""
 class DeviceFactory(object):
     type_desc = None
     member_format = None        # format type for member devices
@@ -104,16 +163,57 @@ class DeviceFactory(object):
     encrypt_members = False
     encrypt_leaves = True
 
-    def __init__(self, storage, size, disks, raid_level, encrypted):
+    def __init__(self, storage, size, disks, fstype=None, mountpoint=None,
+                 label=None, raid_level=None, encrypted=False,
+                 container_name=None, name=None, device=None):
+        """ Create a new DeviceFactory instance.
+
+            Arguments:
+
+                storage             a Blivet instance
+                size                the desired size for the device
+                disks               the set of disks to use
+
+            Keyword args:
+
+                fstype              filesystem type
+                mountpoint          filesystem mount point
+                label               filesystem label text
+
+                raid_level          raid level string, eg: "raid1"
+                encrypted           whether to encrypt (boolean)
+
+                container_name      name of requested container
+                name                name of requested device
+
+                device              an already-defined but non-existent device
+                                    to adjust instead of creating a new device
+        """
+
+
         self.storage = storage          # the Blivet instance
         self.size = size                # the requested size for this device
         self.disks = disks              # the set of disks to allocate from
+
+        self.original_size = size
+        self.original_disks = disks[:]
+
+        self.fstype = fstype
+        self.mountpoint = mountpoint
+        self.label = label
+
         self.raid_level = raid_level
         self.encrypted = encrypted
 
-        # this is a list of member devices, used to short-circuit the logic in
-        # set_container_members for case of a partition
-        self.member_list = None
+        self.container_name = container_name
+        self.device_name = name
+
+        self.device = device
+
+        if not self.fstype:
+            self.fstype = self.storage.getFSType(mountpoint=self.mountpoint)
+            if fstype == "swap":
+                self.mountpoint = None
 
         # choose a size set class for member partition allocation
         if raid_level is not None and raid_level.startswith("raid"):
@@ -141,16 +241,16 @@ class DeviceFactory(object):
         """ Perform actions required after device creation. """
         pass
 
-    def container_size_func(self, container, device=None):
+    def container_size_func(self, container):
         """ Return the total space needed for the specified container. """
         size = container.size
-        size += self.device_size
-        if device:
-            size -= device.size
+        size += self.device_space
+        if self.device:
+            size -= self.device.size
 
         return size
 
-    def handle_no_size(self, device=None, container=None):
+    def handle_no_size(self, container=None):
         """ Set device size so that it grows to the largest size possible. """
         if self.size is not None:
             return
@@ -159,57 +259,55 @@ class DeviceFactory(object):
         free = sum(d[0] for d in free_info.values())
         self.size = int(free.convertTo(spec="mb"))
 
-        if device:
-            self.size += device.size
+        if self.device:
+            self.size += self.device.size
 
     @property
-    def device_size(self):
+    def device_space(self):
         """ The total disk space required for this device. """
         return self.size
 
-    def set_device_size(self, container, device=None):
+    def get_device_size(self, container):
         return self.size
 
-    def set_container_members(self, container, members=None, device=None):
+    def set_device_size(self, container):
+        pass
+
+    @property
+    def use_dev(self):
+        use_dev = None
+        if self.device:
+            if isinstance(self.device, LUKSDevice):
+                use_dev = self.device.slave
+            else:
+                use_dev = self.device
+
+        return use_dev
+
+    ##
+    ## FIXME: This should be a PartitionSetFactory.configure method
+    ##
+    def set_container_members(self):
         """ Set up and return the container's member devices. """
-        log_members = []
-        if members:
-            log_members = [str(m) for m in members]
-        log_method_call(self, container=container,
-                        members=log_members, device=device)
-        if self.member_list is not None:
-            # short-circuit the logic below for partitions
-            return self.member_list
+        log_method_call(self)
+
+        container = self.get_container()
+        members = self.get_members(container=container)
 
         if container and container.exists:
             # don't try to modify an existing container
             return container.parents
 
-        if self.container_size_func is None:
-            return []
-
-        container_size = self.device_size
-
         # list of disks to add/remove member devices to/from
         add_disks = []
         remove_disks = []
 
-        # set up member list and container based on the full argument set
-        if members is None:
-            members = []
-
-        if container:
-            members = container.parents[:]
-        elif members:
-            # mdarray
-            container = device
-
         ##
         ## Determine the target disk set.
         ##
 
         # XXX how can we detect/handle failure to use one or more of the disks?
-        if members and device:
+        if members and self.device:
             # See if we need to add/remove any disks, but only if we are
             # adjusting a device. When adding a new device to a container we do
             # not want to modify the container's disk set.
@@ -335,8 +433,10 @@ class DeviceFactory(object):
         if container:
             log.debug("using container %s with %d devices" % (container.name,
                         len(self.storage.devicetree.getChildren(container))))
-            container_size = self.container_size_func(container, device)
+            container_size = self.container_size_func(container)
             log.debug("raw container size reported as %d" % container_size)
+        else:
+            container_size = self.device_space
 
         ##
         ## Set up SizeSet to manage growth of member partitions.
@@ -376,6 +476,12 @@ class DeviceFactory(object):
     def get_container(self, device=None, name=None, existing=False):
         # XXX would it be useful to implement this as a series of fallbacks
         #     instead of mutually exclusive branches?
+        if self.device and not device:
+            device = self.device
+
+        if self.container_name and not name:
+            name = self.container_name
+
         container = None
         if name:
             container = self.storage.devicetree.getDeviceByName(name)
@@ -384,6 +490,8 @@ class DeviceFactory(object):
                             % (name, container.type))
                 container = None
         elif device:
+            # XXX This should be easier to get to and it should override all
+            #     other logic for determining the container.
             if hasattr(device, "vg"):
                 container = device.vg
             elif hasattr(device, "volume"):
@@ -402,6 +510,9 @@ class DeviceFactory(object):
 
         return container
 
+    def get_members(self, container=None):
+        return getattr(container, "parents", [])
+
     def _clean_up_member_devices(self, members, container=None):
         for member in members:
             if container:
@@ -414,98 +525,25 @@ class DeviceFactory(object):
             if not member.isDisk:
                 self.storage.destroyDevice(member)
 
-    def configure_device(self, device=None, container_name=None, name=None,
-                         fstype=None, mountpoint=None, label=None):
-        """ Schedule creation of a device based on a top-down specification.
-
-            Keyword arguments:
-
-                fstype              filesystem type
-                mountpoint          filesystem mount point
-                label               filesystem label text
-
-                container_name      name of requested container
-                name                name of requested device
-
-                device              an already-defined but non-existent device
-                                    to adjust instead of creating a new device
-
-
-            Error handling:
-
-                If device is None, meaning we're creating a device, the error
-                handling aims to remove all evidence of the attempt to create a
-                new device by removing unused container devices, reverting the
-                size of container devices that contain other devices, &c.
-
-                If the device is not None, meaning we're adjusting the size of
-                a defined device, the error handling aims to revert the device
-                and any container to it previous size.
-
-                In either case, we re-raise the exception so the caller knows
-                there was a failure. If we failed to clean up as described above
-                we raise ErrorRecoveryFailure to alert the caller that things
-                will likely be in an inconsistent state.
-        """
-        # we can't do anything with existing devices
-        if device and device.exists:
-            log.info("factoryDevice refusing to change device %s" % device)
-            return
-
-        if not fstype:
-            fstype = self.storage.getFSType(mountpoint=mountpoint)
-            if fstype == "swap":
-                mountpoint = None
-
-        fmt_args = {}
-        if label:
-            fmt_args["label"] = label
-
-        container = self.get_container(device=device, name=container_name)
-
-        # handle special size value of None, which means to grow unbounded
-        self.handle_no_size(device=device, container=container)
-
-        # TODO: striping, mirroring, &c
-        # TODO: non-partition members (pv-on-md)
-
+    def configure_container(self):
+        """ Configure and return the container device for this factory. """
         ##
-        ## Define and allocate container members.
+        ## look up a suitable container if one exists
         ##
-
-        # set_container_members can modify these, so save them now
-        old_size = None
-        old_disks = []
-        if device:
-            old_size = device.size
-            old_disks = device.disks[:]
-
-        members = []
-        if device and device.type == "mdarray":
-            members = device.parents[:]
+        container = self.get_container()
 
         try:
-            parents = self.set_container_members(container,
-                                                 members=members, device=device)
+            parents = self.set_container_members()
         except PartitioningError as e:
             # If this is a new device, just clean up and get out.
-            if device:
+            if self.device:
                 # If this is a defined device, try to clean up by reallocating
                 # members as before and then get out.
-                self.disks = device.disks
-                self.size = device.size  # this should work
-
-                if members:
-                    # If this is an md array we have to reset its member set
-                    # here.
-                    # If there is a container device, its member set was reset
-                    # in the exception handler in set_container_members.
-                    device.parents = members
+                self.disks = self.device.disks
+                self.size = self.device.size  # this should work
 
                 try:
-                    self.set_container_members(container,
-                                               members=members,
-                                               device=device)
+                    self.set_container_members()
                 except StorageError as e:
                     log.error("failed to revert device size: %s" % e)
                     raise ErrorRecoveryFailure("failed to revert container")
@@ -513,15 +551,15 @@ class DeviceFactory(object):
             raise
 
         ##
-        ## Create (or modify as needed) the container.
+        ## Create (or modify as needed) our container.
         ##
         if not container and self.new_container_attr:
             if not parents:
                 raise StorageError("not enough free space on disks")
 
             log.debug("creating new container")
-            if container_name:
-                kwa = {"name": container_name}
+            if self.container_name:
+                kwa = {"name": self.container_name}
             else:
                 kwa = {}
             try:
@@ -535,130 +573,195 @@ class DeviceFactory(object):
             self.storage.createDevice(container)
         elif container and not container.exists and \
              hasattr(container, "dataLevel"):
+            # FIXME: this is btrfs-specific and belongs in a
+            #        reconfigure_container method or similar
             container.dataLevel = self.raid_level
 
-        if container:
-            parents = [container]
-            log.debug("%r" % container)
+        return container
 
-        ##
-        ## Create (or adjust as needed) the device.
-        ##
+    def reconfigure_device(self, container=None):
+        # We are adjusting a defined device: size, disk set, container
+        # member encryption, container raid level. The StorageDevice
+        # instance exists, but the underlying device does not.
+        # TODO: handle various other changes:
+        #       - toggle encryption for leaf device
+        #       - change raid level for device-level raid (lvm)
+        #       - change fstype, mountpoint, label
+        e = None
 
-        # this will set the device's size if a device is passed in
-        size = self.set_device_size(container, device=device)
-
-        if device:
-            # We are adjusting a defined device: size, disk set, container
-            # member encryption, container raid level. The StorageDevice
-            # instance exists, but the underlying device does not.
-            # TODO: handle various other changes:
-            #       - toggle encryption for leaf device
-            #       - change raid level for device-level raid (lvm)
-            #       - change fstype, mountpoint, label
-            e = None
+        # this is setting the device size based on the factory size and the
+        # current size of the container
+        self.set_device_size(container)
+
+        try:
+            self.post_create()
+        except StorageError as e:
+            log.error("device post-create method failed: %s" % e)
+        else:
+            if self.device.size <= self.device.format.minSize:
+                e = StorageError("failed to adjust device -- not enough free space in specified disks?")
+
+        if e:
+            # Clean up by reverting the device to its previous size.
+            self.size = self.original_size
+            self.disks = self.original_disks[:]
+            try:
+                self.set_container_members()
+            except StorageError as e:
+                # yes, we're replacing e here.
+                log.error("failed to revert device size: %s" % e)
+                raise ErrorRecoveryFailure("failed to revert device size")
+
+            self.set_device_size(container)
             try:
                 self.post_create()
             except StorageError as e:
-                log.error("device post-create method failed: %s" % e)
-            else:
-                if device.size <= device.format.minSize:
-                    e = StorageError("failed to adjust device -- not enough free space in specified disks?")
+                # yes, we're replacing e here.
+                log.error("failed to revert device size: %s" % e)
+                raise ErrorRecoveryFailure("failed to revert device size")
 
-            if e:
-                # Clean up by reverting the device to its previous size.
-                self.size = old_size
-                self.disks = old_disks
-                try:
-                    self.set_container_members(container,
-                                               members=members, device=device)
-                except StorageError as e:
-                    # yes, we're replacing e here.
-                    log.error("failed to revert device size: %s" % e)
-                    raise ErrorRecoveryFailure("failed to revert device size")
+            raise(e)
 
-                self.set_device_size(container, device=device)
-                try:
-                    self.post_create()
-                except StorageError as e:
-                    # yes, we're replacing e here.
-                    log.error("failed to revert device size: %s" % e)
-                    raise ErrorRecoveryFailure("failed to revert device size")
+        return self.device
 
-                raise(e)
+    def create_device(self, container=None):
+        if container:
+            parents = [container]
+        else:
+            parents = self.get_members()
 
-            ret = device
-        elif self.new_device_attr:
-            log.debug("creating new device")
-            if self.encrypted and self.encrypt_leaves:
-                luks_fmt_type = fstype
-                luks_fmt_args = fmt_args
-                luks_mountpoint = mountpoint
-                fstype = "luks"
-                mountpoint = None
-                fmt_args = {}
-
-            def _container_post_error():
-                # Clean up. If there is a container and it has other devices,
-                # try to revert it. If there is a container and it has no other
-                # devices, remove it. If there is not a container, remove all of
-                # the parents.
-                if container:
-                    if container.kids:
-                        self.size = 0
-                        self.disks = container.disks
-                        try:
-                            self.set_container_members(container)
-                        except StorageError as e:
-                            log.error("failed to revert container: %s" % e)
-                            raise ErrorRecoveryFailure("failed to revert container")
-                    else:
-                        self.storage.destroyDevice(container)
-                        self._clean_up_member_devices(container.parents)
+        def _container_post_error():
+            # Clean up. If there is a container and it has other devices,
+            # try to revert it. If there is a container and it has no other
+            # devices, remove it. If there is not a container, remove all of
+            # the parents.
+            if container:
+                if container.kids:
+                    self.size = 0
+                    self.disks = container.disks
+                    try:
+                        self.set_container_members()
+                    except StorageError as e:
+                        log.error("failed to revert container: %s" % e)
+                        raise ErrorRecoveryFailure("failed to revert container")
                 else:
-                    self._clean_up_member_devices(parents)
-
-            if name:
-                kwa = {"name": name}
+                    self.storage.destroyDevice(container)
+                    self._clean_up_member_devices(container.parents)
             else:
-                kwa = {}
+                self._clean_up_member_devices(parents)
 
-            try:
-                device = self.new_device(parents=parents,
-                                            size=size,
-                                            fmt_type=fstype,
-                                            mountpoint=mountpoint,
-                                            fmt_args=fmt_args,
-                                            **kwa)
-            except (StorageError, ValueError) as e:
-                log.error("device instance creation failed: %s" % e)
-                _container_post_error()
-                raise
+        fmt_args = {}
+        if self.encrypted and self.encrypt_leaves:
+            fstype = "luks"
+            mountpoint = None
+        else:
+            fstype = self.fstype
+            mountpoint = self.mountpoint
+            fmt_args = {}
+            if self.label:
+                fmt_args["label"] = self.label
+
+        if self.device_name:
+            kwa = {"name": self.device_name}
+        else:
+            kwa = {}
 
-            self.storage.createDevice(device)
-            e = None
-            try:
-                self.post_create()
-            except StorageError as e:
-                log.error("device post-create method failed: %s" % e)
-            else:
-                if not device.size:
-                    e = StorageError("failed to create device")
-
-            if e:
-                self.storage.destroyDevice(device)
-                _container_post_error()
-                raise StorageError(e)
-
-            ret = device
-            if self.encrypted and self.encrypt_leaves:
-                fmt = getFormat(luks_fmt_type,
-                                mountpoint=luks_mountpoint,
-                                **luks_fmt_args)
-                luks_device = LUKSDevice("luks-" + device.name,
-                                         parents=[device], format=fmt)
-                self.storage.createDevice(luks_device)
-                ret = luks_device
+        # this gets us a size value that takes into account the actual size of
+        # the container
+        size = self.get_device_size(container)
+
+        try:
+            device = self.new_device(parents=parents,
+                                     size=size,
+                                     fmt_type=fstype,
+                                     mountpoint=mountpoint,
+                                     fmt_args=fmt_args,
+                                     **kwa)
+        except (StorageError, ValueError) as e:
+            log.error("device instance creation failed: %s" % e)
+            _container_post_error()
+            raise
+
+        self.storage.createDevice(device)
+        e = None
+        try:
+            self.post_create()
+        except StorageError as e:
+            log.error("device post-create method failed: %s" % e)
+        else:
+            if not device.size:
+                e = StorageError("failed to create device")
+
+        if e:
+            self.storage.destroyDevice(device)
+            _container_post_error()
+            raise StorageError(e)
+
+        ret = device
+        if self.encrypted and self.encrypt_leaves:
+            fmt_args = {}
+            if self.label:
+                fmt_args["label"] = self.label
+
+            fmt = getFormat(self.fstype,
+                            mountpoint=self.mountpoint,
+                            **fmt_args)
+            luks_device = LUKSDevice("luks-" + device.name,
+                                     parents=[device], format=fmt)
+            self.storage.createDevice(luks_device)
+            ret = luks_device
+
+        return ret
+
+    def configure(self):
+        """ Schedule creation of a device based on a top-down specification.
+
+            Error handling:
+
+                If device is None, meaning we're creating a device, the error
+                handling aims to remove all evidence of the attempt to create a
+                new device by removing unused container devices, reverting the
+                size of container devices that contain other devices, &c.
+
+                If the device is not None, meaning we're adjusting the size of
+                a defined device, the error handling aims to revert the device
+                and any container to it previous size.
+
+                In either case, we re-raise the exception so the caller knows
+                there was a failure. If we failed to clean up as described above
+                we raise ErrorRecoveryFailure to alert the caller that things
+                will likely be in an inconsistent state.
+        """
+        # we can't do anything with existing devices
+        if self.device and self.device.exists:
+            log.info("factoryDevice refusing to change device %s" % self.device)
+            return [self.device]
+
+        ##
+        ## look up a suitable container if one exists
+        ##
+        container = self.get_container()
+
+        # handle special size value of None, which means to grow unbounded
+        self.handle_no_size(container=container)
+
+        # TODO: striping, mirroring, &c
+
+        container = self.configure_container()
+        if container:
+            parents = [container]
+            log.debug("%r" % container)
+
+        ##
+        ## Create (or adjust as needed) the device.
+        ##
+        ret = None
+        if self.device:
+            log.debug("reconfiguring device %s" % self.use_dev.name)
+            ret = self.reconfigure_device(container=container)
+        elif self.new_device_attr:
+            log.debug("creating new device")
+            ret = self.create_device(container=container)
 
         return ret
 
@@ -669,15 +772,11 @@ class DiskFactory(DeviceFactory):
     encrypt_leaves = True
 
 class PartitionFactory(DeviceFactory):
+    """ Partition with minimal base size growable up to the requested size """
     type_desc = "partition"
     new_device_attr = "newPartition"
     default_size = 1
 
-    def __init__(self, storage, size, disks, raid_level, encrypted):
-        super(PartitionFactory, self).__init__(storage, size, disks, raid_level,
-                                               encrypted)
-        self.member_list = self.disks
-
     def new_device(self, *args, **kwargs):
         grow = True
         max_size = kwargs.pop("size")
@@ -691,34 +790,43 @@ class PartitionFactory(DeviceFactory):
     def post_create(self):
         self.allocate_partitions()
 
-    def set_device_size(self, container, device=None):
+    def get_device_size(self, container):
         size = self.size
-        if device:
-            if isinstance(device, LUKSDevice):
-                use_dev = device.slave
-            else:
-                use_dev = device
+        if self.device:
+            # use device here since the leaf format is what we're concerned with
+            base_size = max(PartitionFactory.default_size,
+                            self.device.format.minSize)
+            size = max(base_size, size)
+
+        return size
 
-            if size != use_dev.size:
-                log.info("adjusting device size from %.2f to %.2f"
-                                % (use_dev.size, size))
+    def set_device_size(self, container):
+        if self.device and self.size != self.use_dev.size:
+            log.info("adjusting device size from %.2f to %.2f"
+                            % (self.use_dev.size, self.size))
 
             # use device here since the leaf format is what we're concerned with
             base_size = max(PartitionFactory.default_size,
-                            device.format.minSize)
-            size = max(base_size, size)
-            use_dev.req_base_size = base_size
-            use_dev.req_size = base_size
-            use_dev.req_max_size = size
-            use_dev.req_grow = size > base_size
+                            self.device.format.minSize)
+            size = self.get_device_size(container)
+            self.use_dev.req_base_size = base_size
+            self.use_dev.req_size = base_size
+            self.use_dev.req_max_size = size
+            self.use_dev.req_grow = size > base_size
 
             # this probably belongs somewhere else but this is our chance to
             # update the disk set
-            use_dev.req_disks = self.disks[:]
+            # FIXME: Move this into reconfigure_device or similar
+            self.use_dev.req_disks = self.disks[:]
 
-        return size
+    def set_container_members(self):
+        return self.get_members()
+
+    def get_members(self):
+        return self.disks
 
 class BTRFSFactory(DeviceFactory):
+    """ BTRFS subvolume """
     type_desc = "btrfs"
     member_format = "btrfs"
     new_container_attr = "newBTRFS"
@@ -727,32 +835,31 @@ class BTRFSFactory(DeviceFactory):
     encrypt_members = True
     encrypt_leaves = False
 
-    def __init__(self, storage, size, disks, raid_level, encrypted):
-        super(BTRFSFactory, self).__init__(storage, size, disks, raid_level,
-                                           encrypted)
-        self.raid_level = raid_level or "single"
+    def __init__(self, storage, size, disks, **kwargs):
+        super(BTRFSFactory, self).__init__(storage, size, disks, **kwargs)
+        self.raid_level = self.raid_level or "single"
 
     def new_container(self, *args, **kwargs):
         """ Return the newly created container for this device. """
         kwargs["dataLevel"] = self.raid_level
         return getattr(self.storage, self.new_container_attr)(*args, **kwargs)
 
-    def container_size_func(self, container, device=None):
+    def container_size_func(self, container):
         """ Return the total space needed for the specified container. """
         if container.exists:
             container_size = container.size
         else:
             container_size = sum([s.req_size for s in container.subvolumes])
 
-        if device:
-            size = self.device_size
+        if self.device:
+            size = self.device_space
         else:
-            size = container_size + self.device_size
+            size = container_size + self.device_space
 
         return size
 
     @property
-    def device_size(self):
+    def device_space(self):
         # until we get/need something better
         if self.raid_level in ("single", "raid0"):
             return self.size
@@ -765,6 +872,7 @@ class BTRFSFactory(DeviceFactory):
         return super(BTRFSFactory, self).new_device(*args, **kwargs)
 
 class LVMFactory(DeviceFactory):
+    """ LVM logical volume """
     type_desc = "lvm"
     member_format = "lvmpv"
     new_container_attr = "newVG"
@@ -773,7 +881,7 @@ class LVMFactory(DeviceFactory):
     encrypt_members = True      # this should be settable per-instance
     encrypt_leaves = False      # this should be settable per-instance
 
-    def handle_no_size(self, device=None, container=None):
+    def handle_no_size(self, container=None):
         """ Set device size so that it grows to the largest size possible. """
         if self.size is not None:
             return
@@ -781,66 +889,61 @@ class LVMFactory(DeviceFactory):
         if container and container.exists:
             self.size = container.freeSpace
 
-            if device:
-                self.size += device.size
+            if self.device:
+                self.size += self.device.size
         else:
-            super(LVMFactory, self).handle_no_size(device=device,
-                                                   container=container)
+            super(LVMFactory, self).handle_no_size(container=container)
 
     @property
     def size_func_kwargs(self):
         kwargs = {}
-        if not getattr(self, "lvm_on_md"):
-            if self.raid_level in ("raid1", "raid10"):
-                kwargs["mirrored"] = True
-            if self.raid_level in ("raid0", "raid10"):
-                kwargs["striped"] = True
+        if self.raid_level in ("raid1", "raid10"):
+            kwargs["mirrored"] = True
+        if self.raid_level in ("raid0", "raid10"):
+            kwargs["striped"] = True
 
         return kwargs
 
     @property
-    def device_size(self):
+    def device_space(self):
         return get_pv_space(self.size, len(self.disks), **self.size_func_kwargs)
 
-    def container_size_func(self, container, device=None):
+    def container_size_func(self, container):
         size = sum([p.size for p in container.parents])
         size -= container.freeSpace
-        size += self.device_size
-        if device:
-            size -= get_pv_space(device.size, len(container.parents),
+        size += self.device_space
+        if self.device:
+            size -= get_pv_space(self.device.size, len(container.parents),
                                  **self.size_func_kwargs)
 
         return size
 
-    def set_device_size(self, container, device=None):
+    def get_device_size(self, container):
         size = self.size
         free = container.freeSpace
-        if device:
-            if isinstance(device, LUKSDevice):
-                use_dev = device.slave
-            else:
-                use_dev = device
-
-            free += use_dev.size
+        if self.device:
+            free += self.use_dev.size
 
         if free < size:
-            log.info("adjusting device size from %.2f to %.2f so it fits "
-                     "in container" % (size, free))
+            log.info("adjusting size from %.2f to %.2f so it fits "
+                     "in container %s" % (size, free, container.name))
             size = free
 
-        if device:
-            if size != use_dev.size:
-                log.info("adjusting device size from %.2f to %.2f"
-                                % (use_dev.size, size))
-
-            use_dev.size = size
-
         return size
 
+    def set_device_size(self, container):
+        size = self.get_device_size(container)
+        if self.device and size != self.use_dev.size:
+            log.info("adjusting device size from %.2f to %.2f"
+                            % (self.use_dev.size, size))
+            self.use_dev.size = size
+
 class LVMOnMDFactory(LVMFactory):
-    lvm_on_md = True
+    @property
+    def size_func_kwargs(self):
+        return {}
 
-    def set_container_members(self, container, members=None, device=None):
+    def set_container_members(self):
         """ Set up and return the container's member devices. """
         log_members = []
         if members:
@@ -850,11 +953,11 @@ class LVMOnMDFactory(LVMFactory):
 
         pv_name = self.storage.suggestDeviceName(prefix="pv")
         pv_device = None
-        md_size = self.device_size
+        md_size = self.device_space
         if container:
             # get a proper container size estimate and pass any existing
             # member device into configure_device
-            md_size = self.container_size_func(container, device)
+            md_size = self.container_size_func(container)
             pv_device = container.parents[0]    # XXX single pv, right?
 
         md_factory = MDFactory(self.storage, md_size, self.disks,
@@ -875,11 +978,11 @@ class MDFactory(DeviceFactory):
         return []
 
     @property
-    def device_size(self):
+    def device_space(self):
         return get_member_space(self.size, len(self.disks),
                                 level=self.raid_level)
 
-    def container_size_func(self, container, device=None):
+    def container_size_func(self, container):
         return get_member_space(self.size, len(container.parents),
                                 level=self.raid_level)
 
@@ -888,3 +991,6 @@ class MDFactory(DeviceFactory):
         kwargs["totalDevices"] = len(kwargs.get("parents"))
         kwargs["memberDevices"] = len(kwargs.get("parents"))
         return super(MDFactory, self).new_device(*args, **kwargs)
+
+    def get_container(self):
+        return self.device
