[PATCH 1/4] Structure the sources so it matches final structure better and make isys a package

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



---
 70-anaconda.rules                                 |   56 -
 Makefile.am                                       |   33 +-
 __init__.py                                       |  395 ---
 anaconda                                          |  932 ------
 anaconda.py                                       |  932 ++++++
 anaconda_log.py                                   |  170 -
 backend.py                                        |  301 --
 backend_log.py                                    |   88 -
 baseudev.py                                       |   92 -
 bin/Makefile.am                                   |   23 +
 bin/gptsync/.gitignore                            |    2 +
 bin/gptsync/Makefile.am                           |   35 +
 bin/gptsync/README                                |   41 +
 bin/gptsync/gptsync.c                             |  470 +++
 bin/gptsync/gptsync.h                             |  219 ++
 bin/gptsync/lib.c                                 |  469 +++
 bin/gptsync/os_unix.c                             |  267 ++
 bin/gptsync/showpart.c                            |  257 ++
 bin/gptsync/syslinux_mbr.h                        |   90 +
 bin/loader/.gitignore                             |   12 +
 bin/loader/Makefile.am                            |  118 +
 bin/loader/cdinstall.c                            |  509 +++
 bin/loader/cdinstall.h                            |   34 +
 bin/loader/copy.c                                 |  141 +
 bin/loader/copy.h                                 |   26 +
 bin/loader/devices.h                              |  103 +
 bin/loader/devt.h                                 |   39 +
 bin/loader/dirbrowser.c                           |  199 ++
 bin/loader/dirbrowser.h                           |   28 +
 bin/loader/driverdisk.c                           |  861 +++++
 bin/loader/driverdisk.h                           |   51 +
 bin/loader/driverselect.c                         |  251 ++
 bin/loader/fwloader.c                             |  675 ++++
 bin/loader/fwloader.h                             |   35 +
 bin/loader/getparts.c                             |  180 ++
 bin/loader/getparts.h                             |   27 +
 bin/loader/hardware.c                             |  150 +
 bin/loader/hardware.h                             |   28 +
 bin/loader/hdinstall.c                            |  496 +++
 bin/loader/hdinstall.h                            |   38 +
 bin/loader/ibft.c                                 |  105 +
 bin/loader/ibft.h                                 |   45 +
 bin/loader/init.c                                 |  798 +++++
 bin/loader/init.h                                 |   31 +
 bin/loader/kbd.c                                  |  164 +
 bin/loader/kbd.h                                  |   27 +
 bin/loader/keymaps-i386                           |  Bin 0 -> 12173 bytes
 bin/loader/keymaps-ppc                            |  Bin 0 -> 12871 bytes
 bin/loader/keymaps-x86_64                         |  Bin 0 -> 12173 bytes
 bin/loader/kickstart.c                            |  559 ++++
 bin/loader/kickstart.h                            |   54 +
 bin/loader/lang.c                                 |  399 +++
 bin/loader/lang.h                                 |   41 +
 bin/loader/linuxrc.s390                           | 3118 ++++++++++++++++++
 bin/loader/loader.c                               | 2378 ++++++++++++++
 bin/loader/loader.h                               |  193 ++
 bin/loader/loadermisc.c                           |  150 +
 bin/loader/loadermisc.h                           |   33 +
 bin/loader/mediacheck.c                           |  115 +
 bin/loader/mediacheck.h                           |   25 +
 bin/loader/method.c                               |  570 ++++
 bin/loader/method.h                               |   60 +
 bin/loader/mkctype.c                              |   76 +
 bin/loader/moduleinfo.c                           |  276 ++
 bin/loader/moduleinfo.h                           |   78 +
 bin/loader/modules.c                              |  530 +++
 bin/loader/modules.h                              |   47 +
 bin/loader/net.c                                  | 2122 ++++++++++++
 bin/loader/net.h                                  |   77 +
 bin/loader/nfsinstall.c                           |  586 ++++
 bin/loader/nfsinstall.h                           |   40 +
 bin/loader/rpmextract.c                           |  325 ++
 bin/loader/rpmextract.h                           |   45 +
 bin/loader/selinux.c                              |   56 +
 bin/loader/selinux.h                              |   27 +
 bin/loader/shutdown.c                             |  153 +
 bin/loader/simplemot                              |   81 +
 bin/loader/telnet.c                               |  273 ++
 bin/loader/telnet.h                               |   40 +
 bin/loader/telnetd.c                              |  256 ++
 bin/loader/telnetd.h                              |   25 +
 bin/loader/udelay.h                               |  199 ++
 bin/loader/undomounts.c                           |  239 ++
 bin/loader/unicode-linedraw-chars.txt             |   22 +
 bin/loader/urlinstall.c                           |  414 +++
 bin/loader/urlinstall.h                           |   36 +
 bin/loader/urls.c                                 |  371 +++
 bin/loader/urls.h                                 |   35 +
 bin/loader/windows.c                              |  121 +
 bin/loader/windows.h                              |   43 +
 bootdisk/Makefile.am                              |   22 -
 bootdisk/i386/Makefile.am                         |   25 -
 bootdisk/i386/boot.msg                            |    5 -
 bootdisk/i386/grub.conf                           |    8 -
 bootdisk/i386/syslinux.cfg                        |   33 -
 bootdisk/ppc/Makefile.am                          |   26 -
 bootdisk/ppc/bootinfo.txt                         |  169 -
 bootdisk/ppc/magic                                |   81 -
 bootdisk/ppc/mapping                              |   27 -
 bootdisk/ppc/ofboot.b                             |   74 -
 bootdisk/ppc/yaboot.conf.3264                     |   14 -
 bootdisk/ppc/yaboot.conf.in                       |    8 -
 bootdisk/s390x/Makefile.am                        |   25 -
 bootdisk/s390x/generic.ins                        |    5 -
 bootdisk/s390x/generic.prm                        |    1 -
 bootdisk/s390x/redhat.exec                        |    9 -
 bootdisk/sparc/Makefile.am                        |   25 -
 bootdisk/sparc/boot.msg                           |    9 -
 bootdisk/sparc/silo.conf                          |   17 -
 bootdisk/x86_64/Makefile.am                       |   25 -
 bootdisk/x86_64/boot.msg                          |    5 -
 bootdisk/x86_64/grub.conf                         |    8 -
 bootdisk/x86_64/syslinux.cfg                      |   33 -
 bootloader.py                                     |  244 --
 cmdline.py                                        |  221 --
 command-stubs/Makefile.am                         |   23 -
 command-stubs/list-harddrives-stub                |   45 -
 command-stubs/loadkeys-stub                       |   41 -
 command-stubs/losetup-stub                        |   50 -
 command-stubs/mknod-stub                          |   54 -
 command-stubs/raidstart-stub                      |   44 -
 command-stubs/raidstop-stub                       |   31 -
 compssort.py                                      |   69 -
 configure.ac                                      |   53 +-
 constants.py                                      |   89 -
 data/70-anaconda.rules                            |   56 +
 data/Makefile.am                                  |   36 +
 data/bootdisk/Makefile.am                         |   22 +
 data/bootdisk/i386/Makefile.am                    |   25 +
 data/bootdisk/i386/boot.msg                       |    5 +
 data/bootdisk/i386/grub.conf                      |    8 +
 data/bootdisk/i386/syslinux.cfg                   |   33 +
 data/bootdisk/ppc/Makefile.am                     |   26 +
 data/bootdisk/ppc/bootinfo.txt                    |  169 +
 data/bootdisk/ppc/magic                           |   81 +
 data/bootdisk/ppc/mapping                         |   27 +
 data/bootdisk/ppc/ofboot.b                        |   74 +
 data/bootdisk/ppc/yaboot.conf.3264                |   14 +
 data/bootdisk/ppc/yaboot.conf.in                  |    8 +
 data/bootdisk/s390x/Makefile.am                   |   25 +
 data/bootdisk/s390x/generic.ins                   |    5 +
 data/bootdisk/s390x/generic.prm                   |    1 +
 data/bootdisk/s390x/redhat.exec                   |    9 +
 data/bootdisk/sparc/Makefile.am                   |   25 +
 data/bootdisk/sparc/boot.msg                      |    9 +
 data/bootdisk/sparc/silo.conf                     |   17 +
 data/bootdisk/x86_64/Makefile.am                  |   25 +
 data/bootdisk/x86_64/boot.msg                     |    5 +
 data/bootdisk/x86_64/grub.conf                    |    8 +
 data/bootdisk/x86_64/syslinux.cfg                 |   33 +
 data/command-stubs/Makefile.am                    |   23 +
 data/command-stubs/list-harddrives-stub           |   45 +
 data/command-stubs/loadkeys-stub                  |   41 +
 data/command-stubs/losetup-stub                   |   50 +
 data/command-stubs/mknod-stub                     |   54 +
 data/command-stubs/raidstart-stub                 |   44 +
 data/command-stubs/raidstop-stub                  |   31 +
 data/fonts/Makefile.am                            |   39 +
 data/fonts/screenfont-alpha.gz                    |  Bin 0 -> 4893 bytes
 data/fonts/screenfont-i386.gz                     |  Bin 0 -> 5507 bytes
 data/fonts/screenfont-ia64.gz                     |  Bin 0 -> 3821 bytes
 data/fonts/screenfont-ppc.gz                      |  Bin 0 -> 5305 bytes
 data/fonts/screenfont-sparc.gz                    |  Bin 0 -> 6455 bytes
 data/fonts/screenfont-x86_64.gz                   |  Bin 0 -> 5473 bytes
 data/fonts/updfonts                               |   11 +
 data/icons/Makefile.am                            |   22 +
 data/icons/hicolor/16x16/Makefile.am              |   22 +
 data/icons/hicolor/16x16/apps/Makefile.am         |   23 +
 data/icons/hicolor/16x16/apps/anaconda.png        |  Bin 0 -> 925 bytes
 data/icons/hicolor/22x22/Makefile.am              |   22 +
 data/icons/hicolor/22x22/apps/Makefile.am         |   23 +
 data/icons/hicolor/22x22/apps/anaconda.png        |  Bin 0 -> 1326 bytes
 data/icons/hicolor/24x24/Makefile.am              |   22 +
 data/icons/hicolor/24x24/apps/Makefile.am         |   23 +
 data/icons/hicolor/24x24/apps/anaconda.png        |  Bin 0 -> 1368 bytes
 data/icons/hicolor/32x32/Makefile.am              |   22 +
 data/icons/hicolor/32x32/apps/Makefile.am         |   23 +
 data/icons/hicolor/32x32/apps/anaconda.png        |  Bin 0 -> 1860 bytes
 data/icons/hicolor/48x48/Makefile.am              |   22 +
 data/icons/hicolor/48x48/apps/Makefile.am         |   23 +
 data/icons/hicolor/48x48/apps/anaconda.png        |  Bin 0 -> 3020 bytes
 data/icons/hicolor/Makefile.am                    |   22 +
 data/lang-table                                   |   61 +
 data/liveinst/.gitignore                          |    1 +
 data/liveinst/Makefile.am                         |   56 +
 data/liveinst/README                              |    1 +
 data/liveinst/console.apps/Makefile.am            |   26 +
 data/liveinst/console.apps/liveinst               |    6 +
 data/liveinst/liveinst                            |   95 +
 data/liveinst/liveinst.desktop.in                 |   12 +
 data/liveinst/pam.d/Makefile.am                   |   25 +
 data/liveinst/pam.d/liveinst                      |    4 +
 data/liveinst/zz-liveinst.sh                      |   14 +
 data/pixmaps/Makefile.am                          |   23 +
 data/pixmaps/about-to-install.png                 |  Bin 0 -> 10818 bytes
 data/pixmaps/checkMark.png                        |  Bin 0 -> 347 bytes
 data/pixmaps/config-language.png                  |  Bin 0 -> 3079 bytes
 data/pixmaps/done.png                             |  Bin 0 -> 25801 bytes
 data/pixmaps/filter-menu.png                      |  Bin 0 -> 456 bytes
 data/pixmaps/gnome-lock.png                       |  Bin 0 -> 810 bytes
 data/pixmaps/gnome-mouse.png                      |  Bin 0 -> 2744 bytes
 data/pixmaps/install.png                          |  Bin 0 -> 4180 bytes
 data/pixmaps/network.png                          |  Bin 0 -> 2458 bytes
 data/pixmaps/partscheme-all.png                   |  Bin 0 -> 1594 bytes
 data/pixmaps/partscheme-custom.png                |  Bin 0 -> 805 bytes
 data/pixmaps/partscheme-freespace.png             |  Bin 0 -> 1724 bytes
 data/pixmaps/partscheme-replace.png               |  Bin 0 -> 1783 bytes
 data/pixmaps/partscheme-shrink.png                |  Bin 0 -> 1875 bytes
 data/pixmaps/root-password.png                    |  Bin 0 -> 4316 bytes
 data/pixmaps/upgrade.png                          |  Bin 0 -> 4632 bytes
 data/ui/GroupSelector.glade                       |  394 +++
 data/ui/Makefile.am                               |   25 +
 data/ui/account.glade                             |  278 ++
 data/ui/adddrive.glade                            |  196 ++
 data/ui/addrepo.glade                             | 1016 ++++++
 data/ui/anaconda.glade                            |  270 ++
 data/ui/autopart.glade                            |  300 ++
 data/ui/blwhere.glade                             |  378 +++
 data/ui/cleardisks.glade                          |  300 ++
 data/ui/create-storage.glade                      |  379 +++
 data/ui/detailed-dialog.glade                     |  171 +
 data/ui/fcoe-config.glade                         |  130 +
 data/ui/filter.glade                              | 1387 ++++++++
 data/ui/iscsi-config.glade                        |  456 +++
 data/ui/lukspassphrase.glade                      |  446 +++
 data/ui/netconfig.glade                           |  538 ++++
 data/ui/network.glade                             |  259 ++
 data/ui/tasksel.glade                             |  335 ++
 data/ui/zfcp-config.glade                         |  276 ++
 desktop.py                                        |   71 -
 dispatch.py                                       |  254 --
 errors.py                                         |  159 -
 exception.py                                      |  132 -
 firewall.py                                       |   93 -
 flags.py                                          |  122 -
 fonts/Makefile.am                                 |   39 -
 fonts/screenfont-alpha.gz                         |  Bin 4893 -> 0 bytes
 fonts/screenfont-i386.gz                          |  Bin 5507 -> 0 bytes
 fonts/screenfont-ia64.gz                          |  Bin 3821 -> 0 bytes
 fonts/screenfont-ppc.gz                           |  Bin 5305 -> 0 bytes
 fonts/screenfont-sparc.gz                         |  Bin 6455 -> 0 bytes
 fonts/screenfont-x86_64.gz                        |  Bin 5473 -> 0 bytes
 fonts/updfonts                                    |   11 -
 gptsync/.gitignore                                |    2 -
 gptsync/Makefile.am                               |   35 -
 gptsync/README                                    |   41 -
 gptsync/gptsync.c                                 |  470 ---
 gptsync/gptsync.h                                 |  219 --
 gptsync/lib.c                                     |  469 ---
 gptsync/os_unix.c                                 |  267 --
 gptsync/showpart.c                                |  257 --
 gptsync/syslinux_mbr.h                            |   90 -
 gui.py                                            | 1530 ---------
 icons/Makefile.am                                 |   22 -
 icons/hicolor/16x16/Makefile.am                   |   22 -
 icons/hicolor/16x16/apps/Makefile.am              |   23 -
 icons/hicolor/16x16/apps/anaconda.png             |  Bin 925 -> 0 bytes
 icons/hicolor/22x22/Makefile.am                   |   22 -
 icons/hicolor/22x22/apps/Makefile.am              |   23 -
 icons/hicolor/22x22/apps/anaconda.png             |  Bin 1326 -> 0 bytes
 icons/hicolor/24x24/Makefile.am                   |   22 -
 icons/hicolor/24x24/apps/Makefile.am              |   23 -
 icons/hicolor/24x24/apps/anaconda.png             |  Bin 1368 -> 0 bytes
 icons/hicolor/32x32/Makefile.am                   |   22 -
 icons/hicolor/32x32/apps/Makefile.am              |   23 -
 icons/hicolor/32x32/apps/anaconda.png             |  Bin 1860 -> 0 bytes
 icons/hicolor/48x48/Makefile.am                   |   22 -
 icons/hicolor/48x48/apps/Makefile.am              |   23 -
 icons/hicolor/48x48/apps/anaconda.png             |  Bin 3020 -> 0 bytes
 icons/hicolor/Makefile.am                         |   22 -
 image.py                                          |  326 --
 installclass.py                                   |  336 --
 installclasses/Makefile.am                        |   24 -
 installclasses/fedora.py                          |  127 -
 installclasses/rhel.py                            |  113 -
 installinterfacebase.py                           |   76 -
 installmethod.py                                  |   56 -
 isys/.gitignore                                   |    6 -
 isys/Makefile.am                                  |   56 -
 isys/auditd.c                                     |  134 -
 isys/auditd.h                                     |   30 -
 isys/cpio.c                                       |   46 -
 isys/cpio.h                                       |  102 -
 isys/devices.c                                    |  221 --
 isys/devices.h                                    |   42 -
 isys/eddsupport.c                                 |  339 --
 isys/eddsupport.h                                 |   28 -
 isys/ethtool.c                                    |  119 -
 isys/ethtool.h                                    |   41 -
 isys/iface.c                                      |  543 ----
 isys/iface.h                                      |  166 -
 isys/imount.c                                     |  328 --
 isys/imount.h                                     |   50 -
 isys/isofs.c                                      |   55 -
 isys/isys.c                                       |  701 ----
 isys/isys.h                                       |   39 -
 isys/isys.py                                      |  560 ----
 isys/lang.c                                       |  207 --
 isys/lang.h                                       |   44 -
 isys/linkdetect.c                                 |  202 --
 isys/log.c                                        |  224 --
 isys/log.h                                        |   51 -
 isys/stubs.h                                      |   44 -
 isys/uncpio.c                                     |  798 -----
 isys/vio.c                                        |  106 -
 iutil.py                                          | 1073 -------
 iw/DeviceSelector.py                              |  217 --
 iw/GroupSelector.py                               |  620 ----
 iw/Makefile.am                                    |   24 -
 iw/account_gui.py                                 |  148 -
 iw/advanced_storage.py                            |  256 --
 iw/autopart_type.py                               |  284 --
 iw/blpasswidget.py                                |  164 -
 iw/bootloader_main_gui.py                         |  244 --
 iw/checklist.py                                   |  225 --
 iw/cleardisks_gui.py                              |  240 --
 iw/congrats_gui.py                                |  103 -
 iw/datacombo.py                                   |   99 -
 iw/examine_gui.py                                 |  163 -
 iw/filter_gui.py                                  |  764 -----
 iw/filter_type.py                                 |   80 -
 iw/iw_gui.py                                      |   53 -
 iw/kbd_gui.py                                     |   39 -
 iw/language_gui.py                                |  134 -
 iw/lvm_dialog_gui.py                              | 1466 ---------
 iw/netconfig_dialog.py                            |  329 --
 iw/network_gui.py                                 |  106 -
 iw/osbootwidget.py                                |  397 ---
 iw/package_gui.py                                 |   39 -
 iw/partition_dialog_gui.py                        |  534 ---
 iw/partition_gui.py                               | 1835 -----------
 iw/partition_ui_helpers_gui.py                    |  445 ---
 iw/pixmapRadioButtonGroup_gui.py                  |  248 --
 iw/progress_gui.py                                |  150 -
 iw/raid_dialog_gui.py                             |  615 ----
 iw/task_gui.py                                    |  705 ----
 iw/timezone_gui.py                                |  181 --
 iw/upgrade_bootloader_gui.py                      |  209 --
 iw/upgrade_migratefs_gui.py                       |  118 -
 iw/upgrade_swap_gui.py                            |  209 --
 iw/welcome_gui.py                                 |   68 -
 iw/zipl_gui.py                                    |  132 -
 kickstart.py                                      | 1499 ---------
 lang-table                                        |   61 -
 language.py                                       |  280 --
 livecd.py                                         |  469 ---
 liveinst/.gitignore                               |    1 -
 liveinst/Makefile.am                              |   56 -
 liveinst/README                                   |    1 -
 liveinst/console.apps/Makefile.am                 |   26 -
 liveinst/console.apps/liveinst                    |    6 -
 liveinst/liveinst                                 |   95 -
 liveinst/liveinst.desktop.in                      |   12 -
 liveinst/pam.d/Makefile.am                        |   25 -
 liveinst/pam.d/liveinst                           |    4 -
 liveinst/zz-liveinst.sh                           |   14 -
 loader/.gitignore                                 |   12 -
 loader/Makefile.am                                |  118 -
 loader/cdinstall.c                                |  509 ---
 loader/cdinstall.h                                |   34 -
 loader/copy.c                                     |  141 -
 loader/copy.h                                     |   26 -
 loader/devices.h                                  |  103 -
 loader/devt.h                                     |   39 -
 loader/dirbrowser.c                               |  199 --
 loader/dirbrowser.h                               |   28 -
 loader/driverdisk.c                               |  861 -----
 loader/driverdisk.h                               |   51 -
 loader/driverselect.c                             |  251 --
 loader/fwloader.c                                 |  675 ----
 loader/fwloader.h                                 |   35 -
 loader/getparts.c                                 |  180 --
 loader/getparts.h                                 |   27 -
 loader/hardware.c                                 |  150 -
 loader/hardware.h                                 |   28 -
 loader/hdinstall.c                                |  496 ---
 loader/hdinstall.h                                |   38 -
 loader/ibft.c                                     |  105 -
 loader/ibft.h                                     |   45 -
 loader/init.c                                     |  798 -----
 loader/init.h                                     |   31 -
 loader/kbd.c                                      |  164 -
 loader/kbd.h                                      |   27 -
 loader/keymaps-i386                               |  Bin 12173 -> 0 bytes
 loader/keymaps-ppc                                |  Bin 12871 -> 0 bytes
 loader/keymaps-x86_64                             |  Bin 12173 -> 0 bytes
 loader/kickstart.c                                |  559 ----
 loader/kickstart.h                                |   54 -
 loader/lang.c                                     |  399 ---
 loader/lang.h                                     |   41 -
 loader/linuxrc.s390                               | 3118 ------------------
 loader/loader.c                                   | 2378 --------------
 loader/loader.h                                   |  193 --
 loader/loadermisc.c                               |  150 -
 loader/loadermisc.h                               |   33 -
 loader/mediacheck.c                               |  115 -
 loader/mediacheck.h                               |   25 -
 loader/method.c                                   |  570 ----
 loader/method.h                                   |   60 -
 loader/mkctype.c                                  |   76 -
 loader/moduleinfo.c                               |  276 --
 loader/moduleinfo.h                               |   78 -
 loader/modules.c                                  |  530 ---
 loader/modules.h                                  |   47 -
 loader/net.c                                      | 2122 ------------
 loader/net.h                                      |   77 -
 loader/nfsinstall.c                               |  586 ----
 loader/nfsinstall.h                               |   40 -
 loader/rpmextract.c                               |  325 --
 loader/rpmextract.h                               |   45 -
 loader/selinux.c                                  |   56 -
 loader/selinux.h                                  |   27 -
 loader/shutdown.c                                 |  153 -
 loader/simplemot                                  |   81 -
 loader/telnet.c                                   |  273 --
 loader/telnet.h                                   |   40 -
 loader/telnetd.c                                  |  256 --
 loader/telnetd.h                                  |   25 -
 loader/udelay.h                                   |  199 --
 loader/undomounts.c                               |  239 --
 loader/unicode-linedraw-chars.txt                 |   22 -
 loader/urlinstall.c                               |  414 ---
 loader/urlinstall.h                               |   36 -
 loader/urls.c                                     |  371 ---
 loader/urls.h                                     |   35 -
 loader/windows.c                                  |  121 -
 loader/windows.h                                  |   43 -
 network.py                                        |  839 -----
 packages.py                                       |  360 ---
 partIntfHelpers.py                                |  354 --
 pixmaps/Makefile.am                               |   23 -
 pixmaps/about-to-install.png                      |  Bin 10818 -> 0 bytes
 pixmaps/checkMark.png                             |  Bin 347 -> 0 bytes
 pixmaps/config-language.png                       |  Bin 3079 -> 0 bytes
 pixmaps/done.png                                  |  Bin 25801 -> 0 bytes
 pixmaps/filter-menu.png                           |  Bin 456 -> 0 bytes
 pixmaps/gnome-lock.png                            |  Bin 810 -> 0 bytes
 pixmaps/gnome-mouse.png                           |  Bin 2744 -> 0 bytes
 pixmaps/install.png                               |  Bin 4180 -> 0 bytes
 pixmaps/network.png                               |  Bin 2458 -> 0 bytes
 pixmaps/partscheme-all.png                        |  Bin 1594 -> 0 bytes
 pixmaps/partscheme-custom.png                     |  Bin 805 -> 0 bytes
 pixmaps/partscheme-freespace.png                  |  Bin 1724 -> 0 bytes
 pixmaps/partscheme-replace.png                    |  Bin 1783 -> 0 bytes
 pixmaps/partscheme-shrink.png                     |  Bin 1875 -> 0 bytes
 pixmaps/root-password.png                         |  Bin 4316 -> 0 bytes
 pixmaps/upgrade.png                               |  Bin 4632 -> 0 bytes
 platform.py                                       |  574 ----
 product.py                                        |   63 -
 pyanaconda/Makefile.am                            |   34 +
 pyanaconda/__init__.py                            |  395 +++
 pyanaconda/anaconda_log.py                        |  170 +
 pyanaconda/backend.py                             |  301 ++
 pyanaconda/backend_log.py                         |   88 +
 pyanaconda/baseudev.py                            |   92 +
 pyanaconda/bootloader.py                          |  244 ++
 pyanaconda/cmdline.py                             |  221 ++
 pyanaconda/compssort.py                           |   69 +
 pyanaconda/constants.py                           |   89 +
 pyanaconda/desktop.py                             |   71 +
 pyanaconda/dispatch.py                            |  254 ++
 pyanaconda/errors.py                              |  159 +
 pyanaconda/exception.py                           |  132 +
 pyanaconda/firewall.py                            |   93 +
 pyanaconda/flags.py                               |  122 +
 pyanaconda/gui.py                                 | 1530 +++++++++
 pyanaconda/image.py                               |  326 ++
 pyanaconda/installclass.py                        |  336 ++
 pyanaconda/installclasses/Makefile.am             |   24 +
 pyanaconda/installclasses/fedora.py               |  127 +
 pyanaconda/installclasses/rhel.py                 |  113 +
 pyanaconda/installinterfacebase.py                |   76 +
 pyanaconda/installmethod.py                       |   56 +
 pyanaconda/isys/.gitignore                        |    6 +
 pyanaconda/isys/Makefile.am                       |   56 +
 pyanaconda/isys/__init__.py                       |  560 ++++
 pyanaconda/isys/auditd.c                          |  134 +
 pyanaconda/isys/auditd.h                          |   30 +
 pyanaconda/isys/cpio.c                            |   46 +
 pyanaconda/isys/cpio.h                            |  102 +
 pyanaconda/isys/devices.c                         |  221 ++
 pyanaconda/isys/devices.h                         |   42 +
 pyanaconda/isys/eddsupport.c                      |  339 ++
 pyanaconda/isys/eddsupport.h                      |   28 +
 pyanaconda/isys/ethtool.c                         |  119 +
 pyanaconda/isys/ethtool.h                         |   41 +
 pyanaconda/isys/iface.c                           |  543 ++++
 pyanaconda/isys/iface.h                           |  166 +
 pyanaconda/isys/imount.c                          |  328 ++
 pyanaconda/isys/imount.h                          |   50 +
 pyanaconda/isys/isofs.c                           |   55 +
 pyanaconda/isys/isys.c                            |  701 ++++
 pyanaconda/isys/isys.h                            |   39 +
 pyanaconda/isys/lang.c                            |  207 ++
 pyanaconda/isys/lang.h                            |   44 +
 pyanaconda/isys/linkdetect.c                      |  202 ++
 pyanaconda/isys/log.c                             |  224 ++
 pyanaconda/isys/log.h                             |   51 +
 pyanaconda/isys/stubs.h                           |   44 +
 pyanaconda/isys/uncpio.c                          |  798 +++++
 pyanaconda/isys/vio.c                             |  106 +
 pyanaconda/iutil.py                               | 1073 +++++++
 pyanaconda/iw/DeviceSelector.py                   |  217 ++
 pyanaconda/iw/GroupSelector.py                    |  620 ++++
 pyanaconda/iw/Makefile.am                         |   24 +
 pyanaconda/iw/account_gui.py                      |  148 +
 pyanaconda/iw/advanced_storage.py                 |  256 ++
 pyanaconda/iw/autopart_type.py                    |  284 ++
 pyanaconda/iw/blpasswidget.py                     |  164 +
 pyanaconda/iw/bootloader_main_gui.py              |  244 ++
 pyanaconda/iw/checklist.py                        |  225 ++
 pyanaconda/iw/cleardisks_gui.py                   |  240 ++
 pyanaconda/iw/congrats_gui.py                     |  103 +
 pyanaconda/iw/datacombo.py                        |   99 +
 pyanaconda/iw/examine_gui.py                      |  163 +
 pyanaconda/iw/filter_gui.py                       |  764 +++++
 pyanaconda/iw/filter_type.py                      |   80 +
 pyanaconda/iw/iw_gui.py                           |   53 +
 pyanaconda/iw/kbd_gui.py                          |   39 +
 pyanaconda/iw/language_gui.py                     |  134 +
 pyanaconda/iw/lvm_dialog_gui.py                   | 1466 +++++++++
 pyanaconda/iw/netconfig_dialog.py                 |  329 ++
 pyanaconda/iw/network_gui.py                      |  106 +
 pyanaconda/iw/osbootwidget.py                     |  397 +++
 pyanaconda/iw/package_gui.py                      |   39 +
 pyanaconda/iw/partition_dialog_gui.py             |  534 +++
 pyanaconda/iw/partition_gui.py                    | 1835 +++++++++++
 pyanaconda/iw/partition_ui_helpers_gui.py         |  445 +++
 pyanaconda/iw/pixmapRadioButtonGroup_gui.py       |  248 ++
 pyanaconda/iw/progress_gui.py                     |  150 +
 pyanaconda/iw/raid_dialog_gui.py                  |  615 ++++
 pyanaconda/iw/task_gui.py                         |  705 ++++
 pyanaconda/iw/timezone_gui.py                     |  181 ++
 pyanaconda/iw/upgrade_bootloader_gui.py           |  209 ++
 pyanaconda/iw/upgrade_migratefs_gui.py            |  118 +
 pyanaconda/iw/upgrade_swap_gui.py                 |  209 ++
 pyanaconda/iw/welcome_gui.py                      |   68 +
 pyanaconda/iw/zipl_gui.py                         |  132 +
 pyanaconda/kickstart.py                           | 1499 +++++++++
 pyanaconda/language.py                            |  280 ++
 pyanaconda/livecd.py                              |  469 +++
 pyanaconda/network.py                             |  839 +++++
 pyanaconda/packages.py                            |  360 +++
 pyanaconda/partIntfHelpers.py                     |  354 ++
 pyanaconda/platform.py                            |  574 ++++
 pyanaconda/product.py                             |   63 +
 pyanaconda/pyudev.py                              |  225 ++
 pyanaconda/rescue.py                              |  508 +++
 pyanaconda/run_test.py                            |  109 +
 pyanaconda/security.py                            |   87 +
 pyanaconda/simpleconfig.py                        |   88 +
 pyanaconda/sitecustomize.py                       |   22 +
 pyanaconda/sortedtransaction.py                   |   87 +
 pyanaconda/storage/Makefile.am                    |   26 +
 pyanaconda/storage/__init__.py                    | 2252 +++++++++++++
 pyanaconda/storage/dasd.py                        |  225 ++
 pyanaconda/storage/deviceaction.py                |  376 +++
 pyanaconda/storage/devicelibs/Makefile.am         |   24 +
 pyanaconda/storage/devicelibs/crypto.py           |  193 ++
 pyanaconda/storage/devicelibs/dm.py               |  130 +
 pyanaconda/storage/devicelibs/edd.py              |   97 +
 pyanaconda/storage/devicelibs/lvm.py              |  419 +++
 pyanaconda/storage/devicelibs/mdraid.py           |  236 ++
 pyanaconda/storage/devicelibs/mpath.py            |  228 ++
 pyanaconda/storage/devicelibs/swap.py             |  125 +
 pyanaconda/storage/devices.py                     | 3564 +++++++++++++++++++++
 pyanaconda/storage/devicetree.py                  | 2278 +++++++++++++
 pyanaconda/storage/errors.py                      |  153 +
 pyanaconda/storage/fcoe.py                        |  164 +
 pyanaconda/storage/formats/Makefile.am            |   24 +
 pyanaconda/storage/formats/__init__.py            |  403 +++
 pyanaconda/storage/formats/disklabel.py           |  356 ++
 pyanaconda/storage/formats/dmraid.py              |  114 +
 pyanaconda/storage/formats/fs.py                  | 1488 +++++++++
 pyanaconda/storage/formats/luks.py                |  352 ++
 pyanaconda/storage/formats/lvmpv.py               |  156 +
 pyanaconda/storage/formats/mdraid.py              |  124 +
 pyanaconda/storage/formats/multipath.py           |   95 +
 pyanaconda/storage/formats/prepboot.py            |   64 +
 pyanaconda/storage/formats/swap.py                |  186 ++
 pyanaconda/storage/iscsi.py                       |  333 ++
 pyanaconda/storage/miscutils.py                   |   57 +
 pyanaconda/storage/partitioning.py                | 1707 ++++++++++
 pyanaconda/storage/partspec.py                    |   66 +
 pyanaconda/storage/storage_log.py                 |   32 +
 pyanaconda/storage/udev.py                        |  523 +++
 pyanaconda/storage/zfcp.py                        |  441 +++
 pyanaconda/text.py                                |  692 ++++
 pyanaconda/textw/Makefile.am                      |   24 +
 pyanaconda/textw/add_drive_text.py                |  180 ++
 pyanaconda/textw/complete_text.py                 |   65 +
 pyanaconda/textw/constants_text.py                |   68 +
 pyanaconda/textw/keyboard_text.py                 |   67 +
 pyanaconda/textw/language_text.py                 |   70 +
 pyanaconda/textw/netconfig_text.py                |  285 ++
 pyanaconda/textw/network_text.py                  |   33 +
 pyanaconda/textw/partition_text.py                |  162 +
 pyanaconda/textw/progress_text.py                 |  131 +
 pyanaconda/textw/statusline_text.py               |   78 +
 pyanaconda/textw/task_text.py                     |   28 +
 pyanaconda/textw/timezone_text.py                 |  131 +
 pyanaconda/textw/upgrade_bootloader_text.py       |  183 ++
 pyanaconda/textw/upgrade_text.py                  |  258 ++
 pyanaconda/textw/userauth_text.py                 |  107 +
 pyanaconda/textw/welcome_text.py                  |   47 +
 pyanaconda/textw/zipl_text.py                     |  102 +
 pyanaconda/timezone.py                            |   76 +
 pyanaconda/upgrade.py                             |  344 ++
 pyanaconda/users.py                               |  307 ++
 pyanaconda/vnc.py                                 |  437 +++
 pyanaconda/xutils.c                               |  268 ++
 pyanaconda/yuminstall.py                          | 2024 ++++++++++++
 pyudev.py                                         |  225 --
 rescue.py                                         |  508 ---
 run_test.py                                       |  109 -
 security.py                                       |   87 -
 simpleconfig.py                                   |   88 -
 sitecustomize.py                                  |   22 -
 sortedtransaction.py                              |   87 -
 storage/Makefile.am                               |   26 -
 storage/__init__.py                               | 2252 -------------
 storage/dasd.py                                   |  225 --
 storage/deviceaction.py                           |  376 ---
 storage/devicelibs/Makefile.am                    |   24 -
 storage/devicelibs/crypto.py                      |  193 --
 storage/devicelibs/dm.py                          |  130 -
 storage/devicelibs/edd.py                         |   97 -
 storage/devicelibs/lvm.py                         |  419 ---
 storage/devicelibs/mdraid.py                      |  236 --
 storage/devicelibs/mpath.py                       |  228 --
 storage/devicelibs/swap.py                        |  125 -
 storage/devices.py                                | 3564 ---------------------
 storage/devicetree.py                             | 2278 -------------
 storage/errors.py                                 |  153 -
 storage/fcoe.py                                   |  164 -
 storage/formats/Makefile.am                       |   24 -
 storage/formats/__init__.py                       |  403 ---
 storage/formats/disklabel.py                      |  356 --
 storage/formats/dmraid.py                         |  114 -
 storage/formats/fs.py                             | 1488 ---------
 storage/formats/luks.py                           |  352 --
 storage/formats/lvmpv.py                          |  156 -
 storage/formats/mdraid.py                         |  124 -
 storage/formats/multipath.py                      |   95 -
 storage/formats/prepboot.py                       |   64 -
 storage/formats/swap.py                           |  186 --
 storage/iscsi.py                                  |  333 --
 storage/miscutils.py                              |   57 -
 storage/partitioning.py                           | 1707 ----------
 storage/partspec.py                               |   66 -
 storage/storage_log.py                            |   32 -
 storage/udev.py                                   |  523 ---
 storage/zfcp.py                                   |  441 ---
 stubs/.gitignore                                  |    2 -
 tests/Makefile.am                                 |    2 +-
 tests/__init__.py                                 |   31 -
 tests/kickstart/Makefile.am                       |   26 -
 tests/kickstart/commands.py                       |   61 -
 tests/kickstart_test/Makefile.am                  |   26 +
 tests/kickstart_test/commands_test.py             |   90 +
 tests/mock/Makefile.am                            |   24 +
 tests/mock/__init__.py                            |   17 +
 tests/storage/Makefile.am                         |   24 -
 tests/storage/devicelibs/Makefile.am              |   30 -
 tests/storage/devicelibs/baseclass.py             |   55 -
 tests/storage/devicelibs/crypto.py                |  131 -
 tests/storage/devicelibs/lvm.py                   |  234 --
 tests/storage/devicelibs/mdraid.py                |  110 -
 tests/storage/devicelibs/mpath.py                 |   33 -
 tests/storage/devicelibs/swap.py                  |   70 -
 tests/storage_test/Makefile.am                    |   24 +
 tests/storage_test/devicelibs_test/Makefile.am    |   30 +
 tests/storage_test/devicelibs_test/baseclass.py   |   55 +
 tests/storage_test/devicelibs_test/crypto_test.py |  131 +
 tests/storage_test/devicelibs_test/lvm_test.py    |  234 ++
 tests/storage_test/devicelibs_test/mdraid_test.py |  110 +
 tests/storage_test/devicelibs_test/mpath_test.py  |   33 +
 tests/storage_test/devicelibs_test/swap_test.py   |   70 +
 text.py                                           |  692 ----
 textw/Makefile.am                                 |   24 -
 textw/add_drive_text.py                           |  180 --
 textw/complete_text.py                            |   65 -
 textw/constants_text.py                           |   68 -
 textw/keyboard_text.py                            |   67 -
 textw/language_text.py                            |   70 -
 textw/netconfig_text.py                           |  285 --
 textw/network_text.py                             |   33 -
 textw/partition_text.py                           |  162 -
 textw/progress_text.py                            |  131 -
 textw/statusline_text.py                          |   78 -
 textw/task_text.py                                |   28 -
 textw/timezone_text.py                            |  131 -
 textw/upgrade_bootloader_text.py                  |  183 --
 textw/upgrade_text.py                             |  258 --
 textw/userauth_text.py                            |  107 -
 textw/welcome_text.py                             |   47 -
 textw/zipl_text.py                                |  102 -
 timezone.py                                       |   76 -
 ui/GroupSelector.glade                            |  394 ---
 ui/Makefile.am                                    |   25 -
 ui/account.glade                                  |  278 --
 ui/adddrive.glade                                 |  196 --
 ui/addrepo.glade                                  | 1016 ------
 ui/anaconda.glade                                 |  270 --
 ui/autopart.glade                                 |  300 --
 ui/blwhere.glade                                  |  378 ---
 ui/cleardisks.glade                               |  300 --
 ui/create-storage.glade                           |  379 ---
 ui/detailed-dialog.glade                          |  171 -
 ui/fcoe-config.glade                              |  130 -
 ui/filter.glade                                   | 1387 --------
 ui/iscsi-config.glade                             |  456 ---
 ui/lukspassphrase.glade                           |  446 ---
 ui/netconfig.glade                                |  538 ----
 ui/network.glade                                  |  259 --
 ui/tasksel.glade                                  |  335 --
 ui/zfcp-config.glade                              |  276 --
 upgrade.py                                        |  344 --
 users.py                                          |  307 --
 vnc.py                                            |  437 ---
 xutils.c                                          |  268 --
 yuminstall.py                                     | 2024 ------------
 722 files changed, 84215 insertions(+), 84105 deletions(-)
 delete mode 100644 70-anaconda.rules
 delete mode 100644 __init__.py
 delete mode 100755 anaconda
 create mode 100755 anaconda.py
 delete mode 100644 anaconda_log.py
 delete mode 100644 backend.py
 delete mode 100644 backend_log.py
 delete mode 100644 baseudev.py
 create mode 100644 bin/Makefile.am
 create mode 100644 bin/gptsync/.gitignore
 create mode 100644 bin/gptsync/Makefile.am
 create mode 100644 bin/gptsync/README
 create mode 100644 bin/gptsync/gptsync.c
 create mode 100644 bin/gptsync/gptsync.h
 create mode 100644 bin/gptsync/lib.c
 create mode 100644 bin/gptsync/os_unix.c
 create mode 100644 bin/gptsync/showpart.c
 create mode 100644 bin/gptsync/syslinux_mbr.h
 create mode 100644 bin/loader/.gitignore
 create mode 100644 bin/loader/Makefile.am
 create mode 100644 bin/loader/cdinstall.c
 create mode 100644 bin/loader/cdinstall.h
 create mode 100644 bin/loader/copy.c
 create mode 100644 bin/loader/copy.h
 create mode 100644 bin/loader/devices.h
 create mode 100644 bin/loader/devt.h
 create mode 100644 bin/loader/dirbrowser.c
 create mode 100644 bin/loader/dirbrowser.h
 create mode 100644 bin/loader/driverdisk.c
 create mode 100644 bin/loader/driverdisk.h
 create mode 100644 bin/loader/driverselect.c
 create mode 100644 bin/loader/fwloader.c
 create mode 100644 bin/loader/fwloader.h
 create mode 100644 bin/loader/getparts.c
 create mode 100644 bin/loader/getparts.h
 create mode 100644 bin/loader/hardware.c
 create mode 100644 bin/loader/hardware.h
 create mode 100644 bin/loader/hdinstall.c
 create mode 100644 bin/loader/hdinstall.h
 create mode 100644 bin/loader/ibft.c
 create mode 100644 bin/loader/ibft.h
 create mode 100644 bin/loader/init.c
 create mode 100644 bin/loader/init.h
 create mode 100644 bin/loader/kbd.c
 create mode 100644 bin/loader/kbd.h
 create mode 100644 bin/loader/keymaps-i386
 create mode 100644 bin/loader/keymaps-ppc
 create mode 100644 bin/loader/keymaps-x86_64
 create mode 100644 bin/loader/kickstart.c
 create mode 100644 bin/loader/kickstart.h
 create mode 100644 bin/loader/lang.c
 create mode 100644 bin/loader/lang.h
 create mode 100644 bin/loader/linuxrc.s390
 create mode 100644 bin/loader/loader.c
 create mode 100644 bin/loader/loader.h
 create mode 100644 bin/loader/loadermisc.c
 create mode 100644 bin/loader/loadermisc.h
 create mode 100644 bin/loader/mediacheck.c
 create mode 100644 bin/loader/mediacheck.h
 create mode 100644 bin/loader/method.c
 create mode 100644 bin/loader/method.h
 create mode 100644 bin/loader/mkctype.c
 create mode 100644 bin/loader/moduleinfo.c
 create mode 100644 bin/loader/moduleinfo.h
 create mode 100644 bin/loader/modules.c
 create mode 100644 bin/loader/modules.h
 create mode 100644 bin/loader/net.c
 create mode 100644 bin/loader/net.h
 create mode 100644 bin/loader/nfsinstall.c
 create mode 100644 bin/loader/nfsinstall.h
 create mode 100644 bin/loader/rpmextract.c
 create mode 100644 bin/loader/rpmextract.h
 create mode 100644 bin/loader/selinux.c
 create mode 100644 bin/loader/selinux.h
 create mode 100644 bin/loader/shutdown.c
 create mode 100755 bin/loader/simplemot
 create mode 100644 bin/loader/telnet.c
 create mode 100644 bin/loader/telnet.h
 create mode 100644 bin/loader/telnetd.c
 create mode 100644 bin/loader/telnetd.h
 create mode 100644 bin/loader/udelay.h
 create mode 100644 bin/loader/undomounts.c
 create mode 100644 bin/loader/unicode-linedraw-chars.txt
 create mode 100644 bin/loader/urlinstall.c
 create mode 100644 bin/loader/urlinstall.h
 create mode 100644 bin/loader/urls.c
 create mode 100644 bin/loader/urls.h
 create mode 100644 bin/loader/windows.c
 create mode 100644 bin/loader/windows.h
 delete mode 100644 bootdisk/Makefile.am
 delete mode 100644 bootdisk/i386/Makefile.am
 delete mode 100644 bootdisk/i386/boot.msg
 delete mode 100644 bootdisk/i386/grub.conf
 delete mode 100644 bootdisk/i386/syslinux.cfg
 delete mode 100644 bootdisk/ppc/Makefile.am
 delete mode 100644 bootdisk/ppc/bootinfo.txt
 delete mode 100644 bootdisk/ppc/magic
 delete mode 100644 bootdisk/ppc/mapping
 delete mode 100644 bootdisk/ppc/ofboot.b
 delete mode 100644 bootdisk/ppc/yaboot.conf.3264
 delete mode 100644 bootdisk/ppc/yaboot.conf.in
 delete mode 100644 bootdisk/s390x/Makefile.am
 delete mode 100644 bootdisk/s390x/generic.ins
 delete mode 100644 bootdisk/s390x/generic.prm
 delete mode 100644 bootdisk/s390x/redhat.exec
 delete mode 100644 bootdisk/sparc/Makefile.am
 delete mode 100644 bootdisk/sparc/boot.msg
 delete mode 100644 bootdisk/sparc/silo.conf
 delete mode 100644 bootdisk/x86_64/Makefile.am
 delete mode 100644 bootdisk/x86_64/boot.msg
 delete mode 100644 bootdisk/x86_64/grub.conf
 delete mode 100644 bootdisk/x86_64/syslinux.cfg
 delete mode 100644 bootloader.py
 delete mode 100644 cmdline.py
 delete mode 100644 command-stubs/Makefile.am
 delete mode 100755 command-stubs/list-harddrives-stub
 delete mode 100755 command-stubs/loadkeys-stub
 delete mode 100755 command-stubs/losetup-stub
 delete mode 100755 command-stubs/mknod-stub
 delete mode 100755 command-stubs/raidstart-stub
 delete mode 100755 command-stubs/raidstop-stub
 delete mode 100644 compssort.py
 delete mode 100644 constants.py
 create mode 100644 data/70-anaconda.rules
 create mode 100644 data/Makefile.am
 create mode 100644 data/bootdisk/Makefile.am
 create mode 100644 data/bootdisk/i386/Makefile.am
 create mode 100644 data/bootdisk/i386/boot.msg
 create mode 100644 data/bootdisk/i386/grub.conf
 create mode 100644 data/bootdisk/i386/syslinux.cfg
 create mode 100644 data/bootdisk/ppc/Makefile.am
 create mode 100644 data/bootdisk/ppc/bootinfo.txt
 create mode 100644 data/bootdisk/ppc/magic
 create mode 100644 data/bootdisk/ppc/mapping
 create mode 100644 data/bootdisk/ppc/ofboot.b
 create mode 100644 data/bootdisk/ppc/yaboot.conf.3264
 create mode 100644 data/bootdisk/ppc/yaboot.conf.in
 create mode 100644 data/bootdisk/s390x/Makefile.am
 create mode 100644 data/bootdisk/s390x/generic.ins
 create mode 100644 data/bootdisk/s390x/generic.prm
 create mode 100644 data/bootdisk/s390x/redhat.exec
 create mode 100644 data/bootdisk/sparc/Makefile.am
 create mode 100644 data/bootdisk/sparc/boot.msg
 create mode 100644 data/bootdisk/sparc/silo.conf
 create mode 100644 data/bootdisk/x86_64/Makefile.am
 create mode 100644 data/bootdisk/x86_64/boot.msg
 create mode 100644 data/bootdisk/x86_64/grub.conf
 create mode 100644 data/bootdisk/x86_64/syslinux.cfg
 create mode 100644 data/command-stubs/Makefile.am
 create mode 100755 data/command-stubs/list-harddrives-stub
 create mode 100755 data/command-stubs/loadkeys-stub
 create mode 100755 data/command-stubs/losetup-stub
 create mode 100755 data/command-stubs/mknod-stub
 create mode 100755 data/command-stubs/raidstart-stub
 create mode 100755 data/command-stubs/raidstop-stub
 create mode 100644 data/fonts/Makefile.am
 create mode 100644 data/fonts/screenfont-alpha.gz
 create mode 100644 data/fonts/screenfont-i386.gz
 create mode 100644 data/fonts/screenfont-ia64.gz
 create mode 100644 data/fonts/screenfont-ppc.gz
 create mode 100644 data/fonts/screenfont-sparc.gz
 create mode 100644 data/fonts/screenfont-x86_64.gz
 create mode 100755 data/fonts/updfonts
 create mode 100644 data/icons/Makefile.am
 create mode 100644 data/icons/hicolor/16x16/Makefile.am
 create mode 100644 data/icons/hicolor/16x16/apps/Makefile.am
 create mode 100644 data/icons/hicolor/16x16/apps/anaconda.png
 create mode 100644 data/icons/hicolor/22x22/Makefile.am
 create mode 100644 data/icons/hicolor/22x22/apps/Makefile.am
 create mode 100644 data/icons/hicolor/22x22/apps/anaconda.png
 create mode 100644 data/icons/hicolor/24x24/Makefile.am
 create mode 100644 data/icons/hicolor/24x24/apps/Makefile.am
 create mode 100644 data/icons/hicolor/24x24/apps/anaconda.png
 create mode 100644 data/icons/hicolor/32x32/Makefile.am
 create mode 100644 data/icons/hicolor/32x32/apps/Makefile.am
 create mode 100644 data/icons/hicolor/32x32/apps/anaconda.png
 create mode 100644 data/icons/hicolor/48x48/Makefile.am
 create mode 100644 data/icons/hicolor/48x48/apps/Makefile.am
 create mode 100644 data/icons/hicolor/48x48/apps/anaconda.png
 create mode 100644 data/icons/hicolor/Makefile.am
 create mode 100644 data/lang-table
 create mode 100644 data/liveinst/.gitignore
 create mode 100644 data/liveinst/Makefile.am
 create mode 100644 data/liveinst/README
 create mode 100644 data/liveinst/console.apps/Makefile.am
 create mode 100644 data/liveinst/console.apps/liveinst
 create mode 100755 data/liveinst/liveinst
 create mode 100644 data/liveinst/liveinst.desktop.in
 create mode 100644 data/liveinst/pam.d/Makefile.am
 create mode 100644 data/liveinst/pam.d/liveinst
 create mode 100755 data/liveinst/zz-liveinst.sh
 create mode 100644 data/pixmaps/Makefile.am
 create mode 100644 data/pixmaps/about-to-install.png
 create mode 100644 data/pixmaps/checkMark.png
 create mode 100644 data/pixmaps/config-language.png
 create mode 100644 data/pixmaps/done.png
 create mode 100644 data/pixmaps/filter-menu.png
 create mode 100644 data/pixmaps/gnome-lock.png
 create mode 100644 data/pixmaps/gnome-mouse.png
 create mode 100644 data/pixmaps/install.png
 create mode 100644 data/pixmaps/network.png
 create mode 100644 data/pixmaps/partscheme-all.png
 create mode 100644 data/pixmaps/partscheme-custom.png
 create mode 100644 data/pixmaps/partscheme-freespace.png
 create mode 100644 data/pixmaps/partscheme-replace.png
 create mode 100644 data/pixmaps/partscheme-shrink.png
 create mode 100644 data/pixmaps/root-password.png
 create mode 100644 data/pixmaps/upgrade.png
 create mode 100644 data/ui/GroupSelector.glade
 create mode 100644 data/ui/Makefile.am
 create mode 100644 data/ui/account.glade
 create mode 100644 data/ui/adddrive.glade
 create mode 100644 data/ui/addrepo.glade
 create mode 100644 data/ui/anaconda.glade
 create mode 100644 data/ui/autopart.glade
 create mode 100644 data/ui/blwhere.glade
 create mode 100644 data/ui/cleardisks.glade
 create mode 100644 data/ui/create-storage.glade
 create mode 100644 data/ui/detailed-dialog.glade
 create mode 100644 data/ui/fcoe-config.glade
 create mode 100644 data/ui/filter.glade
 create mode 100644 data/ui/iscsi-config.glade
 create mode 100644 data/ui/lukspassphrase.glade
 create mode 100644 data/ui/netconfig.glade
 create mode 100644 data/ui/network.glade
 create mode 100644 data/ui/tasksel.glade
 create mode 100644 data/ui/zfcp-config.glade
 delete mode 100644 desktop.py
 delete mode 100644 dispatch.py
 delete mode 100644 errors.py
 delete mode 100644 exception.py
 delete mode 100644 firewall.py
 delete mode 100644 flags.py
 delete mode 100644 fonts/Makefile.am
 delete mode 100644 fonts/screenfont-alpha.gz
 delete mode 100644 fonts/screenfont-i386.gz
 delete mode 100644 fonts/screenfont-ia64.gz
 delete mode 100644 fonts/screenfont-ppc.gz
 delete mode 100644 fonts/screenfont-sparc.gz
 delete mode 100644 fonts/screenfont-x86_64.gz
 delete mode 100755 fonts/updfonts
 delete mode 100644 gptsync/.gitignore
 delete mode 100644 gptsync/Makefile.am
 delete mode 100644 gptsync/README
 delete mode 100644 gptsync/gptsync.c
 delete mode 100644 gptsync/gptsync.h
 delete mode 100644 gptsync/lib.c
 delete mode 100644 gptsync/os_unix.c
 delete mode 100644 gptsync/showpart.c
 delete mode 100644 gptsync/syslinux_mbr.h
 delete mode 100755 gui.py
 delete mode 100644 icons/Makefile.am
 delete mode 100644 icons/hicolor/16x16/Makefile.am
 delete mode 100644 icons/hicolor/16x16/apps/Makefile.am
 delete mode 100644 icons/hicolor/16x16/apps/anaconda.png
 delete mode 100644 icons/hicolor/22x22/Makefile.am
 delete mode 100644 icons/hicolor/22x22/apps/Makefile.am
 delete mode 100644 icons/hicolor/22x22/apps/anaconda.png
 delete mode 100644 icons/hicolor/24x24/Makefile.am
 delete mode 100644 icons/hicolor/24x24/apps/Makefile.am
 delete mode 100644 icons/hicolor/24x24/apps/anaconda.png
 delete mode 100644 icons/hicolor/32x32/Makefile.am
 delete mode 100644 icons/hicolor/32x32/apps/Makefile.am
 delete mode 100644 icons/hicolor/32x32/apps/anaconda.png
 delete mode 100644 icons/hicolor/48x48/Makefile.am
 delete mode 100644 icons/hicolor/48x48/apps/Makefile.am
 delete mode 100644 icons/hicolor/48x48/apps/anaconda.png
 delete mode 100644 icons/hicolor/Makefile.am
 delete mode 100644 image.py
 delete mode 100644 installclass.py
 delete mode 100644 installclasses/Makefile.am
 delete mode 100644 installclasses/fedora.py
 delete mode 100644 installclasses/rhel.py
 delete mode 100644 installinterfacebase.py
 delete mode 100644 installmethod.py
 delete mode 100644 isys/.gitignore
 delete mode 100644 isys/Makefile.am
 delete mode 100644 isys/auditd.c
 delete mode 100644 isys/auditd.h
 delete mode 100644 isys/cpio.c
 delete mode 100644 isys/cpio.h
 delete mode 100644 isys/devices.c
 delete mode 100644 isys/devices.h
 delete mode 100644 isys/eddsupport.c
 delete mode 100644 isys/eddsupport.h
 delete mode 100644 isys/ethtool.c
 delete mode 100644 isys/ethtool.h
 delete mode 100644 isys/iface.c
 delete mode 100644 isys/iface.h
 delete mode 100644 isys/imount.c
 delete mode 100644 isys/imount.h
 delete mode 100644 isys/isofs.c
 delete mode 100644 isys/isys.c
 delete mode 100644 isys/isys.h
 delete mode 100755 isys/isys.py
 delete mode 100644 isys/lang.c
 delete mode 100644 isys/lang.h
 delete mode 100644 isys/linkdetect.c
 delete mode 100644 isys/log.c
 delete mode 100644 isys/log.h
 delete mode 100644 isys/stubs.h
 delete mode 100644 isys/uncpio.c
 delete mode 100644 isys/vio.c
 delete mode 100644 iutil.py
 delete mode 100644 iw/DeviceSelector.py
 delete mode 100644 iw/GroupSelector.py
 delete mode 100644 iw/Makefile.am
 delete mode 100644 iw/account_gui.py
 delete mode 100644 iw/advanced_storage.py
 delete mode 100644 iw/autopart_type.py
 delete mode 100644 iw/blpasswidget.py
 delete mode 100644 iw/bootloader_main_gui.py
 delete mode 100644 iw/checklist.py
 delete mode 100644 iw/cleardisks_gui.py
 delete mode 100644 iw/congrats_gui.py
 delete mode 100644 iw/datacombo.py
 delete mode 100644 iw/examine_gui.py
 delete mode 100644 iw/filter_gui.py
 delete mode 100644 iw/filter_type.py
 delete mode 100644 iw/iw_gui.py
 delete mode 100644 iw/kbd_gui.py
 delete mode 100644 iw/language_gui.py
 delete mode 100644 iw/lvm_dialog_gui.py
 delete mode 100644 iw/netconfig_dialog.py
 delete mode 100644 iw/network_gui.py
 delete mode 100644 iw/osbootwidget.py
 delete mode 100644 iw/package_gui.py
 delete mode 100644 iw/partition_dialog_gui.py
 delete mode 100644 iw/partition_gui.py
 delete mode 100644 iw/partition_ui_helpers_gui.py
 delete mode 100644 iw/pixmapRadioButtonGroup_gui.py
 delete mode 100644 iw/progress_gui.py
 delete mode 100644 iw/raid_dialog_gui.py
 delete mode 100644 iw/task_gui.py
 delete mode 100644 iw/timezone_gui.py
 delete mode 100644 iw/upgrade_bootloader_gui.py
 delete mode 100644 iw/upgrade_migratefs_gui.py
 delete mode 100644 iw/upgrade_swap_gui.py
 delete mode 100644 iw/welcome_gui.py
 delete mode 100644 iw/zipl_gui.py
 delete mode 100644 kickstart.py
 delete mode 100644 lang-table
 delete mode 100644 language.py
 delete mode 100644 livecd.py
 delete mode 100644 liveinst/.gitignore
 delete mode 100644 liveinst/Makefile.am
 delete mode 100644 liveinst/README
 delete mode 100644 liveinst/console.apps/Makefile.am
 delete mode 100644 liveinst/console.apps/liveinst
 delete mode 100755 liveinst/liveinst
 delete mode 100644 liveinst/liveinst.desktop.in
 delete mode 100644 liveinst/pam.d/Makefile.am
 delete mode 100644 liveinst/pam.d/liveinst
 delete mode 100755 liveinst/zz-liveinst.sh
 delete mode 100644 loader/.gitignore
 delete mode 100644 loader/Makefile.am
 delete mode 100644 loader/cdinstall.c
 delete mode 100644 loader/cdinstall.h
 delete mode 100644 loader/copy.c
 delete mode 100644 loader/copy.h
 delete mode 100644 loader/devices.h
 delete mode 100644 loader/devt.h
 delete mode 100644 loader/dirbrowser.c
 delete mode 100644 loader/dirbrowser.h
 delete mode 100644 loader/driverdisk.c
 delete mode 100644 loader/driverdisk.h
 delete mode 100644 loader/driverselect.c
 delete mode 100644 loader/fwloader.c
 delete mode 100644 loader/fwloader.h
 delete mode 100644 loader/getparts.c
 delete mode 100644 loader/getparts.h
 delete mode 100644 loader/hardware.c
 delete mode 100644 loader/hardware.h
 delete mode 100644 loader/hdinstall.c
 delete mode 100644 loader/hdinstall.h
 delete mode 100644 loader/ibft.c
 delete mode 100644 loader/ibft.h
 delete mode 100644 loader/init.c
 delete mode 100644 loader/init.h
 delete mode 100644 loader/kbd.c
 delete mode 100644 loader/kbd.h
 delete mode 100644 loader/keymaps-i386
 delete mode 100644 loader/keymaps-ppc
 delete mode 100644 loader/keymaps-x86_64
 delete mode 100644 loader/kickstart.c
 delete mode 100644 loader/kickstart.h
 delete mode 100644 loader/lang.c
 delete mode 100644 loader/lang.h
 delete mode 100644 loader/linuxrc.s390
 delete mode 100644 loader/loader.c
 delete mode 100644 loader/loader.h
 delete mode 100644 loader/loadermisc.c
 delete mode 100644 loader/loadermisc.h
 delete mode 100644 loader/mediacheck.c
 delete mode 100644 loader/mediacheck.h
 delete mode 100644 loader/method.c
 delete mode 100644 loader/method.h
 delete mode 100644 loader/mkctype.c
 delete mode 100644 loader/moduleinfo.c
 delete mode 100644 loader/moduleinfo.h
 delete mode 100644 loader/modules.c
 delete mode 100644 loader/modules.h
 delete mode 100644 loader/net.c
 delete mode 100644 loader/net.h
 delete mode 100644 loader/nfsinstall.c
 delete mode 100644 loader/nfsinstall.h
 delete mode 100644 loader/rpmextract.c
 delete mode 100644 loader/rpmextract.h
 delete mode 100644 loader/selinux.c
 delete mode 100644 loader/selinux.h
 delete mode 100644 loader/shutdown.c
 delete mode 100755 loader/simplemot
 delete mode 100644 loader/telnet.c
 delete mode 100644 loader/telnet.h
 delete mode 100644 loader/telnetd.c
 delete mode 100644 loader/telnetd.h
 delete mode 100644 loader/udelay.h
 delete mode 100644 loader/undomounts.c
 delete mode 100644 loader/unicode-linedraw-chars.txt
 delete mode 100644 loader/urlinstall.c
 delete mode 100644 loader/urlinstall.h
 delete mode 100644 loader/urls.c
 delete mode 100644 loader/urls.h
 delete mode 100644 loader/windows.c
 delete mode 100644 loader/windows.h
 delete mode 100644 network.py
 delete mode 100644 packages.py
 delete mode 100644 partIntfHelpers.py
 delete mode 100644 pixmaps/Makefile.am
 delete mode 100644 pixmaps/about-to-install.png
 delete mode 100644 pixmaps/checkMark.png
 delete mode 100644 pixmaps/config-language.png
 delete mode 100644 pixmaps/done.png
 delete mode 100644 pixmaps/filter-menu.png
 delete mode 100644 pixmaps/gnome-lock.png
 delete mode 100644 pixmaps/gnome-mouse.png
 delete mode 100644 pixmaps/install.png
 delete mode 100644 pixmaps/network.png
 delete mode 100644 pixmaps/partscheme-all.png
 delete mode 100644 pixmaps/partscheme-custom.png
 delete mode 100644 pixmaps/partscheme-freespace.png
 delete mode 100644 pixmaps/partscheme-replace.png
 delete mode 100644 pixmaps/partscheme-shrink.png
 delete mode 100644 pixmaps/root-password.png
 delete mode 100644 pixmaps/upgrade.png
 delete mode 100644 platform.py
 delete mode 100644 product.py
 create mode 100644 pyanaconda/Makefile.am
 create mode 100644 pyanaconda/__init__.py
 create mode 100644 pyanaconda/anaconda_log.py
 create mode 100644 pyanaconda/backend.py
 create mode 100644 pyanaconda/backend_log.py
 create mode 100644 pyanaconda/baseudev.py
 create mode 100644 pyanaconda/bootloader.py
 create mode 100644 pyanaconda/cmdline.py
 create mode 100644 pyanaconda/compssort.py
 create mode 100644 pyanaconda/constants.py
 create mode 100644 pyanaconda/desktop.py
 create mode 100644 pyanaconda/dispatch.py
 create mode 100644 pyanaconda/errors.py
 create mode 100644 pyanaconda/exception.py
 create mode 100644 pyanaconda/firewall.py
 create mode 100644 pyanaconda/flags.py
 create mode 100755 pyanaconda/gui.py
 create mode 100644 pyanaconda/image.py
 create mode 100644 pyanaconda/installclass.py
 create mode 100644 pyanaconda/installclasses/Makefile.am
 create mode 100644 pyanaconda/installclasses/fedora.py
 create mode 100644 pyanaconda/installclasses/rhel.py
 create mode 100644 pyanaconda/installinterfacebase.py
 create mode 100644 pyanaconda/installmethod.py
 create mode 100644 pyanaconda/isys/.gitignore
 create mode 100644 pyanaconda/isys/Makefile.am
 create mode 100755 pyanaconda/isys/__init__.py
 create mode 100644 pyanaconda/isys/auditd.c
 create mode 100644 pyanaconda/isys/auditd.h
 create mode 100644 pyanaconda/isys/cpio.c
 create mode 100644 pyanaconda/isys/cpio.h
 create mode 100644 pyanaconda/isys/devices.c
 create mode 100644 pyanaconda/isys/devices.h
 create mode 100644 pyanaconda/isys/eddsupport.c
 create mode 100644 pyanaconda/isys/eddsupport.h
 create mode 100644 pyanaconda/isys/ethtool.c
 create mode 100644 pyanaconda/isys/ethtool.h
 create mode 100644 pyanaconda/isys/iface.c
 create mode 100644 pyanaconda/isys/iface.h
 create mode 100644 pyanaconda/isys/imount.c
 create mode 100644 pyanaconda/isys/imount.h
 create mode 100644 pyanaconda/isys/isofs.c
 create mode 100644 pyanaconda/isys/isys.c
 create mode 100644 pyanaconda/isys/isys.h
 create mode 100644 pyanaconda/isys/lang.c
 create mode 100644 pyanaconda/isys/lang.h
 create mode 100644 pyanaconda/isys/linkdetect.c
 create mode 100644 pyanaconda/isys/log.c
 create mode 100644 pyanaconda/isys/log.h
 create mode 100644 pyanaconda/isys/stubs.h
 create mode 100644 pyanaconda/isys/uncpio.c
 create mode 100644 pyanaconda/isys/vio.c
 create mode 100644 pyanaconda/iutil.py
 create mode 100644 pyanaconda/iw/DeviceSelector.py
 create mode 100644 pyanaconda/iw/GroupSelector.py
 create mode 100644 pyanaconda/iw/Makefile.am
 create mode 100644 pyanaconda/iw/account_gui.py
 create mode 100644 pyanaconda/iw/advanced_storage.py
 create mode 100644 pyanaconda/iw/autopart_type.py
 create mode 100644 pyanaconda/iw/blpasswidget.py
 create mode 100644 pyanaconda/iw/bootloader_main_gui.py
 create mode 100644 pyanaconda/iw/checklist.py
 create mode 100644 pyanaconda/iw/cleardisks_gui.py
 create mode 100644 pyanaconda/iw/congrats_gui.py
 create mode 100644 pyanaconda/iw/datacombo.py
 create mode 100644 pyanaconda/iw/examine_gui.py
 create mode 100644 pyanaconda/iw/filter_gui.py
 create mode 100644 pyanaconda/iw/filter_type.py
 create mode 100644 pyanaconda/iw/iw_gui.py
 create mode 100644 pyanaconda/iw/kbd_gui.py
 create mode 100644 pyanaconda/iw/language_gui.py
 create mode 100644 pyanaconda/iw/lvm_dialog_gui.py
 create mode 100644 pyanaconda/iw/netconfig_dialog.py
 create mode 100644 pyanaconda/iw/network_gui.py
 create mode 100644 pyanaconda/iw/osbootwidget.py
 create mode 100644 pyanaconda/iw/package_gui.py
 create mode 100644 pyanaconda/iw/partition_dialog_gui.py
 create mode 100644 pyanaconda/iw/partition_gui.py
 create mode 100644 pyanaconda/iw/partition_ui_helpers_gui.py
 create mode 100644 pyanaconda/iw/pixmapRadioButtonGroup_gui.py
 create mode 100644 pyanaconda/iw/progress_gui.py
 create mode 100644 pyanaconda/iw/raid_dialog_gui.py
 create mode 100644 pyanaconda/iw/task_gui.py
 create mode 100644 pyanaconda/iw/timezone_gui.py
 create mode 100644 pyanaconda/iw/upgrade_bootloader_gui.py
 create mode 100644 pyanaconda/iw/upgrade_migratefs_gui.py
 create mode 100644 pyanaconda/iw/upgrade_swap_gui.py
 create mode 100644 pyanaconda/iw/welcome_gui.py
 create mode 100644 pyanaconda/iw/zipl_gui.py
 create mode 100644 pyanaconda/kickstart.py
 create mode 100644 pyanaconda/language.py
 create mode 100644 pyanaconda/livecd.py
 create mode 100644 pyanaconda/network.py
 create mode 100644 pyanaconda/packages.py
 create mode 100644 pyanaconda/partIntfHelpers.py
 create mode 100644 pyanaconda/platform.py
 create mode 100644 pyanaconda/product.py
 create mode 100644 pyanaconda/pyudev.py
 create mode 100644 pyanaconda/rescue.py
 create mode 100755 pyanaconda/run_test.py
 create mode 100644 pyanaconda/security.py
 create mode 100644 pyanaconda/simpleconfig.py
 create mode 100644 pyanaconda/sitecustomize.py
 create mode 100644 pyanaconda/sortedtransaction.py
 create mode 100644 pyanaconda/storage/Makefile.am
 create mode 100644 pyanaconda/storage/__init__.py
 create mode 100644 pyanaconda/storage/dasd.py
 create mode 100644 pyanaconda/storage/deviceaction.py
 create mode 100644 pyanaconda/storage/devicelibs/Makefile.am
 create mode 100644 pyanaconda/storage/devicelibs/__init__.py
 create mode 100644 pyanaconda/storage/devicelibs/crypto.py
 create mode 100644 pyanaconda/storage/devicelibs/dm.py
 create mode 100644 pyanaconda/storage/devicelibs/edd.py
 create mode 100644 pyanaconda/storage/devicelibs/lvm.py
 create mode 100644 pyanaconda/storage/devicelibs/mdraid.py
 create mode 100644 pyanaconda/storage/devicelibs/mpath.py
 create mode 100644 pyanaconda/storage/devicelibs/swap.py
 create mode 100644 pyanaconda/storage/devices.py
 create mode 100644 pyanaconda/storage/devicetree.py
 create mode 100644 pyanaconda/storage/errors.py
 create mode 100644 pyanaconda/storage/fcoe.py
 create mode 100644 pyanaconda/storage/formats/Makefile.am
 create mode 100644 pyanaconda/storage/formats/__init__.py
 create mode 100644 pyanaconda/storage/formats/disklabel.py
 create mode 100644 pyanaconda/storage/formats/dmraid.py
 create mode 100644 pyanaconda/storage/formats/fs.py
 create mode 100644 pyanaconda/storage/formats/luks.py
 create mode 100644 pyanaconda/storage/formats/lvmpv.py
 create mode 100644 pyanaconda/storage/formats/mdraid.py
 create mode 100644 pyanaconda/storage/formats/multipath.py
 create mode 100644 pyanaconda/storage/formats/prepboot.py
 create mode 100644 pyanaconda/storage/formats/swap.py
 create mode 100644 pyanaconda/storage/iscsi.py
 create mode 100644 pyanaconda/storage/miscutils.py
 create mode 100644 pyanaconda/storage/partitioning.py
 create mode 100644 pyanaconda/storage/partspec.py
 create mode 100644 pyanaconda/storage/storage_log.py
 create mode 100644 pyanaconda/storage/udev.py
 create mode 100644 pyanaconda/storage/zfcp.py
 create mode 100644 pyanaconda/text.py
 create mode 100644 pyanaconda/textw/Makefile.am
 create mode 100644 pyanaconda/textw/add_drive_text.py
 create mode 100644 pyanaconda/textw/complete_text.py
 create mode 100644 pyanaconda/textw/constants_text.py
 create mode 100644 pyanaconda/textw/keyboard_text.py
 create mode 100644 pyanaconda/textw/language_text.py
 create mode 100644 pyanaconda/textw/netconfig_text.py
 create mode 100644 pyanaconda/textw/network_text.py
 create mode 100644 pyanaconda/textw/partition_text.py
 create mode 100644 pyanaconda/textw/progress_text.py
 create mode 100644 pyanaconda/textw/statusline_text.py
 create mode 100644 pyanaconda/textw/task_text.py
 create mode 100644 pyanaconda/textw/timezone_text.py
 create mode 100644 pyanaconda/textw/upgrade_bootloader_text.py
 create mode 100644 pyanaconda/textw/upgrade_text.py
 create mode 100644 pyanaconda/textw/userauth_text.py
 create mode 100644 pyanaconda/textw/welcome_text.py
 create mode 100644 pyanaconda/textw/zipl_text.py
 create mode 100644 pyanaconda/timezone.py
 create mode 100644 pyanaconda/upgrade.py
 create mode 100644 pyanaconda/users.py
 create mode 100644 pyanaconda/vnc.py
 create mode 100644 pyanaconda/xutils.c
 create mode 100644 pyanaconda/yuminstall.py
 delete mode 100644 pyudev.py
 delete mode 100644 rescue.py
 delete mode 100755 run_test.py
 delete mode 100644 security.py
 delete mode 100644 simpleconfig.py
 delete mode 100644 sitecustomize.py
 delete mode 100644 sortedtransaction.py
 delete mode 100644 storage/Makefile.am
 delete mode 100644 storage/__init__.py
 delete mode 100644 storage/dasd.py
 delete mode 100644 storage/deviceaction.py
 delete mode 100644 storage/devicelibs/Makefile.am
 delete mode 100644 storage/devicelibs/__init__.py
 delete mode 100644 storage/devicelibs/crypto.py
 delete mode 100644 storage/devicelibs/dm.py
 delete mode 100644 storage/devicelibs/edd.py
 delete mode 100644 storage/devicelibs/lvm.py
 delete mode 100644 storage/devicelibs/mdraid.py
 delete mode 100644 storage/devicelibs/mpath.py
 delete mode 100644 storage/devicelibs/swap.py
 delete mode 100644 storage/devices.py
 delete mode 100644 storage/devicetree.py
 delete mode 100644 storage/errors.py
 delete mode 100644 storage/fcoe.py
 delete mode 100644 storage/formats/Makefile.am
 delete mode 100644 storage/formats/__init__.py
 delete mode 100644 storage/formats/disklabel.py
 delete mode 100644 storage/formats/dmraid.py
 delete mode 100644 storage/formats/fs.py
 delete mode 100644 storage/formats/luks.py
 delete mode 100644 storage/formats/lvmpv.py
 delete mode 100644 storage/formats/mdraid.py
 delete mode 100644 storage/formats/multipath.py
 delete mode 100644 storage/formats/prepboot.py
 delete mode 100644 storage/formats/swap.py
 delete mode 100644 storage/iscsi.py
 delete mode 100644 storage/miscutils.py
 delete mode 100644 storage/partitioning.py
 delete mode 100644 storage/partspec.py
 delete mode 100644 storage/storage_log.py
 delete mode 100644 storage/udev.py
 delete mode 100644 storage/zfcp.py
 delete mode 100644 stubs/.gitignore
 delete mode 100644 tests/__init__.py
 delete mode 100644 tests/kickstart/Makefile.am
 delete mode 100644 tests/kickstart/__init__.py
 delete mode 100755 tests/kickstart/commands.py
 create mode 100644 tests/kickstart_test/Makefile.am
 create mode 100644 tests/kickstart_test/commands_test.py
 create mode 100644 tests/mock/Makefile.am
 delete mode 100644 tests/storage/Makefile.am
 delete mode 100644 tests/storage/__init__.py
 delete mode 100644 tests/storage/devicelibs/Makefile.am
 delete mode 100644 tests/storage/devicelibs/__init__.py
 delete mode 100644 tests/storage/devicelibs/baseclass.py
 delete mode 100755 tests/storage/devicelibs/crypto.py
 delete mode 100755 tests/storage/devicelibs/lvm.py
 delete mode 100755 tests/storage/devicelibs/mdraid.py
 delete mode 100755 tests/storage/devicelibs/mpath.py
 delete mode 100755 tests/storage/devicelibs/swap.py
 create mode 100644 tests/storage_test/Makefile.am
 create mode 100644 tests/storage_test/devicelibs_test/Makefile.am
 create mode 100644 tests/storage_test/devicelibs_test/baseclass.py
 create mode 100644 tests/storage_test/devicelibs_test/crypto_test.py
 create mode 100644 tests/storage_test/devicelibs_test/lvm_test.py
 create mode 100644 tests/storage_test/devicelibs_test/mdraid_test.py
 create mode 100644 tests/storage_test/devicelibs_test/mpath_test.py
 create mode 100644 tests/storage_test/devicelibs_test/swap_test.py
 delete mode 100644 text.py
 delete mode 100644 textw/Makefile.am
 delete mode 100644 textw/add_drive_text.py
 delete mode 100644 textw/complete_text.py
 delete mode 100644 textw/constants_text.py
 delete mode 100644 textw/keyboard_text.py
 delete mode 100644 textw/language_text.py
 delete mode 100644 textw/netconfig_text.py
 delete mode 100644 textw/network_text.py
 delete mode 100644 textw/partition_text.py
 delete mode 100644 textw/progress_text.py
 delete mode 100644 textw/statusline_text.py
 delete mode 100644 textw/task_text.py
 delete mode 100644 textw/timezone_text.py
 delete mode 100644 textw/upgrade_bootloader_text.py
 delete mode 100644 textw/upgrade_text.py
 delete mode 100644 textw/userauth_text.py
 delete mode 100644 textw/welcome_text.py
 delete mode 100644 textw/zipl_text.py
 delete mode 100644 timezone.py
 delete mode 100644 ui/GroupSelector.glade
 delete mode 100644 ui/Makefile.am
 delete mode 100644 ui/account.glade
 delete mode 100644 ui/adddrive.glade
 delete mode 100644 ui/addrepo.glade
 delete mode 100644 ui/anaconda.glade
 delete mode 100644 ui/autopart.glade
 delete mode 100644 ui/blwhere.glade
 delete mode 100644 ui/cleardisks.glade
 delete mode 100644 ui/create-storage.glade
 delete mode 100644 ui/detailed-dialog.glade
 delete mode 100644 ui/fcoe-config.glade
 delete mode 100644 ui/filter.glade
 delete mode 100644 ui/iscsi-config.glade
 delete mode 100644 ui/lukspassphrase.glade
 delete mode 100644 ui/netconfig.glade
 delete mode 100644 ui/network.glade
 delete mode 100644 ui/tasksel.glade
 delete mode 100644 ui/zfcp-config.glade
 delete mode 100644 upgrade.py
 delete mode 100644 users.py
 delete mode 100644 vnc.py
 delete mode 100644 xutils.c
 delete mode 100644 yuminstall.py

diff --git a/70-anaconda.rules b/70-anaconda.rules
deleted file mode 100644
index bba0bfb..0000000
--- a/70-anaconda.rules
+++ /dev/null
@@ -1,56 +0,0 @@
-# If $ANACONDA isn't set in the environment, skip all these rules.
-ENV{ANACONDA}!="?*", GOTO="anaconda_end"
-
-ACTION!="add|change", GOTO="anaconda_end"
-SUBSYSTEM!="block", GOTO="anaconda_end"
-
-# for device-mapper device we are supposed to only operate on "change" events
-KERNEL=="dm-*", ACTION=="add", GOTO="anaconda_end"
-
-ENV{ANACBIN}="/sbin"
-TEST!="$env{ANACBIN}/dmsetup", ENV{ANACBIN}="/usr/sbin"
-
-KERNEL=="dm-*", ENV{DM_UDEV_DISABLE_DISK_RULES_FLAG}=="1", GOTO="anaconda_end"
-KERNEL=="dm-*", ENV{DM_NAME}!="?*", GOTO="anaconda_end"
-KERNEL=="dm-*", ENV{DM_SUSPENDED}=="1", GOTO="anaconda_end"
-KERNEL=="dm-*", ENV{DM_SUSPENDED}=="Suspended", GOTO="anaconda_end"
-
-IMPORT{program}="$env{ANACBIN}/blkid -o udev -p $tempnode"
-
-LABEL="anaconda_mdraid"
-KERNEL!="md*", GOTO="anaconda_mdraid_member"
-
-# container devices have a metadata version of e.g. 'external:ddf' and
-# never leave state 'inactive'
-ATTR{md/metadata_version}=="external:[A-Za-z]*", ATTR{md/array_state}=="inactive", GOTO="md_ignore_state"
-TEST!="md/array_state", GOTO="anaconda_mdraid_member"
-ATTR{md/array_state}=="|clear|inactive", GOTO="anaconda_mdraid_member"
-LABEL="md_ignore_state"
-
-IMPORT{program}="$env{ANACBIN}/mdadm --detail --export $tempnode"
-ENV{DEVTYPE}=="disk", ENV{MD_NAME}=="?*", SYMLINK+="disk/by-id/md-name-$env{MD_NAME}", OPTIONS+="string_escape=replace"
-ENV{DEVTYPE}=="disk", ENV{MD_UUID}=="?*", SYMLINK+="disk/by-id/md-uuid-$env{MD_UUID}"
-ENV{DEVTYPE}=="disk", ENV{MD_DEVNAME}=="?*", SYMLINK+="md/$env{MD_DEVNAME}"
-ENV{DEVTYPE}=="partition", ENV{MD_NAME}=="?*", SYMLINK+="disk/by-id/md-name-$env{MD_NAME}-part%n", OPTIONS+="string_escape=replace"
-ENV{DEVTYPE}=="partition", ENV{MD_UUID}=="?*", SYMLINK+="disk/by-id/md-uuid-$env{MD_UUID}-part%n"
-ENV{DEVTYPE}=="partition", ENV{MD_DEVNAME}=="*[^0-9]", SYMLINK+="md/$env{MD_DEVNAME}%n"
-ENV{DEVTYPE}=="partition", ENV{MD_DEVNAME}=="*[0-9]", SYMLINK+="md/$env{MD_DEVNAME}p%n"
-
-OPTIONS+="link_priority=100"
-OPTIONS+="watch"
-ENV{ID_FS_USAGE}=="filesystem|other|crypto", ENV{ID_FS_UUID_ENC}=="?*", SYMLINK+="disk/by-uuid/$env{ID_FS_UUID_ENC}"
-ENV{ID_FS_USAGE}=="filesystem|other", ENV{ID_FS_LABEL_ENC}=="?*", SYMLINK+="disk/by-label/$env{ID_FS_LABEL_ENC}"
-
-LABEL="anaconda_mdraid_member"
-# probe raid metadata of mdraid member devices
-ENV{ID_FS_TYPE}=="linux_raid_member", IMPORT{program}="$env{ANACBIN}/mdadm --examine --export $tempnode"
-ENV{ID_FS_TYPE}=="isw_raid_member", IMPORT{program}="$env{ANACBIN}/mdadm --examine --export $tempnode"
-
-# probe metadata of LVM2 physical volumes
-ENV{ID_FS_TYPE}=="LVM2_member", IMPORT{program}="$env{ANACBIN}/lvm pvs --ignorelockingfailure --units k --nosuffix --nameprefixes --rows --unquoted --noheadings -opv_name,pv_uuid,pv_size,vg_name,vg_uuid,pv_pe_count,pv_pe_alloc_count,pe_start $tempnode"
-ENV{LVM2_VG_NAME}!="?*", GOTO="anaconda_end"
-ENV{ID_FS_TYPE}=="LVM2_member", IMPORT{program}="$env{ANACBIN}/lvm vgs --ignorelockingfailure --units k --nosuffix --nameprefixes --rows --unquoted --noheadings -ouuid,size,free,extent_size,extent_count,free_count,pv_count $env{LVM2_VG_NAME}"
-ENV{ID_FS_TYPE}=="LVM2_member", IMPORT{program}="$env{ANACBIN}/lvm lvs -a --ignorelockingfailure --units k --nosuffix --nameprefixes --rows --unquoted --noheadings -olv_name,lv_uuid,lv_size,lv_attr $env{LVM2_VG_NAME}"
-
-LABEL="anaconda_end"
-
diff --git a/Makefile.am b/Makefile.am
index 9ceac51..7beccbf 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -19,44 +19,24 @@
 
 ACLOCAL_AMFLAGS = -I m4
 
-SUBDIRS = isys po loader booty storage textw utils scripts bootdisk \
-          installclasses iw command-stubs ui docs pixmaps tests fonts \
-          gptsync liveinst icons
+SUBDIRS = po loader utils scripts \
+          command-stubs docs tests \
+          data bin booty pyanaconda
 
 EXTRA_DIST = config.rpath COPYING \
-             lang-table \
              anaconda.spec.in
 
 MAINTAINERCLEANFILES = Makefile.in config.guess config.h.in config.sub \
                        depcomp install-sh ltmain.sh missing ABOUT-NLS \
                        INSTALL aclocal.m4 configure *.pyc py-compile
 
-CLEANFILES = *~ lang-names anaconda.spec
+CLEANFILES = *~ anaconda.spec
 
 MOSTLYCLEANDIRS = m4
 
-pkgpyexecdir          = $(pyexecdir)/py$(PACKAGE_NAME)
-
 dist_noinst_DATA      = $(PACKAGE_NAME).spec
 
-dist_sbin_SCRIPTS     = anaconda
-
-udevdir               = /lib/udev/rules.d
-dist_udev_DATA        = 70-anaconda.rules
-
-langdir               = $(datadir)/$(PACKAGE_NAME)
-lang_DATA             = lang-names
-dist_lang_DATA        = lang-table
-
-pkgpyexec_LTLIBRARIES = xutils.la
-xutils_la_CFLAGS      = $(PYTHON_INCLUDES) $(GDK_CFLAGS) -fno-strict-aliasing
-xutils_la_LDFLAGS     = -module -avoid-version $(PYTHON_LDFLAGS) $(GDK_LDFLAGS)
-xutils_la_LIBADD      = $(PYTHON_LIBS) $(GDK_LIBS)
-xutils_la_SOURCES     = xutils.c
-
-# anaconda Python code
-anacondadir     = $(pkgpyexecdir)
-anaconda_PYTHON = *.py
+dist_sbin_SCRIPTS     = anaconda.py
 
 ARCHIVE_TAG   = $(PACKAGE_NAME)-$(PACKAGE_VERSION)-$(PACKAGE_RELEASE)
 
@@ -67,9 +47,6 @@ sed_verbose_0 = @echo "  SED    "$@;
 $(PACKAGE_NAME).spec: $(PACKAGE_NAME).spec.in
 	$(sed_verbose)sed -e 's/#VERSION#/$(PACKAGE_VERSION)/' < $< > $@
 
-lang-names: lang-table
-	PYTHONPATH="." $(PYTHON) scripts/getlangnames.py > lang-names
-
 testiso: install
 	@if [ "$(REPO)" = "" ]; then echo "ERROR: Need a repo to pull packages from!" ; exit 1 ; fi
 	@pushd scripts ; sudo ./buildinstall --version $(PACKAGE_VERSION) --product $(PACKAGE_NAME) --release $(PACKAGE_NAME)-$(PACKAGE_VERSION) --output $(shell pwd)/outiso --updates $(DESTDIR) $(REPO) ; popd ; cp outiso/images/boot.iso ./boot.iso ; sudo rm -rf outiso
diff --git a/__init__.py b/__init__.py
deleted file mode 100644
index b53877c..0000000
--- a/__init__.py
+++ /dev/null
@@ -1,395 +0,0 @@
-#!/usr/bin/python
-#
-# anaconda: The Red Hat Linux Installation program
-#
-# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007
-# Red Hat, Inc.  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 as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# 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, see <http://www.gnu.org/licenses/>.
-#
-# Author(s): Brent Fox <bfox@xxxxxxxxxx>
-#            Mike Fulbright <msf@xxxxxxxxxx>
-#            Jakub Jelinek <jakub@xxxxxxxxxx>
-#            Jeremy Katz <katzj@xxxxxxxxxx>
-#            Chris Lumens <clumens@xxxxxxxxxx>
-#            Paul Nasrat <pnasrat@xxxxxxxxxx>
-#            Erik Troan <ewt@xxxxxxxxx>
-#            Matt Wilson <msw@xxxxxxxxx>
-#
-
-import os, time, string
-import iutil
-import isys
-from tempfile import mkstemp
-
-import logging
-log = logging.getLogger("anaconda")
-stdoutLog = logging.getLogger("anaconda.stdout")
-
-import gettext
-_ = lambda x: gettext.ldgettext("anaconda", x)
-
-class Anaconda(object):
-    def __init__(self):
-        import desktop, dispatch, firewall, security
-        import system_config_keyboard.keyboard as keyboard
-        from flags import flags
-
-        self._backend = None
-        self._bootloader = None
-        self.canReIPL = False
-        self.desktop = desktop.Desktop()
-        self.dir = None
-        self.dispatch = dispatch.Dispatcher(self)
-        self.displayMode = None
-        self.extraModules = []
-        self.firewall = firewall.Firewall()
-        self.id = None
-        self._instClass = None
-        self._instLanguage = None
-        self._intf = None
-        self.isHeadless = False
-        self.keyboard = keyboard.Keyboard()
-        self.ksdata = None
-        self.mediaDevice = None
-        self.methodstr = None
-        self._network = None
-        self._platform = None
-        self.proxy = None
-        self.proxyUsername = None
-        self.proxyPassword = None
-        self.reIPLMessage = None
-        self.rescue = False
-        self.rescue_mount = True
-        self.rootParts = None
-        self.rootPath = "/mnt/sysimage"
-        self.security = security.Security()
-        self.simpleFilter = not iutil.isS390()
-        self.stage2 = None
-        self._storage = None
-        self._timezone = None
-        self.updateSrc = None
-        self.upgrade = flags.cmdline.has_key("preupgrade")
-        self.upgradeRoot = None
-        self.upgradeSwapInfo = None
-        self._users = None
-        self.mehConfig = None
-
-        # *sigh* we still need to be able to write this out
-        self.xdriver = None
-
-    @property
-    def backend(self):
-        if not self._backend:
-            b = self.instClass.getBackend()
-            self._backend = apply(b, (self, ))
-
-        return self._backend
-
-    @property
-    def bootloader(self):
-        if not self._bootloader:
-            import booty
-            self._bootloader = booty.getBootloader(self)
-
-        return self._bootloader
-
-    @property
-    def firstboot(self):
-        from pykickstart.constants import FIRSTBOOT_SKIP, FIRSTBOOT_DEFAULT
-
-        if self.ksdata:
-            return self.ksdata.firstboot.firstboot
-        elif iutil.isS390():
-            return FIRSTBOOT_SKIP
-        else:
-            return FIRSTBOOT_DEFAULT
-
-    @property
-    def instClass(self):
-        if not self._instClass:
-            from installclass import DefaultInstall
-            self._instClass = DefaultInstall()
-
-        return self._instClass
-
-    @property
-    def instLanguage(self):
-        if not self._instLanguage:
-            import language
-            self._instLanguage = language.Language(self.displayMode)
-
-        return self._instLanguage
-
-    def _getInterface(self):
-        return self._intf
-
-    def _setInterface(self, v):
-        # "lambda cannot contain assignment"
-        self._intf = v
-
-    def _delInterface(self):
-        del self._intf
-
-    intf = property(_getInterface, _setInterface, _delInterface)
-
-    @property
-    def network(self):
-        if not self._network:
-            import network
-            self._network = network.Network()
-
-        return self._network
-
-    @property
-    def platform(self):
-        if not self._platform:
-            import platform
-            self._platform = platform.getPlatform(self)
-
-        return self._platform
-
-    @property
-    def protected(self):
-        import stat
-
-        if os.path.exists("/dev/live") and \
-           stat.S_ISBLK(os.stat("/dev/live")[stat.ST_MODE]):
-            return [os.readlink("/dev/live")]
-        elif self.methodstr and self.methodstr.startswith("hd:"):
-            method = self.methodstr[3:]
-            return [method.split(":", 3)[0]]
-        else:
-            return []
-
-    @property
-    def users(self):
-        if not self._users:
-            import users
-            self._users = users.Users(self)
-
-        return self._users
-
-    @property
-    def storage(self):
-        if not self._storage:
-            import storage
-            self._storage = storage.Storage(self)
-
-        return self._storage
-
-    @property
-    def timezone(self):
-        if not self._timezone:
-            import timezone
-            self._timezone = timezone.Timezone()
-            self._timezone.setTimezoneInfo(self.instLanguage.getDefaultTimeZone(self.rootPath))
-
-        return self._timezone
-
-    def dumpState(self):
-        from meh.dump import ReverseExceptionDump
-        from inspect import stack as _stack
-
-        # Skip the frames for dumpState and the signal handler.
-        stack = _stack()[2:]
-        stack.reverse()
-        exn = ReverseExceptionDump((None, None, stack), self.mehConfig)
-
-        (fd, filename) = mkstemp("", "anaconda-tb-", "/tmp")
-        fo = os.fdopen(fd, "w")
-
-        exn.write(self, fo)
-
-    def initInterface(self):
-        if self._intf:
-            raise RuntimeError, "Second attempt to initialize the InstallInterface"
-
-        # setup links required by graphical mode if installing and verify display mode
-        if self.displayMode == 'g':
-            stdoutLog.info (_("Starting graphical installation."))
-
-            try:
-                from gui import InstallInterface
-            except Exception, e:
-                from flags import flags
-                stdoutLog.error("Exception starting GUI installer: %s" %(e,))
-                # if we're not going to really go into GUI mode, we need to get
-                # back to vc1 where the text install is going to pop up.
-                if not flags.livecdInstall:
-                    isys.vtActivate (1)
-                stdoutLog.warning("GUI installer startup failed, falling back to text mode.")
-                self.displayMode = 't'
-                if 'DISPLAY' in os.environ.keys():
-                    del os.environ['DISPLAY']
-                time.sleep(2)
-
-        if self.displayMode == 't':
-            from text import InstallInterface
-            if not os.environ.has_key("LANG"):
-                os.environ["LANG"] = "en_US.UTF-8"
-
-        if self.displayMode == 'c':
-            from cmdline import InstallInterface
-
-        self._intf = InstallInterface()
-        return self._intf
-
-    def writeXdriver(self, root = None):
-        # this should go away at some point, but until it does, we
-        # need to keep it around.
-        if self.xdriver is None:
-            return
-        if root is None:
-            root = self.rootPath
-        if not os.path.isdir("%s/etc/X11" %(root,)):
-            os.makedirs("%s/etc/X11" %(root,), mode=0755)
-        f = open("%s/etc/X11/xorg.conf" %(root,), 'w')
-        f.write('Section "Device"\n\tIdentifier "Videocard0"\n\tDriver "%s"\nEndSection\n' % self.xdriver)
-        f.close()
-
-    def setMethodstr(self, methodstr):
-        if methodstr.startswith("cdrom://"):
-            (device, tree) = string.split(methodstr[8:], ":", 1)
-
-            if not tree.startswith("/"):
-                tree = "/%s" %(tree,)
-
-            if device.startswith("/dev/"):
-                device = device[5:]
-
-            self.mediaDevice = device
-            self.methodstr = "cdrom://%s" % tree
-        else:
-            self.methodstr = methodstr
-
-    def requiresNetworkInstall(self):
-        fail = False
-        numNetDevs = isys.getNetworkDeviceCount()
-
-        if self.methodstr is not None:
-            if (self.methodstr.startswith("http") or \
-                self.methodstr.startswith("ftp://";) or \
-                self.methodstr.startswith("nfs:")) and \
-               numNetDevs == 0:
-                fail = True
-        elif self.stage2 is not None:
-            if self.stage2.startswith("cdrom://") and \
-               not os.path.isdir("/mnt/stage2/Packages") and \
-               numNetDevs == 0:
-                fail = True
-
-        if fail:
-            log.error("network install required, but no network devices available")
-
-        return fail
-
-    def write(self):
-        self.writeXdriver()
-        self.instLanguage.write(self.rootPath)
-
-        self.timezone.write(self.rootPath)
-        self.network.write(instPath=self.rootPath, anaconda=self)
-        self.desktop.write(self.rootPath)
-        self.users.write(self.rootPath)
-        self.security.write(self.rootPath)
-        self.firewall.write(self.rootPath)
-
-        if self.ksdata:
-            for svc in self.ksdata.services.disabled:
-                iutil.execWithRedirect("/sbin/chkconfig",
-                                       [svc, "off"],
-                                       stdout="/dev/tty5", stderr="/dev/tty5",
-                                       root=self.rootPath)
-
-            for svc in self.ksdata.services.enabled:
-                iutil.execWithRedirect("/sbin/chkconfig",
-                                       [svc, "on"],
-                                       stdout="/dev/tty5", stderr="/dev/tty5",
-                                       root=self.rootPath)
-
-    def writeKS(self, filename):
-        import urllib
-        from pykickstart.version import versionToString, DEVEL
-
-        f = open(filename, "w")
-
-        f.write("# Kickstart file automatically generated by anaconda.\n\n")
-        f.write("#version=%s\n" % versionToString(DEVEL))
-
-        if self.upgrade:
-            f.write("upgrade\n")
-        else:
-            f.write("install\n")
-
-        m = None
-
-        if self.methodstr:
-            m = self.methodstr
-        elif self.stage2:
-            m = self.stage2
-
-        if m:
-            if m.startswith("cdrom:"):
-                f.write("cdrom\n")
-            elif m.startswith("hd:"):
-                if m.count(":") == 3:
-                    (part, fs, dir) = string.split(m[3:], ":")
-                else:
-                    (part, dir) = string.split(m[3:], ":")
-
-                f.write("harddrive --partition=%s --dir=%s\n" % (part, dir))
-            elif m.startswith("nfs:"):
-                if m.count(":") == 3:
-                    (server, opts, dir) = string.split(m[4:], ":")
-                    f.write("nfs --server=%s --opts=%s --dir=%s" % (server, opts, dir))
-                else:
-                    (server, dir) = string.split(m[4:], ":")
-                    f.write("nfs --server=%s --dir=%s\n" % (server, dir))
-            elif m.startswith("ftp://";) or m.startswith("http"):
-                f.write("url --url=%s\n" % urllib.unquote(m))
-
-        # Some kickstart commands do not correspond to any anaconda UI
-        # component.  If this is a kickstart install, we need to make sure
-        # the information from the input file ends up in the output file.
-        if self.ksdata:
-            f.write(self.ksdata.user.__str__())
-            f.write(self.ksdata.services.__str__())
-            f.write(self.ksdata.reboot.__str__())
-
-        self.instLanguage.writeKS(f)
-
-        if not self.isHeadless:
-            self.keyboard.writeKS(f)
-            self.network.writeKS(f)
-
-        self.timezone.writeKS(f)
-        self.users.writeKS(f)
-        self.security.writeKS(f)
-        self.firewall.writeKS(f)
-
-        self.storage.writeKS(f)
-        self.bootloader.writeKS(f)
-
-        if self.backend:
-            self.backend.writeKS(f)
-            self.backend.writePackagesKS(f, self)
-
-        # Also write out any scripts from the input ksfile.
-        if self.ksdata:
-            for s in self.ksdata.scripts:
-                f.write(s.__str__())
-
-        # make it so only root can read, could have password
-        os.chmod(filename, 0600)
diff --git a/anaconda b/anaconda
deleted file mode 100755
index b5532b0..0000000
--- a/anaconda
+++ /dev/null
@@ -1,932 +0,0 @@
-#!/usr/bin/python
-#
-# anaconda: The Red Hat Linux Installation program
-#
-# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007
-# Red Hat, Inc.  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 as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# 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, see <http://www.gnu.org/licenses/>.
-#
-# Author(s): Brent Fox <bfox@xxxxxxxxxx>
-#            Mike Fulbright <msf@xxxxxxxxxx>
-#            Jakub Jelinek <jakub@xxxxxxxxxx>
-#            Jeremy Katz <katzj@xxxxxxxxxx>
-#            Chris Lumens <clumens@xxxxxxxxxx>
-#            Paul Nasrat <pnasrat@xxxxxxxxxx>
-#            Erik Troan <ewt@xxxxxxxxx>
-#            Matt Wilson <msw@xxxxxxxxx>
-#
-
-# This toplevel file is a little messy at the moment...
-
-import sys, os, re, time, subprocess
-from optparse import OptionParser
-from tempfile import mkstemp
-
-# keep up with process ID of the window manager if we start it
-wm_pid = None
-
-# Make sure messages sent through python's warnings module get logged.
-def AnacondaShowWarning(message, category, filename, lineno, file=sys.stderr, line=None):
-    log.warning("%s" % warnings.formatwarning(message, category, filename, lineno, line))
-
-def startMetacityWM():
-    childpid = os.fork()
-    if not childpid:
-        cmd = '/usr/bin/metacity'
-        if not os.access(cmd, os.X_OK):
-            log.error("Unable to find the window manager binary.")
-            sys.exit(1)
-        args = ['--display', ':1',
-                '--sm-disable']
-        rc = iutil.execWithRedirect(cmd, args, 
-                               stdout='/dev/null', stderr='/dev/null')
-        if rc:
-            log.error("Error running window manager.")
-            sys.exit (rc)
-        else:
-            log.info("The window manager has terminated.")
-            sys.exit(0)
-    return childpid
-
-def startAuditDaemon():
-    childpid = os.fork()
-    if not childpid:
-        cmd = '/sbin/auditd'
-        try:
-            os.execl(cmd, cmd)
-        except OSError as e:
-            log.error("Error running the audit daemon: %s" % str(e))
-        sys.exit(0)
-    # auditd will turn into a daemon so catch the immediate child pid now:
-    os.waitpid(childpid, 0)
-
-# function to handle X startup special issues for anaconda
-def doStartupX11Actions(runres="800x600"):
-    global wm_pid
-
-    setupGraphicalLinks()
-
-    # now start up the window manager
-    try:
-        wm_pid = startMetacityWM()
-        log.info("Starting window manager, pid %s." % (wm_pid,))
-    except Exception:
-        wm_pid = None
-        log.error("Unable to start the window manager.")
-
-    if wm_pid is not None:
-        import xutils
-        import gtk
-
-        try:
-            xutils.setRootResource('Xcursor.size', '24')
-            xutils.setRootResource('Xcursor.theme', 'Bluecurve')
-            xutils.setRootResource('Xcursor.theme_core', 'true')
-
-            xutils.setRootResource('Xft.antialias', '1')
-            xutils.setRootResource('Xft.hinting', '1')
-            xutils.setRootResource('Xft.hintstyle', 'hintslight')
-            xutils.setRootResource('Xft.rgba', 'none')
-        except:
-            sys.stderr.write("X SERVER STARTED, THEN FAILED");
-            raise RuntimeError, "X server failed to start"
-
-def doShutdownX11Actions():
-    global wm_pid
-    
-    if wm_pid is not None:
-        try:
-            os.kill(wm_pid, 15)
-            os.waitpid(wm_pid, 0)
-        except:
-            pass
-
-def setupPythonUpdates():
-    from distutils.sysconfig import get_python_lib
-
-    if not os.path.exists("/tmp/updates"):
-        return
-
-    for pkg in os.listdir("/tmp/updates"):
-        d = "/tmp/updates/%s" % pkg
-
-        if not os.path.isdir(d):
-            continue
-
-        # See if the package exists in /usr/lib{64,}/python/?.?/site-packages.
-        # If it does, we can set it up as an update.  If not, the pkg is
-        # likely a completely new directory and should not be looked at.
-        dest = "%s/%s" % (get_python_lib(), pkg)
-        if not os.access(dest, os.R_OK):
-            dest = "%s/%s" % (get_python_lib(1), pkg)
-            if not os.access(dest, os.R_OK):
-                continue
-
-        contents = os.listdir(d)
-
-        # Symlink over everything that's in the python libdir but not in
-        # the updates directory.
-        for f in filter(lambda fn: fn not in contents, os.listdir(dest)):
-            if f.endswith(".pyc") or f.endswith(".pyo"):
-                continue
-
-            os.symlink("%s/%s" % (dest, f), "/tmp/updates/%s/%s" % (pkg, f))
-
-
-    import glob
-    import shutil
-    for rule in glob.glob("/tmp/updates/*.rules"):
-        target = "/etc/udev/rules.d/" + rule.split('/')[-1]
-        shutil.copyfile(rule, target)
-
-def parseOptions(argv = None):
-    def resolution_cb (option, opt_str, value, parser):
-        parser.values.runres = value
-
-    op = OptionParser()
-    # Interface
-    op.add_option("-C", "--cmdline", dest="display_mode", action="store_const", const="c",
-                  default="g")
-    op.add_option("-G", "--graphical", dest="display_mode", action="store_const", const="g")
-    op.add_option("-T", "--text", dest="display_mode", action="store_const", const="t")
-
-    # Network
-    op.add_option("--noipv4", action="store_true", default=False)
-    op.add_option("--noipv6", action="store_true", default=False)
-    op.add_option("--proxy")
-    op.add_option("--proxyAuth")
-
-    # Method of operation
-    op.add_option("--autostep", action="store_true", default=False)
-    op.add_option("-d", "--debug", dest="debug", action="store_true", default=False)
-    op.add_option("--kickstart", dest="ksfile")
-    op.add_option("--rescue", dest="rescue", action="store_true", default=False)
-    op.add_option("--targetarch", dest="targetArch", nargs=1, type="string")
-
-    op.add_option("-m", "--method", dest="method", default=None)
-    op.add_option("--repo", dest="method", default=None)
-    op.add_option("--stage2", dest="stage2", default=None)
-
-    op.add_option("--liveinst", action="store_true", default=False)
-
-    # Display
-    op.add_option("--headless", dest="isHeadless", action="store_true", default=False)
-    op.add_option("--nofb")
-    op.add_option("--resolution", action="callback", callback=resolution_cb, dest="runres",
-                  default="800x600", nargs=1, type="string")
-    op.add_option("--serial", action="store_true", default=False)
-    op.add_option("--usefbx", dest="xdriver", action="store_const", const="fbdev")
-    op.add_option("--virtpconsole")
-    op.add_option("--vnc", action="store_true", default=False)
-    op.add_option("--vncconnect")
-    op.add_option("--xdriver", dest="xdriver", action="store", type="string", default=None)
-
-    # Language
-    op.add_option("--keymap")
-    op.add_option("--kbdtype")
-    op.add_option("--lang")
-
-    # Obvious
-    op.add_option("--loglevel")
-    op.add_option("--syslog")
-
-    op.add_option("--noselinux", dest="selinux", action="store_false", default=True)
-    op.add_option("--selinux", action="store_true")
-
-    op.add_option("--nompath", dest="mpath", action="store_false", default=True)
-    op.add_option("--mpath", action="store_true")
-
-    op.add_option("--nodmraid", dest="dmraid", action="store_false", default=True)
-    op.add_option("--dmraid", action="store_true")
-
-    op.add_option("--noibft", dest="ibft", action="store_false", default=True)
-    op.add_option("--ibft", action="store_true")
-    op.add_option("--noiscsi", dest="iscsi", action="store_false", default=False)
-    op.add_option("--iscsi", action="store_true")
-
-    # Miscellaneous
-    op.add_option("--module", action="append", default=[])
-    op.add_option("--nomount", dest="rescue_nomount", action="store_true", default=False)
-    op.add_option("--updates", dest="updateSrc", action="store", type="string")
-    op.add_option("--dogtail", dest="dogtail",   action="store", type="string")
-    op.add_option("--dlabel", action="store_true", default=False)
-
-    # Deprecated, unloved, unused
-    op.add_option("-r", "--rootPath", dest="unsupportedMode",
-                  action="store_const", const="root path")
-    op.add_option("-t", "--test", dest="unsupportedMode",
-                  action="store_const", const="test")
-
-    return op.parse_args(argv)
-
-def setupPythonPath():
-    haveUpdates = False
-    for ndx in range(len(sys.path)-1, -1, -1):
-        if sys.path[ndx].endswith('updates'):
-            haveUpdates = True
-            break
-
-    # With anaconda being a real module this isn't strictly necessary, but
-    # setting up the path now prevents having to change every import line in
-    # anaconda.
-    from distutils.sysconfig import get_python_lib
-    d = get_python_lib(plat_specific=1)
-
-    if haveUpdates:
-        sys.path.insert(ndx+1, "%s/pyanaconda" % d)
-        sys.path.insert(ndx+2, "%s/pyanaconda/textw" % d)
-        sys.path.insert(ndx+3, "%s/pyanaconda/iw" % d)
-    else:
-        sys.path.insert(0, "%s/pyanaconda" % d)
-        sys.path.insert(1, "%s/pyanaconda/textw" % d)
-        sys.path.insert(2, "%s/pyanaconda/iw" % d)
-
-    sys.path.append('/usr/share/system-config-date')
-
-def addPoPath(dir):
-    """ Looks to see what translations are under a given path and tells
-    the gettext module to use that path as the base dir """
-    for d in os.listdir(dir):
-        if not os.path.isdir("%s/%s" %(dir,d)):
-            continue
-        if not os.path.exists("%s/%s/LC_MESSAGES" %(dir,d)):
-            continue
-        for basename in os.listdir("%s/%s/LC_MESSAGES" %(dir,d)):
-            if not basename.endswith(".mo"):
-                continue
-            log.info("setting %s as translation source for %s" %(dir, basename[:-3]))
-            gettext.bindtextdomain(basename[:-3], dir)
-
-def setupTranslations():
-    if os.path.isdir("/tmp/updates/po"):
-        addPoPath("/tmp/updates/po")
-    gettext.textdomain("anaconda")
-
-def setupEnvironment():
-    # Silly GNOME stuff
-    if os.environ.has_key('HOME') and not os.environ.has_key("XAUTHORITY"):
-        os.environ['XAUTHORITY'] = os.environ['HOME'] + '/.Xauthority'
-    os.environ['HOME'] = '/tmp'
-    os.environ['LC_NUMERIC'] = 'C'
-    os.environ["GCONF_GLOBAL_LOCKS"] = "1"
-
-    # In theory, this gets rid of our LVM file descriptor warnings
-    os.environ["LVM_SUPPRESS_FD_WARNINGS"] = "1"
-
-    # make sure we have /sbin and /usr/sbin in our path
-    os.environ["PATH"] += ":/sbin:/usr/sbin"
-
-    # we can't let the LD_PRELOAD hang around because it will leak into
-    # rpm %post and the like.  ick :/
-    if os.environ.has_key("LD_PRELOAD"):
-        del os.environ["LD_PRELOAD"]
-
-    os.environ["GLADEPATH"] = "/tmp/updates/:/tmp/updates/ui/:ui/:/usr/share/anaconda/ui/:/usr/share/python-meh/"
-    os.environ["PIXMAPPATH"] = "/tmp/updates/pixmaps/:/tmp/updates/:/tmp/product/pixmaps/:/tmp/product/:pixmaps/:/usr/share/anaconda/pixmaps/:/usr/share/pixmaps/:/usr/share/anaconda/:/usr/share/python-meh/"
-
-def setupLoggingFromOpts(opts):
-    if opts.loglevel and anaconda_log.logLevelMap.has_key(opts.loglevel):
-        level = anaconda_log.logLevelMap[opts.loglevel]
-        anaconda_log.logger.tty_loglevel = level
-        anaconda_log.setHandlersLevel(log, level)
-        anaconda_log.setHandlersLevel(storage.storage_log.logger, level)
-
-    if opts.syslog:
-        anaconda_log.logger.remote_syslog = opts.syslog
-        if opts.syslog.find(":") != -1:
-            (host, port) = opts.syslog.split(":")
-            anaconda_log.logger.addSysLogHandler(log, host, port=int(port))
-        else:
-            anaconda_log.logger.addSysLogHandler(log, opts.syslog)
-
-# ftp installs pass the password via a file in /tmp so
-# ps doesn't show it
-def expandFTPMethod(str):
-    ret = None
-
-    try:
-        filename = str[1:]
-        ret = open(filename, "r").readline()
-        ret = ret[:len(ret) - 1]
-        os.unlink(filename)
-        return ret
-    except:
-        return None
-
-def runVNC():
-    global vncS
-    vncS.startServer()
-
-    child = os.fork()
-    if child == 0:
-        for p in ('/tmp/updates/pyrc.py', \
-                '/usr/share/anaconda/pyrc.py'):
-            if os.access(p, os.R_OK|os.X_OK):
-                os.environ['PYTHONSTARTUP'] = p
-                break
-
-        while True:
-            # s390/s390x are the only places we /really/ need a shell on tty1,
-            # and everywhere else this just gets in the way of pdb.  But we
-            # don't want to return, because that'll return try to start X
-            # a second time.
-            if iutil.isConsoleOnVirtualTerminal():
-                    time.sleep(10000)
-            else:
-                    print _("Press <enter> for a shell")
-                    sys.stdin.readline()
-                    iutil.execConsole()
-
-def within_available_memory(needed_ram):
-    # kernel binary code estimate that is
-    # not reported in MemTotal by /proc/meminfo:
-    epsilon = 15360 # 15 MB
-    return needed_ram < (iutil.memInstalled() + epsilon)
-
-def check_memory(anaconda, opts, display_mode=None):
-
-    if not display_mode:
-        display_mode = anaconda.displayMode
-
-    extra_ram = 0
-    reason = ''
-    if opts.stage2.startswith(('http', 'ftp', '@')):
-        extra_ram += isys.URL_INSTALL_EXTRA_RAM
-        reason = " using this install method"
-
-    needed_ram = isys.MIN_RAM + extra_ram
-    if not within_available_memory(needed_ram):
-        from snack import SnackScreen, ButtonChoiceWindow
-        screen = SnackScreen()
-        ButtonChoiceWindow(screen, _('Fatal Error'),
-                            _('You do not have enough RAM to install %s '
-                              'on this machine%s.\n'
-                              '\n'
-                              'Press <return> to reboot your system.\n')
-                           %(product.productName, reason),
-                           buttons = (_("OK"),))
-        screen.finish()
-        sys.exit(0)
-
-    # override display mode if machine cannot nicely run X
-    if display_mode not in ('t', 'c') and not flags.usevnc:
-        needed_ram = isys.MIN_GUI_RAM + extra_ram
-
-        if not within_available_memory(needed_ram):
-            complain = _("You do not have enough RAM to use the graphical "
-                         "installer.")
-            if flags.livecdInstall:
-                stdoutLog.warning(complain)
-                recommendation = _("Try the text mode installer by running:\n\n"
-                                   "'/usr/bin/liveinst -T'\n\n from a root "
-                                   "terminal.")
-                title = _("Not enough RAM")
-                text = "%s %s" %(complain, recommendation)
-                import gtk
-                dialog = gtk.MessageDialog(type = gtk.MESSAGE_ERROR, 
-                                           buttons = gtk.BUTTONS_CLOSE,
-                                           message_format=text)
-                dialog.set_title(title)
-                dialog.run()
-                sys.exit(1)
-            else:
-                resolution = _("Starting text mode.")
-                stdoutLog.warning("%s %s" % (complain, resolution))
-                anaconda.displayMode = 't'
-                time.sleep(2)
-
-def setupGraphicalLinks():
-    for i in ( "imrc", "im_palette.pal", "gtk-2.0", "pango", "fonts",
-               "fb.modes"):
-        try:
-            if os.path.exists("/mnt/runtime/etc/%s" %(i,)):
-                os.symlink ("../mnt/runtime/etc/" + i, "/etc/" + i)
-        except:
-            pass
-
-def handleSshPw(anaconda):
-    if not anaconda.ksdata:
-        return
-
-    import users
-    u = users.Users(anaconda)
-
-    userdata = anaconda.ksdata.sshpw.dataList()
-    for ud in userdata:
-        if u.checkUserExists(ud.username, root="/"):
-            u.setUserPassword(username=ud.username, password=ud.password,
-                              isCrypted=ud.isCrypted, lock=ud.lock)
-        else:
-            u.createUser(name=ud.username, password=ud.password,
-                         isCrypted=ud.isCrypted, lock=ud.lock,
-                         root="/")
-
-    del u
-
-def createSshKey(algorithm, keyfile):
-    path = '/etc/ssh/%s' % (keyfile,)
-    argv = ['-q','-t',algorithm,'-f',path,'-C','','-N','']
-    log.info("running \"%s\"" % (" ".join(['ssh-keygen']+argv),))
-
-    so = "/tmp/ssh-keygen-%s-stdout.log" % (algorithm,)
-    se = "/tmp/ssh-keygen-%s-stderr.log" % (algorithm,)
-    iutil.execWithRedirect('ssh-keygen', argv, stdout=so, stderr=se)
-
-def fork_orphan():
-    """Forks an orphan.
-    
-    Returns 1 in the parent and 0 in the orphaned child.
-    """
-    intermediate = os.fork()
-    if not intermediate:
-        if os.fork():
-            # the intermediate child dies
-            os._exit(0)
-        return 0;
-    # the original process waits for the intermediate child
-    os.waitpid(intermediate, 0)
-    return 1
-
-def startSsh():
-    if iutil.isS390():
-        return
-
-    if not fork_orphan():
-        os.mkdir("/var/log", 0755)
-        os.open("/var/log/lastlog", os.O_RDWR | os.O_CREAT, 0644)
-        ssh_keys = {
-            'rsa1':'ssh_host_key',
-            'rsa':'ssh_host_rsa_key',
-            'dsa':'ssh_host_dsa_key',
-            }
-        for (algorithm, keyfile) in ssh_keys.items():
-            createSshKey(algorithm, keyfile)
-        args = ["/sbin/sshd", "-f", "/etc/ssh/sshd_config.anaconda"]
-        os.execv("/sbin/sshd", args)
-        sys.exit(1)
-
-def startDebugger(signum, frame):
-    import epdb
-    epdb.serve(skip=1)
-
-if __name__ == "__main__":
-    setupPythonPath()
-
-    # Allow a file to be loaded as early as possible
-    try:
-        import updates_disk_hook
-    except ImportError:
-        pass
-
-    # Set up logging as early as possible.
-    import logging
-    import anaconda_log
-    anaconda_log.init()
-
-    log = logging.getLogger("anaconda")
-    stdoutLog = logging.getLogger("anaconda.stdout")
-
-    if os.geteuid() != 0:
-        stdoutLog.error("anaconda must be run as root.")
-        sys.exit(0)
-
-    # pull this in to get product name and versioning
-    import product
-
-    # this handles setting up updates for pypackages to minimize the set needed
-    setupPythonUpdates()
-
-    import isys
-    isys.initLog()
-
-    import signal, string, iutil, time
-    import warnings
-    import vnc
-    import users
-    import kickstart
-    import storage.storage_log
-
-    from flags import flags
-
-    # the following makes me very sad. -- katzj
-    # we have a slightly different set of udev rules in the second 
-    # stage than the first stage.  why this doesn't get picked up
-    # automatically, I don't know.  but we need to trigger so that we
-    # have all the information about netdevs that we care about for 
-    # NetworkManager in the udev database
-    from baseudev import udev_trigger, udev_settle
-    udev_trigger("net")
-    udev_settle()
-    # and for added fun, once doesn't seem to be enough?  so we 
-    # do it twice, it works and we scream at the world "OH WHY?"
-    udev_trigger("net")
-    udev_settle()
-
-    import gettext
-    _ = lambda x: gettext.ldgettext("anaconda", x)
-
-    from pyanaconda import Anaconda
-    anaconda = Anaconda()
-    warnings.showwarning = AnacondaShowWarning
-    setupTranslations()
-
-    # reset python's default SIGINT handler
-    signal.signal(signal.SIGINT, signal.SIG_DFL)
-    signal.signal(signal.SIGSEGV, isys.handleSegv)
-
-    setupEnvironment()
-
-    pidfile = open("/var/run/anaconda.pid", "w")
-    pidfile.write("%s\n" % (os.getpid(),))
-    del pidfile
-    # add our own additional signal handlers
-    signal.signal(signal.SIGHUP, startDebugger)
-
-    # we need to do this really early so we make sure its done before rpm
-    # is imported
-    iutil.writeRpmPlatform()
-
-    graphical_failed = 0
-    vncS = vnc.VncServer()          # The vnc Server object.
-    vncS.anaconda = anaconda
-    xserver_pid = None
-
-    (opts, args) = parseOptions()
-
-    # check memory, just the text mode for now:
-    check_memory(anaconda, opts, 't')
-
-    if opts.unsupportedMode:
-        stdoutLog.error("Running anaconda in %s mode is no longer supported." % opts.unsupportedMode)
-        sys.exit(0)
-
-    # Now that we've got arguments, do some extra processing.
-    setupLoggingFromOpts(opts)
-
-    # Default is to prompt to mount the installed system.
-    anaconda.rescue_mount = not opts.rescue_nomount
-
-    if opts.dlabel: #autodetected driverdisc in use
-        flags.dlabel = True
-
-    anaconda.displayMode = opts.display_mode
-    anaconda.isHeadless = opts.isHeadless
-
-    if opts.noipv4:
-        flags.useIPv4 = False
-
-    if opts.noipv6:
-        flags.useIPv6 = False
-
-    if opts.proxy:
-        anaconda.proxy = opts.proxy
-
-        if opts.proxyAuth:
-            filename = opts.proxyAuth
-            ret = open(filename, "r").readlines()
-            os.unlink(filename)
-
-            anaconda.proxyUsername = ret[0].rstrip()
-            if len(ret) == 2:
-                anaconda.proxyPassword = ret[1].rstrip()
-
-    if opts.updateSrc:
-        anaconda.updateSrc = opts.updateSrc
-
-    if opts.method:
-        if opts.method[0] == '@':
-            opts.method = expandFTPMethod(opts.method)
-
-        anaconda.setMethodstr(opts.method)
-    else:
-        anaconda.methodstr = None
-
-    if opts.stage2:
-        if opts.stage2[0] == '@':
-            opts.stage2 = expandFTPMethod(opts.stage2)
-
-        anaconda.stage2 = opts.stage2
-
-    if opts.liveinst:
-        flags.livecdInstall = True
-
-    if opts.module:
-        for mod in opts.module:
-            (path, name) = string.split(mod, ":")
-            anaconda.extraModules.append((path, name))
-
-    if opts.vnc:
-        flags.usevnc = 1
-        anaconda.displayMode = 'g'
-        vncS.recoverVNCPassword()
-
-        # Only consider vncconnect when vnc is a param
-        if opts.vncconnect:
-            cargs = string.split(opts.vncconnect, ":")
-            vncS.vncconnecthost = cargs[0]
-            if len(cargs) > 1 and len(cargs[1]) > 0:
-                if len(cargs[1]) > 0:
-                    vncS.vncconnectport = cargs[1]
-
-    if opts.ibft:
-        flags.ibft = 1
-
-    if opts.iscsi:
-        flags.iscsi = 1
-
-    if opts.targetArch:
-        flags.targetarch = opts.targetArch
-
-    # set flags 
-    flags.dmraid = opts.dmraid
-    flags.mpath = opts.mpath
-    flags.selinux = opts.selinux
-
-    if opts.serial:
-        flags.serial = True
-    if opts.virtpconsole:
-        flags.virtpconsole = opts.virtpconsole
-
-    if opts.xdriver:
-        anaconda.xdriver = opts.xdriver
-        anaconda.writeXdriver(root="/")
-
-    if not flags.livecdInstall:
-        startAuditDaemon()
-
-    # setup links required for all install types
-    for i in ( "services", "protocols", "nsswitch.conf", "joe", "selinux",
-               "mke2fs.conf" ):
-        try:
-            if os.path.exists("/mnt/runtime/etc/" + i):
-                os.symlink ("../mnt/runtime/etc/" + i, "/etc/" + i)
-        except:
-            pass
-
-    # This is the one place we do all kickstart file parsing.
-    if opts.ksfile:
-        kickstart.preScriptPass(anaconda, opts.ksfile)
-        anaconda.ksdata = kickstart.parseKickstart(anaconda, opts.ksfile)
-        opts.rescue = anaconda.ksdata.rescue.rescue
-
-    if flags.sshd:
-        # we need to have a libuser.conf that points to the installer root for
-        # sshpw, but after that we start sshd, we need one that points to the
-        # install target.
-        luserConf = users.createLuserConf(instPath="")
-        handleSshPw(anaconda)
-        startSsh()
-        del(os.environ["LIBUSER_CONF"])
-
-    users.createLuserConf(anaconda.rootPath)
-
-    if opts.rescue:
-        anaconda.rescue = True
-
-        import rescue
-
-        if anaconda.ksdata:
-            anaconda.instClass.configure(anaconda)
-
-            # We need an interface before running kickstart execute methods for
-            # storage.
-            from snack import *
-            screen = SnackScreen()
-            anaconda.intf = rescue.RescueInterface(screen)
-
-            anaconda.ksdata.execute()
-
-            anaconda.intf = None
-            screen.finish()
-
-            # command line 'nomount' overrides kickstart /same for vnc/
-            anaconda.rescue_mount = not (opts.rescue_nomount or anaconda.ksdata.rescue.nomount)
-
-        rescue.runRescue(anaconda)
-
-        # shouldn't get back here
-        sys.exit(1)
-
-    if anaconda.ksdata:
-        if anaconda.ksdata.vnc.enabled:
-            flags.usevnc = 1
-            anaconda.displayMode = 'g'
-
-            if vncS.password == "":
-                vncS.password = anaconda.ksdata.vnc.password
-
-            if vncS.vncconnecthost == "":
-                vncS.vncconnecthost = anaconda.ksdata.vnc.host
-
-            if vncS.vncconnectport == "":
-                vncS.vncconnectport = anaconda.ksdata.vnc.port
-
-        flags.vncquestion = False
-
-    # disable VNC over text question when not enough memory is available
-    if iutil.memInstalled() < isys.MIN_GUI_RAM:
-        flags.vncquestion = False
-
-    if os.environ.has_key('DISPLAY'):
-        flags.preexisting_x11 = True
-
-    if anaconda.displayMode == 't' and flags.vncquestion: #we prefer vnc over text mode, so ask about that
-        title = _("Would you like to use VNC?")
-        message = _("Text mode provides a limited set of installation options.  "
-                    "It does not allow you to specify your own partitioning "
-                    "layout or package selections.  Would you like to use VNC "
-                    "mode instead?")
-
-        ret = vnc.askVncWindow(title, message)
-        if ret != -1:
-            anaconda.displayMode = 'g'
-            flags.usevnc = 1
-            if ret is not None:
-                vncS.password = ret
-
-    if opts.debug:
-        flags.debug = True
-
-    log.info("anaconda called with cmdline = %s" %(sys.argv,))
-    log.info("Display mode = %s" % anaconda.displayMode)
-    log.info("Default encoding = %s " % sys.getdefaultencoding())
-
-    check_memory(anaconda, opts)
-
-    #
-    # now determine if we're going to run in GUI or TUI mode
-    #
-    # if no X server, we have to use text mode
-    if not flags.livecdInstall and not iutil.isS390() and not os.access("/usr/bin/Xorg", os.X_OK):
-         stdoutLog.warning(_("Graphical installation is not available. "
-                             "Starting text mode."))
-         time.sleep(2)
-         anaconda.displayMode = 't'
-
-    # s390/iSeries checks
-    if anaconda.isHeadless and anaconda.displayMode == "g" and not \
-       (flags.preexisting_x11 or flags.usevnc):
-        stdoutLog.warning(_("DISPLAY variable not set. Starting text mode."))
-        anaconda.displayMode = 't'
-        graphical_failed = 1
-        time.sleep(2)
-
-    # if DISPLAY not set either vnc server failed to start or we're not
-    # running on a redirected X display, so start local X server
-    if anaconda.displayMode == 'g' and not flags.preexisting_x11 and not flags.usevnc:
-        try:
-            # The following code depends on no SIGCHLD being delivered, possibly
-            # only except the one from a failing X.org. Thus make sure before
-            # entering this section that all the other children of anaconda have
-            # terminated or were forked into an orphan (which won't deliver a
-            # SIGCHLD to mess up the fragile signaling below).
-
-            # start X with its USR1 handler set to ignore.  this will make it send
-            # us SIGUSR1 if it succeeds.  if it fails, catch SIGCHLD and bomb out.
-
-            def sigchld_handler(num, frame):
-                raise OSError
-
-            def sigusr1_handler(num, frame):
-                pass
-
-            def preexec_fn():
-                signal.signal(signal.SIGUSR1, signal.SIG_IGN)
-
-            old_sigusr1 = signal.signal(signal.SIGUSR1, sigusr1_handler)
-            old_sigchld = signal.signal(signal.SIGCHLD, sigchld_handler)
-            xout = open("/dev/tty5", "w")
-
-            proc = subprocess.Popen(["Xorg", "-br", "-logfile", "/tmp/X.log",
-                                     ":1", "vt6", "-s", "1440", "-ac",
-                                     "-nolisten", "tcp", "-dpi", "96"],
-                                     close_fds=True, stdout=xout, stderr=xout,
-                                     preexec_fn=preexec_fn)
-
-            signal.pause()
-
-            os.environ["DISPLAY"] = ":1"
-            doStartupX11Actions(opts.runres)
-            xserver_pid = proc.pid
-        except (OSError, RuntimeError):
-            stdoutLog.warning(" X startup failed, falling back to text mode")
-            anaconda.displayMode = 't'
-            graphical_failed = 1
-            time.sleep(2)
-        finally:
-            signal.signal(signal.SIGUSR1, old_sigusr1)
-            signal.signal(signal.SIGCHLD, old_sigchld)
-
-    if anaconda.displayMode == 't' and graphical_failed and not anaconda.ksdata:
-        ret = vnc.askVncWindow()
-        if ret != -1:
-            anaconda.displayMode = 'g'
-            flags.usevnc = 1
-            if ret is not None:
-                vncS.password = ret
-
-    # if they want us to use VNC do that now
-    if anaconda.displayMode == 'g' and flags.usevnc:
-        runVNC()
-        doStartupX11Actions(opts.runres)
-
-    # with X running we can initialize the UI interface
-    anaconda.initInterface()
-    anaconda.instClass.configure(anaconda)
-
-    # comment out the next line to make exceptions non-fatal
-    from exception import initExceptionHandling
-    anaconda.mehConfig = initExceptionHandling(anaconda)
-
-    # add our own additional signal handlers
-    signal.signal(signal.SIGUSR2, lambda signum, frame: anaconda.dumpState())
-
-    # download and run Dogtail script
-    if opts.dogtail:
-       try:
-           import urlgrabber
-
-           try:
-               fr = urlgrabber.urlopen(opts.dogtail)
-           except urlgrabber.grabber.URLGrabError, e:
-               log.error("Could not retrieve Dogtail script from %s.\nError was\n%s" % (opts.dogtail, e))
-               fr = None
-                           
-           if fr:
-               (fw, testcase) = mkstemp(prefix='testcase.py.', dir='/tmp')
-               os.write(fw, fr.read())
-               fr.close()
-               os.close(fw)
-               
-               # download completed, run the test
-               if not os.fork():
-                   # we are in the child
-                   os.chmod(testcase, 0755)
-                   os.execv(testcase, [testcase])
-                   sys.exit(0)
-               else:
-                   # we are in the parent, sleep to give time for the testcase to initialize
-                   # todo: is this needed, how to avoid possible race conditions
-                   time.sleep(1)
-       except Exception, e:
-           log.error("Exception %s while running Dogtail testcase" % e)
-
-    if opts.lang:
-        # this is lame, but make things match what we expect (#443408)
-        opts.lang = opts.lang.replace(".utf8", ".UTF-8")
-        anaconda.dispatch.skipStep("language", permanent = 1)
-        anaconda.instLanguage.instLang = opts.lang
-        anaconda.instLanguage.systemLang = opts.lang
-        anaconda.timezone.setTimezoneInfo(anaconda.instLanguage.getDefaultTimeZone(anaconda.rootPath))
-
-    if opts.keymap:
-        anaconda.dispatch.skipStep("keyboard", permanent = 1)
-        anaconda.keyboard.set(opts.keymap)
-        anaconda.keyboard.activate()
-
-    if anaconda.ksdata:
-        import storage
-        storage.storageInitialize(anaconda)
-
-        # Now having initialized storage, we can apply all the other kickstart
-        # commands.  This gives us the ability to check that storage commands
-        # are correctly formed and refer to actual devices.
-        anaconda.ksdata.execute()
-
-    # set up the headless case
-    if anaconda.isHeadless:
-        anaconda.dispatch.skipStep("keyboard", permanent = 1)
-
-    if not anaconda.ksdata:
-        anaconda.instClass.setSteps(anaconda)
-    else:
-        kickstart.setSteps(anaconda)
-
-    try:
-        anaconda.intf.run(anaconda)
-    except SystemExit, code:
-        anaconda.intf.shutdown()
-
-    if anaconda.ksdata and anaconda.ksdata.reboot.eject:
-        for drive in anaconda.storage.devicetree.devices:
-            if drive.type != "cdrom":
-                continue
-
-            log.info("attempting to eject %s" % drive.path)
-            drive.eject()
-
-    del anaconda.intf
-
-# vim:tw=78:ts=4:et:sw=4
diff --git a/anaconda.py b/anaconda.py
new file mode 100755
index 0000000..b5532b0
--- /dev/null
+++ b/anaconda.py
@@ -0,0 +1,932 @@
+#!/usr/bin/python
+#
+# anaconda: The Red Hat Linux Installation program
+#
+# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007
+# Red Hat, Inc.  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 as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# 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, see <http://www.gnu.org/licenses/>.
+#
+# Author(s): Brent Fox <bfox@xxxxxxxxxx>
+#            Mike Fulbright <msf@xxxxxxxxxx>
+#            Jakub Jelinek <jakub@xxxxxxxxxx>
+#            Jeremy Katz <katzj@xxxxxxxxxx>
+#            Chris Lumens <clumens@xxxxxxxxxx>
+#            Paul Nasrat <pnasrat@xxxxxxxxxx>
+#            Erik Troan <ewt@xxxxxxxxx>
+#            Matt Wilson <msw@xxxxxxxxx>
+#
+
+# This toplevel file is a little messy at the moment...
+
+import sys, os, re, time, subprocess
+from optparse import OptionParser
+from tempfile import mkstemp
+
+# keep up with process ID of the window manager if we start it
+wm_pid = None
+
+# Make sure messages sent through python's warnings module get logged.
+def AnacondaShowWarning(message, category, filename, lineno, file=sys.stderr, line=None):
+    log.warning("%s" % warnings.formatwarning(message, category, filename, lineno, line))
+
+def startMetacityWM():
+    childpid = os.fork()
+    if not childpid:
+        cmd = '/usr/bin/metacity'
+        if not os.access(cmd, os.X_OK):
+            log.error("Unable to find the window manager binary.")
+            sys.exit(1)
+        args = ['--display', ':1',
+                '--sm-disable']
+        rc = iutil.execWithRedirect(cmd, args, 
+                               stdout='/dev/null', stderr='/dev/null')
+        if rc:
+            log.error("Error running window manager.")
+            sys.exit (rc)
+        else:
+            log.info("The window manager has terminated.")
+            sys.exit(0)
+    return childpid
+
+def startAuditDaemon():
+    childpid = os.fork()
+    if not childpid:
+        cmd = '/sbin/auditd'
+        try:
+            os.execl(cmd, cmd)
+        except OSError as e:
+            log.error("Error running the audit daemon: %s" % str(e))
+        sys.exit(0)
+    # auditd will turn into a daemon so catch the immediate child pid now:
+    os.waitpid(childpid, 0)
+
+# function to handle X startup special issues for anaconda
+def doStartupX11Actions(runres="800x600"):
+    global wm_pid
+
+    setupGraphicalLinks()
+
+    # now start up the window manager
+    try:
+        wm_pid = startMetacityWM()
+        log.info("Starting window manager, pid %s." % (wm_pid,))
+    except Exception:
+        wm_pid = None
+        log.error("Unable to start the window manager.")
+
+    if wm_pid is not None:
+        import xutils
+        import gtk
+
+        try:
+            xutils.setRootResource('Xcursor.size', '24')
+            xutils.setRootResource('Xcursor.theme', 'Bluecurve')
+            xutils.setRootResource('Xcursor.theme_core', 'true')
+
+            xutils.setRootResource('Xft.antialias', '1')
+            xutils.setRootResource('Xft.hinting', '1')
+            xutils.setRootResource('Xft.hintstyle', 'hintslight')
+            xutils.setRootResource('Xft.rgba', 'none')
+        except:
+            sys.stderr.write("X SERVER STARTED, THEN FAILED");
+            raise RuntimeError, "X server failed to start"
+
+def doShutdownX11Actions():
+    global wm_pid
+    
+    if wm_pid is not None:
+        try:
+            os.kill(wm_pid, 15)
+            os.waitpid(wm_pid, 0)
+        except:
+            pass
+
+def setupPythonUpdates():
+    from distutils.sysconfig import get_python_lib
+
+    if not os.path.exists("/tmp/updates"):
+        return
+
+    for pkg in os.listdir("/tmp/updates"):
+        d = "/tmp/updates/%s" % pkg
+
+        if not os.path.isdir(d):
+            continue
+
+        # See if the package exists in /usr/lib{64,}/python/?.?/site-packages.
+        # If it does, we can set it up as an update.  If not, the pkg is
+        # likely a completely new directory and should not be looked at.
+        dest = "%s/%s" % (get_python_lib(), pkg)
+        if not os.access(dest, os.R_OK):
+            dest = "%s/%s" % (get_python_lib(1), pkg)
+            if not os.access(dest, os.R_OK):
+                continue
+
+        contents = os.listdir(d)
+
+        # Symlink over everything that's in the python libdir but not in
+        # the updates directory.
+        for f in filter(lambda fn: fn not in contents, os.listdir(dest)):
+            if f.endswith(".pyc") or f.endswith(".pyo"):
+                continue
+
+            os.symlink("%s/%s" % (dest, f), "/tmp/updates/%s/%s" % (pkg, f))
+
+
+    import glob
+    import shutil
+    for rule in glob.glob("/tmp/updates/*.rules"):
+        target = "/etc/udev/rules.d/" + rule.split('/')[-1]
+        shutil.copyfile(rule, target)
+
+def parseOptions(argv = None):
+    def resolution_cb (option, opt_str, value, parser):
+        parser.values.runres = value
+
+    op = OptionParser()
+    # Interface
+    op.add_option("-C", "--cmdline", dest="display_mode", action="store_const", const="c",
+                  default="g")
+    op.add_option("-G", "--graphical", dest="display_mode", action="store_const", const="g")
+    op.add_option("-T", "--text", dest="display_mode", action="store_const", const="t")
+
+    # Network
+    op.add_option("--noipv4", action="store_true", default=False)
+    op.add_option("--noipv6", action="store_true", default=False)
+    op.add_option("--proxy")
+    op.add_option("--proxyAuth")
+
+    # Method of operation
+    op.add_option("--autostep", action="store_true", default=False)
+    op.add_option("-d", "--debug", dest="debug", action="store_true", default=False)
+    op.add_option("--kickstart", dest="ksfile")
+    op.add_option("--rescue", dest="rescue", action="store_true", default=False)
+    op.add_option("--targetarch", dest="targetArch", nargs=1, type="string")
+
+    op.add_option("-m", "--method", dest="method", default=None)
+    op.add_option("--repo", dest="method", default=None)
+    op.add_option("--stage2", dest="stage2", default=None)
+
+    op.add_option("--liveinst", action="store_true", default=False)
+
+    # Display
+    op.add_option("--headless", dest="isHeadless", action="store_true", default=False)
+    op.add_option("--nofb")
+    op.add_option("--resolution", action="callback", callback=resolution_cb, dest="runres",
+                  default="800x600", nargs=1, type="string")
+    op.add_option("--serial", action="store_true", default=False)
+    op.add_option("--usefbx", dest="xdriver", action="store_const", const="fbdev")
+    op.add_option("--virtpconsole")
+    op.add_option("--vnc", action="store_true", default=False)
+    op.add_option("--vncconnect")
+    op.add_option("--xdriver", dest="xdriver", action="store", type="string", default=None)
+
+    # Language
+    op.add_option("--keymap")
+    op.add_option("--kbdtype")
+    op.add_option("--lang")
+
+    # Obvious
+    op.add_option("--loglevel")
+    op.add_option("--syslog")
+
+    op.add_option("--noselinux", dest="selinux", action="store_false", default=True)
+    op.add_option("--selinux", action="store_true")
+
+    op.add_option("--nompath", dest="mpath", action="store_false", default=True)
+    op.add_option("--mpath", action="store_true")
+
+    op.add_option("--nodmraid", dest="dmraid", action="store_false", default=True)
+    op.add_option("--dmraid", action="store_true")
+
+    op.add_option("--noibft", dest="ibft", action="store_false", default=True)
+    op.add_option("--ibft", action="store_true")
+    op.add_option("--noiscsi", dest="iscsi", action="store_false", default=False)
+    op.add_option("--iscsi", action="store_true")
+
+    # Miscellaneous
+    op.add_option("--module", action="append", default=[])
+    op.add_option("--nomount", dest="rescue_nomount", action="store_true", default=False)
+    op.add_option("--updates", dest="updateSrc", action="store", type="string")
+    op.add_option("--dogtail", dest="dogtail",   action="store", type="string")
+    op.add_option("--dlabel", action="store_true", default=False)
+
+    # Deprecated, unloved, unused
+    op.add_option("-r", "--rootPath", dest="unsupportedMode",
+                  action="store_const", const="root path")
+    op.add_option("-t", "--test", dest="unsupportedMode",
+                  action="store_const", const="test")
+
+    return op.parse_args(argv)
+
+def setupPythonPath():
+    haveUpdates = False
+    for ndx in range(len(sys.path)-1, -1, -1):
+        if sys.path[ndx].endswith('updates'):
+            haveUpdates = True
+            break
+
+    # With anaconda being a real module this isn't strictly necessary, but
+    # setting up the path now prevents having to change every import line in
+    # anaconda.
+    from distutils.sysconfig import get_python_lib
+    d = get_python_lib(plat_specific=1)
+
+    if haveUpdates:
+        sys.path.insert(ndx+1, "%s/pyanaconda" % d)
+        sys.path.insert(ndx+2, "%s/pyanaconda/textw" % d)
+        sys.path.insert(ndx+3, "%s/pyanaconda/iw" % d)
+    else:
+        sys.path.insert(0, "%s/pyanaconda" % d)
+        sys.path.insert(1, "%s/pyanaconda/textw" % d)
+        sys.path.insert(2, "%s/pyanaconda/iw" % d)
+
+    sys.path.append('/usr/share/system-config-date')
+
+def addPoPath(dir):
+    """ Looks to see what translations are under a given path and tells
+    the gettext module to use that path as the base dir """
+    for d in os.listdir(dir):
+        if not os.path.isdir("%s/%s" %(dir,d)):
+            continue
+        if not os.path.exists("%s/%s/LC_MESSAGES" %(dir,d)):
+            continue
+        for basename in os.listdir("%s/%s/LC_MESSAGES" %(dir,d)):
+            if not basename.endswith(".mo"):
+                continue
+            log.info("setting %s as translation source for %s" %(dir, basename[:-3]))
+            gettext.bindtextdomain(basename[:-3], dir)
+
+def setupTranslations():
+    if os.path.isdir("/tmp/updates/po"):
+        addPoPath("/tmp/updates/po")
+    gettext.textdomain("anaconda")
+
+def setupEnvironment():
+    # Silly GNOME stuff
+    if os.environ.has_key('HOME') and not os.environ.has_key("XAUTHORITY"):
+        os.environ['XAUTHORITY'] = os.environ['HOME'] + '/.Xauthority'
+    os.environ['HOME'] = '/tmp'
+    os.environ['LC_NUMERIC'] = 'C'
+    os.environ["GCONF_GLOBAL_LOCKS"] = "1"
+
+    # In theory, this gets rid of our LVM file descriptor warnings
+    os.environ["LVM_SUPPRESS_FD_WARNINGS"] = "1"
+
+    # make sure we have /sbin and /usr/sbin in our path
+    os.environ["PATH"] += ":/sbin:/usr/sbin"
+
+    # we can't let the LD_PRELOAD hang around because it will leak into
+    # rpm %post and the like.  ick :/
+    if os.environ.has_key("LD_PRELOAD"):
+        del os.environ["LD_PRELOAD"]
+
+    os.environ["GLADEPATH"] = "/tmp/updates/:/tmp/updates/ui/:ui/:/usr/share/anaconda/ui/:/usr/share/python-meh/"
+    os.environ["PIXMAPPATH"] = "/tmp/updates/pixmaps/:/tmp/updates/:/tmp/product/pixmaps/:/tmp/product/:pixmaps/:/usr/share/anaconda/pixmaps/:/usr/share/pixmaps/:/usr/share/anaconda/:/usr/share/python-meh/"
+
+def setupLoggingFromOpts(opts):
+    if opts.loglevel and anaconda_log.logLevelMap.has_key(opts.loglevel):
+        level = anaconda_log.logLevelMap[opts.loglevel]
+        anaconda_log.logger.tty_loglevel = level
+        anaconda_log.setHandlersLevel(log, level)
+        anaconda_log.setHandlersLevel(storage.storage_log.logger, level)
+
+    if opts.syslog:
+        anaconda_log.logger.remote_syslog = opts.syslog
+        if opts.syslog.find(":") != -1:
+            (host, port) = opts.syslog.split(":")
+            anaconda_log.logger.addSysLogHandler(log, host, port=int(port))
+        else:
+            anaconda_log.logger.addSysLogHandler(log, opts.syslog)
+
+# ftp installs pass the password via a file in /tmp so
+# ps doesn't show it
+def expandFTPMethod(str):
+    ret = None
+
+    try:
+        filename = str[1:]
+        ret = open(filename, "r").readline()
+        ret = ret[:len(ret) - 1]
+        os.unlink(filename)
+        return ret
+    except:
+        return None
+
+def runVNC():
+    global vncS
+    vncS.startServer()
+
+    child = os.fork()
+    if child == 0:
+        for p in ('/tmp/updates/pyrc.py', \
+                '/usr/share/anaconda/pyrc.py'):
+            if os.access(p, os.R_OK|os.X_OK):
+                os.environ['PYTHONSTARTUP'] = p
+                break
+
+        while True:
+            # s390/s390x are the only places we /really/ need a shell on tty1,
+            # and everywhere else this just gets in the way of pdb.  But we
+            # don't want to return, because that'll return try to start X
+            # a second time.
+            if iutil.isConsoleOnVirtualTerminal():
+                    time.sleep(10000)
+            else:
+                    print _("Press <enter> for a shell")
+                    sys.stdin.readline()
+                    iutil.execConsole()
+
+def within_available_memory(needed_ram):
+    # kernel binary code estimate that is
+    # not reported in MemTotal by /proc/meminfo:
+    epsilon = 15360 # 15 MB
+    return needed_ram < (iutil.memInstalled() + epsilon)
+
+def check_memory(anaconda, opts, display_mode=None):
+
+    if not display_mode:
+        display_mode = anaconda.displayMode
+
+    extra_ram = 0
+    reason = ''
+    if opts.stage2.startswith(('http', 'ftp', '@')):
+        extra_ram += isys.URL_INSTALL_EXTRA_RAM
+        reason = " using this install method"
+
+    needed_ram = isys.MIN_RAM + extra_ram
+    if not within_available_memory(needed_ram):
+        from snack import SnackScreen, ButtonChoiceWindow
+        screen = SnackScreen()
+        ButtonChoiceWindow(screen, _('Fatal Error'),
+                            _('You do not have enough RAM to install %s '
+                              'on this machine%s.\n'
+                              '\n'
+                              'Press <return> to reboot your system.\n')
+                           %(product.productName, reason),
+                           buttons = (_("OK"),))
+        screen.finish()
+        sys.exit(0)
+
+    # override display mode if machine cannot nicely run X
+    if display_mode not in ('t', 'c') and not flags.usevnc:
+        needed_ram = isys.MIN_GUI_RAM + extra_ram
+
+        if not within_available_memory(needed_ram):
+            complain = _("You do not have enough RAM to use the graphical "
+                         "installer.")
+            if flags.livecdInstall:
+                stdoutLog.warning(complain)
+                recommendation = _("Try the text mode installer by running:\n\n"
+                                   "'/usr/bin/liveinst -T'\n\n from a root "
+                                   "terminal.")
+                title = _("Not enough RAM")
+                text = "%s %s" %(complain, recommendation)
+                import gtk
+                dialog = gtk.MessageDialog(type = gtk.MESSAGE_ERROR, 
+                                           buttons = gtk.BUTTONS_CLOSE,
+                                           message_format=text)
+                dialog.set_title(title)
+                dialog.run()
+                sys.exit(1)
+            else:
+                resolution = _("Starting text mode.")
+                stdoutLog.warning("%s %s" % (complain, resolution))
+                anaconda.displayMode = 't'
+                time.sleep(2)
+
+def setupGraphicalLinks():
+    for i in ( "imrc", "im_palette.pal", "gtk-2.0", "pango", "fonts",
+               "fb.modes"):
+        try:
+            if os.path.exists("/mnt/runtime/etc/%s" %(i,)):
+                os.symlink ("../mnt/runtime/etc/" + i, "/etc/" + i)
+        except:
+            pass
+
+def handleSshPw(anaconda):
+    if not anaconda.ksdata:
+        return
+
+    import users
+    u = users.Users(anaconda)
+
+    userdata = anaconda.ksdata.sshpw.dataList()
+    for ud in userdata:
+        if u.checkUserExists(ud.username, root="/"):
+            u.setUserPassword(username=ud.username, password=ud.password,
+                              isCrypted=ud.isCrypted, lock=ud.lock)
+        else:
+            u.createUser(name=ud.username, password=ud.password,
+                         isCrypted=ud.isCrypted, lock=ud.lock,
+                         root="/")
+
+    del u
+
+def createSshKey(algorithm, keyfile):
+    path = '/etc/ssh/%s' % (keyfile,)
+    argv = ['-q','-t',algorithm,'-f',path,'-C','','-N','']
+    log.info("running \"%s\"" % (" ".join(['ssh-keygen']+argv),))
+
+    so = "/tmp/ssh-keygen-%s-stdout.log" % (algorithm,)
+    se = "/tmp/ssh-keygen-%s-stderr.log" % (algorithm,)
+    iutil.execWithRedirect('ssh-keygen', argv, stdout=so, stderr=se)
+
+def fork_orphan():
+    """Forks an orphan.
+    
+    Returns 1 in the parent and 0 in the orphaned child.
+    """
+    intermediate = os.fork()
+    if not intermediate:
+        if os.fork():
+            # the intermediate child dies
+            os._exit(0)
+        return 0;
+    # the original process waits for the intermediate child
+    os.waitpid(intermediate, 0)
+    return 1
+
+def startSsh():
+    if iutil.isS390():
+        return
+
+    if not fork_orphan():
+        os.mkdir("/var/log", 0755)
+        os.open("/var/log/lastlog", os.O_RDWR | os.O_CREAT, 0644)
+        ssh_keys = {
+            'rsa1':'ssh_host_key',
+            'rsa':'ssh_host_rsa_key',
+            'dsa':'ssh_host_dsa_key',
+            }
+        for (algorithm, keyfile) in ssh_keys.items():
+            createSshKey(algorithm, keyfile)
+        args = ["/sbin/sshd", "-f", "/etc/ssh/sshd_config.anaconda"]
+        os.execv("/sbin/sshd", args)
+        sys.exit(1)
+
+def startDebugger(signum, frame):
+    import epdb
+    epdb.serve(skip=1)
+
+if __name__ == "__main__":
+    setupPythonPath()
+
+    # Allow a file to be loaded as early as possible
+    try:
+        import updates_disk_hook
+    except ImportError:
+        pass
+
+    # Set up logging as early as possible.
+    import logging
+    import anaconda_log
+    anaconda_log.init()
+
+    log = logging.getLogger("anaconda")
+    stdoutLog = logging.getLogger("anaconda.stdout")
+
+    if os.geteuid() != 0:
+        stdoutLog.error("anaconda must be run as root.")
+        sys.exit(0)
+
+    # pull this in to get product name and versioning
+    import product
+
+    # this handles setting up updates for pypackages to minimize the set needed
+    setupPythonUpdates()
+
+    import isys
+    isys.initLog()
+
+    import signal, string, iutil, time
+    import warnings
+    import vnc
+    import users
+    import kickstart
+    import storage.storage_log
+
+    from flags import flags
+
+    # the following makes me very sad. -- katzj
+    # we have a slightly different set of udev rules in the second 
+    # stage than the first stage.  why this doesn't get picked up
+    # automatically, I don't know.  but we need to trigger so that we
+    # have all the information about netdevs that we care about for 
+    # NetworkManager in the udev database
+    from baseudev import udev_trigger, udev_settle
+    udev_trigger("net")
+    udev_settle()
+    # and for added fun, once doesn't seem to be enough?  so we 
+    # do it twice, it works and we scream at the world "OH WHY?"
+    udev_trigger("net")
+    udev_settle()
+
+    import gettext
+    _ = lambda x: gettext.ldgettext("anaconda", x)
+
+    from pyanaconda import Anaconda
+    anaconda = Anaconda()
+    warnings.showwarning = AnacondaShowWarning
+    setupTranslations()
+
+    # reset python's default SIGINT handler
+    signal.signal(signal.SIGINT, signal.SIG_DFL)
+    signal.signal(signal.SIGSEGV, isys.handleSegv)
+
+    setupEnvironment()
+
+    pidfile = open("/var/run/anaconda.pid", "w")
+    pidfile.write("%s\n" % (os.getpid(),))
+    del pidfile
+    # add our own additional signal handlers
+    signal.signal(signal.SIGHUP, startDebugger)
+
+    # we need to do this really early so we make sure its done before rpm
+    # is imported
+    iutil.writeRpmPlatform()
+
+    graphical_failed = 0
+    vncS = vnc.VncServer()          # The vnc Server object.
+    vncS.anaconda = anaconda
+    xserver_pid = None
+
+    (opts, args) = parseOptions()
+
+    # check memory, just the text mode for now:
+    check_memory(anaconda, opts, 't')
+
+    if opts.unsupportedMode:
+        stdoutLog.error("Running anaconda in %s mode is no longer supported." % opts.unsupportedMode)
+        sys.exit(0)
+
+    # Now that we've got arguments, do some extra processing.
+    setupLoggingFromOpts(opts)
+
+    # Default is to prompt to mount the installed system.
+    anaconda.rescue_mount = not opts.rescue_nomount
+
+    if opts.dlabel: #autodetected driverdisc in use
+        flags.dlabel = True
+
+    anaconda.displayMode = opts.display_mode
+    anaconda.isHeadless = opts.isHeadless
+
+    if opts.noipv4:
+        flags.useIPv4 = False
+
+    if opts.noipv6:
+        flags.useIPv6 = False
+
+    if opts.proxy:
+        anaconda.proxy = opts.proxy
+
+        if opts.proxyAuth:
+            filename = opts.proxyAuth
+            ret = open(filename, "r").readlines()
+            os.unlink(filename)
+
+            anaconda.proxyUsername = ret[0].rstrip()
+            if len(ret) == 2:
+                anaconda.proxyPassword = ret[1].rstrip()
+
+    if opts.updateSrc:
+        anaconda.updateSrc = opts.updateSrc
+
+    if opts.method:
+        if opts.method[0] == '@':
+            opts.method = expandFTPMethod(opts.method)
+
+        anaconda.setMethodstr(opts.method)
+    else:
+        anaconda.methodstr = None
+
+    if opts.stage2:
+        if opts.stage2[0] == '@':
+            opts.stage2 = expandFTPMethod(opts.stage2)
+
+        anaconda.stage2 = opts.stage2
+
+    if opts.liveinst:
+        flags.livecdInstall = True
+
+    if opts.module:
+        for mod in opts.module:
+            (path, name) = string.split(mod, ":")
+            anaconda.extraModules.append((path, name))
+
+    if opts.vnc:
+        flags.usevnc = 1
+        anaconda.displayMode = 'g'
+        vncS.recoverVNCPassword()
+
+        # Only consider vncconnect when vnc is a param
+        if opts.vncconnect:
+            cargs = string.split(opts.vncconnect, ":")
+            vncS.vncconnecthost = cargs[0]
+            if len(cargs) > 1 and len(cargs[1]) > 0:
+                if len(cargs[1]) > 0:
+                    vncS.vncconnectport = cargs[1]
+
+    if opts.ibft:
+        flags.ibft = 1
+
+    if opts.iscsi:
+        flags.iscsi = 1
+
+    if opts.targetArch:
+        flags.targetarch = opts.targetArch
+
+    # set flags 
+    flags.dmraid = opts.dmraid
+    flags.mpath = opts.mpath
+    flags.selinux = opts.selinux
+
+    if opts.serial:
+        flags.serial = True
+    if opts.virtpconsole:
+        flags.virtpconsole = opts.virtpconsole
+
+    if opts.xdriver:
+        anaconda.xdriver = opts.xdriver
+        anaconda.writeXdriver(root="/")
+
+    if not flags.livecdInstall:
+        startAuditDaemon()
+
+    # setup links required for all install types
+    for i in ( "services", "protocols", "nsswitch.conf", "joe", "selinux",
+               "mke2fs.conf" ):
+        try:
+            if os.path.exists("/mnt/runtime/etc/" + i):
+                os.symlink ("../mnt/runtime/etc/" + i, "/etc/" + i)
+        except:
+            pass
+
+    # This is the one place we do all kickstart file parsing.
+    if opts.ksfile:
+        kickstart.preScriptPass(anaconda, opts.ksfile)
+        anaconda.ksdata = kickstart.parseKickstart(anaconda, opts.ksfile)
+        opts.rescue = anaconda.ksdata.rescue.rescue
+
+    if flags.sshd:
+        # we need to have a libuser.conf that points to the installer root for
+        # sshpw, but after that we start sshd, we need one that points to the
+        # install target.
+        luserConf = users.createLuserConf(instPath="")
+        handleSshPw(anaconda)
+        startSsh()
+        del(os.environ["LIBUSER_CONF"])
+
+    users.createLuserConf(anaconda.rootPath)
+
+    if opts.rescue:
+        anaconda.rescue = True
+
+        import rescue
+
+        if anaconda.ksdata:
+            anaconda.instClass.configure(anaconda)
+
+            # We need an interface before running kickstart execute methods for
+            # storage.
+            from snack import *
+            screen = SnackScreen()
+            anaconda.intf = rescue.RescueInterface(screen)
+
+            anaconda.ksdata.execute()
+
+            anaconda.intf = None
+            screen.finish()
+
+            # command line 'nomount' overrides kickstart /same for vnc/
+            anaconda.rescue_mount = not (opts.rescue_nomount or anaconda.ksdata.rescue.nomount)
+
+        rescue.runRescue(anaconda)
+
+        # shouldn't get back here
+        sys.exit(1)
+
+    if anaconda.ksdata:
+        if anaconda.ksdata.vnc.enabled:
+            flags.usevnc = 1
+            anaconda.displayMode = 'g'
+
+            if vncS.password == "":
+                vncS.password = anaconda.ksdata.vnc.password
+
+            if vncS.vncconnecthost == "":
+                vncS.vncconnecthost = anaconda.ksdata.vnc.host
+
+            if vncS.vncconnectport == "":
+                vncS.vncconnectport = anaconda.ksdata.vnc.port
+
+        flags.vncquestion = False
+
+    # disable VNC over text question when not enough memory is available
+    if iutil.memInstalled() < isys.MIN_GUI_RAM:
+        flags.vncquestion = False
+
+    if os.environ.has_key('DISPLAY'):
+        flags.preexisting_x11 = True
+
+    if anaconda.displayMode == 't' and flags.vncquestion: #we prefer vnc over text mode, so ask about that
+        title = _("Would you like to use VNC?")
+        message = _("Text mode provides a limited set of installation options.  "
+                    "It does not allow you to specify your own partitioning "
+                    "layout or package selections.  Would you like to use VNC "
+                    "mode instead?")
+
+        ret = vnc.askVncWindow(title, message)
+        if ret != -1:
+            anaconda.displayMode = 'g'
+            flags.usevnc = 1
+            if ret is not None:
+                vncS.password = ret
+
+    if opts.debug:
+        flags.debug = True
+
+    log.info("anaconda called with cmdline = %s" %(sys.argv,))
+    log.info("Display mode = %s" % anaconda.displayMode)
+    log.info("Default encoding = %s " % sys.getdefaultencoding())
+
+    check_memory(anaconda, opts)
+
+    #
+    # now determine if we're going to run in GUI or TUI mode
+    #
+    # if no X server, we have to use text mode
+    if not flags.livecdInstall and not iutil.isS390() and not os.access("/usr/bin/Xorg", os.X_OK):
+         stdoutLog.warning(_("Graphical installation is not available. "
+                             "Starting text mode."))
+         time.sleep(2)
+         anaconda.displayMode = 't'
+
+    # s390/iSeries checks
+    if anaconda.isHeadless and anaconda.displayMode == "g" and not \
+       (flags.preexisting_x11 or flags.usevnc):
+        stdoutLog.warning(_("DISPLAY variable not set. Starting text mode."))
+        anaconda.displayMode = 't'
+        graphical_failed = 1
+        time.sleep(2)
+
+    # if DISPLAY not set either vnc server failed to start or we're not
+    # running on a redirected X display, so start local X server
+    if anaconda.displayMode == 'g' and not flags.preexisting_x11 and not flags.usevnc:
+        try:
+            # The following code depends on no SIGCHLD being delivered, possibly
+            # only except the one from a failing X.org. Thus make sure before
+            # entering this section that all the other children of anaconda have
+            # terminated or were forked into an orphan (which won't deliver a
+            # SIGCHLD to mess up the fragile signaling below).
+
+            # start X with its USR1 handler set to ignore.  this will make it send
+            # us SIGUSR1 if it succeeds.  if it fails, catch SIGCHLD and bomb out.
+
+            def sigchld_handler(num, frame):
+                raise OSError
+
+            def sigusr1_handler(num, frame):
+                pass
+
+            def preexec_fn():
+                signal.signal(signal.SIGUSR1, signal.SIG_IGN)
+
+            old_sigusr1 = signal.signal(signal.SIGUSR1, sigusr1_handler)
+            old_sigchld = signal.signal(signal.SIGCHLD, sigchld_handler)
+            xout = open("/dev/tty5", "w")
+
+            proc = subprocess.Popen(["Xorg", "-br", "-logfile", "/tmp/X.log",
+                                     ":1", "vt6", "-s", "1440", "-ac",
+                                     "-nolisten", "tcp", "-dpi", "96"],
+                                     close_fds=True, stdout=xout, stderr=xout,
+                                     preexec_fn=preexec_fn)
+
+            signal.pause()
+
+            os.environ["DISPLAY"] = ":1"
+            doStartupX11Actions(opts.runres)
+            xserver_pid = proc.pid
+        except (OSError, RuntimeError):
+            stdoutLog.warning(" X startup failed, falling back to text mode")
+            anaconda.displayMode = 't'
+            graphical_failed = 1
+            time.sleep(2)
+        finally:
+            signal.signal(signal.SIGUSR1, old_sigusr1)
+            signal.signal(signal.SIGCHLD, old_sigchld)
+
+    if anaconda.displayMode == 't' and graphical_failed and not anaconda.ksdata:
+        ret = vnc.askVncWindow()
+        if ret != -1:
+            anaconda.displayMode = 'g'
+            flags.usevnc = 1
+            if ret is not None:
+                vncS.password = ret
+
+    # if they want us to use VNC do that now
+    if anaconda.displayMode == 'g' and flags.usevnc:
+        runVNC()
+        doStartupX11Actions(opts.runres)
+
+    # with X running we can initialize the UI interface
+    anaconda.initInterface()
+    anaconda.instClass.configure(anaconda)
+
+    # comment out the next line to make exceptions non-fatal
+    from exception import initExceptionHandling
+    anaconda.mehConfig = initExceptionHandling(anaconda)
+
+    # add our own additional signal handlers
+    signal.signal(signal.SIGUSR2, lambda signum, frame: anaconda.dumpState())
+
+    # download and run Dogtail script
+    if opts.dogtail:
+       try:
+           import urlgrabber
+
+           try:
+               fr = urlgrabber.urlopen(opts.dogtail)
+           except urlgrabber.grabber.URLGrabError, e:
+               log.error("Could not retrieve Dogtail script from %s.\nError was\n%s" % (opts.dogtail, e))
+               fr = None
+                           
+           if fr:
+               (fw, testcase) = mkstemp(prefix='testcase.py.', dir='/tmp')
+               os.write(fw, fr.read())
+               fr.close()
+               os.close(fw)
+               
+               # download completed, run the test
+               if not os.fork():
+                   # we are in the child
+                   os.chmod(testcase, 0755)
+                   os.execv(testcase, [testcase])
+                   sys.exit(0)
+               else:
+                   # we are in the parent, sleep to give time for the testcase to initialize
+                   # todo: is this needed, how to avoid possible race conditions
+                   time.sleep(1)
+       except Exception, e:
+           log.error("Exception %s while running Dogtail testcase" % e)
+
+    if opts.lang:
+        # this is lame, but make things match what we expect (#443408)
+        opts.lang = opts.lang.replace(".utf8", ".UTF-8")
+        anaconda.dispatch.skipStep("language", permanent = 1)
+        anaconda.instLanguage.instLang = opts.lang
+        anaconda.instLanguage.systemLang = opts.lang
+        anaconda.timezone.setTimezoneInfo(anaconda.instLanguage.getDefaultTimeZone(anaconda.rootPath))
+
+    if opts.keymap:
+        anaconda.dispatch.skipStep("keyboard", permanent = 1)
+        anaconda.keyboard.set(opts.keymap)
+        anaconda.keyboard.activate()
+
+    if anaconda.ksdata:
+        import storage
+        storage.storageInitialize(anaconda)
+
+        # Now having initialized storage, we can apply all the other kickstart
+        # commands.  This gives us the ability to check that storage commands
+        # are correctly formed and refer to actual devices.
+        anaconda.ksdata.execute()
+
+    # set up the headless case
+    if anaconda.isHeadless:
+        anaconda.dispatch.skipStep("keyboard", permanent = 1)
+
+    if not anaconda.ksdata:
+        anaconda.instClass.setSteps(anaconda)
+    else:
+        kickstart.setSteps(anaconda)
+
+    try:
+        anaconda.intf.run(anaconda)
+    except SystemExit, code:
+        anaconda.intf.shutdown()
+
+    if anaconda.ksdata and anaconda.ksdata.reboot.eject:
+        for drive in anaconda.storage.devicetree.devices:
+            if drive.type != "cdrom":
+                continue
+
+            log.info("attempting to eject %s" % drive.path)
+            drive.eject()
+
+    del anaconda.intf
+
+# vim:tw=78:ts=4:et:sw=4
diff --git a/anaconda_log.py b/anaconda_log.py
deleted file mode 100644
index 961cba1..0000000
--- a/anaconda_log.py
+++ /dev/null
@@ -1,170 +0,0 @@
-#
-# anaconda_log.py: Support for logging to multiple destinations with log
-# levels.
-#
-# Copyright (C) 2000, 2001, 2002, 2005  Red Hat, Inc.  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 as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# 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, see <http://www.gnu.org/licenses/>.
-#
-# Author(s): Chris Lumens <clumens@xxxxxxxxxx>
-#            Matt Wilson <msw@xxxxxxxxxx>
-#            Michael Fulbright <msf@xxxxxxxxxx>
-#
-
-import os
-import signal
-import sys
-import logging
-from logging.handlers import SysLogHandler, SYSLOG_UDP_PORT
-import types
-
-import iutil
-
-DEFAULT_TTY_LEVEL = logging.INFO
-ENTRY_FORMAT = "%(asctime)s,%(msecs)03d %(levelname)s %(name)s: %(message)s"
-TTY_FORMAT = "%(levelname)s %(name)s: %(message)s"
-STDOUT_FORMAT = "%(asctime)s %(message)s"
-DATE_FORMAT = "%H:%M:%S"
-
-MAIN_LOG_FILE = "/tmp/anaconda.log"
-MAIN_LOG_TTY = "/dev/tty3"
-PROGRAM_LOG_FILE = "/tmp/program.log"
-ANACONDA_SYSLOG_FACILITY = SysLogHandler.LOG_LOCAL1
-
-logLevelMap = {"debug": logging.DEBUG, "info": logging.INFO,
-               "warning": logging.WARNING, "error": logging.ERROR,
-               "critical": logging.CRITICAL}
-
-# sets autoSetLevel for the given handler
-def autoSetLevel(handler, value):
-    handler.autoSetLevel = value
-
-# all handlers of given logger with autoSetLevel == True are set to level
-def setHandlersLevel(logger, level):
-    map(lambda hdlr: hdlr.setLevel(level),
-        filter (lambda hdlr: hasattr(hdlr, "autoSetLevel") and hdlr.autoSetLevel, logger.handlers))
-
-class AnacondaSyslogHandler(SysLogHandler):
-    def __init__(self, 
-                 address=('localhost', SYSLOG_UDP_PORT),
-                 facility=SysLogHandler.LOG_USER, 
-                 tag=''):
-        self.tag = tag
-        SysLogHandler.__init__(self, address, facility)
-
-    def emit(self, record):
-        original_msg = record.msg
-        record.msg = '%s: %s' %(self.tag, original_msg)
-        SysLogHandler.emit(self, record)
-        record.msg = original_msg
-
-class AnacondaLog:
-    def __init__ (self):
-        self.tty_loglevel = DEFAULT_TTY_LEVEL
-        self.remote_syslog = None
-        # Create the base of the logger hierarcy.
-        logger = logging.getLogger("anaconda")
-        logger.setLevel(logging.DEBUG)
-        self.addFileHandler(MAIN_LOG_FILE, logger,
-                            minLevel=logging.DEBUG)
-        self.forwardToSyslog(logger)
-        # Log to tty3.
-        if not iutil.isS390() and os.access(MAIN_LOG_TTY, os.W_OK):
-            self.addFileHandler(MAIN_LOG_TTY, logger,
-                                fmtStr=TTY_FORMAT,
-                                autoLevel=True)
-
-        # External program output log
-        program_logger = logging.getLogger("program")
-        program_logger.setLevel(logging.DEBUG)
-        self.addFileHandler(PROGRAM_LOG_FILE, program_logger,
-                            minLevel=logging.DEBUG)
-        self.forwardToSyslog(program_logger)
-
-        # Create a second logger for just the stuff we want to dup on
-        # stdout.  Anything written here will also get passed up to the
-        # parent loggers for processing and possibly be written to the
-        # log.
-        stdoutLogger = logging.getLogger("anaconda.stdout")
-        stdoutLogger.setLevel(logging.INFO)
-        # Add a handler for the duped stuff.  No fancy formatting, thanks.
-        self.addFileHandler(sys.stdout, stdoutLogger,
-                            fmtStr=STDOUT_FORMAT, minLevel=logging.INFO)
-
-        # Stderr logger
-        stderrLogger = logging.getLogger("anaconda.stderr")
-        stderrLogger.setLevel(logging.INFO)
-        self.addFileHandler(sys.stderr, stderrLogger,
-                            fmtStr=STDOUT_FORMAT, minLevel=logging.INFO)
-
-    # Add a simple handler - file or stream, depending on what we're given.
-    def addFileHandler (self, file, addToLogger, minLevel=DEFAULT_TTY_LEVEL,
-                        fmtStr=ENTRY_FORMAT,
-                        autoLevel=False):
-        if isinstance(file, types.StringTypes):
-            logfileHandler = logging.FileHandler(file)
-        else:
-            logfileHandler = logging.StreamHandler(file)
-
-        logfileHandler.setLevel(minLevel)
-        logfileHandler.setFormatter(logging.Formatter(fmtStr, DATE_FORMAT))
-        autoSetLevel(logfileHandler, autoLevel)
-        addToLogger.addHandler(logfileHandler)
-
-    # Add another logger to the hierarchy.  For best results, make sure
-    # name falls under anaconda in the tree.
-    def addLogger (self, name, minLevel=DEFAULT_TTY_LEVEL):
-        newLogger = logging.getLogger(name)
-        newLogger.setLevel(minLevel)
-
-    # Add a handler for remote syslogs.
-    def addSysLogHandler (self, logger, host, port=SYSLOG_UDP_PORT,
-                          minLevel=DEFAULT_TTY_LEVEL):
-        fmt = logging.Formatter("%(levelname)-8s %(message)s")
-        syslogHandler = SysLogHandler((host, port))
-        syslogHandler.setLevel(minLevel)
-        syslogHandler.setFormatter(fmt)
-        logger.addHandler(syslogHandler)
-
-    def forwardToSyslog(self, logger):
-        """Forward everything that goes in the logger to the syslog daemon.
-        """
-        syslogHandler = AnacondaSyslogHandler(
-            '/dev/log', 
-            ANACONDA_SYSLOG_FACILITY,
-            logger.name)
-        syslogHandler.setLevel(logging.DEBUG)
-        logger.addHandler(syslogHandler)
-
-    def updateRemote(self, remote_syslog):
-        """Updates the location of remote rsyslogd to forward to.
-
-        Requires updating rsyslogd config and sending SIGHUP to the daemon.
-        """
-        PIDFILE  = "/var/run/syslogd.pid"
-        CFGFILE  = "/etc/rsyslog.conf"
-        TEMPLATE = "*.* @@%s\n"
-
-        self.remote_syslog = remote_syslog
-        with open(CFGFILE, 'a') as cfgfile:
-            forward_line = TEMPLATE % remote_syslog
-            cfgfile.write(forward_line)
-        with open(PIDFILE, 'r') as pidfile:
-            pid = int(pidfile.read())
-            os.kill(pid, signal.SIGHUP)
-
-logger = None
-def init():
-    global logger
-    logger = AnacondaLog()
diff --git a/backend.py b/backend.py
deleted file mode 100644
index 217fa55..0000000
--- a/backend.py
+++ /dev/null
@@ -1,301 +0,0 @@
-#
-# backend.py: Interface for installation backends
-#
-# Copyright (C) 2005, 2006, 2007  Red Hat, Inc.  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 as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# 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, see <http://www.gnu.org/licenses/>.
-#
-# Author(s): Paul Nasrat <pnasrat@xxxxxxxxxx>
-#            Jeremy Katz <katzj@xxxxxxxxxx>
-#
-
-import glob
-import shutil
-import iutil
-import os, sys
-import logging
-import backend_log
-from constants import *
-
-import isys
-import kickstart
-import packages
-import storage
-
-from flags import flags
-log = logging.getLogger("anaconda")
-
-import gettext
-_ = lambda x: gettext.ldgettext("anaconda", x)
-
-class AnacondaBackend:
-    def __init__(self, anaconda):
-        """Abstract backend class all backends should inherit from this
-           @param instPath: root path for the installation to occur"""
-        self.anaconda = anaconda
-        self.instPath = anaconda.rootPath
-        self.instLog = None
-        self.modeText = ""
-
-        # some backends may not support upgrading
-        self.supportsUpgrades = True
-        self.supportsPackageSelection = False
-
-        # some backends may have a special case for rootfs formatting
-        # FIXME: we should handle this a little more elegantly
-        self.skipFormatRoot = False
-        self.rootFsType = None
-
-        self._loopbackFile = None
-
-    def postAction(self, anaconda):
-        pass
-
-    def doPreSelection(self, intf, id, instPath):
-        pass
-
-    def doPostSelection(self, anaconda):
-        pass
-
-    def doPreInstall(self, anaconda):
-        self.initLog(anaconda.rootPath)
-
-    def copyFirmware(self, anaconda):
-        # Multiple driver disks may be loaded, so we need to glob for all
-        # the firmware files in the common DD firmware directory
-        for f in glob.glob(DD_EXTRACTED+"/lib/firmware/*"):
-            try:
-                shutil.copyfile(f, "%s/lib/firmware/" % anaconda.rootPath)
-            except IOError, e:
-                log.error("Could not copy firmware file %s: %s" % (f, e.strerror))
-
-    def doPostInstall(self, anaconda):
-        #always copy the firmware files from DD
-        self.copyFirmware(anaconda)
-
-        if anaconda.extraModules:
-            for (n, arch, tag) in self.kernelVersionList(anaconda.rootPath):
-                packages.recreateInitrd(n, anaconda.rootPath)
-
-        #copy RPMS
-        for d in glob.glob(DD_RPMS):
-            shutil.copytree(d, anaconda.rootPath + "/root/" + os.path.basename(d))
-
-        #copy modules and firmware
-        if os.path.exists(DD_EXTRACTED):
-            try:
-                shutil.copytree(DD_EXTRACTED, anaconda.rootPath + "/root/DD")
-            except IOError, e:
-                pass
-
-        storage.writeEscrowPackets(anaconda)
-        sys.stdout.flush()
-        backend_log.log.stop()
-
-    def doInstall(self, anaconda):
-        log.warning("doInstall not implemented for backend!")
-        raise NotImplementedError
-
-    def initLog(self, instPath):
-        if not os.path.isdir(instPath + "/root"):
-            iutil.mkdirChain(instPath + "/root")
-
-        if self.anaconda.upgrade:
-            logname = '/root/upgrade.log'
-        else:
-            logname = '/root/install.log'
-
-        instLogName = instPath + logname
-        try:
-            shutil.rmtree (instLogName)
-        except OSError:
-            pass
-
-        self.instLog = open(instLogName, "w+")
-
-        syslogname = "%s%s.syslog" % (instPath, logname)
-        try:
-            shutil.rmtree (syslogname)
-        except OSError:
-            pass
-        backend_log.log.start(instPath, syslogname)
-
-        if self.anaconda.upgrade:
-            self.modeText = _("Upgrading %s\n")
-        else:
-            self.modeText = _("Installing %s\n")
-
-    def mountInstallImage(self, anaconda, installimg):
-        if self._loopbackFile and os.path.exists(self._loopbackFile):
-            return
-
-        # Copy the install.img to the filesystem and switch loopback devices
-        # to there.  Otherwise we won't be able to unmount and swap media.
-        free = anaconda.storage.fsFreeSpace
-        self._loopbackFile = "%s%s/rhinstall-install.img" % (anaconda.rootPath,
-                                                             free[-1][0])
-        try:
-            log.info("transferring install image to install target")
-            win = anaconda.intf.waitWindow(_("Copying File"),
-                    _("Transferring install image to hard drive"))
-            shutil.copyfile(installimg, self._loopbackFile)
-            win.pop()
-        except Exception, e:
-            if win:
-                win.pop()
-
-            log.critical("error transferring install.img: %s" %(e,))
-
-            if isinstance(e, IOError) and e.errno == 5:
-                msg = _("An error occurred transferring the install image "
-                        "to your hard drive.  This is often cause by "
-                        "damaged or low quality media.")
-            else:
-                msg = _("An error occurred transferring the install image "
-                        "to your hard drive. You are probably out of disk "
-                        "space.")
-
-            anaconda.intf.messageWindow(_("Error"), msg)
-            try:
-                os.unlink(self._loopbackFile)
-            except:
-                pass
-
-            return 1
-
-        isys.lochangefd("/dev/loop0", self._loopbackFile)
-        if os.path.ismount("/mnt/stage2"):
-            isys.umount("/mnt/stage2")
-
-    def removeInstallImage(self):
-        if self._loopbackFile:
-            try:
-                os.unlink(self._loopbackFile)
-            except SystemError:
-                pass
-   
-    def freetmp(self, anaconda):
-    # installs that don't use /mnt/stage2 hold the install.img on
-    # a tmpfs, free this ram if things are tight.
-        stage2img = "/tmp/install.img"
-        if os.path.exists(stage2img):
-            # free up /tmp for more memory before yum is called,
-            if self.mountInstallImage(anaconda, stage2img):
-               	return DISPATCH_BACK
-            try:
-                os.unlink(stage2img)
-            except SystemError:
-                log.info("clearing /tmp failed")
-                return DISPATCH_BACK
-
-    def kernelVersionList(self, rootPath="/"):
-        return []
-
-    def getMinimumSizeMB(self, part):
-        """Return the minimal size for part in megabytes if we can."""
-        return 0
-
-    def doBackendSetup(self, anaconda):
-        log.warning("doBackendSetup not implemented for backend!")
-        raise NotImplementedError
-
-    def groupExists(self, group):
-        log.warning("groupExists not implemented for backend!")
-        raise NotImplementedError
-
-    def selectGroup(self, group, *args):
-        log.warning("selectGroup not implemented for backend!")
-        raise NotImplementedError
-
-    def deselectGroup(self, group, *args):
-        log.warning("deselectGroup not implemented for backend!")
-        raise NotImplementedError
-
-    def packageExists(self, pkg):
-        log.warning("packageExists not implemented for backend!")
-        raise NotImplementedError
-    
-    def selectPackage(self, pkg, *args):
-        log.warning("selectPackage not implemented for backend!")
-        raise NotImplementedError
-
-    def deselectPackage(self, pkg, *args):
-        log.warning("deselectPackage not implemented for backend!")
-        raise NotImplementedError
-
-    def getDefaultGroups(self, anaconda):
-        log.warning("getDefaultGroups not implemented for backend!")
-        raise NotImplementedError
-
-    def resetPackageSelections(self):
-        # we just leave this one unimplemented if it's not needed
-        pass
-
-    # write out the %packages section of anaconda-ks.cfg
-    def writePackagesKS(self, f, anaconda):
-        log.warning("writePackagesKS not implemented for backend!")
-        raise NotImplementedError
-
-    # write out any config files that live on the installed system
-    # (e.g., /etc/yum.repos.d/* files)
-    def writeConfiguration(self):
-        log.warning("writeConfig not implemented for backend!")
-        raise NotImplementedError
-
-    # write out any other kickstart bits the backend requires - no warning
-    # here because this may not be needed
-    def writeKS(self, f):
-        pass
-
-    def getRequiredMedia(self):
-        log.warning("getRequiredMedia not implmented for backend!")
-        raise NotImplementedError
-
-    def complete(self, anaconda):
-        pass
-
-def doBackendSetup(anaconda):
-    if anaconda.backend.doBackendSetup(anaconda) == DISPATCH_BACK:
-        return DISPATCH_BACK
-
-    if anaconda.upgrade:
-        anaconda.backend.checkSupportedUpgrade(anaconda)
-        iutil.writeRpmPlatform(anaconda.rootPath)
-
-def doPostSelection(anaconda):
-    return anaconda.backend.doPostSelection(anaconda)
-
-def doPreInstall(anaconda):
-    anaconda.backend.doPreInstall(anaconda)
-
-def doPostInstall(anaconda):
-    anaconda.backend.doPostInstall(anaconda)
-
-def doInstall(anaconda):
-    return anaconda.backend.doInstall(anaconda)
-
-# does this need to be per-backend?  we'll just leave here until it does :)
-def doBasePackageSelect(anaconda):
-    if anaconda.ksdata:
-        anaconda.backend.resetPackageSelections()
-        kickstart.selectPackages(anaconda)
-    elif anaconda.displayMode != 't':
-        anaconda.backend.resetPackageSelections()
-        anaconda.instClass.setPackageSelection(anaconda)
-        anaconda.instClass.setGroupSelection(anaconda)
-
-def writeConfiguration(anaconda):
-    log.info("Writing main configuration")
-    anaconda.write()
-    anaconda.backend.writeConfiguration()
diff --git a/backend_log.py b/backend_log.py
deleted file mode 100644
index fd11692..0000000
--- a/backend_log.py
+++ /dev/null
@@ -1,88 +0,0 @@
-# backend_log.py
-# Logging infrastructure for Anaconda's backend.
-#
-# Copyright (C) 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, or (at your option) any later version.
-# 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.
-#
-# Red Hat Author(s): Ales Kozumplik <akozumpl@xxxxxxxxxx>
-#
-
-import logging
-import os
-import signal
-
-import anaconda_log
-import iutil
-
-SYSLOG_PATH           = '/sbin/rsyslogd'
-SYSLOG_PIDFILE        = '/var/run/rsyslog_backend.pid'
-SYSLOG_CFGFILE        = '/etc/rsyslog_backend.conf'
-
-CFG_TEMPLATE = """
-$ModLoad imuxsock
-$InputUnixListenSocketHostName sysimage
-$AddUnixListenSocket %(socket)s
-+sysimage
-*.* %(logfile)s;RSYSLOG_TraditionalFileFormat
-%(remote_syslog)s
-"""
-
-global_log = logging.getLogger("anaconda")
-class BackendSyslog:
-    def __init__(self):
-        pass
-    
-    def build_cfg(self, root, log):
-        socket = "%s/dev/log" % (root, )
-        remote_syslog = ''
-        if anaconda_log.logger.remote_syslog:
-            remote_syslog = "*.* @@%s" % (anaconda_log.logger.remote_syslog, )
-        
-        cfg = CFG_TEMPLATE % {
-            'socket' : socket,
-            'logfile' : log,
-            'remote_syslog' : remote_syslog
-            }
-        with open(SYSLOG_CFGFILE, 'w') as cfg_file:
-            cfg_file.write(cfg)
-
-    def start(self, root, log):
-        """ Start an rsyslogd instance dedicated for the sysimage.
-
-        Other possibility would be to change configuration and SIGHUP the
-        existing instance, but it could lose some of its internal queues and
-        give us problems with remote logging.
-        """
-        self.build_cfg(root, log)
-        args = ['-c', '4', 
-                '-f', SYSLOG_CFGFILE,
-                '-i', str(SYSLOG_PIDFILE)]
-        status = iutil.execWithRedirect(SYSLOG_PATH, args)
-        if status == 0:
-            global_log.info("Backend logger started.")
-        else:
-            global_log.error("Unable to start backend logger")
-    
-    def stop(self):
-        try:
-            with open(SYSLOG_PIDFILE, 'r') as pidfile:
-                pid = int(pidfile.read())
-            os.kill(pid, signal.SIGKILL)
-        except:
-            return
-        global_log.info("Backend logger stopped.")
-
-log = BackendSyslog()
diff --git a/baseudev.py b/baseudev.py
deleted file mode 100644
index 3d9ee45..0000000
--- a/baseudev.py
+++ /dev/null
@@ -1,92 +0,0 @@
-# udev.py
-# Python module for querying the udev database for device information.
-#
-# Copyright (C) 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, or (at your option) any later version.
-# 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.
-#
-# Red Hat Author(s): Dave Lehman <dlehman@xxxxxxxxxx>
-#                    Chris Lumens <clumens@xxxxxxxxxx>
-#
-
-import iutil
-import os
-
-import pyudev
-global_udev = pyudev.Udev()
-
-import logging
-log = logging.getLogger("storage")
-
-def udev_enumerate_devices(deviceClass="block"):
-    devices = global_udev.enumerate_devices(subsystem=deviceClass)
-    return [path[4:] for path in devices]
-
-def udev_get_device(sysfs_path):
-    if not os.path.exists("/sys%s" % sysfs_path):
-        log.debug("%s does not exist" % sysfs_path)
-        return None
-
-    # XXX we remove the /sys part when enumerating devices,
-    # so we have to prepend it when creating the device
-    dev = global_udev.create_device("/sys" + sysfs_path)
-
-    if dev:
-        dev["name"] = dev.sysname
-        dev["sysfs_path"] = sysfs_path
-
-        # now add in the contents of the uevent file since they're handy
-        dev = udev_parse_uevent_file(dev)
-
-    return dev
-
-def udev_get_devices(deviceClass="block"):
-    udev_settle()
-    entries = []
-    for path in udev_enumerate_devices(deviceClass):
-        entry = udev_get_device(path)
-        if entry:
-            entries.append(entry)
-    return entries
-
-def udev_parse_uevent_file(dev):
-    path = os.path.normpath("/sys/%s/uevent" % dev['sysfs_path'])
-    if not os.access(path, os.R_OK):
-        return dev
-
-    with open(path) as f:
-        for line in f.readlines():
-            (key, equals, value) = line.strip().partition("=")
-            if not equals:
-                continue
-
-            dev[key] = value
-
-    return dev
-
-def udev_settle():
-    # wait maximal 300 seconds for udev to be done running blkid, lvm,
-    # mdadm etc. This large timeout is needed when running on machines with
-    # lots of disks, or with slow disks
-    argv = ["settle", "--timeout=300"]
-
-    iutil.execWithRedirect("udevadm", argv, stderr="/dev/null")
-
-def udev_trigger(subsystem=None, action="add"):
-    argv = ["trigger", "--action=%s" % action]
-    if subsystem:
-        argv.append("--subsystem-match=%s" % subsystem)
-
-    iutil.execWithRedirect("udevadm", argv, stderr="/dev/null")
diff --git a/bin/Makefile.am b/bin/Makefile.am
new file mode 100644
index 0000000..53a5c44
--- /dev/null
+++ b/bin/Makefile.am
@@ -0,0 +1,23 @@
+# liveinst/Makefile.am for anaconda
+#
+# Copyright (C) 2009  Red Hat, Inc.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License as published
+# by the Free Software Foundation; either version 2.1 of the License, or
+# (at your option) any later version.
+#
+# 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 Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+#
+# Author: Martin Sivak <msivak@xxxxxxxxxx>
+
+SUBDIRS = loader gptsync 
+
+MAINTAINERCLEANFILES = Makefile.in
+
diff --git a/bin/gptsync/.gitignore b/bin/gptsync/.gitignore
new file mode 100644
index 0000000..4971cfa
--- /dev/null
+++ b/bin/gptsync/.gitignore
@@ -0,0 +1,2 @@
+gptsync
+showpart
diff --git a/bin/gptsync/Makefile.am b/bin/gptsync/Makefile.am
new file mode 100644
index 0000000..7f66432
--- /dev/null
+++ b/bin/gptsync/Makefile.am
@@ -0,0 +1,35 @@
+# gptsync/Makefile.am for anaconda
+#
+# Copyright (C) 2009  Red Hat, Inc.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License as published
+# by the Free Software Foundation; either version 2.1 of the License, or
+# (at your option) any later version.
+#
+# 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 Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+#
+# Author: David Cantrell <dcantrell@xxxxxxxxxx>
+
+COMMON_SRCS      = lib.c os_unix.c
+noinst_HEADERS   = gptsync.h syslinux_mbr.h
+
+if IS_GPTSYNC_ARCH
+sbin_PROGRAMS    = gptsync showpart
+
+gptsync_CFLAGS   = -DPROGNAME=gptsync
+gptsync_SOURCES  = gptsync.c $(COMMON_SRCS)
+
+showpart_CFLAGS  = -DPROGNAME=showpart
+showpart_SOURCES = showpart.c $(COMMON_SRCS)
+endif
+
+EXTRA_DIST       = README
+
+MAINTAINERCLEANFILES = Makefile.in
diff --git a/bin/gptsync/README b/bin/gptsync/README
new file mode 100644
index 0000000..cb306bd
--- /dev/null
+++ b/bin/gptsync/README
@@ -0,0 +1,41 @@
+gptsync is from refit (refit.sf.net).  It has been modified to
+1) Not prompt if you want to copy
+2) Default to Linux native (0x83) instead of fat32 partition id
+
+The original license follows.
+
+
+ rEFIt License
+===============
+
+Copyright (c) 2006-2007 Christoph Pfisterer
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+ * Redistributions of source code must retain the above copyright
+   notice, this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright
+   notice, this list of conditions and the following disclaimer in the
+   documentation and/or other materials provided with the
+   distribution.
+
+ * Neither the name of Christoph Pfisterer nor the names of the
+   contributors may be used to endorse or promote products derived
+   from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
diff --git a/bin/gptsync/gptsync.c b/bin/gptsync/gptsync.c
new file mode 100644
index 0000000..3ad26bf
--- /dev/null
+++ b/bin/gptsync/gptsync.c
@@ -0,0 +1,470 @@
+/*
+ * gptsync/gptsync.c
+ * Platform-independent code for syncing GPT and MBR
+ *
+ * Copyright (c) 2006-2007 Christoph Pfisterer
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *  * Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ *  * Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the
+ *    distribution.
+ *
+ *  * Neither the name of Christoph Pfisterer nor the names of the
+ *    contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "gptsync.h"
+
+#include "syslinux_mbr.h"
+
+//
+// MBR functions
+//
+
+static UINTN check_mbr(VOID)
+{
+    UINTN       i, k;
+    
+    // check each entry
+    for (i = 0; i < mbr_part_count; i++) {
+        // check for overlap
+        for (k = 0; k < mbr_part_count; k++) {
+            if (k != i && !(mbr_parts[i].start_lba > mbr_parts[k].end_lba || mbr_parts[k].start_lba > mbr_parts[i].end_lba)) {
+                Print(L"Status: MBR partition table is invalid, partitions overlap.\n");
+                return 1;
+            }
+        }
+        
+        // check for extended partitions
+        if (mbr_parts[i].mbr_type == 0x05 || mbr_parts[i].mbr_type == 0x0f || mbr_parts[i].mbr_type == 0x85) {
+            Print(L"Status: Extended partition found in MBR table, will not touch this disk.\n",
+                  gpt_parts[i].gpt_parttype->name);
+            return 1;
+        }
+    }
+    
+    return 0;
+}
+
+static UINTN write_mbr(VOID)
+{
+    UINTN               status;
+    UINTN               i, k;
+    UINT8               active;
+    UINT64              lba;
+    MBR_PARTITION_INFO  *table;
+    BOOLEAN             have_bootcode;
+    
+    Print(L"\nWriting new MBR...\n");
+    
+    // read MBR data
+    status = read_sector(0, sector);
+    if (status != 0)
+        return status;
+    
+    // write partition table
+    *((UINT16 *)(sector + 510)) = 0xaa55;
+    
+    table = (MBR_PARTITION_INFO *)(sector + 446);
+    active = 0x80;
+    for (i = 0; i < 4; i++) {
+        for (k = 0; k < new_mbr_part_count; k++) {
+            if (new_mbr_parts[k].index == i)
+                break;
+        }
+        if (k >= new_mbr_part_count) {
+            // unused entry
+            table[i].flags        = 0;
+            table[i].start_chs[0] = 0;
+            table[i].start_chs[1] = 0;
+            table[i].start_chs[2] = 0;
+            table[i].type         = 0;
+            table[i].end_chs[0]   = 0;
+            table[i].end_chs[1]   = 0;
+            table[i].end_chs[2]   = 0;
+            table[i].start_lba    = 0;
+            table[i].size         = 0;
+        } else {
+            if (new_mbr_parts[k].active) {
+                table[i].flags        = active;
+                active = 0x00;
+            } else
+                table[i].flags        = 0x00;
+            table[i].start_chs[0] = 0xfe;
+            table[i].start_chs[1] = 0xff;
+            table[i].start_chs[2] = 0xff;
+            table[i].type         = new_mbr_parts[k].mbr_type;
+            table[i].end_chs[0]   = 0xfe;
+            table[i].end_chs[1]   = 0xff;
+            table[i].end_chs[2]   = 0xff;
+            
+            lba = new_mbr_parts[k].start_lba;
+            if (lba > 0xffffffffULL) {
+                Print(L"Warning: Partition %d starts beyond 2 TiB limit\n", i+1);
+                lba = 0xffffffffULL;
+            }
+            table[i].start_lba    = (UINT32)lba;
+            
+            lba = new_mbr_parts[k].end_lba + 1 - new_mbr_parts[k].start_lba;
+            if (lba > 0xffffffffULL) {
+                Print(L"Warning: Partition %d extends beyond 2 TiB limit\n", i+1);
+                lba = 0xffffffffULL;
+            }
+            table[i].size         = (UINT32)lba;
+        }
+    }
+    
+    // add boot code if necessary
+    have_bootcode = FALSE;
+    for (i = 0; i < MBR_BOOTCODE_SIZE; i++) {
+        if (sector[i] != 0) {
+            have_bootcode = TRUE;
+            break;
+        }
+    }
+    if (!have_bootcode) {
+        // no boot code found in the MBR, add the syslinux MBR code
+        SetMem(sector, 0, MBR_BOOTCODE_SIZE);
+        CopyMem(sector, syslinux_mbr, SYSLINUX_MBR_SIZE);
+    }
+    
+    // write MBR data
+    status = write_sector(0, sector);
+    if (status != 0)
+        return status;
+    
+    Print(L"MBR updated successfully!\n");
+    
+    return 0;
+}
+
+//
+// GPT functions
+//
+
+static UINTN check_gpt(VOID)
+{
+    UINTN       i, k;
+    BOOLEAN     found_data_parts;
+    
+    if (gpt_part_count == 0) {
+        Print(L"Status: No GPT partition table, no need to sync.\n");
+        return 1;
+    }
+    
+    // check each entry
+    found_data_parts = FALSE;
+    for (i = 0; i < gpt_part_count; i++) {
+        // check sanity
+        if (gpt_parts[i].end_lba < gpt_parts[i].start_lba) {
+            Print(L"Status: GPT partition table is invalid.\n");
+            return 1;
+        }
+        // check for overlap
+        for (k = 0; k < gpt_part_count; k++) {
+            if (k != i && !(gpt_parts[i].start_lba > gpt_parts[k].end_lba || gpt_parts[k].start_lba > gpt_parts[i].end_lba)) {
+                Print(L"Status: GPT partition table is invalid, partitions overlap.\n");
+                return 1;
+            }
+        }
+        
+        // check for partitions kind
+        if (gpt_parts[i].gpt_parttype->kind == GPT_KIND_FATAL) {
+            Print(L"Status: GPT partition of type '%s' found, will not touch this disk.\n",
+                  gpt_parts[i].gpt_parttype->name);
+            return 1;
+        }
+        if (gpt_parts[i].gpt_parttype->kind == GPT_KIND_DATA ||
+            gpt_parts[i].gpt_parttype->kind == GPT_KIND_BASIC_DATA)
+            found_data_parts = TRUE;
+    }
+    
+    if (!found_data_parts) {
+        Print(L"Status: GPT partition table has no data partitions, no need to sync.\n");
+        return 1;
+    }
+    
+    return 0;
+}
+
+//
+// compare GPT and MBR tables
+//
+
+#define ACTION_NONE        (0)
+#define ACTION_NOP         (1)
+#define ACTION_REWRITE     (2)
+
+static UINTN analyze(VOID)
+{
+    UINTN   action;
+    UINTN   i, k, iter, count_active, detected_parttype;
+    CHARN   *fsname;
+    UINT64  min_start_lba;
+    UINTN   status;
+    BOOLEAN have_esp;
+    
+    new_mbr_part_count = 0;
+    
+    // determine correct MBR types for GPT partitions
+    if (gpt_part_count == 0) {
+        Print(L"Status: No GPT partitions defined, nothing to sync.\n");
+        return 0;
+    }
+    have_esp = FALSE;
+    for (i = 0; i < gpt_part_count; i++) {
+        gpt_parts[i].mbr_type = gpt_parts[i].gpt_parttype->mbr_type;
+        if (gpt_parts[i].gpt_parttype->kind == GPT_KIND_BASIC_DATA) {
+            // Basic Data: need to look at data in the partition
+            status = detect_mbrtype_fs(gpt_parts[i].start_lba, &detected_parttype, &fsname);
+            if (detected_parttype)
+                gpt_parts[i].mbr_type = detected_parttype;
+            else
+                gpt_parts[i].mbr_type = 0x0b;  // fallback: FAT32
+        } else if (gpt_parts[i].mbr_type == 0xef) {
+            // EFI System Partition: GNU parted can put this on any partition,
+            // need to detect file systems
+            status = detect_mbrtype_fs(gpt_parts[i].start_lba, &detected_parttype, &fsname);
+            if (!have_esp && (detected_parttype == 0x01 || detected_parttype == 0x0e || detected_parttype == 0x0c))
+                ;  // seems to be a legitimate ESP, don't change
+            else if (detected_parttype)
+                gpt_parts[i].mbr_type = detected_parttype;
+            else if (have_esp)    // make sure there's no more than one ESP per disk
+                gpt_parts[i].mbr_type = 0x83;  // fallback: Linux
+        }
+        // NOTE: mbr_type may still be 0 if content detection fails for exotic GPT types or file systems
+        
+        if (gpt_parts[i].mbr_type == 0xef)
+            have_esp = TRUE;
+    }
+    
+    // check for common scenarios
+    action = ACTION_NONE;
+    if (mbr_part_count == 0) {
+        // current MBR is empty
+        action = ACTION_REWRITE;
+    } else if (mbr_part_count == 1 && mbr_parts[0].mbr_type == 0xee) {
+        // MBR has just the EFI Protective partition (i.e. untouched)
+        action = ACTION_REWRITE;
+    }
+    if (action == ACTION_NONE && mbr_part_count > 0) {
+        if (mbr_parts[0].mbr_type == 0xee &&
+            gpt_parts[0].mbr_type == 0xef &&
+            mbr_parts[0].start_lba == 1 &&
+            mbr_parts[0].end_lba == gpt_parts[0].end_lba) {
+            // The Apple Way, "EFI Protective" covering the tables and the ESP
+            action = ACTION_NOP;
+            if ((mbr_part_count != gpt_part_count && gpt_part_count <= 4) ||
+                (mbr_part_count != 4              && gpt_part_count > 4)) {
+                // number of partitions has changed
+                action = ACTION_REWRITE;
+            } else {
+                // check partition ranges and types
+                for (i = 1; i < mbr_part_count; i++) {
+                    if (mbr_parts[i].start_lba != gpt_parts[i].start_lba ||
+                        mbr_parts[i].end_lba   != gpt_parts[i].end_lba ||
+                        (gpt_parts[i].mbr_type && mbr_parts[i].mbr_type != gpt_parts[i].mbr_type))
+                        // position or type has changed
+                        action = ACTION_REWRITE;
+                }
+            }
+            // check number of active partitions
+            count_active = 0;
+            for (i = 0; i < mbr_part_count; i++)
+                if (mbr_parts[i].active)
+                    count_active++;
+            if (count_active!= 1)
+                action = ACTION_REWRITE;
+        }
+    }
+    if (action == ACTION_NONE && mbr_part_count > 0 && mbr_parts[0].mbr_type == 0xef) {
+        // The XOM Way, all partitions mirrored 1:1
+        action = ACTION_REWRITE;
+        // check partition ranges and types
+        for (i = 0; i < mbr_part_count; i++) {
+            if (mbr_parts[i].start_lba != gpt_parts[i].start_lba ||
+                mbr_parts[i].end_lba   != gpt_parts[i].end_lba ||
+                (gpt_parts[i].mbr_type && mbr_parts[i].mbr_type != gpt_parts[i].mbr_type))
+                // position or type has changed -> better don't touch
+                action = ACTION_NONE;
+        }
+    }
+    
+    if (action == ACTION_NOP) {
+        Print(L"Status: Tables are synchronized, no need to sync.\n");
+        return 0;
+    } else if (action == ACTION_REWRITE) {
+        Print(L"Status: MBR table must be updated.\n");
+    } else {
+        Print(L"Status: Analysis inconclusive, will not touch this disk.\n");
+        return 1;
+    }
+    
+    // generate the new table
+    
+    // first entry: EFI Protective
+    new_mbr_parts[0].index     = 0;
+    new_mbr_parts[0].start_lba = 1;
+    new_mbr_parts[0].mbr_type  = 0xee;
+    new_mbr_part_count = 1;
+    
+    if (gpt_parts[0].mbr_type == 0xef) {
+        new_mbr_parts[0].end_lba = gpt_parts[0].end_lba;
+        i = 1;
+    } else {
+        min_start_lba = gpt_parts[0].start_lba;
+        for (k = 0; k < gpt_part_count; k++) {
+            if (min_start_lba > gpt_parts[k].start_lba)
+                min_start_lba = gpt_parts[k].start_lba;
+        }
+        new_mbr_parts[0].end_lba = min_start_lba - 1;
+        i = 0;
+    }
+    
+    // add other GPT partitions until the table is full
+    // TODO: in the future, prioritize partitions by kind
+    for (; i < gpt_part_count && new_mbr_part_count < 4; i++) {
+        new_mbr_parts[new_mbr_part_count].index     = new_mbr_part_count;
+        new_mbr_parts[new_mbr_part_count].start_lba = gpt_parts[i].start_lba;
+        new_mbr_parts[new_mbr_part_count].end_lba   = gpt_parts[i].end_lba;
+        new_mbr_parts[new_mbr_part_count].mbr_type  = gpt_parts[i].mbr_type;
+        new_mbr_parts[new_mbr_part_count].active    = FALSE;
+        
+        // find matching partition in the old MBR table
+        for (k = 0; k < mbr_part_count; k++) {
+            if (mbr_parts[k].start_lba == gpt_parts[i].start_lba) {
+                // keep type if not detected
+                if (new_mbr_parts[new_mbr_part_count].mbr_type == 0)
+                    new_mbr_parts[new_mbr_part_count].mbr_type = mbr_parts[k].mbr_type;
+                // keep active flag
+                new_mbr_parts[new_mbr_part_count].active = mbr_parts[k].active;
+                break;
+            }
+        }
+        
+        if (new_mbr_parts[new_mbr_part_count].mbr_type == 0)
+            // final fallback: set to a (hopefully) unused type
+            new_mbr_parts[new_mbr_part_count].mbr_type = 0xc0;
+        
+        new_mbr_part_count++;
+    }
+    
+    // make sure there's exactly one active partition
+    for (iter = 0; iter < 3; iter++) {
+        // check
+        count_active = 0;
+        for (i = 0; i < new_mbr_part_count; i++)
+            if (new_mbr_parts[i].active)
+                count_active++;
+        if (count_active == 1)
+            break;
+        
+        // set active on the first matching partition
+        if (count_active == 0) {
+            for (i = 0; i < new_mbr_part_count; i++) {
+                if ((iter >= 0 && (new_mbr_parts[i].mbr_type == 0x07 ||    // NTFS
+                                   new_mbr_parts[i].mbr_type == 0x0b ||    // FAT32
+                                   new_mbr_parts[i].mbr_type == 0x0c)) ||  // FAT32 (LBA)
+                    (iter >= 1 && (new_mbr_parts[i].mbr_type == 0x83)) ||  // Linux
+                    (iter >= 2 && i > 0)) {
+                    new_mbr_parts[i].active = TRUE;
+                    break;
+                }
+            }
+        } else if (count_active > 1 && iter == 0) {
+            // too many active partitions, try deactivating the ESP / EFI Protective entry
+            if ((new_mbr_parts[0].mbr_type == 0xee || new_mbr_parts[0].mbr_type == 0xef) &&
+                new_mbr_parts[0].active) {
+                new_mbr_parts[0].active = FALSE;
+            }
+        } else if (count_active > 1 && iter > 0) {
+            // too many active partitions, deactivate all but the first one
+            count_active = 0;
+            for (i = 0; i < new_mbr_part_count; i++)
+                if (new_mbr_parts[i].active) {
+                    if (count_active > 0)
+                        new_mbr_parts[i].active = FALSE;
+                    count_active++;
+                }
+        }
+    }
+    
+    // dump table
+    Print(L"\nProposed new MBR partition table:\n");
+    Print(L" # A    Start LBA      End LBA  Type\n");
+    for (i = 0; i < new_mbr_part_count; i++) {
+        Print(L" %d %s %12lld %12lld  %02x  %s\n",
+              new_mbr_parts[i].index + 1,
+              new_mbr_parts[i].active ? STR("*") : STR(" "),
+              new_mbr_parts[i].start_lba,
+              new_mbr_parts[i].end_lba,
+              new_mbr_parts[i].mbr_type,
+              mbr_parttype_name(new_mbr_parts[i].mbr_type));
+    }
+    
+    return 0;
+}
+
+//
+// sync algorithm entry point
+//
+
+UINTN gptsync(VOID)
+{
+    UINTN   status = 0;
+    UINTN   status_gpt, status_mbr;
+    // BOOLEAN proceed = FALSE;
+    
+    // get full information from disk
+    status_gpt = read_gpt();
+    status_mbr = read_mbr();
+    if (status_gpt != 0 || status_mbr != 0)
+        return (status_gpt || status_mbr);
+    
+    // cross-check current situation
+    Print(L"\n");
+    status = check_gpt();   // check GPT for consistency
+    if (status != 0)
+        return status;
+    status = check_mbr();   // check MBR for consistency
+    if (status != 0)
+        return status;
+    status = analyze();     // analyze the situation & compose new MBR table
+    if (status != 0)
+        return status;
+    if (new_mbr_part_count == 0)
+        return status;
+    
+    // offer user the choice what to do
+    // status = input_boolean(STR("\nMay I update the MBR as printed above? [y/N] "), &proceed);
+    // if (status != 0 || proceed != TRUE)
+    //    return status;
+    
+    // adjust the MBR and write it back
+    status = write_mbr();
+    if (status != 0)
+        return status;
+    
+    return status;
+}
diff --git a/bin/gptsync/gptsync.h b/bin/gptsync/gptsync.h
new file mode 100644
index 0000000..d1bf3c2
--- /dev/null
+++ b/bin/gptsync/gptsync.h
@@ -0,0 +1,219 @@
+/*
+ * gptsync/gptsync.h
+ * Common header for gptsync and showpart
+ *
+ * Copyright (c) 2006 Christoph Pfisterer
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *  * Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ *  * Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the
+ *    distribution.
+ *
+ *  * Neither the name of Christoph Pfisterer nor the names of the
+ *    contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+//
+// config
+//
+
+#if defined(EFI32) || defined(EFIX64)
+#define CONFIG_EFI
+#endif
+
+//
+// platform-dependent types
+//
+
+#ifdef CONFIG_EFI
+
+#include <efi.h>
+#include <efilib.h>
+
+#define copy_guid(destguid, srcguid) (CopyMem(destguid, srcguid, 16))
+#define guids_are_equal(guid1, guid2) (CompareMem(guid1, guid2, 16) == 0)
+
+typedef CHAR16 CHARN;
+#define STR(x) L##x
+
+#endif
+
+
+#ifndef CONFIG_EFI
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdint.h>
+#include <unistd.h>
+#include <errno.h>
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/time.h>
+#include <fcntl.h>
+
+typedef int                 INTN;
+typedef unsigned int        UINTN;
+typedef uint8_t             UINT8;
+typedef uint16_t            UINT16;
+typedef uint32_t            UINT32;
+typedef uint64_t            UINT64;
+typedef void                VOID;
+
+typedef int                 BOOLEAN;
+#ifndef FALSE
+#define FALSE (0)
+#endif
+#ifndef TRUE
+#define TRUE  (1)
+#endif
+
+typedef unsigned short      CHAR16;
+typedef char                CHARN;
+#define STR(x) x
+
+void Print(wchar_t *format, ...);
+
+// FUTURE: use STR(),  #define Print printf
+
+#define CopyMem     memcpy
+#define SetMem      memset
+#define CompareMem  memcmp
+
+#define copy_guid(destguid, srcguid) (memcpy(destguid, srcguid, 16))
+#define guids_are_equal(guid1, guid2) (memcmp(guid1, guid2, 16) == 0)
+
+#endif
+
+//
+// platform-independent types
+//
+
+typedef struct {
+    UINT8   flags;
+    UINT8   start_chs[3];
+    UINT8   type;
+    UINT8   end_chs[3];
+    UINT32  start_lba;
+    UINT32  size;
+} MBR_PARTITION_INFO;
+
+typedef struct {
+    UINT8   type;
+    CHARN   *name;
+} MBR_PARTTYPE;
+
+typedef struct {
+    UINT64  signature;
+    UINT32  spec_revision;
+    UINT32  header_size;
+    UINT32  header_crc32;
+    UINT32  reserved;
+    UINT64  header_lba;
+    UINT64  alternate_header_lba;
+    UINT64  first_usable_lba;
+    UINT64  last_usable_lba;
+    UINT8   disk_guid[16];
+    UINT64  entry_lba;
+    UINT32  entry_count;
+    UINT32  entry_size;
+    UINT32  entry_crc32;
+} GPT_HEADER;
+
+typedef struct {
+    UINT8   type_guid[16];
+    UINT8   partition_guid[16];
+    UINT64  start_lba;
+    UINT64  end_lba;
+    UINT64  attributes;
+    CHAR16  name[36];
+} GPT_ENTRY;
+
+#define GPT_KIND_SYSTEM     (0)
+#define GPT_KIND_DATA       (1)
+#define GPT_KIND_BASIC_DATA (2)
+#define GPT_KIND_FATAL      (3)
+
+typedef struct {
+    UINT8   guid[16];
+    UINT8   mbr_type;
+    CHARN   *name;
+    UINTN   kind;
+} GPT_PARTTYPE;
+
+typedef struct {
+    UINTN   index;
+    UINT64  start_lba;
+    UINT64  end_lba;
+    UINTN   mbr_type;
+    UINT8   gpt_type[16];
+    GPT_PARTTYPE *gpt_parttype;
+    BOOLEAN active;
+} PARTITION_INFO;
+
+//
+// functions provided by the OS-specific module
+//
+
+UINTN read_sector(UINT64 lba, UINT8 *buffer);
+UINTN write_sector(UINT64 lba, UINT8 *buffer);
+UINTN input_boolean(CHARN *prompt, BOOLEAN *bool_out);
+
+//
+// vars and functions provided by the common lib module
+//
+
+extern UINT8           empty_guid[16];
+
+extern PARTITION_INFO  mbr_parts[4];
+extern UINTN           mbr_part_count;
+extern PARTITION_INFO  gpt_parts[128];
+extern UINTN           gpt_part_count;
+
+extern PARTITION_INFO  new_mbr_parts[4];
+extern UINTN           new_mbr_part_count;
+
+extern UINT8           sector[512];
+
+extern MBR_PARTTYPE    mbr_types[];
+extern GPT_PARTTYPE    gpt_types[];
+extern GPT_PARTTYPE    gpt_dummy_type;
+
+CHARN * mbr_parttype_name(UINT8 type);
+UINTN read_mbr(VOID);
+
+GPT_PARTTYPE * gpt_parttype(UINT8 *type_guid);
+UINTN read_gpt(VOID);
+
+UINTN detect_mbrtype_fs(UINT64 partlba, UINTN *parttype, CHARN **fsname);
+
+//
+// actual platform-independent programs
+//
+
+UINTN gptsync(VOID);
+UINTN showpart(VOID);
+
+/* EOF */
diff --git a/bin/gptsync/lib.c b/bin/gptsync/lib.c
new file mode 100644
index 0000000..f2d71b2
--- /dev/null
+++ b/bin/gptsync/lib.c
@@ -0,0 +1,469 @@
+/*
+ * gptsync/lib.c
+ * Platform-independent code common to gptsync and showpart
+ *
+ * Copyright (c) 2006-2007 Christoph Pfisterer
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *  * Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ *  * Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the
+ *    distribution.
+ *
+ *  * Neither the name of Christoph Pfisterer nor the names of the
+ *    contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "gptsync.h"
+
+// variables
+
+UINT8           empty_guid[16] = { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 };
+
+PARTITION_INFO  mbr_parts[4];
+UINTN           mbr_part_count = 0;
+PARTITION_INFO  gpt_parts[128];
+UINTN           gpt_part_count = 0;
+
+PARTITION_INFO  new_mbr_parts[4];
+UINTN           new_mbr_part_count = 0;
+
+UINT8           sector[512];
+
+MBR_PARTTYPE    mbr_types[] = {
+    { 0x01, STR("FAT12 (CHS)") },
+    { 0x04, STR("FAT16 <32M (CHS)") },
+    { 0x05, STR("Extended (CHS)") },
+    { 0x06, STR("FAT16 (CHS)") },
+    { 0x07, STR("NTFS/HPFS") },
+    { 0x0b, STR("FAT32 (CHS)") },
+    { 0x0c, STR("FAT32 (LBA)") },
+    { 0x0e, STR("FAT16 (LBA)") },
+    { 0x0f, STR("Extended (LBA)") },
+    { 0x11, STR("Hidden FAT12 (CHS)") },
+    { 0x14, STR("Hidden FAT16 <32M (CHS)") },
+    { 0x16, STR("Hidden FAT16 (CHS)") },
+    { 0x17, STR("Hidden NTFS/HPFS") },
+    { 0x1b, STR("Hidden FAT32 (CHS)") },
+    { 0x1c, STR("Hidden FAT32 (LBA)") },
+    { 0x1e, STR("Hidden FAT16 (LBA)") },
+    { 0x82, STR("Linux swap / Solaris") },
+    { 0x83, STR("Linux") },
+    { 0x85, STR("Linux Extended") },
+    { 0x86, STR("NT FAT volume set") },
+    { 0x87, STR("NTFS volume set") },
+    { 0x8e, STR("Linux LVM") },
+    { 0xa5, STR("FreeBSD") },
+    { 0xa6, STR("OpenBSD") },
+    { 0xa7, STR("NeXTSTEP") },
+    { 0xa8, STR("Mac OS X UFS") },
+    { 0xa9, STR("NetBSD") },
+    { 0xab, STR("Mac OS X Boot") },
+    { 0xac, STR("Apple RAID") },
+    { 0xaf, STR("Mac OS X HFS+") },
+    { 0xbe, STR("Solaris Boot") },
+    { 0xbf, STR("Solaris") },
+    { 0xeb, STR("BeOS") },
+    { 0xee, STR("EFI Protective") },
+    { 0xef, STR("EFI System (FAT)") },
+    { 0xfd, STR("Linux RAID") },
+    { 0, NULL },
+};
+
+GPT_PARTTYPE    gpt_types[] = {
+    { "\x28\x73\x2A\xC1\x1F\xF8\xD2\x11\xBA\x4B\x00\xA0\xC9\x3E\xC9\x3B", 0xef, STR("EFI System (FAT)"), GPT_KIND_SYSTEM },
+    { "\x41\xEE\x4D\x02\xE7\x33\xD3\x11\x9D\x69\x00\x08\xC7\x81\xF3\x9F", 0x00, STR("MBR partition scheme"), GPT_KIND_FATAL },
+    { "\x16\xE3\xC9\xE3\x5C\x0B\xB8\x4D\x81\x7D\xF9\x2D\xF0\x02\x15\xAE", 0x00, STR("MS Reserved"), GPT_KIND_SYSTEM },
+    { "\xA2\xA0\xD0\xEB\xE5\xB9\x33\x44\x87\xC0\x68\xB6\xB7\x26\x99\xC7", 0x00, STR("Basic Data"), GPT_KIND_BASIC_DATA },
+    { "\xAA\xC8\x08\x58\x8F\x7E\xE0\x42\x85\xD2\xE1\xE9\x04\x34\xCF\xB3", 0x00, STR("MS LDM Metadata"), GPT_KIND_FATAL },
+    { "\xA0\x60\x9B\xAF\x31\x14\x62\x4F\xBC\x68\x33\x11\x71\x4A\x69\xAD", 0x00, STR("MS LDM Data"), GPT_KIND_FATAL },
+    { "\x1E\x4C\x89\x75\xEB\x3A\xD3\x11\xB7\xC1\x7B\x03\xA0\x00\x00\x00", 0x00, STR("HP/UX Data"), GPT_KIND_DATA },
+    { "\x28\xE7\xA1\xE2\xE3\x32\xD6\x11\xA6\x82\x7B\x03\xA0\x00\x00\x00", 0x00, STR("HP/UX Service"), GPT_KIND_SYSTEM },
+    { "\x0F\x88\x9D\xA1\xFC\x05\x3B\x4D\xA0\x06\x74\x3F\x0F\x84\x91\x1E", 0xfd, STR("Linux RAID"), GPT_KIND_DATA },
+    { "\x6D\xFD\x57\x06\xAB\xA4\xC4\x43\x84\xE5\x09\x33\xC8\x4B\x4F\x4F", 0x82, STR("Linux Swap"), GPT_KIND_SYSTEM },
+    { "\x79\xD3\xD6\xE6\x07\xF5\xC2\x44\xA2\x3C\x23\x8F\x2A\x3D\xF9\x28", 0x8e, STR("Linux LVM"), GPT_KIND_DATA },
+    { "\x39\x33\xA6\x8D\x07\x00\xC0\x60\xC4\x36\x08\x3A\xC8\x23\x09\x08", 0x00, STR("Linux Reserved"), GPT_KIND_SYSTEM },
+    { "\xB4\x7C\x6E\x51\xCF\x6E\xD6\x11\x8F\xF8\x00\x02\x2D\x09\x71\x2B", 0xa5, STR("FreeBSD Data"), GPT_KIND_DATA },
+    { "\xB5\x7C\x6E\x51\xCF\x6E\xD6\x11\x8F\xF8\x00\x02\x2D\x09\x71\x2B", 0x00, STR("FreeBSD Swap"), GPT_KIND_SYSTEM },
+    { "\xB6\x7C\x6E\x51\xCF\x6E\xD6\x11\x8F\xF8\x00\x02\x2D\x09\x71\x2B", 0xa5, STR("FreeBSD UFS"), GPT_KIND_DATA },
+    { "\xB8\x7C\x6E\x51\xCF\x6E\xD6\x11\x8F\xF8\x00\x02\x2D\x09\x71\x2B", 0x00, STR("FreeBSD Vinum"), GPT_KIND_DATA },
+    { "\x00\x53\x46\x48\x00\x00\xAA\x11\xAA\x11\x00\x30\x65\x43\xEC\xAC", 0xaf, STR("Mac OS X HFS+"), GPT_KIND_DATA },
+    { "\x00\x53\x46\x55\x00\x00\xAA\x11\xAA\x11\x00\x30\x65\x43\xEC\xAC", 0xa8, STR("Mac OS X UFS"), GPT_KIND_DATA },
+    { "\x74\x6F\x6F\x42\x00\x00\xAA\x11\xAA\x11\x00\x30\x65\x43\xEC\xAC", 0xab, STR("Mac OS X Boot"), GPT_KIND_DATA },
+    { "\x44\x49\x41\x52\x00\x00\xAA\x11\xAA\x11\x00\x30\x65\x43\xEC\xAC", 0xac, STR("Apple RAID"), GPT_KIND_DATA },
+    { "\x44\x49\x41\x52\x4F\x5F\xAA\x11\xAA\x11\x00\x30\x65\x43\xEC\xAC", 0xac, STR("Apple RAID (Offline)"), GPT_KIND_DATA },
+    { "\x65\x62\x61\x4C\x00\x6C\xAA\x11\xAA\x11\x00\x30\x65\x43\xEC\xAC", 0x00, STR("Apple Label"), GPT_KIND_SYSTEM },
+    { "\x6F\x63\x65\x52\x65\x76\xAA\x11\xAA\x11\x00\x30\x65\x43\xEC\xAC", 0x00, STR("Apple Recovery"), GPT_KIND_BASIC_DATA },
+    { "\x7f\x23\x96\x6A\xD2\x1D\xB2\x11\x99\xa6\x08\x00\x20\x73\x66\x31", 0x00, STR("Solaris Reserved"), GPT_KIND_SYSTEM },
+    { "\x45\xCB\x82\x6A\xD2\x1D\xB2\x11\x99\xa6\x08\x00\x20\x73\x66\x31", 0xbf, STR("Solaris Boot"), GPT_KIND_DATA },
+    { "\x4D\xCF\x85\x6A\xD2\x1D\xB2\x11\x99\xa6\x08\x00\x20\x73\x66\x31", 0xbf, STR("Solaris Root"), GPT_KIND_DATA },
+    { "\x6F\xC4\x87\x6A\xD2\x1D\xB2\x11\x99\xa6\x08\x00\x20\x73\x66\x31", 0x00, STR("Solaris Swap"), GPT_KIND_SYSTEM },
+    { "\xC3\x8C\x89\x6A\xD2\x1D\xB2\x11\x99\xa6\x08\x00\x20\x73\x66\x31", 0xbf, STR("Solaris Usr"), GPT_KIND_DATA },
+    { "\x2B\x64\x8B\x6A\xD2\x1D\xB2\x11\x99\xa6\x08\x00\x20\x73\x66\x31", 0x00, STR("Solaris Backup"), GPT_KIND_SYSTEM },
+    { "\xC7\x2A\x8D\x6A\xD2\x1D\xB2\x11\x99\xa6\x08\x00\x20\x73\x66\x31", 0xbf, STR("Solaris Stand"), GPT_KIND_DATA },
+    { "\xE9\xF2\x8E\x6A\xD2\x1D\xB2\x11\x99\xa6\x08\x00\x20\x73\x66\x31", 0xbf, STR("Solaris Var"), GPT_KIND_DATA },
+    { "\x39\xBA\x90\x6A\xD2\x1D\xB2\x11\x99\xa6\x08\x00\x20\x73\x66\x31", 0xbf, STR("Solaris Home"), GPT_KIND_DATA },
+    { "\xA5\x83\x92\x6A\xD2\x1D\xB2\x11\x99\xa6\x08\x00\x20\x73\x66\x31", 0xbf, STR("Solaris ALTSCTR"), GPT_KIND_DATA },
+    { "\x3B\x5A\x94\x6A\xD2\x1D\xB2\x11\x99\xa6\x08\x00\x20\x73\x66\x31", 0x00, STR("Solaris Cache"), GPT_KIND_SYSTEM },
+    { { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 }, 0, NULL, 0 },
+};
+GPT_PARTTYPE    gpt_dummy_type =
+    { { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 }, 0, STR("Unknown"), GPT_KIND_FATAL };
+
+//
+// MBR functions
+//
+
+CHARN * mbr_parttype_name(UINT8 type)
+{
+    int i;
+    
+    for (i = 0; mbr_types[i].name; i++)
+        if (mbr_types[i].type == type)
+            return mbr_types[i].name;
+    return STR("Unknown");
+}
+
+UINTN read_mbr(VOID)
+{
+    UINTN               status;
+    UINTN               i;
+    BOOLEAN             used;
+    MBR_PARTITION_INFO  *table;
+    
+    Print(L"\nCurrent MBR partition table:\n");
+    
+    // read MBR data
+    status = read_sector(0, sector);
+    if (status != 0)
+        return status;
+    
+    // check for validity
+    if (*((UINT16 *)(sector + 510)) != 0xaa55) {
+        Print(L" No MBR partition table present!\n");
+        return 1;
+    }
+    table = (MBR_PARTITION_INFO *)(sector + 446);
+    for (i = 0; i < 4; i++) {
+        if (table[i].flags != 0x00 && table[i].flags != 0x80) {
+            Print(L" MBR partition table is invalid!\n");
+            return 1;
+        }
+    }
+    
+    // check if used
+    used = FALSE;
+    for (i = 0; i < 4; i++) {
+        if (table[i].start_lba > 0 && table[i].size > 0) {
+            used = TRUE;
+            break;
+        }
+    }
+    if (!used) {
+        Print(L" No partitions defined\n");
+        return 0;
+    }
+    
+    // dump current state & fill internal structures
+    Print(L" # A    Start LBA      End LBA  Type\n");
+    for (i = 0; i < 4; i++) {
+        if (table[i].start_lba == 0 || table[i].size == 0)
+            continue;
+        
+        mbr_parts[mbr_part_count].index     = i;
+        mbr_parts[mbr_part_count].start_lba = (UINT64)table[i].start_lba;
+        mbr_parts[mbr_part_count].end_lba   = (UINT64)table[i].start_lba + (UINT64)table[i].size - 1;
+        mbr_parts[mbr_part_count].mbr_type  = table[i].type;
+        mbr_parts[mbr_part_count].active    = (table[i].flags == 0x80) ? TRUE : FALSE;
+        
+        Print(L" %d %s %12lld %12lld  %02x  %s\n",
+              mbr_parts[mbr_part_count].index + 1,
+              mbr_parts[mbr_part_count].active ? STR("*") : STR(" "),
+              mbr_parts[mbr_part_count].start_lba,
+              mbr_parts[mbr_part_count].end_lba,
+              mbr_parts[mbr_part_count].mbr_type,
+              mbr_parttype_name(mbr_parts[mbr_part_count].mbr_type));
+        
+        mbr_part_count++;
+    }
+    
+    return 0;
+}
+
+//
+// GPT functions
+//
+
+GPT_PARTTYPE * gpt_parttype(UINT8 *type_guid)
+{
+    int i;
+    
+    for (i = 0; gpt_types[i].name; i++)
+        if (guids_are_equal(gpt_types[i].guid, type_guid))
+            return &(gpt_types[i]);
+    return &gpt_dummy_type;
+}
+
+UINTN read_gpt(VOID)
+{
+    UINTN       status;
+    GPT_HEADER  *header;
+    GPT_ENTRY   *entry;
+    UINT64      entry_lba;
+    UINTN       entry_count, entry_size, i;
+    
+    Print(L"\nCurrent GPT partition table:\n");
+    
+    // read GPT header
+    status = read_sector(1, sector);
+    if (status != 0)
+        return status;
+    
+    // check signature
+    header = (GPT_HEADER *)sector;
+    if (header->signature != 0x5452415020494645ULL) {
+        Print(L" No GPT partition table present!\n");
+        return 0;
+    }
+    if (header->spec_revision != 0x00010000UL) {
+        Print(L" Warning: Unknown GPT spec revision 0x%08x\n", header->spec_revision);
+    }
+    if ((512 % header->entry_size) > 0 || header->entry_size > 512) {
+        Print(L" Error: Invalid GPT entry size (misaligned or more than 512 bytes)\n");
+        return 0;
+    }
+    
+    // read entries
+    entry_lba   = header->entry_lba;
+    entry_size  = header->entry_size;
+    entry_count = header->entry_count;
+    
+    for (i = 0; i < entry_count; i++) {
+        if (((i * entry_size) % 512) == 0) {
+            status = read_sector(entry_lba, sector);
+            if (status != 0)
+                return status;
+            entry_lba++;
+        }
+        entry = (GPT_ENTRY *)(sector + ((i * entry_size) % 512));
+        
+        if (guids_are_equal(entry->type_guid, empty_guid))
+            continue;
+        if (gpt_part_count == 0) {
+            Print(L" #      Start LBA      End LBA  Type\n");
+        }
+        
+        gpt_parts[gpt_part_count].index     = i;
+        gpt_parts[gpt_part_count].start_lba = entry->start_lba;
+        gpt_parts[gpt_part_count].end_lba   = entry->end_lba;
+        gpt_parts[gpt_part_count].mbr_type  = 0;
+        copy_guid(gpt_parts[gpt_part_count].gpt_type, entry->type_guid);
+        gpt_parts[gpt_part_count].gpt_parttype = gpt_parttype(gpt_parts[gpt_part_count].gpt_type);
+        gpt_parts[gpt_part_count].active    = FALSE;
+        
+        Print(L" %d   %12lld %12lld  %s\n",
+              gpt_parts[gpt_part_count].index + 1,
+              gpt_parts[gpt_part_count].start_lba,
+              gpt_parts[gpt_part_count].end_lba,
+              gpt_parts[gpt_part_count].gpt_parttype->name);
+        
+        gpt_part_count++;
+    }
+    if (gpt_part_count == 0) {
+        Print(L" No partitions defined\n");
+        return 0;
+    }
+    
+    return 0;
+}
+
+//
+// detect file system type
+//
+
+UINTN detect_mbrtype_fs(UINT64 partlba, UINTN *parttype, CHARN **fsname)
+{
+    UINTN   status;
+    UINTN   signature, score;
+    UINTN   sectsize, clustersize, reserved, fatcount, dirsize, sectcount, fatsize, clustercount;
+    
+    *fsname = STR("Unknown");
+    *parttype = 0;
+    
+    // READ sector 0 / offset 0K
+    status = read_sector(partlba, sector);
+    if (status != 0)
+        return status;
+    
+    // detect XFS
+    memcpy(&signature, sector, sizeof(UINT32));
+    if (signature == 0x42534658) {
+        *parttype = 0x83;
+        *fsname = STR("XFS");
+        return 0;
+    }
+    
+    // detect FAT and NTFS
+    sectsize = *((UINT16 *)(sector + 11));
+    clustersize = sector[13];
+    if (sectsize >= 512 && (sectsize & (sectsize - 1)) == 0 &&
+        clustersize > 0 && (clustersize & (clustersize - 1)) == 0) {
+        // preconditions for both FAT and NTFS are now met
+        
+        if (CompareMem(sector + 3, "NTFS    ", 8) == 0) {
+            *parttype = 0x07;
+            *fsname = STR("NTFS");
+            return 0;
+        }
+        
+        score = 0;
+        // boot jump
+        if ((sector[0] == 0xEB && sector[2] == 0x90) || 
+            sector[0] == 0xE9)
+            score++;
+        // boot signature
+        if (sector[510] == 0x55 && sector[511] == 0xAA)
+            score++;
+        // reserved sectors
+        reserved = *((UINT16 *)(sector + 14));
+        if (reserved == 1 || reserved == 32)
+            score++;
+        // number of FATs
+        fatcount = sector[16];
+        if (fatcount == 2)
+            score++;
+        // number of root dir entries
+        dirsize = *((UINT16 *)(sector + 17));
+        // sector count (16-bit and 32-bit versions)
+        sectcount = *((UINT16 *)(sector + 19));
+        if (sectcount == 0)
+            sectcount = *((UINT32 *)(sector + 32));
+        // media byte
+        if (sector[21] == 0xF0 || sector[21] >= 0xF8)
+            score++;
+        // FAT size in sectors
+        fatsize = *((UINT16 *)(sector + 22));
+        if (fatsize == 0)
+            fatsize = *((UINT32 *)(sector + 36));
+        
+        // determine FAT type
+        dirsize = ((dirsize * 32) + (sectsize - 1)) / sectsize;
+        clustercount = sectcount - (reserved + (fatcount * fatsize) + dirsize);
+        clustercount /= clustersize;
+        
+        if (score >= 3) {
+            if (clustercount < 4085) {
+                *parttype = 0x01;
+                *fsname = STR("FAT12");
+            } else if (clustercount < 65525) {
+                *parttype = 0x0e;
+                *fsname = STR("FAT16");
+            } else {
+                *parttype = 0x0c;
+                *fsname = STR("FAT32");
+            }
+            // TODO: check if 0e and 0c are okay to use, maybe we should use 06 and 0b instead...
+            return 0;
+        }
+    }
+    
+    // READ sector 2 / offset 1K
+    status = read_sector(partlba + 2, sector);
+    if (status != 0)
+        return status;
+    
+    // detect HFS+
+    memcpy(&signature, sector, sizeof(UINT16));
+    if (signature == 0x4442) {
+        *parttype = 0xaf;
+        if (*((UINT16 *)(sector + 0x7c)) == 0x2B48)
+            *fsname = STR("HFS Extended (HFS+)");
+        else
+            *fsname = STR("HFS Standard");
+        return 0;
+    } else if (signature == 0x2B48) {
+        *parttype = 0xaf;
+        *fsname = STR("HFS Extended (HFS+)");
+        return 0;
+    }
+    
+    // detect ext2/ext3
+    signature = *((UINT16 *)(sector + 56));
+    if (signature == 0xEF53) {
+        *parttype = 0x83;
+        if (*((UINT16 *)(sector + 92)) & 0x0004)
+            *fsname = STR("ext3");
+        else
+            *fsname = STR("ext2");
+        return 0;
+    }
+    
+    // READ sector 128 / offset 64K
+    status = read_sector(partlba + 128, sector);
+    if (status != 0)
+        return status;
+    
+    // detect ReiserFS
+    if (CompareMem(sector + 52, "ReIsErFs", 8) == 0 ||
+        CompareMem(sector + 52, "ReIsEr2Fs", 9) == 0 ||
+        CompareMem(sector + 52, "ReIsEr3Fs", 9) == 0) {
+        *parttype = 0x83;
+        *fsname = STR("ReiserFS");
+        return 0;
+    }
+    
+    // detect Reiser4
+    if (CompareMem(sector, "ReIsEr4", 7) == 0) {
+        *parttype = 0x83;
+        *fsname = STR("Reiser4");
+        return 0;
+    }
+    
+    // READ sector 64 / offset 32K
+    status = read_sector(partlba + 64, sector);
+    if (status != 0)
+        return status;
+    
+    // detect JFS
+    if (CompareMem(sector, "JFS1", 4) == 0) {
+        *parttype = 0x83;
+        *fsname = STR("JFS");
+        return 0;
+    }
+    
+    // READ sector 16 / offset 8K
+    status = read_sector(partlba + 16, sector);
+    if (status != 0)
+        return status;
+    
+    // detect ReiserFS
+    if (CompareMem(sector + 52, "ReIsErFs", 8) == 0 ||
+        CompareMem(sector + 52, "ReIsEr2Fs", 9) == 0 ||
+        CompareMem(sector + 52, "ReIsEr3Fs", 9) == 0) {
+        *parttype = 0x83;
+        *fsname = STR("ReiserFS");
+        return 0;
+    }
+    
+    return 0;
+}
diff --git a/bin/gptsync/os_unix.c b/bin/gptsync/os_unix.c
new file mode 100644
index 0000000..b43685b
--- /dev/null
+++ b/bin/gptsync/os_unix.c
@@ -0,0 +1,267 @@
+/*
+ * gptsync/os_unix.c
+ * Unix OS glue for gptsync
+ *
+ * Copyright (c) 2006 Christoph Pfisterer
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *  * Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ *  * Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the
+ *    distribution.
+ *
+ *  * Neither the name of Christoph Pfisterer nor the names of the
+ *    contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "gptsync.h"
+
+#include <stdarg.h>
+
+#define STRINGIFY(s) #s
+#define STRINGIFY2(s) STRINGIFY(s)
+#define PROGNAME_S STRINGIFY2(PROGNAME)
+
+// variables
+
+static int      fd;
+
+//
+// error functions
+//
+
+void error(const char *msg, ...)
+{
+    va_list par;
+    char buf[4096];
+    
+    va_start(par, msg);
+    vsnprintf(buf, 4096, msg, par);
+    va_end(par);
+    
+    fprintf(stderr, PROGNAME_S ": %s\n", buf);
+}
+
+void errore(const char *msg, ...)
+{
+    va_list par;
+    char buf[4096];
+    
+    va_start(par, msg);
+    vsnprintf(buf, 4096, msg, par);
+    va_end(par);
+    
+    fprintf(stderr, PROGNAME_S ": %s: %s\n", buf, strerror(errno));
+}
+
+//
+// sector I/O functions
+//
+
+UINTN read_sector(UINT64 lba, UINT8 *buffer)
+{
+    off_t   offset;
+    off_t   result_seek;
+    ssize_t result_read;
+    
+    offset = lba * 512;
+    result_seek = lseek(fd, offset, SEEK_SET);
+    if (result_seek != offset) {
+        errore("Seek to %llu failed", offset);
+        return 1;
+    }
+    
+    result_read = read(fd, buffer, 512);
+    if (result_read < 0) {
+        errore("Data read failed at position %llu", offset);
+        return 1;
+    }
+    if (result_read != 512) {
+        errore("Data read fell short at position %llu", offset);
+        return 1;
+    }
+    return 0;
+}
+
+UINTN write_sector(UINT64 lba, UINT8 *buffer)
+{
+    off_t   offset;
+    off_t   result_seek;
+    ssize_t result_write;
+    
+    offset = lba * 512;
+    result_seek = lseek(fd, offset, SEEK_SET);
+    if (result_seek != offset) {
+        errore("Seek to %llu failed", offset);
+        return 1;
+    }
+    
+    result_write = write(fd, buffer, 512);
+    if (result_write < 0) {
+        errore("Data write failed at position %llu", offset);
+        return 1;
+    }
+    if (result_write != 512) {
+        errore("Data write fell short at position %llu", offset);
+        return 1;
+    }
+    return 0;
+}
+
+//
+// keyboard input
+//
+
+UINTN input_boolean(CHARN *prompt, BOOLEAN *bool_out)
+{
+    int c;
+    
+    printf("%s", prompt);
+    fflush(NULL);
+    
+    c = getchar();
+    if (c == EOF)
+        return 1;
+    
+    if (c == 'y' || c == 'Y') {
+        printf("Yes\n");
+        *bool_out = TRUE;
+    } else {
+        printf("No\n");
+        *bool_out = FALSE;
+    }
+    
+    return 0;
+}
+
+//
+// EFI-style print function
+//
+
+void Print(wchar_t *format, ...)
+{
+    va_list par;
+    char formatbuf[256];
+    char buf[4096];
+    int i;
+    
+    for (i = 0; format[i]; i++)
+        formatbuf[i] = (format[i] > 255) ? '?' : (char)(format[i] & 0xff);
+    formatbuf[i] = 0;
+    
+    va_start(par, format);
+    vsnprintf(buf, 4096, formatbuf, par);
+    va_end(par);
+    
+    printf("%s", buf);
+}
+
+//
+// main entry point
+//
+
+int main(int argc, char *argv[])
+{
+    char        *filename;
+    struct stat sb;
+    int         filekind;
+    UINT64      filesize;
+    char        *reason;
+    int         status;
+    
+    // argument check
+    if (argc != 2) {
+        fprintf(stderr, "Usage: " PROGNAME_S " <device>\n");
+        return 1;
+    }
+    filename = argv[1];
+    
+    // set input to unbuffered
+    fflush(NULL);
+    setvbuf(stdin, NULL, _IONBF, 0);
+    
+    // stat check
+    if (stat(filename, &sb) < 0) {
+        errore("Can't stat %.300s", filename);
+        return 1;
+    }
+    
+    filekind = 0;
+    filesize = 0;
+    reason = NULL;
+    if (S_ISREG(sb.st_mode))
+        filesize = sb.st_size;
+    else if (S_ISBLK(sb.st_mode))
+        filekind = 1;
+    else if (S_ISCHR(sb.st_mode))
+        filekind = 2;
+    else if (S_ISDIR(sb.st_mode))
+        reason = "Is a directory";
+    else if (S_ISFIFO(sb.st_mode))
+        reason = "Is a FIFO";
+#ifdef S_ISSOCK
+    else if (S_ISSOCK(sb.st_mode))
+        reason = "Is a socket";
+#endif
+    else
+        reason = "Is an unknown kind of special file";
+    
+    if (reason != NULL) {
+        error("%.300s: %s", filename, reason);
+        return 1;
+    }
+    
+    // open file
+    fd = open(filename, O_RDWR);
+    if (fd < 0 && errno == EBUSY) {
+        fd = open(filename, O_RDONLY);
+#ifndef NOREADONLYWARN
+        if (fd >= 0)
+            printf("Warning: %.300s opened read-only\n", filename);
+#endif
+    }
+    if (fd < 0) {
+        errore("Can't open %.300s", filename);
+        return 1;
+    }
+    
+    // (try to) guard against TTY character devices
+    if (filekind == 2) {
+        if (isatty(fd)) {
+            error("%.300s: Is a TTY device", filename);
+            return 1;
+        }
+    }
+    
+    // run sync algorithm
+    status = PROGNAME();
+    printf("\n");
+    
+    // close file
+    if (close(fd) != 0) {
+        errore("Error while closing %.300s", filename);
+        return 1;
+    }
+    
+    return status;
+}
diff --git a/bin/gptsync/showpart.c b/bin/gptsync/showpart.c
new file mode 100644
index 0000000..3d52ba3
--- /dev/null
+++ b/bin/gptsync/showpart.c
@@ -0,0 +1,257 @@
+/*
+ * gptsync/showpart.c
+ * Platform-independent code for analyzing hard disk partitioning
+ *
+ * Copyright (c) 2006 Christoph Pfisterer
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *  * Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ *  * Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the
+ *    distribution.
+ *
+ *  * Neither the name of Christoph Pfisterer nor the names of the
+ *    contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "gptsync.h"
+
+//
+// memory string search
+//
+
+static INTN FindMem(VOID *Buffer, UINTN BufferLength, VOID *SearchString, UINTN SearchStringLength)
+{
+    UINT8 *BufferPtr;
+    UINTN Offset;
+    
+    BufferPtr = Buffer;
+    BufferLength -= SearchStringLength;
+    for (Offset = 0; Offset < BufferLength; Offset++, BufferPtr++) {
+        if (CompareMem(BufferPtr, SearchString, SearchStringLength) == 0)
+            return (INTN)Offset;
+    }
+    
+    return -1;
+}
+
+//
+// detect boot code
+//
+
+static UINTN detect_bootcode(UINT64 partlba, CHARN **bootcodename)
+{
+    UINTN   status;
+    BOOLEAN bootable;
+    
+    // read MBR data
+    status = read_sector(partlba, sector);
+    if (status != 0)
+        return status;
+    
+    // check bootable signature
+    if (*((UINT16 *)(sector + 510)) == 0xaa55 && sector[0] != 0)
+        bootable = TRUE;
+    else
+        bootable = FALSE;
+    *bootcodename = NULL;
+    
+    // detect specific boot codes
+    if (CompareMem(sector + 2, "LILO", 4) == 0 ||
+        CompareMem(sector + 6, "LILO", 4) == 0) {
+        *bootcodename = STR("LILO");
+        
+    } else if (CompareMem(sector + 3, "SYSLINUX", 8) == 0) {
+        *bootcodename = STR("SYSLINUX");
+        
+    } else if (FindMem(sector, 512, "ISOLINUX", 8) >= 0) {
+        *bootcodename = STR("ISOLINUX");
+        
+    } else if (FindMem(sector, 512, "Geom\0Hard Disk\0Read\0 Error\0", 27) >= 0) {
+        *bootcodename = STR("GRUB");
+        
+    } else if ((*((UINT32 *)(sector + 502)) == 0 &&
+                *((UINT32 *)(sector + 506)) == 50000 &&
+                *((UINT16 *)(sector + 510)) == 0xaa55) ||
+               FindMem(sector, 512, "Starting the BTX loader", 23) >= 0) {
+        *bootcodename = STR("FreeBSD");
+        
+    } else if (FindMem(sector, 512, "!Loading", 8) >= 0 ||
+               FindMem(sector, 512, "/cdboot\0/CDBOOT\0", 16) >= 0) {
+        *bootcodename = STR("OpenBSD");
+        
+    } else if (FindMem(sector, 512, "NTLDR", 5) >= 0) {
+        *bootcodename = STR("Windows NTLDR");
+        
+    } else if (FindMem(sector, 512, "BOOTMGR", 7) >= 0) {
+        *bootcodename = STR("Windows BOOTMGR (Vista)");
+        
+    } else if (FindMem(sector, 512, "CPUBOOT SYS", 11) >= 0 ||
+               FindMem(sector, 512, "KERNEL  SYS", 11) >= 0) {
+        *bootcodename = STR("FreeDOS");
+        
+    } else if (FindMem(sector, 512, "OS2LDR", 6) >= 0 ||
+               FindMem(sector, 512, "OS2BOOT", 7) >= 0) {
+        *bootcodename = STR("eComStation");
+        
+    } else if (FindMem(sector, 512, "Be Boot Loader", 14) >= 0) {
+        *bootcodename = STR("BeOS");
+        
+    } else if (FindMem(sector, 512, "yT Boot Loader", 14) >= 0) {
+        *bootcodename = STR("ZETA");
+        
+    } else if (FindMem(sector, 512, "\x04" "beos\x06" "system\x05" "zbeos", 18) >= 0) {
+        *bootcodename = STR("Haiku");
+        
+    }
+    
+    if (FindMem(sector, 512, "Non-system disk", 15) >= 0)   // dummy FAT boot sector
+        *bootcodename = STR("None (Non-system disk message)");
+    
+    // TODO: Add a note if a specific code was detected, but the sector is not bootable?
+    
+    if (*bootcodename == NULL) {
+        if (bootable)
+            *bootcodename = STR("Unknown, but bootable");
+        else
+            *bootcodename = STR("None");
+    }
+    
+    return 0;
+}
+
+//
+// check one partition
+//
+
+static UINTN analyze_part(UINT64 partlba)
+{
+    UINTN   status;
+    UINTN   i;
+    CHARN   *bootcodename;
+    UINTN   parttype;
+    CHARN   *fsname;
+    
+    if (partlba == 0)
+        Print(L"\nMBR contents:\n");
+    else
+        Print(L"\nPartition at LBA %lld:\n", partlba);
+    
+    // detect boot code
+    status = detect_bootcode(partlba, &bootcodename);
+    if (status)
+        return status;
+    Print(L" Boot Code: %s\n", bootcodename);
+    
+    if (partlba == 0)
+        return 0;   // short-circuit MBR analysis
+    
+    // detect file system
+    status = detect_mbrtype_fs(partlba, &parttype, &fsname);
+    if (status)
+        return status;
+    Print(L" File System: %s\n", fsname);
+    
+    // cross-reference with partition table
+    for (i = 0; i < gpt_part_count; i++) {
+        if (gpt_parts[i].start_lba == partlba) {
+            Print(L" Listed in GPT as partition %d, type %s\n", i+1,
+                  gpt_parts[i].gpt_parttype->name);
+        }
+    }
+    for (i = 0; i < mbr_part_count; i++) {
+        if (mbr_parts[i].start_lba == partlba) {
+            Print(L" Listed in MBR as partition %d, type %02x  %s%s\n", i+1,
+                  mbr_parts[i].mbr_type,
+                  mbr_parttype_name(mbr_parts[i].mbr_type),
+                  mbr_parts[i].active ? STR(", active") : STR(""));
+        }
+    }
+    
+    return 0;
+}
+
+//
+// check all partitions
+//
+
+static UINTN analyze_parts(VOID)
+{
+    UINTN   i, k;
+    UINTN   status;
+    BOOLEAN is_dupe;
+    
+    // check MBR (bootcode only)
+    status = analyze_part(0);
+    if (status)
+        return status;
+    
+    // check partitions listed in GPT
+    for (i = 0; i < gpt_part_count; i++) {
+        status = analyze_part(gpt_parts[i].start_lba);
+        if (status)
+            return status;
+    }
+    
+    // check partitions listed in MBR, but not in GPT
+    for (i = 0; i < mbr_part_count; i++) {
+        if (mbr_parts[i].start_lba == 1 && mbr_parts[i].mbr_type == 0xee)
+            continue;   // skip EFI Protective entry
+        
+        is_dupe = FALSE;
+        for (k = 0; k < gpt_part_count; k++)
+            if (gpt_parts[k].start_lba == mbr_parts[i].start_lba)
+                is_dupe = TRUE;
+        
+        if (!is_dupe) {
+            status = analyze_part(mbr_parts[i].start_lba);
+            if (status)
+                return status;
+        }
+    }
+    
+    return 0;
+}
+
+//
+// display algorithm entry point
+//
+
+UINTN showpart(VOID)
+{
+    UINTN   status = 0;
+    UINTN   status_gpt, status_mbr;
+    
+    // get full information from disk
+    status_gpt = read_gpt();
+    status_mbr = read_mbr();
+    if (status_gpt != 0 || status_mbr != 0)
+        return (status_gpt || status_mbr);
+    
+    // analyze all partitions
+    status = analyze_parts();
+    if (status != 0)
+        return status;
+    
+    return status;
+}
diff --git a/bin/gptsync/syslinux_mbr.h b/bin/gptsync/syslinux_mbr.h
new file mode 100644
index 0000000..1c33e11
--- /dev/null
+++ b/bin/gptsync/syslinux_mbr.h
@@ -0,0 +1,90 @@
+/*
+ * include/syslinux_mbr.h
+ * MBR boot code
+ *
+ * The boot code in this file was taken from syslinux-3.11. It is covered
+ * by the following license:
+ *
+ ; -----------------------------------------------------------------------
+ ;   
+ ;   Copyright 2003-2004 H. Peter Anvin - All Rights Reserved
+ ;
+ ;   Permission is hereby granted, free of charge, to any person
+ ;   obtaining a copy of this software and associated documentation
+ ;   files (the "Software"), to deal in the Software without
+ ;   restriction, including without limitation the rights to use,
+ ;   copy, modify, merge, publish, distribute, sublicense, and/or
+ ;   sell copies of the Software, and to permit persons to whom
+ ;   the Software is furnished to do so, subject to the following
+ ;   conditions:
+ ;   
+ ;   The above copyright notice and this permission notice shall
+ ;   be included in all copies or substantial portions of the Software.
+ ;   
+ ;   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ ;   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ ;   OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ ;   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ ;   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ ;   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ ;   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ ;   OTHER DEALINGS IN THE SOFTWARE.
+ ;
+ ; -----------------------------------------------------------------------
+ *
+ */
+
+#ifndef __SYSLINUX_MBR_H__
+#define __SYSLINUX_MBR_H__
+
+
+#define MBR_BOOTCODE_SIZE (440)
+
+
+#define SYSLINUX_MBR_SIZE (304)
+
+static UINT8 syslinux_mbr[SYSLINUX_MBR_SIZE] = {
+    0xfa, 0x31, 0xc0, 0x8e, 0xd8, 0x8e, 0xc0, 0x8e,
+    0xd0, 0xbc, 0x00, 0x7c, 0xfb, 0xfc, 0x89, 0xe6,
+    0xbf, 0x00, 0x06, 0xb9, 0x00, 0x01, 0xf3, 0xa5,
+    0xea, 0x1d, 0x06, 0x00, 0x00, 0x88, 0x16, 0x00,
+    0x08, 0xb4, 0x08, 0xcd, 0x13, 0x31, 0xc0, 0x88,
+    0xf0, 0x40, 0xa3, 0xf0, 0x06, 0x80, 0xe1, 0x3f,
+    0x88, 0x0e, 0xf2, 0x06, 0xbe, 0xbe, 0x07, 0x31,
+    0xc0, 0xb9, 0x04, 0x00, 0xf6, 0x04, 0x80, 0x74,
+    0x03, 0x40, 0x89, 0xf7, 0x83, 0xc6, 0x10, 0xe2,
+    0xf3, 0x83, 0xf8, 0x01, 0x75, 0x73, 0x8a, 0x16,
+    0x00, 0x08, 0xb8, 0x00, 0x41, 0xbb, 0xaa, 0x55,
+    0x31, 0xc9, 0x30, 0xf6, 0xf9, 0xcd, 0x13, 0x72,
+    0x23, 0x81, 0xfb, 0x55, 0xaa, 0x75, 0x1d, 0xf6,
+    0xc1, 0x01, 0x74, 0x18, 0x57, 0xbe, 0xe0, 0x06,
+    0x8b, 0x5d, 0x08, 0x89, 0x5c, 0x08, 0x8b, 0x5d,
+    0x0a, 0x89, 0x5c, 0x0a, 0x8a, 0x16, 0x00, 0x08,
+    0xb4, 0x42, 0xeb, 0x2a, 0x57, 0x8b, 0x45, 0x08,
+    0x8b, 0x55, 0x0a, 0xf7, 0x36, 0xf2, 0x06, 0x42,
+    0x89, 0xd1, 0x31, 0xd2, 0xf7, 0x36, 0xf0, 0x06,
+    0x88, 0xc5, 0xd1, 0xe8, 0xd1, 0xe8, 0x24, 0xc0,
+    0x08, 0xc1, 0x88, 0xd6, 0x8a, 0x16, 0x00, 0x08,
+    0xbb, 0x00, 0x7c, 0xb8, 0x01, 0x02, 0xcd, 0x13,
+    0x72, 0x16, 0x5e, 0x81, 0x3e, 0xfe, 0x7d, 0x55,
+    0xaa, 0x75, 0x08, 0xfa, 0xea, 0x00, 0x7c, 0x00,
+    0x00, 0x77, 0x05, 0xbe, 0xf4, 0x06, 0xeb, 0x03,
+    0xbe, 0x0f, 0x07, 0xac, 0x20, 0xc0, 0x74, 0x0c,
+    0xb4, 0x0e, 0x8a, 0x3e, 0x62, 0x04, 0xb3, 0x07,
+    0xcd, 0x10, 0xeb, 0xef, 0xeb, 0xfe, 0x00, 0x00,
+    0x10, 0x00, 0x01, 0x00, 0x00, 0x7c, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x4d, 0x69, 0x73, 0x73,
+    0x69, 0x6e, 0x67, 0x20, 0x6f, 0x70, 0x65, 0x72,
+    0x61, 0x74, 0x69, 0x6e, 0x67, 0x20, 0x73, 0x79,
+    0x73, 0x74, 0x65, 0x6d, 0x0d, 0x0a, 0x00, 0x4f,
+    0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6e, 0x67,
+    0x20, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x20,
+    0x6c, 0x6f, 0x61, 0x64, 0x69, 0x6e, 0x67, 0x20,
+    0x65, 0x72, 0x72, 0x6f, 0x72, 0x0d, 0x0a, 0x00
+};
+
+
+#endif /* __SYSLINUX_MBR_H__ */
+
+/* EOF */
diff --git a/bin/loader/.gitignore b/bin/loader/.gitignore
new file mode 100644
index 0000000..021a962
--- /dev/null
+++ b/bin/loader/.gitignore
@@ -0,0 +1,12 @@
+ctype.c
+mkctype
+loader
+init
+debug.log
+loader.tr
+.depend
+font.bgf.gz
+loader.po
+shutdown
+checkisomd5
+tr
diff --git a/bin/loader/Makefile.am b/bin/loader/Makefile.am
new file mode 100644
index 0000000..18f1fbe
--- /dev/null
+++ b/bin/loader/Makefile.am
@@ -0,0 +1,118 @@
+# loader/Makefile.am for anaconda
+#
+# Copyright (C) 2009  Red Hat, Inc.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License as published
+# by the Free Software Foundation; either version 2.1 of the License, or
+# (at your option) any later version.
+#
+# 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 Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+#
+# Author: David Cantrell <dcantrell@xxxxxxxxxx>
+
+bootdir            = $(libdir)/$(PACKAGE_NAME)
+shareddir          = $(datadir)/$(PACKAGE_NAME)
+
+boot_PROGRAMS      = loader
+shared_DATA        = loader.tr
+dist_shared_DATA   = unicode-linedraw-chars.txt
+noinst_PROGRAMS    = mkctype dirbrowser
+noinst_DATA        = ctype.c
+noinst_HEADERS     = *.h
+
+if IS_S390
+boot_PROGRAMS      += shutdown
+dist_shared_SCRIPTS  = linuxrc.s390
+else
+boot_PROGRAMS       += init
+endif
+
+if IS_KEYMAPS_OVERRIDE_ARCH
+keymapsdir         = $(datadir)/$(PACKAGE_NAME)
+keymaps_DATA       = keymaps-override-$(ARCH)
+endif
+
+COMMON_CFLAGS      = -DUSE_LOGDEV -DVERSION='"$(PACKAGE_VERSION)"'
+
+loader_CFLAGS      = $(COMMON_CFLAGS) $(GLIB_CFLAGS) $(LIBNM_GLIB_CFLAGS) \
+                     $(LIBCURL_CFLAGS) $(IPV6_CFLAGS) $(LIBARCHIVE_CFLAGS) \
+                     $(RPM_CFLAGS) -DINCLUDE_LOCAL -DINCLUDE_NETWORK
+loader_LDADD       = $(NEWT_LIBS) $(GLIB_LIBS) $(LIBNL_LIBS) \
+                     $(LIBNM_GLIB_LIBS) $(CHECKISOMD5_LIBS) \
+                     $(LIBCURL_LIBS) $(LIBARCHIVE_LIBS) $(RPM_LIBS) \
+                     $(ISCSI_LIBS) $(top_srcdir)/isys/libisys.la -lm
+loader_SOURCES     = loader.c copy.c moduleinfo.c loadermisc.c \
+                     modules.c windows.c lang.c kbd.c driverdisk.c \
+                     selinux.c mediacheck.c kickstart.c driverselect.c \
+                     getparts.c dirbrowser.c fwloader.c ibft.c hardware.c \
+                     method.c cdinstall.c hdinstall.c nfsinstall.c \
+                     urlinstall.c net.c urls.c telnet.c telnetd.c \
+                     rpmextract.c
+
+init_CFLAGS        = $(COMMON_CFLAGS) $(GLIB_CFLAGS)
+init_LDADD	   = $(GLIB_LIBS)
+init_SOURCES       = init.c undomounts.c shutdown.c copy.c
+
+shutdown_CFLAGS    = $(COMMON_CFLAGS) -DAS_SHUTDOWN=1
+shutdown_SOURCES   = shutdown.c undomounts.c
+
+mkctype_CFLAGS     = $(COMMON_CFLAGS)
+mkctype_SOURCES    = mkctype.c
+
+dirbrowser_CFLAGS  = $(COMMON_CFLAGS) -DSTANDALONE
+dirbrowser_LDADD   = $(NEWT_LIBS)
+dirbrowser_SOURCES = dirbrowser.c
+
+EXTRA_DIST = simplemot keymaps-*
+
+CLEANFILES = keymaps-override-$(ARCH) ctype.c tr/*.tr
+
+MAINTAINERCLEANFILES = Makefile.in
+
+sed_verbose = $(sed_verbose_$(V))
+sed_verbose_ = $(sed_verbose_$(AM_DEFAULT_VERBOSITY))
+sed_verbose_0 = @echo "  SED    "$@;
+
+cp_verbose = $(cp_verbose_$(V))
+cp_verbose_ = $(cp_verbose_$(AM_DEFAULT_VERBOSITY))
+cp_verbose_0 = @echo "  CP     "$@;
+
+mkctype_verbose = $(mkctype_verbose_$(V))
+mkctype_verbose_ = $(mkctype_verbose_$(AM_DEFAULT_VERBOSITY))
+mkctype_verbose_0 = @echo "  MAKE   "$@;
+
+msgmerge_verbose = $(msgmerge_verbose_$(V))
+msgmerge_verbose_ = $(msgmerge_verbose_$(AM_DEFAULT_VERBOSITY))
+msgmerge_verbose_0 = echo "  MERGE  "$${lang}.po;
+
+xgettext_verbose = $(xgettext_verbose_$(V))
+xgettext_verbose_ = $(xgettext_verbose_$(AM_DEFAULT_VERBOSITY))
+xgettext_verbose_0 = @echo "  GETTXT "$@;
+
+keymaps-override-$(ARCH): keymaps-$(ARCH)
+	$(cp_verbose)cp -p $< $@
+
+ctype.c: mkctype
+	$(mkctype_verbose)./mkctype > ctype.c
+
+loader.tr: $(top_srcdir)/lang-table loader.po
+	@LANGS="`cut -f 2 $(top_srcdir)/lang-table | egrep -v '(^en$$)'`" ; \
+	if [ ! -d tr ]; then \
+		mkdir -p tr ; \
+	fi ; \
+	for lang in $$LANGS ; do \
+		$(msgmerge_verbose)msgmerge -q $(top_srcdir)/po/$$lang.po loader.po | msgconv -t utf-8 | ./simplemot > tr/$$lang.tr ; \
+	done ; \
+	(cd tr ; ls -1 *.tr | cpio --quiet -Hcrc -o | gzip -9) > $@
+
+loader.po:
+	$(xgettext_verbose)xgettext --default-domain=loader --add-comments \
+		--keyword=_ --keyword=N_ *.c
+	$(sed_verbose)sed -i 's/charset=CHARSET/charset=UTF-8/' $@
diff --git a/bin/loader/cdinstall.c b/bin/loader/cdinstall.c
new file mode 100644
index 0000000..9d5cee1
--- /dev/null
+++ b/bin/loader/cdinstall.c
@@ -0,0 +1,509 @@
+/*
+ * cdinstall.c - code to set up cdrom installs
+ *
+ * Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003  Red Hat, Inc.
+ * 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 as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ *
+ * Author(s): Erik Troan <ewt@xxxxxxxxxx>
+ *            Matt Wilson <msw@xxxxxxxxxx>
+ *            Michael Fulbright <msf@xxxxxxxxxx>
+ *            Jeremy Katz <katzj@xxxxxxxxxx>
+ */
+
+#include <ctype.h>
+#include <dirent.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <newt.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/mount.h>
+#include <sys/ioctl.h>
+#include <unistd.h>
+/* FIXME Remove hack when: https://bugzilla.redhat.com/show_bug.cgi?id=478663
+   is resolved */
+/* Hack both __BIG_ENDIAN and __LITTLE_ENDIAN get defined by glibc, the
+   kernel headers we need do not like this! */
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+#undef __BIG_ENDIAN 
+#else
+#undef __LITTLE_ENDIAN
+#endif
+#include <asm/types.h>
+#include <limits.h>
+#include <linux/cdrom.h>
+
+#include "kickstart.h"
+#include "loader.h"
+#include "loadermisc.h"
+#include "lang.h"
+#include "modules.h"
+#include "method.h"
+#include "cdinstall.h"
+#include "mediacheck.h"
+#include "windows.h"
+
+#include "../isys/imount.h"
+#include "../isys/isys.h"
+#include "../isys/log.h"
+
+/* boot flags */
+extern uint64_t flags;
+
+/* ejects the CD device the device node points at */
+static void ejectCdrom(char *device) {
+    int ejectfd;
+
+    if (!device) return;
+    logMessage(INFO, "ejecting %s...",device);
+    if ((ejectfd = open(device, O_RDONLY | O_NONBLOCK, 0)) >= 0) {
+        ioctl(ejectfd, CDROM_LOCKDOOR, 0);
+        if (ioctl(ejectfd, CDROMEJECT, 0))
+            logMessage(ERROR, "eject failed on device %s: %m", device);
+        close(ejectfd);
+    } else {
+        logMessage(ERROR, "could not open device %s: %m", device);
+    }
+}
+
+static char *cdrom_drive_status(int rc) {
+    struct {
+        int code;
+        char *str;
+    } status_codes[] =
+        {
+            { CDS_NO_INFO, "CDS_NO_INFO" },
+            { CDS_NO_DISC, "CDS_NO_DISC" },
+            { CDS_TRAY_OPEN, "CDS_TRAY_OPEN" },
+            { CDS_DRIVE_NOT_READY, "CDS_DRIVE_NOT_READY" },
+            { CDS_DISC_OK, "CDS_DISC_OK" },
+            { CDS_AUDIO, "CDS_AUDIO" },
+            { CDS_DATA_1, "CDS_DATA_1" },
+            { CDS_DATA_2, "CDS_DATA_2" },
+            { CDS_XA_2_1, "CDS_XA_2_1" },
+            { CDS_XA_2_2, "CDS_XA_2_2" },
+            { CDS_MIXED, "CDS_MIXED" },
+            { INT_MAX, NULL },
+        };
+    int i;
+
+    if (rc < 0)
+        return strerror(-rc);
+
+    for (i = 0; status_codes[i].code != INT_MAX; i++) {
+        if (status_codes[i].code == rc)
+            return status_codes[i].str;
+    }
+    return NULL;
+}
+
+static int waitForCdromTrayClose(int fd) {
+    int rc;
+    int prev = INT_MAX;
+
+    do {
+        char *status = NULL;
+        rc = ioctl(fd, CDROM_DRIVE_STATUS, CDSL_CURRENT);
+        if (rc < 0)
+            rc = -errno;
+
+        /* only bother to print the status if it changes */
+        if (prev == INT_MAX || prev != rc) {
+            status = cdrom_drive_status(rc);
+            if (status != NULL) {
+                logMessage(INFO, "drive status is %s", status);
+            } else {
+                logMessage(INFO, "drive status is unknown status code %d", rc);
+            }
+        }
+        prev = rc;
+        if (rc == CDS_DRIVE_NOT_READY)
+            usleep(100000);
+    } while (rc == CDS_DRIVE_NOT_READY);
+    return rc;
+}
+
+static void closeCdromTray(char *device) {
+    int fd;
+
+    if (!device || !*device)
+        return;
+
+    logMessage(INFO, "closing CD tray on %s .", device);
+    if ((fd = open(device, O_RDONLY | O_NONBLOCK, 0)) >= 0) {
+        if (ioctl(fd, CDROMCLOSETRAY, 0)) {
+            logMessage(ERROR, "closetray failed on device %s: %m", device);
+        } else {
+            waitForCdromTrayClose(fd);
+            ioctl(fd, CDROM_LOCKDOOR, 1);
+        }
+        close(fd);
+    } else {
+        logMessage(ERROR, "could not open device %s: %m", device);
+    }
+}
+
+/* Given cd device cddriver, this function will attempt to check its internal
+ * checksum.
+ */
+static void mediaCheckCdrom(char *cddriver) {
+    int rc;
+    int first;
+
+    first = 1;
+    do {
+        char *descr;
+        char *tstamp;
+        int ejectcd;
+
+        /* init every pass */
+        ejectcd = 0;
+        descr = NULL;
+
+        closeCdromTray(cddriver);
+
+        /* if first time through, see if they want to eject the CD      */
+        /* currently in the drive (most likely the CD they booted from) */
+        /* and test a different disk.  Otherwise just test the disk in  */
+        /* the drive since it was inserted in the previous pass through */
+        /* this loop, so they want it tested.                           */
+        if (first) {
+            first = 0;
+            rc = newtWinChoice(_("Media Check"), _("Test"), _("Eject Disc"),
+                               _("Choose \"%s\" to test the disc currently in "
+                                 "the drive, or \"%s\" to eject the disc and "
+                                 "insert another for testing."), _("Test"),
+                               _("Eject Disc"));
+
+            if (rc == 2)
+                ejectcd = 1;
+        }
+
+        if (!ejectcd) {
+            /* XXX MSFFIXME: should check return code for error */
+            readStampFileFromIso(cddriver, &tstamp, &descr);
+            doMediaCheck(cddriver, descr);
+
+            if (descr)
+                free(descr);
+        }
+
+        ejectCdrom(cddriver);
+
+        rc = newtWinChoice(_("Media Check"), _("Test"), _("Continue"),
+                       _("If you would like to test additional media, "
+                       "insert the next disc and press \"%s\". "
+                       "Testing each disc is not strictly required, however "
+                       "it is highly recommended.  Minimally, the discs should "
+                       "be tested prior to using them for the first time. "
+                       "After they have been successfully tested, it is not "
+                       "required to retest each disc prior to using it again."),
+                       _("Test"), _("Continue"));
+
+        if (rc == 2) {
+            closeCdromTray(cddriver);
+            return;
+        } else {
+            continue;
+        }
+    } while (1);
+}
+
+/* output an error message when CD in drive is not the correct one */
+/* Used by mountCdromStage2()                                      */
+static void wrongCDMessage(void) {
+    newtWinMessage(_("Error"), _("OK"),
+                   _("The %s disc was not found "
+                     "in any of your drives. Please insert "
+                     "the %s disc and press %s to retry."),
+                   getProductName(), getProductName(), _("OK"));
+}
+
+/* ask about doing media check */
+static void queryCDMediaCheck(char *dev, char *location) {
+    int rc;
+    char *stage2loc;
+
+    /* dont bother to test in automated installs */
+    if (FL_KICKSTART(flags) && !FL_MEDIACHECK(flags))
+        return;
+
+    /* see if we should check image(s) */
+    /* in rescue mode only test if they explicitly asked to */
+    if (!FL_RESCUE(flags) || FL_MEDIACHECK(flags)) {
+        startNewt();
+        rc = newtWinChoice(_("Disc Found"), _("OK"), _("Skip"),
+             _("To begin testing the media before installation press %s.\n\n"
+               "Choose %s to skip the media test and start the installation."),
+             _("OK"), _("Skip"));
+
+        if (rc != 2) {
+            /* We already mounted the CD earlier to verify there's at least a
+             * stage2 image.  Now we need to unmount to perform the check, then
+             * remount to pretend nothing ever happened.
+             */
+            umount(location);
+            mediaCheckCdrom(dev);
+
+            do {
+                if (doPwMount(dev, location, "iso9660", "ro", NULL)) {
+                    ejectCdrom(dev);
+                    wrongCDMessage();
+                    continue;
+                }
+
+                checked_asprintf(&stage2loc, "%s/images/install.img",
+                                 location);
+
+                if (access(stage2loc, R_OK)) {
+                    free(stage2loc);
+                    umount(location);
+                    ejectCdrom(dev);
+                    wrongCDMessage();
+                    continue;
+                }
+
+                free(stage2loc);
+                break;
+            } while (1);
+        }
+    }
+}
+
+/* Set up a CD/DVD drive to mount the stage2 image from.  If successful, the
+ * stage2 image will be left mounted on /mnt/runtime.
+ *
+ * location:     Where to mount the media at (usually /mnt/stage2)
+ * loaderData:   The usual, can be NULL if no info
+ * interactive:  Whether or not to prompt about questions/errors
+ * mediaCheck:   Do we run media check or not?
+ */
+static char *setupCdrom(char *location, struct loaderData_s *loaderData,
+                        int interactive, int mediaCheck) {
+    int i, rc;
+    int stage2inram = 0;
+    char *retbuf = NULL, *stage2loc, *stage2img;
+    struct device ** devices;
+    char *cddev = NULL;
+
+    devices = getDevices(DEVICE_CDROM);
+    if (!devices) {
+        logMessage(ERROR, "got to setupCdrom without a CD device");
+        return NULL;
+    }
+
+    checked_asprintf(&stage2loc, "%s/images/install.img", location);
+
+    /* JKFIXME: ASSERT -- we have a cdrom device when we get here */
+    do {
+        for (i = 0; devices[i]; i++) {
+            char *tmp = NULL;
+            int fd;
+
+            if (!devices[i]->device)
+                continue;
+
+            if (strncmp("/dev/", devices[i]->device, 5)) {
+                checked_asprintf(&tmp, "/dev/%s", devices[i]->device);
+
+                free(devices[i]->device);
+                devices[i]->device = tmp;
+            }
+
+            logMessage(INFO, "trying to mount CD device %s on %s",
+                       devices[i]->device, location);
+
+            if (!FL_CMDLINE(flags))
+                winStatus(60, 3, _("Scanning"), _("Looking for installation images on CD device %s\n"), devices[i]->device);
+            else
+                printf(_("Looking for installation images on CD device %s"), devices[i]->device);
+
+            fd = open(devices[i]->device, O_RDONLY | O_NONBLOCK);
+            if (fd < 0) {
+                logMessage(ERROR, "Couldn't open %s: %m", devices[i]->device);
+                if (!FL_CMDLINE(flags))
+                    newtPopWindow();
+                continue;
+            }
+
+            rc = waitForCdromTrayClose(fd);
+            close(fd);
+            switch (rc) {
+                case CDS_NO_INFO:
+                    logMessage(ERROR, "Drive tray reports CDS_NO_INFO");
+                    break;
+                case CDS_NO_DISC:
+                    if (!FL_CMDLINE(flags))
+                            newtPopWindow();
+                    continue;
+                case CDS_TRAY_OPEN:
+                    logMessage(ERROR, "Drive tray reports open when it should be closed");
+                    break;
+                default:
+                    break;
+            }
+
+            if (!FL_CMDLINE(flags))
+                newtPopWindow();
+
+            if (!(rc=doPwMount(devices[i]->device, location, "iso9660", "ro", NULL))) {
+                cddev = devices[i]->device;
+                if (!access(stage2loc, R_OK)) {
+                    char *updpath;
+
+                    if (mediaCheck)
+                        queryCDMediaCheck(devices[i]->device, location);
+
+                    /* if in rescue mode lets copy stage 2 into RAM so we can */
+                    /* free up the CD drive and user can have it avaiable to  */
+                    /* aid system recovery.                                   */
+                    if (FL_RESCUE(flags) && !FL_TEXT(flags) &&
+                        totalMemory() > MIN_GUI_RAM ) {
+                        rc = copyFile(stage2loc, "/tmp/install.img");
+                        stage2img = strdup("/tmp/install.img");
+                        stage2inram = 1;
+                    } else {
+                        stage2img = strdup(stage2loc);
+                        stage2inram = 0;
+                    }
+
+                    rc = mountStage2(stage2img);
+                    free(stage2img);
+
+                    if (rc) {
+                        logMessage(INFO, "mounting stage2 failed");
+                        umount(location);
+                        continue;
+                    }
+
+                    checked_asprintf(&updpath, "%s/images/updates.img", location);
+
+                    logMessage(INFO, "Looking for updates in %s", updpath);
+                    copyUpdatesImg(updpath);
+                    free(updpath);
+
+                    checked_asprintf(&updpath, "%s/images/product.img", location);
+
+                    logMessage(INFO, "Looking for product in %s", updpath);
+                    copyProductImg(updpath);
+                    free(updpath);
+
+                    /* if in rescue mode and we copied stage2 to RAM */
+                    /* we can now unmount the CD                     */
+                    if (FL_RESCUE(flags) && stage2inram) {
+                        umount(location);
+                    }
+
+                    checked_asprintf(&retbuf, "cdrom://%s:%s",
+                                     devices[i]->device, location);
+                } else {
+                    /* this wasnt the CD we were looking for, clean up and */
+                    /* try the next CD drive                               */
+                    umount(location);
+                }
+            }
+        }
+
+        if (!retbuf) {
+            if (interactive) {
+                char * buf;
+
+                checked_asprintf(&buf, _("The %s disc was not found in any of your "
+                                         "CDROM drives. Please insert the %s disc "
+                                         "and press %s to retry."),
+                                 getProductName(), getProductName(), _("OK"));
+
+                ejectCdrom(cddev);
+                rc = newtWinChoice(_("Disc Not Found"),
+                                   _("OK"), _("Back"), buf, _("OK"));
+                free(buf);
+                if (rc == 2)
+                    goto err;
+            } else {
+                /* we can't ask them about it, so just return not found */
+                goto err;
+            }
+        }
+    } while (!retbuf);
+
+err:
+    free(stage2loc);
+    return retbuf;
+}
+
+/* try to find a install CD non-interactively */
+char * findAnacondaCD(char *location) {
+    return setupCdrom(location, NULL, 0, 1);
+}
+
+/* look for a CD and mount it.  if we have problems, ask */
+char * mountCdromImage(struct installMethod * method,
+                       char * location, struct loaderData_s * loaderData) {
+    return setupCdrom(location, loaderData, 1, 1);
+}
+
+void setKickstartCD(struct loaderData_s * loaderData, int argc, char ** argv) {
+
+    logMessage(INFO, "kickstartFromCD");
+    loaderData->method = METHOD_CDROM;
+}
+
+int kickstartFromCD(char *kssrc) {
+    int rc, i;
+    char *p, *kspath;
+    struct device ** devices;
+
+    logMessage(INFO, "getting kickstart file from first CDROM");
+
+    devices = getDevices(DEVICE_CDROM);
+    /* usb can take some time to settle, even with the various hacks we
+     * have in place.  some systems use portable USB CD-ROM drives, try to
+     * make sure there really isn't one before bailing */
+    for (i = 0; !devices && i < 10; ++i) {
+        logMessage(INFO, "sleeping to wait for a USB CD-ROM");
+        sleep(2);
+        devices = getDevices(DEVICE_CDROM);
+    }
+    if (!devices) {
+        logMessage(ERROR, "No CDROM devices found!");
+        return 1;
+    }
+
+    /* format is cdrom:[/path/to/ks.cfg] */
+    kspath = "";
+    p = strchr(kssrc, ':');
+    if (p)
+        kspath = p + 1;
+
+    if (!p || strlen(kspath) < 1)
+        kspath = "/ks.cfg";
+
+    for (i=0; devices[i]; i++) {
+        if (!devices[i]->device)
+            continue;
+
+        rc = getKickstartFromBlockDevice(devices[i]->device, kspath);
+        if (rc == 0)
+            return 0;
+    }
+
+    startNewt();
+    newtWinMessage(_("Error"), _("OK"),
+                   _("Cannot find kickstart file on CDROM."));
+    return 1;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 et */
diff --git a/bin/loader/cdinstall.h b/bin/loader/cdinstall.h
new file mode 100644
index 0000000..a0ecbc3
--- /dev/null
+++ b/bin/loader/cdinstall.h
@@ -0,0 +1,34 @@
+/*
+ * cdinstall.h
+ *
+ * Copyright (C) 2007  Red Hat, Inc.  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 as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef H_CDINSTALL
+#define H_CDINSTALL
+
+#include "method.h"
+
+char * mountCdromImage(struct installMethod * method,
+                       char * location, struct loaderData_s * loaderData);
+
+char * findAnacondaCD(char * location);
+
+void setKickstartCD(struct loaderData_s * loaderData, int argc,
+		    char ** argv);
+
+int kickstartFromCD(char *kssrc);
+#endif
diff --git a/bin/loader/copy.c b/bin/loader/copy.c
new file mode 100644
index 0000000..1c61233
--- /dev/null
+++ b/bin/loader/copy.c
@@ -0,0 +1,141 @@
+/*
+ * copy.c - functions for copying files and directories
+ *
+ * Copyright (C) 2007  Red Hat, Inc.  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 as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <dirent.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#include "lang.h"
+
+/* Recursive */
+int copyDirectory(char * from, char * to, void (*warnFn)(char *),
+                  void (*errorFn)(char *)) {
+    char *msg;
+    DIR * dir;
+    struct dirent * ent;
+    int fd, outfd;
+    char buf[4096];
+    int i;
+    struct stat sb;
+    char filespec[256];
+    char filespec2[256];
+    char link[1024];
+
+    mkdir(to, 0755);
+
+    if (!(dir = opendir(from))) {
+        if (errorFn) {
+           if (asprintf(&msg, N_("Failed to read directory %s: %m"), from) == -1) {
+               fprintf(stderr, "%s: %d: %m\n", __func__, __LINE__);
+               fflush(stderr);
+               abort();
+           }
+
+           errorFn(msg);
+           free(msg);
+        }
+
+        return 1;
+    }
+
+    errno = 0;
+    while ((ent = readdir(dir))) {
+        if (!strcmp(ent->d_name, ".") || !strcmp(ent->d_name, ".."))
+           continue;
+
+        sprintf(filespec, "%s/%s", from, ent->d_name);
+        sprintf(filespec2, "%s/%s", to, ent->d_name);
+
+        lstat(filespec, &sb);
+
+        if (S_ISDIR(sb.st_mode)) {
+            if (copyDirectory(filespec, filespec2, warnFn, errorFn)) {
+                closedir(dir);
+                return 1;
+            }
+        } else if (S_ISLNK(sb.st_mode)) {
+            i = readlink(filespec, link, sizeof(link) - 1);
+            link[i] = '\0';
+            if (symlink(link, filespec2)) {
+                if (warnFn) {
+                    if (asprintf(&msg, "Failed to symlink %s to %s: %m",
+                                 filespec2, link) == -1) {
+                        fprintf(stderr, "%s: %d: %m\n", __func__, __LINE__);
+                        fflush(stderr);
+                        abort();
+                    }
+
+                    warnFn(msg);
+                    free(msg);
+                }
+            }
+        } else {
+            fd = open(filespec, O_RDONLY);
+            if (fd == -1) {
+                if (errorFn) {
+                    if (asprintf(&msg, "Failed to open %s: %m", filespec) == -1) {
+                        fprintf(stderr, "%s: %d: %m\n", __func__, __LINE__);
+                        fflush(stderr);
+                        abort();
+                    }
+
+                    errorFn(msg);
+                    free(msg);
+                }
+
+                closedir(dir);
+                return 1;
+            } 
+            outfd = open(filespec2, O_RDWR | O_TRUNC | O_CREAT, 0644);
+            if (outfd == -1) {
+                if (warnFn) {
+                    if (asprintf(&msg, "Failed to create %s: %m", filespec2) == -1) {
+                        fprintf(stderr, "%s: %d: %m\n", __func__, __LINE__);
+                        fflush(stderr);
+                        abort();
+                    }
+
+                    warnFn(msg);
+                    free(msg);
+                }
+            } else {
+                fchmod(outfd, sb.st_mode & 07777);
+
+                while ((i = read(fd, buf, sizeof(buf))) > 0)
+                    i = write(outfd, buf, i);
+                close(outfd);
+            }
+
+            close(fd);
+        }
+
+        errno = 0;
+    }
+
+    closedir(dir);
+
+    return 0;
+}
diff --git a/bin/loader/copy.h b/bin/loader/copy.h
new file mode 100644
index 0000000..1153bf8
--- /dev/null
+++ b/bin/loader/copy.h
@@ -0,0 +1,26 @@
+/*
+ * copy.h
+ *
+ * Copyright (C) 2007  Red Hat, Inc.  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 as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef H_COPY
+#define H_COPY
+
+int copyDirectory (char *from, char *to, void (*warnFn)(char *),
+                   void (*errorFn)(char *));
+
+#endif
diff --git a/bin/loader/devices.h b/bin/loader/devices.h
new file mode 100644
index 0000000..974e792
--- /dev/null
+++ b/bin/loader/devices.h
@@ -0,0 +1,103 @@
+/*
+ * devices.h: handle declaration of devices to be created under /dev
+ *
+ * Copyright (C) 2004  Red Hat, Inc.  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 as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef LOADER_INIT_DEVICES_H
+#define LOADER_INIT_DEVICES_H
+
+struct devnode {
+    char * devname;
+    int type;
+    int major;
+    int minor;
+    int perms;
+    char * owner;
+    char * group;
+};
+
+#define CHARDEV 0
+#define BLOCKDEV 1
+#define DIRTYPE 2
+
+struct devnode devnodes[] = {
+    /* consoles */
+    {"console", CHARDEV, 5, 1, 0600, "root", "root"},
+    {"ttyS0", CHARDEV, 4, 64, 0600, "root", "root"},
+    {"ttyS1", CHARDEV, 4, 65, 0600, "root", "root"},
+    {"ttyS2", CHARDEV, 4, 66, 0600, "root", "root"},
+    {"ttyS3", CHARDEV, 4, 67, 0600, "root", "root"},
+#ifdef __ia64__
+    {"ttySG0", CHARDEV, 204, 40, 0600, "root", "root"},
+#endif
+#ifdef __powerpc__
+    {"hvsi0", CHARDEV, 229, 128, 0600, "root", "root"},
+    {"hvsi1", CHARDEV, 229, 129, 0600, "root", "root"},
+    {"hvsi2", CHARDEV, 229, 130, 0600, "root", "root"},
+#endif
+    {"hvc0", CHARDEV, 229, 0, 0600, "root", "root"},
+#if defined(__i386__) || defined(__x86_64__) || defined(__ia64__)
+    {"xvc0", CHARDEV, 204, 191, 0600, "root", "root"},
+#endif
+    /* base unix */
+    {"null", CHARDEV, 1, 3, 0666, "root", "root"},
+    {"zero", CHARDEV, 1, 5, 0666, "root", "root"},
+    {"mem", CHARDEV, 1, 1, 0600, "root", "root"},
+    /* ttys */
+    {"pts", DIRTYPE, 0, 0, 0755, "root", "root"},
+    {"ptmx", CHARDEV, 5, 2, 0666, "root", "root"},
+    {"tty", CHARDEV, 5, 0, 0666, "root", "root"},
+    {"tty0", CHARDEV, 4, 0, 0600, "root", "tty"},
+    {"tty1", CHARDEV, 4, 1, 0600, "root", "tty"},
+    {"tty2", CHARDEV, 4, 2, 0600, "root", "tty"},
+    {"tty3", CHARDEV, 4, 3, 0600, "root", "tty"},
+    {"tty4", CHARDEV, 4, 4, 0600, "root", "tty"},
+    {"tty5", CHARDEV, 4, 5, 0600, "root", "tty"},
+    {"tty6", CHARDEV, 4, 6, 0600, "root", "tty"},
+    {"tty7", CHARDEV, 4, 7, 0600, "root", "tty"},
+    {"tty8", CHARDEV, 4, 8, 0600, "root", "tty"},
+    {"tty9", CHARDEV, 4, 9, 0600, "root", "tty"},
+    /* fb */
+    {"fb0", CHARDEV, 29, 0, 0600, "root", "tty"},
+    /* sparc specific */
+#ifdef __sparc__
+    {"openprom", CHARDEV, 10, 139, 0644, "root", "root"},
+    {"sunmouse", CHARDEV, 10, 6, 0644, "root", "root"},
+    {"kbd", CHARDEV, 11, 0, 0644, "root", "root"},
+#endif
+    /* X */
+    {"agpgart", CHARDEV, 10, 175, 0664, "root", "root"},
+    {"psaux", CHARDEV, 10, 1, 0644, "root", "root"},
+    {"input", DIRTYPE, 0, 0, 0755, "root", "root"},
+    {"input/mice", CHARDEV, 13, 63, 0664, "root", "root"},
+    /* floppies */
+    {"fd0", BLOCKDEV, 2, 0, 0644, "root", "root"},
+    {"fd1", BLOCKDEV, 2, 1, 0644, "root", "root"},
+    /* random */
+    {"random", CHARDEV, 1, 8, 0644, "root", "root"},
+    {"urandom", CHARDEV, 1, 9, 0644, "root", "root"},
+    /* mac stuff */
+#ifdef __powerpc__
+    {"nvram", CHARDEV, 10, 144, 0644, "root", "root"},
+    {"adb", CHARDEV, 56, 0, 0644, "root", "root"},
+    {"iseries", DIRTYPE, 0, 0, 0755, "root", "root" },
+#endif
+    {"rtc", CHARDEV, 10, 135, 0644, "root", "root"},
+    { NULL, 0, 0, 0, 0, NULL, NULL },
+};
+
+#endif
diff --git a/bin/loader/devt.h b/bin/loader/devt.h
new file mode 100644
index 0000000..364a134
--- /dev/null
+++ b/bin/loader/devt.h
@@ -0,0 +1,39 @@
+/*
+ * devt.h: handle declaration of dev_t to be sane for loopback purposes
+ *
+ * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003  Red Hat, Inc.
+ * 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 as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef DEVT_H
+#define DEVT_H
+
+/* Need to tell loop.h what the actual dev_t type is. */
+#undef dev_t
+#if defined(__alpha) || (defined(__sparc__) && defined(__arch64__))
+#define dev_t unsigned int
+#else
+#if defined(__x86_64__)
+#define dev_t unsigned long
+#else
+#define dev_t unsigned short
+#endif
+#endif
+#include <linux/loop.h>
+#undef dev_t
+#define dev_t dev_t
+
+#endif
diff --git a/bin/loader/dirbrowser.c b/bin/loader/dirbrowser.c
new file mode 100644
index 0000000..9199850
--- /dev/null
+++ b/bin/loader/dirbrowser.c
@@ -0,0 +1,199 @@
+/*
+ * dirbrowser.c - newt-based directory browser to get a file name
+ *
+ * Copyright (C) 2004  Red Hat, Inc.  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 as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ *
+ * Author(s): Jeremy Katz <katzj@xxxxxxxxxx>
+ */
+
+#include <newt.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <sys/types.h>
+#include <dirent.h>
+#include <errno.h>
+#include <string.h>
+#include <sys/stat.h>
+
+#ifndef STANDALONE
+#include "../isys/log.h"
+
+#include "loader.h"
+#include "loadermisc.h"
+#include "lang.h"
+#endif
+
+#ifdef STANDALONE
+#define _(x) x
+
+static int simpleStringCmp(const void * a, const void * b) {
+    const char * first = *((const char **) a);
+    const char * second = *((const char **) b);
+
+    return strcmp(first, second);
+}
+#endif
+
+#define FSTEP 10
+
+static char ** get_file_list(char * dirname, 
+                             int (*filterfunc)(char *, struct dirent *)) {
+    DIR * dir;
+    struct dirent *entry;
+    char ** files;
+    int numfiles = FSTEP, i = 0;
+
+    dir = opendir(dirname);
+    if (dir == NULL) {
+        fprintf(stderr, "error opening %s: %m", dirname);
+        return NULL;
+    }
+
+    files = malloc(numfiles * sizeof(char *));
+
+    while ((entry = readdir(dir))) {
+        if ((strlen(entry->d_name) == 1) && !strncmp(entry->d_name, ".", 1))
+            continue;
+        if ((strlen(entry->d_name) == 2) && !strncmp(entry->d_name, "..", 2))
+            continue;
+        if (filterfunc && filterfunc(dirname, entry))
+            continue;
+
+        files[i] = strdup(entry->d_name);
+        if (i++ >= (numfiles - 1)) {
+            numfiles += FSTEP;
+            files = realloc(files, numfiles * sizeof(char *));
+        }
+    }
+    files[i] = NULL;
+    closedir(dir);
+
+    qsort(files, i, sizeof(*files), simpleStringCmp);
+    return files;
+}
+
+/* Browse through a directory structure looking for a file.
+ * Returns the full path to the file.
+ *
+ * Parameters:
+ * title: Title for newt dialog window
+ * dirname: Directory to use for root of browsing.  NOTE: you cannot go
+ *          up above this root.
+ * filterfunc: An (optional)  function to filter out files based on whatever 
+ *             criteria you want.  Returns 1 if it passes, 0 if not.  
+ *             Function should take arguments of the directory name and 
+ *             the dirent for the file.
+ */
+char * newt_select_file(char * title, char * text, char * dirname,
+                        int (*filterfunc)(char *, struct dirent *)) {
+    char ** files;
+    char * fn = NULL;
+    int i, done = 0;
+    char * topdir = dirname;
+    char * dir = malloc(PATH_MAX);
+    char * path = NULL;
+    newtGrid grid, buttons;
+    newtComponent f, tb, listbox, ok, cancel;
+    struct stat sb;
+    struct newtExitStruct es;
+
+    dir = realpath(dirname, dir);
+
+    do {
+        files = get_file_list(dir, filterfunc);
+
+        f = newtForm(NULL, NULL, 0);
+        grid = newtCreateGrid(1, 4);
+
+        tb = newtTextboxReflowed(-1, -1, text, 60, 0, 10, 0);
+
+        listbox = newtListbox(12, 65, 10, 
+                              NEWT_FLAG_SCROLL | NEWT_FLAG_RETURNEXIT);
+
+        newtListboxSetWidth(listbox, 55);
+        buttons = newtButtonBar(_("OK"), &ok, _("Cancel"), &cancel, NULL);
+        newtGridSetField(grid, 0, 0, NEWT_GRID_COMPONENT, tb,
+                         0, 0, 0, 1, 0, 0);
+        newtGridSetField(grid, 0, 1, NEWT_GRID_COMPONENT, listbox,
+                         0, 0, 0, 1, 0, 0);
+        newtGridSetField(grid, 0, 3, NEWT_GRID_SUBGRID, buttons,
+                         0, 0, 0, 0, 0, NEWT_GRID_FLAG_GROWX);
+        
+        /* if this isn't our topdir, we want to let them go up a dir */
+        if (strcmp(topdir, dir))
+            newtListboxAppendEntry(listbox, "../", "..");
+
+        for (i = 0; (files[i] != NULL); i++) {
+            if ((files[i] == NULL) || (strlen(files[i]) == 0)) continue;
+            path = malloc(strlen(files[i]) + strlen(dir) + 2);
+            sprintf(path, "%s/%s", dir, files[i]);
+            stat(path, &sb);
+            free(path);
+            if (S_ISDIR(sb.st_mode)) {
+                char *dir = malloc(strlen(files[i]) + 2);
+                sprintf(dir, "%s/", files[i]);
+                newtListboxAppendEntry(listbox, dir, files[i]);
+            } else {
+                newtListboxAppendEntry(listbox, files[i], files[i]);
+            }
+        }
+
+        newtGridWrappedWindow(grid, title);
+        newtGridAddComponentsToForm(grid, f, 1);
+        newtFormRun(f, &es);
+
+        if (es.reason  == NEWT_EXIT_COMPONENT && es.u.co == cancel) {
+            fn = NULL;
+            done = -1;
+        } else {
+            fn = (char *) newtListboxGetCurrent(listbox);
+            path = malloc(strlen(fn) + strlen(dir) + 2);
+            sprintf(path, "%s/%s", dir, fn);
+
+            stat(path, &sb);
+            if (!S_ISDIR(sb.st_mode)) {
+                fn = path;
+                done = 1;
+            } else { 
+                dir = realpath(path, dir);
+                free(path);
+            }
+        }
+
+        newtGridFree(grid, 1);
+        newtFormDestroy(f);
+        newtPopWindow();
+    } while (done == 0);
+
+    return fn;
+}
+
+#ifdef STANDALONE
+int main(int argc, char ** argv) {
+    char * foo;
+
+    newtInit();
+    newtCls();
+      
+    foo = newt_select_file("Get File Name", "foo, blah blah blah", 
+                           "/etc", NULL);
+    newtFinished();
+    printf("got %s\n", foo);
+    return 0;
+}
+#endif
diff --git a/bin/loader/dirbrowser.h b/bin/loader/dirbrowser.h
new file mode 100644
index 0000000..7fb22f2
--- /dev/null
+++ b/bin/loader/dirbrowser.h
@@ -0,0 +1,28 @@
+/*
+ * dirbrowser.h
+ *
+ * Copyright (C) 2007  Red Hat, Inc.  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 as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef DIRBROWSER_H
+#define DIRBROWSER_H
+
+#include <dirent.h>
+
+char * newt_select_file(char * title, char * text, char * dirname,
+                        int (*filterfunc)(char *, struct dirent *));
+
+#endif
diff --git a/bin/loader/driverdisk.c b/bin/loader/driverdisk.c
new file mode 100644
index 0000000..4f4446c
--- /dev/null
+++ b/bin/loader/driverdisk.c
@@ -0,0 +1,861 @@
+/*
+ * driverdisk.c - driver disk functionality
+ *
+ * Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007  Red Hat, Inc.
+ * 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 as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ *
+ * Author(s): Jeremy Katz <katzj@xxxxxxxxxx>
+ */
+
+#include <errno.h>
+#include <fcntl.h>
+#include <newt.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <glib.h>
+
+#include <blkid/blkid.h>
+
+#include <glob.h>
+#include <rpm/rpmlib.h>
+#include <sys/utsname.h>
+
+#include "copy.h"
+#include "loader.h"
+#include "loadermisc.h"
+#include "lang.h"
+#include "fwloader.h"
+#include "method.h"
+#include "modules.h"
+#include "moduleinfo.h"
+#include "windows.h"
+#include "hardware.h"
+#include "driverdisk.h"
+#include "getparts.h"
+#include "dirbrowser.h"
+
+#include "nfsinstall.h"
+#include "urlinstall.h"
+
+#include "rpmextract.h"
+
+#include "../isys/isys.h"
+#include "../isys/imount.h"
+#include "../isys/eddsupport.h"
+#include "../isys/log.h"
+
+/* boot flags */
+extern uint64_t flags;
+
+/*
+ * check if the RPM in question provides
+ * Provides: userptr
+ * we use it to check kernel-modules-<kernelversion>
+ */
+int dlabelProvides(const char* dep, void *userptr)
+{
+    char *kernelver = (char*)userptr;
+
+    logMessage(DEBUGLVL, "Provides: %s\n", dep);
+
+    return strcmp(dep, kernelver);
+}
+
+/*
+ * during cpio extraction, only extract files we need
+ * eg. module .ko files and firmware directory
+ */
+int dlabelFilter(const char* name, const struct stat *fstat, void *userptr)
+{
+    int l = strlen(name);
+
+    logMessage(DEBUGLVL, "Unpacking %s\n", name);
+
+    /* we want firmware files */
+    if (!strncmp("lib/firmware/", name, 13)) return 0; 
+
+    if (l<3)
+        return 1;
+    l-=3;
+
+    /* and we want only .ko files */
+    if (strcmp(".ko", name+l))
+        return 1;
+
+    /* TODO we are unpacking kernel module, read it's description */
+
+    return 0;
+}
+
+char* moduleDescription(const char* modulePath)
+{
+    char *command = NULL;
+    FILE *f = NULL;
+    char *description = NULL;
+    int size;
+
+    checked_asprintf(&command, "modinfo --description '%s'", modulePath);
+    f = popen(command, "r");
+    free(command);
+
+    if (f==NULL)
+        return NULL;
+
+    description = malloc(sizeof(char)*256);
+    if (!description)
+        return NULL;
+
+    size = fread(description, 1, 255, f);
+    if (size == 0) {
+        free(description);
+        return NULL;
+    }
+
+    description[size-1]=0; /* strip the trailing newline */
+    pclose(f);
+
+    return description;
+}
+
+int globErrFunc(const char *epath, int eerrno)
+{
+    /* TODO check fatal errors */
+
+    return 0;
+}
+
+int dlabelUnpackRPMDir(char* rpmdir, char* destination)
+{
+    char *kernelver;
+    struct utsname unamedata;
+    char *oldcwd;
+    char *globpattern;
+    int rc;
+
+    /* get current working directory */ 
+    oldcwd = getcwd(NULL, 0);
+    if (!oldcwd) {
+        logMessage(ERROR, "getcwd() failed: %m");
+        return 1;
+    }
+
+    /* set the cwd to destination */
+    if (chdir(destination)) {
+        logMessage(ERROR, "We weren't able to CWD to \"%s\": %m", destination);
+        free(oldcwd);
+        return 1;
+    }
+
+    /* get running kernel version */
+    rc = uname(&unamedata);
+    checked_asprintf(&kernelver, "kernel-modules-%s",
+            rc ? "unknown" : unamedata.release);
+    logMessage(DEBUGLVL, "Kernel version: %s\n", kernelver);
+
+    checked_asprintf(&globpattern, "%s/*.rpm", rpmdir);
+    glob_t globres;
+    char** globitem;
+    if (!glob(globpattern, GLOB_NOSORT|GLOB_NOESCAPE, globErrFunc, &globres)) {
+        /* iterate over all rpm files */
+        globitem = globres.gl_pathv;
+        while (globres.gl_pathc>0 && globitem != NULL) {
+            explodeRPM(*globitem, dlabelFilter, dlabelProvides, NULL, kernelver);
+        }
+        globfree(&globres);
+        /* end of iteration */
+    }
+    free(globpattern);
+
+    /* restore CWD */
+    if (chdir(oldcwd)) {
+        logMessage(WARNING, "We weren't able to restore CWD to \"%s\": %m", oldcwd);
+    }
+
+    /* cleanup */
+    free(kernelver);
+    free(oldcwd);
+    return rc;
+}
+
+
+static char * driverDiskFiles[] = { "repodata", NULL };
+
+static int verifyDriverDisk(char *mntpt) {
+    char ** fnPtr;
+    char file[200];
+    struct stat sb;
+
+    /* check for dd descriptor */
+    sprintf(file, "%s/rhdd3", mntpt);
+    if (access(file, R_OK)) {
+        logMessage(ERROR, "can't find driver disk identifier, bad "
+                          "driver disk");
+        return LOADER_BACK;
+    }
+
+    /* side effect: file is still mntpt/ddident */
+    stat(file, &sb);
+    if (!sb.st_size)
+        return LOADER_BACK;
+
+    for (fnPtr = driverDiskFiles; *fnPtr; fnPtr++) {
+        snprintf(file, 200, "%s/rpms/%s/%s", mntpt, getProductArch(), *fnPtr);
+        if (access(file, R_OK)) {
+            logMessage(ERROR, "cannot find %s, bad driver disk", file);
+            return LOADER_BACK;
+        }
+    }
+
+    return LOADER_OK;
+}
+
+static void copyWarnFn (char *msg) {
+   logMessage(WARNING, msg);
+}
+
+static void copyErrorFn (char *msg) {
+   newtWinMessage(_("Error"), _("OK"), _(msg));
+}
+
+/* this copies the contents of the driver disk to a ramdisk and loads
+ * the moduleinfo, etc.  assumes a "valid" driver disk mounted at mntpt */
+static int loadDriverDisk(struct loaderData_s *loaderData, char *mntpt) {
+    /* FIXME moduleInfoSet modInfo = loaderData->modInfo; */
+    char file[200], dest[200], src[200];
+    char *title;
+    char *fwdir = NULL;
+    struct moduleBallLocation * location;
+    struct stat sb;
+    static int disknum = 0;
+    int fd, ret;
+
+    /* check for new version */
+    sprintf(file, "%s/rhdd3", mntpt);
+    if (access(file, R_OK)) {
+      /* this can't happen, we already verified it! */
+      return LOADER_BACK;
+    }
+    stat(file, &sb);
+    title = malloc(sb.st_size + 1);
+
+    fd = open(file, O_RDONLY);
+    ret = read(fd, title, sb.st_size);
+    if (title[sb.st_size - 1] == '\n')
+        sb.st_size--;
+    title[sb.st_size] = '\0';
+    close(fd);
+
+    sprintf(file, DD_RPMDIR_TEMPLATE, disknum);
+    mkdirChain(file);
+    mkdirChain(DD_MODULES);
+    mkdirChain(DD_FIRMWARE);
+
+    if (!FL_CMDLINE(flags)) {
+        startNewt();
+        winStatus(40, 3, _("Loading"), _("Reading driver disk"));
+    }
+
+    location = malloc(sizeof(struct moduleBallLocation));
+    location->title = strdup(title);
+    checked_asprintf(&location->path, DD_MODULES);
+
+    sprintf(dest, DD_RPMDIR_TEMPLATE, disknum);
+    sprintf(src, "%s/rpms/%s", mntpt, getProductArch());
+    copyDirectory(src, dest, copyWarnFn, copyErrorFn);
+
+    /* unpack packages from dest into location->path */
+    if (dlabelUnpackRPMDir(dest, DD_EXTRACTED)) {
+        /* fatal error, log this and jump to exception handler */
+        logMessage(ERROR, "Error unpacking RPMs from driver disc no.%d",
+                disknum);
+        goto loadDriverDiscException;
+    }
+
+    /* run depmod to refresh modules db */
+    if (system("depmod -a")) {
+      /* this is not really fatal error, it might still work, log it */
+      logMessage(ERROR, "Error running depmod -a for driverdisc no.%d", disknum);
+    }
+
+    checked_asprintf(&fwdir, DD_FIRMWARE);
+    if (!access(fwdir, R_OK|X_OK)) {
+        add_fw_search_dir(loaderData, fwdir);
+        stop_fw_loader(loaderData);
+        start_fw_loader(loaderData);
+    }
+    free(fwdir);
+
+    /* TODO generate and read module info
+     *
+     * sprintf(file, "%s/modinfo", mntpt);
+     * readModuleInfo(file, modInfo, location, 1);
+     */
+
+loadDriverDiscException:
+
+    if (!FL_CMDLINE(flags))
+        newtPopWindow();
+
+    disknum++;
+    return 0;
+}
+
+/* Get the list of removable devices (floppy/cdrom) available.  Used to
+ * find suitable devices for update disk / driver disk source.  
+ * Returns the number of devices.  ***devNames will be a NULL-terminated list
+ * of device names
+ */
+int getRemovableDevices(char *** devNames) {
+    struct device **devs;
+    int numDevices = 0;
+    int i = 0;
+
+    devs = getDevices(DEVICE_DISK | DEVICE_CDROM);
+
+    if (!devs)
+        return numDevices;
+
+    for (i = 0; devs[i] ; i++) {
+        logMessage(DEBUGLVL, "Considering device %s (isremovable: %d)", devs[i]->device, devs[i]->priv.removable);
+        if (devs[i]->priv.removable) {
+            *devNames = realloc(*devNames, (numDevices + 2) * sizeof(char *));
+            (*devNames)[numDevices] = strdup(devs[i]->device);
+            (*devNames)[numDevices+1] = NULL;
+            numDevices ++;
+        }
+    }
+    if (!numDevices) {
+        logMessage(ERROR, "no devices found to load drivers from");
+    }
+    return numDevices;
+}
+
+/* Prompt for loading a driver from "media"
+ *
+ * class: type of driver to load.
+ * usecancel: if 1, use cancel instead of back
+ */
+int loadDriverFromMedia(int class, struct loaderData_s *loaderData,
+                        int usecancel, int noprobe, GTree *moduleState) {
+    char * device = NULL, * part = NULL, * ddfile = NULL;
+    char ** devNames = NULL;
+    enum { DEV_DEVICE, DEV_PART, DEV_CHOOSEFILE, DEV_LOADFILE, 
+           DEV_INSERT, DEV_LOAD, DEV_PROBE, 
+           DEV_DONE } stage = DEV_DEVICE;
+    int rc, num = 0;
+    int dir = 1;
+    int found = 0, before = 0;
+
+    while (stage != DEV_DONE) {
+        switch(stage) {
+        case DEV_DEVICE:
+            rc = getRemovableDevices(&devNames);
+            if (rc == 0)
+                return LOADER_BACK;
+
+            /* we don't need to ask which to use if they only have one */
+            if (rc == 1) {
+                device = strdup(devNames[0]);
+                free(devNames);
+                if (dir == -1)
+                    return LOADER_BACK;
+                
+                stage = DEV_PART;
+                break;
+            }
+            dir = 1;
+
+            startNewt();
+            rc = newtWinMenu(_("Driver Disk Source"),
+                             _("You have multiple devices which could serve "
+                               "as sources for a driver disk.  Which would "
+                               "you like to use?"), 40, 10, 10,
+                             rc < 6 ? rc : 6, devNames,
+                             &num, _("OK"), 
+                             (usecancel) ? _("Cancel") : _("Back"), NULL);
+
+            if (rc == 2) {
+                free(devNames);
+                return LOADER_BACK;
+            }
+            device = strdup(devNames[num]);
+            free(devNames);
+
+            stage = DEV_PART;
+        case DEV_PART: {
+            char ** part_list = getPartitionsList(device);
+            int nump = 0, num = 0;
+
+            if (part != NULL)
+                free(part);
+
+            if ((nump = lenPartitionsList(part_list)) == 0) {
+                if (dir == -1)
+                    stage = DEV_DEVICE;
+                else
+                    stage = DEV_INSERT;
+                break;
+            }
+            dir = 1;
+
+            startNewt();
+            rc = newtWinMenu(_("Driver Disk Source"),
+                             _("There are multiple partitions on this device "
+                               "which could contain the driver disk image.  "
+                               "Which would you like to use?"), 40, 10, 10,
+                             nump < 6 ? nump : 6, part_list, &num, _("OK"),
+                             _("Back"), NULL);
+
+            if (rc == 2) {
+                freePartitionsList(part_list);
+                stage = DEV_DEVICE;
+                dir = -1;
+                break;
+            }
+
+            part = strdup(part_list[num]);
+            stage = DEV_CHOOSEFILE;
+
+        }
+
+        case DEV_CHOOSEFILE: {
+            if (part == NULL) {
+                logMessage(ERROR, "somehow got to choosing file with a NULL part, going back");
+                stage = DEV_PART;
+                break;
+            }
+            /* make sure nothing is mounted when we get here */
+            num = umount("/tmp/dpart");
+            if (num == -1) { 
+                logMessage(ERROR, "error unmounting: %m");
+                if ((errno != EINVAL) && (errno != ENOENT))
+                    exit(1);
+            }
+
+            logMessage(INFO, "trying to mount %s as partition", part);
+            if (doPwMount(part, "/tmp/dpart", "auto", "ro", NULL)) {
+                newtWinMessage(_("Error"), _("OK"),
+                               _("Failed to mount partition."));
+                stage = DEV_PART;
+                break;
+            }
+
+            ddfile = newt_select_file(_("Select driver disk image"),
+                                      _("Select the file which is your driver "
+                                        "disk image."),
+                                      "/tmp/dpart", NULL);
+            if (ddfile == NULL) {
+                umount("/tmp/dpart");
+                stage = DEV_PART;
+                dir = -1;
+                break;
+            }
+            dir = 1;
+
+            stage = DEV_LOADFILE;
+        }
+
+        case DEV_LOADFILE: {
+            if (ddfile == NULL) {
+                logMessage(DEBUGLVL, "trying to load dd from NULL");
+                stage = DEV_CHOOSEFILE;
+                break;
+            }
+            if (dir == -1) {
+                umountLoopback("/tmp/drivers", "/dev/loop6");
+                unlink("/tmp/drivers");
+                ddfile = NULL;
+                stage = DEV_CHOOSEFILE;
+                break;
+            }
+            if (mountLoopback(ddfile, "/tmp/drivers", "/dev/loop6")) {
+                newtWinMessage(_("Error"), _("OK"),
+                               _("Failed to load driver disk from file."));
+                stage = DEV_CHOOSEFILE;
+                break;
+            }
+            stage = DEV_LOAD;
+            break;
+        }
+
+        case DEV_INSERT: {
+            char * buf;
+
+            checked_asprintf(&buf,
+                             _("Insert your driver disk into /dev/%s "
+                               "and press \"OK\" to continue."), device);
+
+            rc = newtWinChoice(_("Insert Driver Disk"), _("OK"), _("Back"),
+                               buf);
+            free(buf);
+            if (rc == 2) {
+                stage = DEV_DEVICE;
+                dir = -1;
+                break;
+            }
+            dir = 1;
+
+            logMessage(INFO, "trying to mount %s", device);
+            if (doPwMount(device, "/tmp/drivers", "auto", "ro", NULL)) {
+                newtWinMessage(_("Error"), _("OK"),
+                               _("Failed to mount driver disk."));
+                stage = DEV_INSERT;
+                break;
+            }
+
+            rc = verifyDriverDisk("/tmp/drivers");
+            if (rc == LOADER_BACK) {
+                newtWinMessage(_("Error"), _("OK"),
+                               _("Driver disk is invalid for this "
+                                 "release of %s."), getProductName());
+                umount("/tmp/drivers");
+                stage = DEV_INSERT;
+                break;
+            }
+
+            stage = DEV_LOAD;
+            break;
+        }
+        case DEV_LOAD: {
+            struct device ** devices;
+
+	    before = 0;
+	    found = 0;
+
+            devices = getDevices(class);
+            if (devices)
+                for(; devices[before]; before++);
+
+            rc = loadDriverDisk(loaderData, "/tmp/drivers");
+            umount("/tmp/drivers");
+            if (rc == LOADER_BACK) {
+                dir = -1;
+                if (ddfile != NULL)
+                    stage = DEV_CHOOSEFILE;
+                else
+                    stage = DEV_INSERT;
+                break;
+            }
+            /* fall through to probing */
+            stage = DEV_PROBE;
+
+            if (ddfile != NULL) {
+                umountLoopback("/tmp/drivers", "/dev/loop6");
+                unlink("/tmp/drivers");
+                umount("/tmp/dpart");
+            }
+        }
+
+        case DEV_PROBE: {
+            struct device ** devices;
+
+            /* if they didn't specify that we should probe, then we should
+             * just fall out */
+            if (noprobe) {
+                stage = DEV_DONE;
+                break;
+            }
+
+            /* Unload all devices and load them again to use the updated modules */
+            logMessage(INFO, "Trying to refresh loaded drivers");
+            mlRestoreModuleState(moduleState);
+            busProbe(0);
+
+            devices = getDevices(class);
+            if (devices)
+                for(; devices[found]; found++);
+
+            if (found > before) {
+                stage = DEV_DONE;
+                break;
+            }
+
+            /* we don't have any more modules of the proper class.  ask
+             * them to manually load */
+            rc = newtWinTernary(_("Error"), _("Manually choose"), 
+                                _("Continue"), _("Load another disk"),
+                                _("No devices of the appropriate type were "
+                                  "found on this driver disk.  Would you "
+                                  "like to manually select the driver, "
+                                  "continue anyway, or load another "
+                                  "driver disk?"));
+
+            if (rc == 2) {
+                /* if they choose to continue, just go ahead and continue */
+                stage = DEV_DONE;
+            } else if (rc == 3) {
+                /* if they choose to load another disk, back to the 
+                 * beginning with them */
+                stage = DEV_DEVICE;
+            } else {
+                rc = chooseManualDriver(class, loaderData);
+                /* if they go back from a manual driver, we'll ask again.
+                 * if they load something, assume it's what we need */
+                if (rc == LOADER_OK) {
+                    stage = DEV_DONE;
+                }
+            }
+
+            break;
+        }
+
+        case DEV_DONE:
+            break;
+        }
+    }
+
+    return LOADER_OK;
+}
+
+
+/* looping way to load driver disks */
+int loadDriverDisks(int class, struct loaderData_s *loaderData, GTree *moduleState) {
+    int rc;
+
+    rc = newtWinChoice(_("Driver disk"), _("Yes"), _("No"), 
+                       _("Do you have a driver disk?"));
+    if (rc != 1)
+        return LOADER_OK;
+
+    rc = loadDriverFromMedia(DEVICE_ANY, loaderData, 1, 0, moduleState);
+    if (rc == LOADER_BACK)
+        return LOADER_OK;
+
+    do {
+        rc = newtWinChoice(_("More Driver Disks?"), _("Yes"), _("No"),
+                           _("Do you wish to load any more driver disks?"));
+        if (rc != 1)
+            break;
+        loadDriverFromMedia(DEVICE_ANY, loaderData, 0, 0, moduleState);
+    } while (1);
+
+    return LOADER_OK;
+}
+
+static void loadFromLocation(struct loaderData_s * loaderData, char * dir, GTree *moduleState) {
+    if (verifyDriverDisk(dir) == LOADER_BACK) {
+        logMessage(ERROR, "not a valid driver disk");
+        return;
+    }
+
+    loadDriverDisk(loaderData, dir);
+
+    /* Unload all devices and load them again to use the updated modules */
+    logMessage(INFO, "Trying to refresh loaded drivers");
+    mlRestoreModuleState(moduleState);
+    busProbe(0);
+}
+
+void getDDFromSource(struct loaderData_s * loaderData, char * src, GTree *moduleState) {
+    char *path = "/tmp/dd.img";
+    int unlinkf = 0;
+
+    if (!strncmp(src, "nfs:", 4)) {
+        unlinkf = 1;
+        if (getFileFromNfs(src + 4, "/tmp/dd.img", loaderData)) {
+            logMessage(ERROR, "unable to retrieve driver disk: %s", src);
+            return;
+        }
+    } else if (!strncmp(src, "ftp://";, 6) || !strncmp(src, "http", 4)) {
+        unlinkf = 1;
+        if (getFileFromUrl(src, "/tmp/dd.img", loaderData)) {
+            logMessage(ERROR, "unable to retrieve driver disk: %s", src);
+            return;
+        }
+    /* FIXME: this is a hack so that you can load a driver disk from, eg, 
+     * scsi cdrom drives */
+#if !defined(__s390__) && !defined(__s390x__)
+    } else if (!strncmp(src, "cdrom", 5)) {
+        loadDriverDisks(DEVICE_ANY, loaderData, moduleState);
+        return;
+#endif
+    } else if (!strncmp(src, "path:", 5)) {
+	path = src + 5;
+    } else {
+        newtWinMessage(_("Kickstart Error"), _("OK"),
+                       _("Unknown driver disk kickstart source: %s"), src);
+        return;
+    }
+
+    if (!mountLoopback(path, "/tmp/drivers", "/dev/loop6")) {
+        loadFromLocation(loaderData, "/tmp/drivers", moduleState);
+        umountLoopback("/tmp/drivers", "/dev/loop6");
+        unlink("/tmp/drivers");
+        if (unlinkf) unlink(path);
+    }
+
+}
+
+static void getDDFromDev(struct loaderData_s * loaderData, char * dev, GTree *moduleState);
+
+void useKickstartDD(struct loaderData_s * loaderData,
+                    int argc, char ** argv) {
+    char * dev = NULL;
+    char * biospart = NULL, * p = NULL; 
+    gchar *fstype = NULL, *src = NULL;
+    gint usebiosdev = 0;
+    gchar **remaining = NULL;
+    GOptionContext *optCon = g_option_context_new(NULL);
+    GError *optErr = NULL;
+    GOptionEntry ksDDOptions[] = {
+        /* The --type option is deprecated and now has no effect. */
+        { "type", 0, 0, G_OPTION_ARG_STRING, &fstype, NULL, NULL },
+        { "source", 0, 0, G_OPTION_ARG_STRING, &src, NULL, NULL },
+        { "biospart", 0, 0, G_OPTION_ARG_INT, &usebiosdev, NULL, NULL },
+        { G_OPTION_REMAINING, 0, 0, G_OPTION_ARG_STRING_ARRAY, &remaining,
+          NULL, NULL },
+        { NULL },
+    };
+
+    g_option_context_set_help_enabled(optCon, FALSE);
+    g_option_context_add_main_entries(optCon, ksDDOptions, NULL);
+
+    if (!g_option_context_parse(optCon, &argc, &argv, &optErr)) {
+        newtWinMessage(_("Kickstart Error"), _("OK"),
+                       _("The following invalid argument was specified for "
+                         "the kickstart driver disk command: %s"),
+                       optErr->message);
+        g_error_free(optErr);
+        g_option_context_free(optCon);
+        g_strfreev(remaining);
+        return;
+    }
+
+    g_option_context_free(optCon);
+
+    if ((remaining != NULL) && (g_strv_length(remaining) == 1)) {
+        dev = remaining[0];
+    }
+
+    if (!dev && !src) {
+        logMessage(ERROR, "bad arguments to kickstart driver disk command");
+        return;
+    }
+
+    if (usebiosdev != 0) {
+        p = strchr(dev,'p');
+        if (!p){
+            logMessage(ERROR, "Bad argument for biospart");
+            return;
+        }
+        *p = '\0';
+        
+        biospart = getBiosDisk(dev);
+        if (biospart == NULL) {
+            logMessage(ERROR, "Unable to locate BIOS dev %s",dev);
+            return;
+        }
+        dev = malloc(strlen(biospart) + strlen(p + 1) + 2);
+        sprintf(dev, "%s%s", biospart, p + 1);
+    }
+
+    if (dev) {
+        getDDFromDev(loaderData, dev, NULL);
+    } else {
+        getDDFromSource(loaderData, src, NULL);
+    }
+
+    g_strfreev(remaining);
+    return;
+}
+
+static void getDDFromDev(struct loaderData_s * loaderData, char * dev, GTree* moduleState) {
+    if (doPwMount(dev, "/tmp/drivers", "auto", "ro", NULL)) {
+        logMessage(ERROR, "unable to mount driver disk %s", dev);
+        return;
+    }
+
+    loadFromLocation(loaderData, "/tmp/drivers", moduleState);
+    umount("/tmp/drivers");
+    unlink("/tmp/drivers");
+}
+
+
+/*
+ * Look for partition with specific label (part of #316481)
+ */
+GSList* findDriverDiskByLabel(void)
+{
+    char *ddLabel = "OEMDRV";
+    GSList *ddDevice = NULL;
+    blkid_cache bCache;
+    
+    int res;
+    blkid_dev_iterate bIter;
+    blkid_dev bDev;
+
+    if (blkid_get_cache(&bCache, NULL)<0) {
+        logMessage(ERROR, "Cannot initialize cache instance for blkid");
+        return NULL;
+    }
+    if ((res = blkid_probe_all(bCache))<0) {
+        logMessage(ERROR, "Cannot probe devices in blkid: %d", res);
+        return NULL;
+    }
+    if ((res = blkid_probe_all_removable(bCache))<0) {
+        logMessage(ERROR, "Cannot probe removable devices in blkid: %d", res);
+    }
+
+    bIter = blkid_dev_iterate_begin(bCache);
+    blkid_dev_set_search(bIter, "LABEL", ddLabel);
+    while ((res = blkid_dev_next(bIter, &bDev)) == 0) {
+        bDev = blkid_verify(bCache, bDev);
+        if (!bDev)
+            continue;
+
+        char *devname = strdup(blkid_dev_devname(bDev));
+        logMessage(DEBUGLVL, "Adding driver disc %s to the list "
+                             "of available DDs.", devname);
+        ddDevice = g_slist_prepend(ddDevice, (gpointer)devname);
+        /* Freeing bDev is taken care of by the put cache call */
+    }
+    blkid_dev_iterate_end(bIter);
+
+    blkid_put_cache(bCache);
+
+    return ddDevice;
+}
+
+int loadDriverDiskFromPartition(struct loaderData_s *loaderData, char* device)
+{
+    int rc;
+
+    logMessage(INFO, "trying to mount %s", device);
+    if (doPwMount(device, "/tmp/drivers", "auto", "ro", NULL)) {
+        logMessage(ERROR, "Failed to mount driver disk.");
+        return -1;
+    }
+
+    rc = verifyDriverDisk("/tmp/drivers");
+    if (rc == LOADER_BACK) {
+        logMessage(ERROR, "Driver disk is invalid for this "
+                "release of %s.", getProductName());
+        umount("/tmp/drivers");
+        return -2;
+    }
+
+    rc = loadDriverDisk(loaderData, "/tmp/drivers");
+    umount("/tmp/drivers");
+    if (rc == LOADER_BACK) {
+        return -3;
+    }
+
+    return 0;
+}
+
diff --git a/bin/loader/driverdisk.h b/bin/loader/driverdisk.h
new file mode 100644
index 0000000..4dc8685
--- /dev/null
+++ b/bin/loader/driverdisk.h
@@ -0,0 +1,51 @@
+/*
+ * driverdisk.h
+ *
+ * Copyright (C) 2007  Red Hat, Inc.  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 as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef DRIVERDISK_H
+#define DRIVERDISK_H
+
+#include "loader.h"
+#include "modules.h"
+#include "moduleinfo.h"
+
+#define DD_RPMDIR_TEMPLATE "/tmp/DD-%d"
+#define DD_EXTRACTED "/tmp/DD"
+#define DD_MODULES "/tmp/DD/lib/modules"
+#define DD_FIRMWARE "/tmp/DD/lib/firmware"
+
+extern char *ddFsTypes[];
+
+int loadDriverFromMedia(int class, struct loaderData_s *loaderData,
+                        int usecancel, int noprobe, GTree *moduleState);
+
+int loadDriverDisks(int class, struct loaderData_s *loaderData, GTree *moduleState);
+
+int getRemovableDevices(char *** devNames);
+
+int chooseManualDriver(int class, struct loaderData_s *loaderData);
+void useKickstartDD(struct loaderData_s * loaderData, int argc, 
+                    char ** argv);
+
+void getDDFromSource(struct loaderData_s * loaderData, char * src, GTree *moduleState);
+
+int loadDriverDiskFromPartition(struct loaderData_s *loaderData, char* device);
+
+GSList* findDriverDiskByLabel(void);
+
+#endif
diff --git a/bin/loader/driverselect.c b/bin/loader/driverselect.c
new file mode 100644
index 0000000..85b777b
--- /dev/null
+++ b/bin/loader/driverselect.c
@@ -0,0 +1,251 @@
+/*
+ * driverselect.c - functionality for manually selecting drivers
+ *
+ * Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002  Red Hat, Inc.
+ * 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 as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ *
+ * Author(s): Erik Troan <ewt@xxxxxxxxxx>
+ *            Jeremy Katz <katzj@xxxxxxxxxx>
+ */
+
+#include <ctype.h>
+#include <newt.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <errno.h>
+
+#include "../isys/log.h"
+
+#include "modules.h"
+#include "moduleinfo.h"
+#include "loader.h"
+#include "loadermisc.h"
+#include "lang.h"
+#include "driverdisk.h"
+
+struct sortModuleList {
+    int index;
+    moduleInfoSet modInfo;
+};
+
+static int sortDrivers(const void * a, const void * b) {
+    const struct sortModuleList * one = a;
+    const struct sortModuleList * two = b;
+
+    return strcmp(one->modInfo->moduleList[one->index].description,
+                  one->modInfo->moduleList[two->index].description);
+}
+
+static int getManualModuleArgs(struct moduleInfo * mod, gchar *** moduleArgs) {
+    newtGrid grid, buttons;
+    newtComponent text, f, ok, back, entry;
+    struct newtExitStruct es;
+    int done = 0, i;
+    char * buf;
+    char *argsEntry = "";
+
+    if (*moduleArgs) {
+        for (i = 0; (*moduleArgs)[i]; i++)
+            argsEntry = strcat(argsEntry, (*moduleArgs)[i]);
+    }
+
+    f = newtForm(NULL, NULL, 0);
+    checked_asprintf(&buf,
+                     _("Please enter any parameters which you wish to pass "
+                       "to the %s module separated by spaces.  If you don't "
+                       "know what parameters to supply, skip this screen "
+                       "by pressing the \"OK\" button."), mod->moduleName);
+
+    text = newtTextboxReflowed(-1, -1, buf, 60, 0, 10, 0);
+    entry = newtEntry(-1, -1, argsEntry, 50, (const char **) &argsEntry, 
+                      NEWT_ENTRY_SCROLL);
+    
+    newtFormAddHotKey(f, NEWT_KEY_F12);
+    
+    buttons = newtButtonBar(_("OK"), &ok, _("Back"), &back, NULL);
+    
+    grid = newtCreateGrid(1, 3);
+    newtGridSetField(grid, 0, 0, NEWT_GRID_COMPONENT, text,
+                     0, 0, 0, 1, 0, 0);
+    newtGridSetField(grid, 0, 1, NEWT_GRID_COMPONENT, entry, 
+                     0, 0, 0, 1, 0, 0);
+    newtGridSetField(grid, 0, 2, NEWT_GRID_SUBGRID, buttons,
+                     0, 0, 0, 0, 0, NEWT_GRID_FLAG_GROWX);
+    
+    newtGridWrappedWindow(grid, _("Enter Module Parameters"));
+    newtGridAddComponentsToForm(grid, f, 1);
+    
+    do {
+        newtFormRun(f, &es);
+
+        if (es.reason  == NEWT_EXIT_COMPONENT && es.u.co == back) {
+            done = -1;
+        } else {
+            done = 1;
+        }
+    } while (done == 0);
+
+    free(buf);
+    newtGridFree(grid, 1);
+
+    if (done == -1) {
+        newtFormDestroy(f);
+        newtPopWindow();
+
+        return LOADER_BACK;
+    }
+    logMessage(INFO, "specified args of %s for %s", argsEntry, mod->moduleName);
+
+    if (strlen(argsEntry) > 0) {
+        *moduleArgs = g_strsplit(argsEntry, " ", 0);
+    }
+
+    newtFormDestroy(f);
+    newtPopWindow();
+
+    return LOADER_OK;
+}
+
+int chooseManualDriver(int class, struct loaderData_s *loaderData) {
+    int i, numSorted, num = 0, done = 0;
+    enum driverMajor type;
+    struct sortModuleList * sortedOrder;
+    char giveArgs = ' ';
+    gchar **moduleArgs = NULL;
+    moduleInfoSet modInfo = loaderData->modInfo;
+
+    newtComponent text, f, ok, back, argcheckbox, listbox;
+    newtGrid grid, buttons;
+    struct newtExitStruct es;
+
+    if (class == DEVICE_NETWORK)
+        type = DRIVER_NET;
+    else if (class == DEVICE_DISK || class == DEVICE_CDROM)
+        type = DRIVER_SCSI;
+    else
+        type = DRIVER_ANY;
+
+    do {
+        sortedOrder = malloc(sizeof(*sortedOrder) * modInfo->numModules);
+        numSorted = 0;
+        
+        for (i = 0; i < modInfo->numModules; i++) {
+            sortedOrder[numSorted].index = i;
+            sortedOrder[numSorted++].modInfo = modInfo;
+        }
+        
+        if (numSorted == 0) {
+            i = newtWinChoice(_("No drivers found"), _("Load driver disk"), 
+                              _("Back"), _("No drivers were found to manually "
+                                           "insert.  Would you like to use "
+                                           "a driver disk?"));
+            if (i != 1)
+                return LOADER_BACK;
+            
+            loadDriverFromMedia(class, loaderData, 1, 1, NULL);
+            continue;
+        } else {
+            break;
+        }
+    } while (1);
+        
+    qsort(sortedOrder, numSorted, sizeof(*sortedOrder), sortDrivers);
+
+    f = newtForm(NULL, NULL, 0);
+
+    text = newtTextboxReflowed(-1, -1,
+                               _("Please select the driver below which you "
+                                 "wish to load.  If it does not appear and "
+                                 "you have a driver disk, press F2."),
+                               60, 0, 10, 0);
+
+    listbox = newtListbox(-1, -1, 6, NEWT_FLAG_SCROLL | NEWT_FLAG_RETURNEXIT);
+    newtListboxSetWidth(listbox, 55);
+
+    buttons = newtButtonBar(_("OK"), &ok, _("Back"), &back, NULL);
+    argcheckbox = newtCheckbox(-1, -1, _("Specify optional module arguments"),
+                               giveArgs, NULL, &giveArgs);
+
+    newtFormAddHotKey(f, NEWT_KEY_F2);
+    newtFormAddHotKey(f, NEWT_KEY_F12);
+
+    for (i = 0; i < numSorted; i++) {
+        char *buf = NULL;
+
+        checked_asprintf(&buf, "%s (%s)", 
+                         modInfo->moduleList[sortedOrder[i].index].description,
+                         modInfo->moduleList[sortedOrder[i].index].moduleName);
+
+        newtListboxAppendEntry(listbox, buf, 
+                INT_TO_POINTER(sortedOrder[i].index));
+    }
+
+    grid = newtCreateGrid(1, 4);
+    newtGridSetField(grid, 0, 0, NEWT_GRID_COMPONENT, text, 0, 0, 0, 1, 0, 0);
+    newtGridSetField(grid, 0, 1, NEWT_GRID_COMPONENT, listbox, 
+                     0, 0, 0, 1, 0, 0);
+    newtGridSetField(grid, 0, 2, NEWT_GRID_COMPONENT, argcheckbox,
+                     0, 0, 0, 1, 0, 0);
+    newtGridSetField(grid, 0, 3, NEWT_GRID_SUBGRID, buttons, 
+                     0, 0, 0, 0, 0, NEWT_GRID_FLAG_GROWX);
+    newtGridWrappedWindow(grid, _("Select Device Driver to Load"));
+
+    newtGridAddComponentsToForm(grid, f, 1);
+
+    do { 
+        newtFormRun(f, &es);
+
+        num = POINTER_TO_INT(newtListboxGetCurrent(listbox));
+
+        if (es.reason == NEWT_EXIT_COMPONENT && es.u.co == back) {
+            done = -1;
+        } else if (es.reason == NEWT_EXIT_HOTKEY && es.u.key == NEWT_KEY_F2) {
+            done = -2;
+        } else {
+            if (giveArgs != ' ') {
+                i = getManualModuleArgs(&(modInfo->moduleList[num]),
+                                        &moduleArgs);
+                if (i == LOADER_BACK)
+                    done = 0;
+                else
+                    done = 1;
+            } else {
+                done = 1;
+            }
+        }
+    } while (done == 0);
+
+    newtGridFree(grid, 1);
+    newtFormDestroy(f);
+    newtPopWindow();
+
+    if (done == -1) 
+        return LOADER_BACK;
+    if (done == -2) {
+        loadDriverFromMedia(class, loaderData, 1, 1, NULL);
+        return chooseManualDriver(class, loaderData);
+    }
+
+    mlLoadModule(modInfo->moduleList[num].moduleName, moduleArgs);
+    free(sortedOrder);
+
+    if (moduleArgs) {
+        g_strfreev(moduleArgs);
+    }
+
+    return LOADER_OK;
+}
diff --git a/bin/loader/fwloader.c b/bin/loader/fwloader.c
new file mode 100644
index 0000000..5ad1d8e
--- /dev/null
+++ b/bin/loader/fwloader.c
@@ -0,0 +1,675 @@
+/*
+ * fwloader.c -- a small firmware loader.
+ *
+ * Copyright (C) 2006, 2007  Red Hat, Inc.  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 as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ *
+ * Author(s): Peter Jones (pjones@xxxxxxxxxx)
+ */
+
+#define _GNU_SOURCE 1
+
+#include <argz.h>
+#include <envz.h>
+#include <fcntl.h>
+#include <poll.h>
+#include <signal.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <sys/mman.h>
+#include <sys/poll.h>
+#include <sys/prctl.h>
+#include <sys/socket.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <unistd.h>
+
+#include <asm/types.h>
+#include <linux/netlink.h>
+
+#include "../isys/log.h"
+
+#include "loader.h"
+#include "fwloader.h"
+#include "udelay.h"
+
+#ifndef FWDEBUG
+#define logMessage(x, ...)
+#endif
+
+struct fw_loader {
+    int netlinkfd;
+    sigset_t sigmask;
+    char *fw_pathz;
+    size_t fw_pathz_len;
+    struct pollfd *fds;
+};
+
+int done = 0;
+
+static inline int set_fd_coe(int fd, int enable)
+{
+    int rc;
+    long flags = 0;
+
+    rc = fcntl(fd, F_GETFD, &flags);
+    if (rc < 0)
+        return rc;
+
+    if (enable)
+        flags |= FD_CLOEXEC;
+    else
+        flags &= ~FD_CLOEXEC;
+
+    rc = fcntl(fd, F_SETFD, flags);
+    return rc;
+}
+
+static int open_uevent_socket(struct fw_loader *fwl)
+{
+    int fd, rc;
+    struct sockaddr_nl sa;
+
+    fd = socket(PF_NETLINK, SOCK_DGRAM, NETLINK_KOBJECT_UEVENT);
+    if (fd < 0)
+        return -1;
+    set_fd_coe(fd, 1);
+
+    memset(&sa, '\0', sizeof (sa));
+    sa.nl_family = AF_NETLINK;
+    sa.nl_pid = getpid();
+    sa.nl_groups = -1;
+
+    if (bind(fd, (struct sockaddr *)&sa, sizeof (sa)) < 0) {
+        close(fd);
+        return -1;
+    }
+
+    fwl->netlinkfd = fd;
+
+    fd = open("/proc/sys/kernel/hotplug", O_RDWR);
+    if (fd >= 0) {
+        rc = ftruncate(fd, 0);
+        rc = write(fd, "\n", 1);
+        close(fd);
+    }
+
+    fd = open("/sys/class/firmware/timeout", O_RDWR);
+    if (fd >= 0) {
+        rc = write(fd, "10", 2);
+        close(fd);
+    }
+
+    return 0;
+}
+
+extern void loaderSegvHandler(int signum);
+
+static void kill_hotplug_signal(int signum)
+{
+    signal(signum, kill_hotplug_signal);
+    logMessage(DEBUGLVL, "fwloader: got exit signal, quitting");
+    done = 1;
+}
+
+static int daemonize(struct fw_loader *fwl)
+{
+    int fd;
+    int rc;
+
+    signal(SIGTERM, kill_hotplug_signal);
+    signal(SIGSEGV, loaderSegvHandler);
+    signal(SIGTTOU, SIG_IGN);
+    signal(SIGTTIN, SIG_IGN);
+    signal(SIGTSTP, SIG_IGN);
+
+    sigfillset(&fwl->sigmask);
+    sigdelset(&fwl->sigmask, SIGTERM);
+    sigdelset(&fwl->sigmask, SIGSEGV);
+    sigemptyset(&fwl->sigmask);
+
+    prctl(PR_SET_NAME, "hotplug", 0, 0, 0);
+    rc = chdir("/");
+
+    fd = open("/proc/self/oom_adj", O_RDWR);
+    if (fd >= 0) {
+        rc = write(fd, "-17", 3);
+        close(fd);
+    }
+
+    for (fd = 0; fd < getdtablesize(); fd++) {
+        if (fd == STDIN_FILENO || fd == STDOUT_FILENO || fd == STDERR_FILENO)
+            continue;
+        if (fd == tty_logfd || fd == file_logfd)
+            continue;
+        close(fd);
+    }
+
+    setsid();
+    fd = open("/dev/null", O_RDONLY);
+    close(STDIN_FILENO);
+    dup2(fd, STDIN_FILENO);
+    set_fd_coe(STDIN_FILENO, 1);
+    close(fd);
+    fd = open("/dev/null", O_WRONLY);
+    close(STDOUT_FILENO);
+    dup2(fd, STDOUT_FILENO);
+    set_fd_coe(STDOUT_FILENO, 1);
+    close(STDERR_FILENO);
+    dup2(fd, STDERR_FILENO);
+    set_fd_coe(STDERR_FILENO, 1);
+    close(fd);
+
+    logMessage(DEBUGLVL, "fwloader: starting up (pid %d)", getpid());
+    return 0;
+}
+
+struct uevent {
+    char *msg;
+    char *path;
+    char *envz;
+    size_t envz_len;
+};
+
+static int get_netlink_msg(struct fw_loader *fwl, struct uevent *uevent)
+{
+    size_t len;
+    ssize_t size;
+    static char buffer[2560];
+    char *pos;
+    char *msg = NULL, *path = NULL, *envz = NULL;
+    char *argv[] = { NULL };
+    size_t envz_len;
+    error_t errnum;
+
+    size = recv(fwl->netlinkfd, &buffer, sizeof (buffer), 0);
+    if (size < 0)
+        return -1;
+
+    if ((size_t)size > sizeof (buffer) - 1)
+        size = sizeof (buffer) - 1;
+    buffer[size] = '\0';
+
+    len = strcspn(buffer, "@");
+    if (!buffer[len])
+        return -1;
+
+    if ((errnum = argz_create(argv, &envz, &envz_len)) > 0)
+        goto err;
+
+    pos = buffer;
+    msg = strndup(pos, len++);
+    pos += len;
+    path = strdup(pos);
+
+    pos += strlen(pos) + 1;
+    if (len < size + 1) {
+        while (pos[0]) {
+            char *value = strchr(pos, '=');
+            if (value)
+                *(value++) = '\0';
+
+            if ((errnum = envz_add(&envz, &envz_len, pos, value)) > 0)
+                goto err;
+            pos += strlen(pos) + 1;
+            if (*pos)
+                pos += strlen(pos) + 1;
+        }
+    }
+
+    uevent->msg = msg;
+    uevent->path = path;
+    uevent->envz = envz;
+    uevent->envz_len = envz_len;
+    return 0;
+err:
+    if (msg)
+        free(msg);
+    if (path)
+        free(path);
+    while(envz)
+        argz_delete(&envz, &envz_len, envz);
+    errno = errnum;
+    return -1;
+}
+
+/* Set the 'loading' attribute for a firmware device.
+ * 1 == currently loading
+ * 0 == done loading
+ * -1 == error
+ */
+static int
+get_loading_fd(const char *device)
+{
+    int fd = -1;
+    char *loading_path = NULL;
+
+    if (asprintf(&loading_path, "%s/loading", device) < 0) {
+        logMessage(ERROR, "fwloader: device %s: asprintf: %m", device);
+        return -1;
+    }
+    logMessage(DEBUGLVL, "fwloader: looking for loading file at %s", loading_path);
+    fd = open(loading_path, O_RDWR | O_SYNC );
+    if (fd < 0)
+        logMessage(ERROR, "fwloader: open %s: %m", loading_path);
+    free(loading_path);
+    return fd;
+}
+
+static int
+set_loading(int fd, int value)
+{
+    int rc = 0;
+
+    if (value == -1)
+        rc = write(fd, "-1", 3);
+    else if (value == 0)
+        rc = write(fd, "0", 2);
+    else if (value == 1)
+        rc = write(fd, "1", 2);
+    fsync(fd);
+    fdatasync(fd);
+
+    return rc < 0 ? rc : 0;
+}
+
+static int
+fd_map(int fd, char **buf, size_t *bufsize)
+{
+    struct stat stats;
+    int en = 0;
+
+    if (fstat(fd, &stats) < 0) {
+        en = errno;
+        close(fd);
+        errno = en;
+        return -1;
+    }
+
+    *buf = mmap(NULL, stats.st_size, PROT_READ, MAP_SHARED, fd, 0);
+    if (*buf == MAP_FAILED) {
+        *buf = NULL;
+        en = errno;
+        close(fd);
+        errno = en;
+        return -1;
+    }
+    *bufsize = stats.st_size;
+    return 0;
+}
+
+static int
+file_map(const char *filename, char **buf, size_t *bufsize, int flags)
+{
+    int fd, en, rc = 0;
+
+    if ((fd = open(filename, flags ? flags : O_RDONLY)) < 0)
+        return -1;
+
+    if (fd_map(fd, buf, bufsize) < 0)
+        rc = -1;
+
+    en = errno;
+    close(fd);
+    errno = en;
+
+    return rc;
+}
+
+static void
+file_unmap(void *buf, size_t bufsize)
+{
+    munmap(buf, bufsize);
+}
+
+static int
+fetcher(char *inpath, int outfd)
+{
+    char *inbuf = NULL;
+    size_t inlen;
+    int count;
+    int en = 0;
+    int rc;
+
+    errno = 0;
+    if (access(inpath, F_OK))
+        goto out;
+
+    if (file_map(inpath, &inbuf, &inlen, O_RDONLY) < 0)
+        goto out;
+
+    lseek(outfd, 0, SEEK_SET);
+    rc = ftruncate(outfd, 0);
+    rc = ftruncate(outfd, inlen);
+
+    count = 0;
+    while (count < inlen) {
+        ssize_t c;
+        c = write(outfd, inbuf + count, inlen - count);
+        if (c <= 0)
+            goto out;
+        count += c;
+    }
+
+out:
+    en = errno;
+    if (inbuf)
+        file_unmap(inbuf, inlen);
+    if (en) {
+        errno = en;
+        return -1;
+    }
+    return 0;
+}
+
+
+static int
+_load_firmware(struct fw_loader *fwl, int fw_fd, char *sysdir, int timeout)
+{
+    int rc = 0;
+    char *fw_buf = NULL, *data = NULL;
+    size_t fw_len = 0;
+    int dfd = -1, lfd = -1;
+    int loading = -2;
+    size_t count;
+
+    logMessage(DEBUGLVL, "fwloader: waiting for firmware dir at %s", sysdir);
+    timeout *= 1000000;
+    while (access(sysdir, F_OK) && timeout) {
+        udelay(100);
+        timeout -= 100;
+    }
+    if (!timeout) {
+        logMessage(ERROR, "fwloader: never found firmware dir at %s", sysdir);
+        return -ENOENT;
+    }
+
+    if ((lfd = get_loading_fd(sysdir)) < 0)
+        return lfd;
+
+    set_loading(lfd, 1);
+    loading = -1;
+
+    if (fd_map(fw_fd, &fw_buf, &fw_len) < 0) {
+        rc = -errno;
+        goto out;
+    }
+
+    if (asprintf(&data, "%s/data", sysdir) < 0) {
+        rc = -errno;
+        goto out;
+    }
+    if ((dfd = open(data, O_RDWR)) < 0) {
+        rc = -errno;
+        goto out;
+    }
+    count = 0;
+    while (count < fw_len) {
+        ssize_t c;
+        if ((c = write(dfd, fw_buf + count, fw_len - count)) <= 0)
+            goto out;
+        count += c;
+    }
+    loading = 0;
+
+out:
+    if (dfd >= 0)
+        close(dfd);
+    if (fw_buf)
+        file_unmap(fw_buf, fw_len);
+    if (loading != -2)
+        set_loading(lfd, loading);
+    if (lfd >= 0)
+        close(lfd);
+    if (data)
+        free(data);
+
+    return rc;
+}
+
+static void load_firmware(struct fw_loader *fwl, struct uevent *uevent)
+{
+    char *devpath = NULL, *firmware = NULL, *timeout;
+    char *fw_file = NULL, *sys_file = NULL;
+    char *entry;
+    int timeout_secs;
+    char *tempfile;
+    int fd = -1;
+
+    tempfile = strdup("/tmp/fw-XXXXXX");
+    fd = mkstemp(tempfile);
+    if (fd < 0) {
+        logMessage(ERROR, "fwloader: mkstemp(\"%s\") failed: %m", tempfile);
+        free(tempfile);
+        return;
+    }
+    unlink(tempfile);
+    free(tempfile);
+
+    devpath = envz_get(uevent->envz, uevent->envz_len, "DEVPATH");
+    firmware = envz_get(uevent->envz, uevent->envz_len, "FIRMWARE");
+    timeout = envz_get(uevent->envz, uevent->envz_len, "TIMEOUT");
+    
+    if (!devpath || !firmware) {
+        argz_stringify(uevent->envz, uevent->envz_len, ' ');
+        logMessage(ERROR, "fwloader: environment: %s", uevent->envz);
+        return;
+    }
+
+    errno = 0;
+    timeout_secs = strtol(timeout, NULL, 10);
+
+    if ((errno == ERANGE && (timeout_secs == LONG_MIN ||
+                             timeout_secs == LONG_MAX)) ||
+        (errno != 0 && timeout_secs == 0)) {
+        logMessage(ERROR, "%s: %d: %m", __func__, __LINE__);
+        abort();
+    }
+
+    /* find the file */
+    for (entry = fwl->fw_pathz; entry;
+            entry = argz_next(fwl->fw_pathz, fwl->fw_pathz_len, entry)) {
+        if (asprintf(&fw_file, "%s/%s", entry, firmware) < 0)
+            return;
+
+        logMessage(INFO, "fwloader: trying to find %s at %s", firmware, fw_file);
+
+        if (fetcher(fw_file, fd) >= 0)
+            break;
+
+        free(fw_file);
+        fw_file = NULL;
+        if (errno == ENOENT || errno == EPERM)
+            continue;
+        break;
+    }
+    if (!fw_file)
+        goto out;
+
+    if (asprintf(&sys_file, "/sys%s/", devpath) < 0)
+        goto out;
+
+    _load_firmware(fwl, fd, sys_file, timeout_secs);
+
+out:
+    if (fw_file)
+        free(fw_file);
+    if (sys_file)
+        free(sys_file);
+    if (fd != -1)
+        close(fd);
+}
+
+static void handle_single_uevent(struct fw_loader *fwl, struct uevent *uevent)
+{
+    char *action = NULL;
+    char *subsystem = NULL;
+
+    action = envz_get(uevent->envz, uevent->envz_len, "ACTION");
+    subsystem = envz_get(uevent->envz, uevent->envz_len, "SUBSYSTEM");
+
+    logMessage(DEBUGLVL, "fwloader: subsystem %s got action %s", subsystem, action);
+    if (!strcmp(action, "add") && !strcmp(subsystem, "firmware"))
+        load_firmware(fwl, uevent);
+}
+
+static void handle_events(struct fw_loader *fwl)
+{
+    int rc;
+    struct uevent uevent;
+    if (fwl->fds == NULL)
+        fwl->fds = calloc(1, sizeof (struct pollfd));
+
+    do {
+        do {
+            if (done)
+                exit(0);
+            fwl->fds[0].events = POLLIN | POLLPRI;
+            fwl->fds[0].revents = 0;
+            fwl->fds[0].fd = fwl->netlinkfd;
+
+            //logMessage(DEBUGLVL, "fwloader: polling on netlink socket");
+            errno = 0;
+            rc = poll(fwl->fds, 1, -1);
+            //logMessage(DEBUGLVL, "fwloader: poll returned %d", rc);
+
+            if (done)
+                exit(0);
+        } while (rc < 1 || (rc < 0 && errno == EINTR));
+
+        memset(&uevent, '\0', sizeof (uevent));
+        if (get_netlink_msg(fwl, &uevent) < 0)
+            continue;
+
+        handle_single_uevent(fwl, &uevent);
+    } while (1);
+
+    if (fwl->fds) {
+        free(fwl->fds);
+        fwl->fds = NULL;
+    }
+}
+
+void set_fw_search_path(struct loaderData_s *loaderData, char *path)
+{
+    char *old = loaderData->fw_search_pathz, *new = NULL;
+    size_t old_len = loaderData->fw_search_pathz_len;
+
+    loaderData->fw_search_pathz = NULL;
+    loaderData->fw_search_pathz_len = -1;
+    if (!path) {
+        if (old)
+            free(old);
+        return;
+    }
+
+    if ((new = strdup(path)) == NULL)
+        goto out;
+
+    loaderData->fw_search_pathz = NULL;
+    loaderData->fw_search_pathz_len = 0;
+    if (argz_create_sep(new, ':', &loaderData->fw_search_pathz,
+                &loaderData->fw_search_pathz_len) != 0)
+        goto out;
+
+    if (old)
+        free(old);
+
+    return;
+out:
+    if (new)
+        free(new);
+    loaderData->fw_search_pathz = old;
+    loaderData->fw_search_pathz_len = old_len;
+
+    return;
+}
+
+void add_fw_search_dir(struct loaderData_s *loaderData, char *dir)
+{
+    argz_add(&loaderData->fw_search_pathz, &loaderData->fw_search_pathz_len,
+            dir);
+}
+
+void do_fw_loader(struct loaderData_s *loaderData)
+{
+    struct fw_loader fwl;
+    int rc;
+
+    memset(&fwl, '\0', sizeof (fwl));
+    fwl.netlinkfd = -1;
+
+    fwl.fw_pathz = loaderData->fw_search_pathz;
+    fwl.fw_pathz_len = loaderData->fw_search_pathz_len;
+
+    logMessage(INFO, "fwloader: starting firmware loader");
+
+    rc = daemonize(&fwl);
+    if (rc < 0) {
+        logMessage(ERROR, "fwloader: daemonize() failed with %d: %m", rc);
+        exit(1);
+    }
+
+    if (open_uevent_socket(&fwl) < 0) {
+        logMessage(ERROR, "fwloader: open_uevent_socket() failed: %m");
+        exit(1);
+    }
+
+    logMessage(DEBUGLVL, "fwloader: entering event loop");
+    handle_events(&fwl);
+
+    exit(1);
+}
+
+
+void start_fw_loader(struct loaderData_s *loaderData) {
+    pid_t loader;
+
+    loader = fork();
+    if (loader > 0)
+        loaderData->fw_loader_pid = loader;
+    if (loader != 0)
+        return;
+    
+    do_fw_loader(loaderData);
+}
+
+void stop_fw_loader(struct loaderData_s *loaderData) {
+    int x = 0, rc;
+    siginfo_t siginfo;
+    if (loaderData->fw_loader_pid > 0)
+        kill(loaderData->fw_loader_pid, SIGTERM);
+    while (x <= 100) {
+        if (x > 90)
+            kill(loaderData->fw_loader_pid, SIGKILL);
+        memset(&siginfo, '\0', sizeof (siginfo));
+        rc = waitid(P_PID, loaderData->fw_loader_pid, &siginfo, WNOHANG|WEXITED);
+        if (rc < 0 && errno == ECHILD)
+            return;
+        else if (rc == 0 && siginfo.si_pid != 0)
+            return;
+        else if (rc == 0)
+            x++;
+        usleep(10000);
+    }
+    return;
+}
+
+
+/*
+ * vim:ts=8:sw=4:sts=4:et
+ */
diff --git a/bin/loader/fwloader.h b/bin/loader/fwloader.h
new file mode 100644
index 0000000..e0b0fe8
--- /dev/null
+++ b/bin/loader/fwloader.h
@@ -0,0 +1,35 @@
+/*
+ * fwloader.h -- a small firmware loader.
+ *
+ * Copyright (C) 2006, 2007  Red Hat, Inc.  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 as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ *
+ * Author(s): Peter Jones <pjones@xxxxxxxxxx>
+ */
+
+#ifndef FWLOADER_H
+#define FWLOADER_H 1
+
+#include "loader.h"
+
+extern void set_fw_search_path(struct loaderData_s *loaderData, char *path);
+extern void add_fw_search_dir(struct loaderData_s *loaderData, char *dir);
+extern void start_fw_loader(struct loaderData_s *loaderData);
+extern void stop_fw_loader(struct loaderData_s *loaderData);
+
+#endif /* FWLOADER_H */
+/*
+ * vim:ts=8:sw=4:sts=4:et
+ */
diff --git a/bin/loader/getparts.c b/bin/loader/getparts.c
new file mode 100644
index 0000000..c60dc83
--- /dev/null
+++ b/bin/loader/getparts.c
@@ -0,0 +1,180 @@
+/*
+ * getparts.c - functions associated with getting partitions for a disk
+ *
+ * Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004  Red Hat, Inc.
+ * 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 as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ *
+ * Author(s): Michael Fulbright <msf@xxxxxxxxxx>
+ *            Jeremy Katz <katzj@xxxxxxxxxx>
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <ctype.h>
+#include <string.h>
+
+#include "../isys/log.h"
+
+/* see if this is a partition name or not */
+static int isPartitionName(char *pname) {
+
+    /* if it doesnt start with a alpha its not one */
+    if (!isalpha(*pname) || strstr(pname, "ram"))
+	return 0;
+
+    /* if it has a '/' in it then treat it specially */
+    if (strchr(pname, '/') && !strstr(pname, "iseries") && 
+        !strstr(pname, "i2o")) {
+	/* assume its either a /dev/ida/ or /dev/cciss device */
+	/* these have form of c?d?p? if its a partition */
+	return strchr(pname, 'p') != NULL;
+    } else {
+	/* if it ends with a digit we're ok */
+	return isdigit(pname[strlen(pname)-1]);
+    }
+}
+
+/* return NULL terminated array of pointers to names of partitons in
+ * /proc/partitions
+ */
+char **getPartitionsList(char * disk) {
+    FILE *f;
+    int numfound = 0;
+    char **rc=NULL;
+
+    f = fopen("/proc/partitions", "r");
+    if (!f) {
+	logMessage(ERROR, "getPartitionsList: could not open /proc/partitions");
+	return NULL;
+    }
+
+    /* read through /proc/partitions and parse out partitions */
+    while (1) {
+	char *tmpptr, *pptr;
+	char tmpstr[4096];
+
+	tmpptr = fgets(tmpstr, sizeof(tmpstr), f);
+
+	if (tmpptr) {
+	    char *a, *b;
+	    int toknum = 0;
+
+	    a = tmpstr;
+	    while (1) {
+		b = strsep(&a, " \n");
+
+		/* if no fields left abort */
+		if (!b)
+		    break;
+
+		/* if field was empty means we hit another delimiter */
+		if (!*b)
+		    continue;
+
+		/* make sure this is a valid partition line, should start */
+		/* with a numeral */
+		if (toknum == 0) {
+		    if (!isdigit(*b))
+			break;
+		} else if (toknum == 2) {
+		    /* if size is exactly 1 then ignore it as an extended */
+		    if (!strcmp(b, "1"))
+			break;
+		} else if (toknum == 3) {
+		    /* this should be the partition name */
+		    /* now we need to see if this is the block device or */
+		    /* actually a partition name                         */
+		    if (!isPartitionName(b))
+			break;
+
+                    /* make sure that either we don't care about the disk
+                     * or it's this one */
+                    if ((disk != NULL) && (strncmp(disk, b, strlen(disk))))
+                        break;
+
+		    /* we found a partition! */
+		    pptr = (char *) malloc(strlen(b) + 7);
+		    sprintf(pptr, "/dev/%s", b);
+
+		    if (!rc) {
+			rc = (char **) malloc(2*sizeof(char *));
+		        rc[0] = pptr;
+			rc[1] = NULL;
+		    } else {
+			int idx;
+			
+			rc = (char **) realloc(rc, (numfound+2)*sizeof(char *));
+			idx = 0;
+			while (idx < numfound) {
+			    if (strcmp(pptr, rc[idx]) < 0)
+				break;
+
+			    idx++;
+			}
+
+			/* move existing out of way if necessary */
+			if (idx != numfound)
+			    memmove(rc+idx+1, rc+idx, (numfound-idx)*sizeof(char *));
+
+			rc[idx] = pptr;
+			rc[numfound+1] = NULL;
+		    }
+		    numfound++;
+		    break;
+		}
+		toknum++;
+	    }
+	} else {
+	    break;
+	}
+    }
+
+    fclose(f);
+
+    return rc;
+}
+
+/* returns length of partitionlist */
+int lenPartitionsList(char **list) {
+    char **part;
+    int  rc;
+
+    if (!list) return 0;
+    for (rc = 0, part = list; *part; rc++, part++);
+
+    return rc;
+}
+
+/* frees partition list */
+void freePartitionsList(char **list) {
+    char **part;
+
+    if (!list)
+        return;
+
+    for (part = list; *part; part++) {
+	if (*part) {
+            free(*part);
+            *part = NULL;
+        }
+    }
+
+    free(list);
+    list = NULL;
+}
diff --git a/bin/loader/getparts.h b/bin/loader/getparts.h
new file mode 100644
index 0000000..b672a77
--- /dev/null
+++ b/bin/loader/getparts.h
@@ -0,0 +1,27 @@
+/*
+ * getparts.h
+ *
+ * Copyright (C) 2007  Red Hat, Inc.  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 as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GETPARTS_H
+#define GETPARTS_H
+
+char **getPartitionsList(char * disk);
+int lenPartitionsList(char **list);
+void freePartitionsList(char **list);
+
+#endif
diff --git a/bin/loader/hardware.c b/bin/loader/hardware.c
new file mode 100644
index 0000000..ad20ed5
--- /dev/null
+++ b/bin/loader/hardware.c
@@ -0,0 +1,150 @@
+/*
+ * hardware.c - various hardware probing functionality
+ *
+ * Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003  Red Hat, Inc.
+ * 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 as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ *
+ * Author(s): Erik Troan <ewt@xxxxxxxxxx>
+ *            Matt Wilson <msw@xxxxxxxxxx>
+ *            Michael Fulbright <msf@xxxxxxxxxx>
+ *            Jeremy Katz <katzj@xxxxxxxxxx>
+ */
+
+#include <errno.h>
+#include <fcntl.h>
+#include <string.h>
+#include <strings.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <ctype.h>
+#include <sys/wait.h>
+#include <glib.h>
+
+#include "loader.h"
+#include "hardware.h"
+
+/* FIXME: for turning off dma */
+#include <sys/ioctl.h>
+#include <linux/hdreg.h>
+#include "../isys/isys.h"
+#include "../isys/log.h"
+
+/* boot flags */
+extern uint64_t flags;
+
+static int detectHardware() {
+    int child, rc, status;
+    int timeout = 0; /* FIXME: commandline option for this */
+
+    fprintf(stderr, "detecting hardware...\n");
+    logMessage(DEBUGLVL, "probing buses");
+
+    if (!(child = fork())) {
+        int fd = open("/dev/tty3", O_RDWR);
+
+        dup2(fd, 0);
+        dup2(fd, 1);
+        dup2(fd, 2);
+        close(fd);
+
+        rc = execl("/sbin/udevadm", "udevadm", "trigger", NULL);
+        _exit(1);
+    }
+
+    waitpid(child, &status, 0);
+    if (!WIFEXITED(status) || (WIFEXITED(status) && WEXITSTATUS(status))) {
+        rc = 1;
+    } else {
+        rc = 0;
+    }
+
+    fprintf(stderr, "waiting for hardware to initialize...\n");
+    logMessage(DEBUGLVL, "waiting for hardware to initialize");
+
+    if (!(child = fork())) {
+        char *args[] = { "/sbin/udevadm", "settle", NULL, NULL };
+        int fd = open("/dev/tty3", O_RDWR);
+
+        dup2(fd, 0);
+        dup2(fd, 1);
+        dup2(fd, 2);
+        close(fd);
+
+        if (timeout) {
+            checked_asprintf(&args[2], "--timeout=%d", timeout);
+        }
+
+        rc = execv("/sbin/udevadm", args);
+        _exit(1);
+    }
+
+    waitpid(child, &status, 0);
+    if (!WIFEXITED(status) || (WIFEXITED(status) && WEXITSTATUS(status))) {
+        rc = 1;
+    } else {
+        rc = 0;
+    }
+    if (rc) {
+        return LOADER_ERROR;
+    }
+    return LOADER_OK;
+}
+
+/* this allows us to do an early load of modules specified on the
+ * command line to allow automating the load order of modules so that
+ * eg, certain scsi controllers are definitely first.
+ * FIXME: this syntax is likely to change in a future release
+ *        but is done as a quick hack for the present.
+ */
+int earlyModuleLoad(int justProbe) {
+    int fd, len, i;
+    char buf[1024], *cmdLine;
+    gint argc = 0;
+    gchar **argv = NULL;
+    GError *optErr = NULL;
+
+    /* FIXME: reparsing /proc/cmdline to avoid major loader changes.  
+     * should probably be done in loader.c:parseCmdline() like everything 
+     * else
+     */
+    if ((fd = open("/proc/cmdline", O_RDONLY)) < 0) return 1;
+    len = read(fd, buf, sizeof(buf) - 1);
+    close(fd);
+    if (len <= 0) return 1;
+
+    buf[len] = '\0';
+    cmdLine = buf;
+
+    if (!g_shell_parse_argv(cmdLine, &argc, &argv, &optErr)) {
+        g_error_free(optErr);
+        return 1;
+    }
+
+    for (i=0; i < argc; i++) {
+        if (!strncasecmp(argv[i], "driverload=", 11)) {
+            logMessage(INFO, "loading %s early", argv[i] + 11);
+            mlLoadModuleSet(argv[i] + 11);
+        }
+    }
+    return 0;
+}
+
+int busProbe(int justProbe) {
+    /* autodetect whatever we can */
+    if (justProbe)
+        return 0;
+    return detectHardware();
+}
diff --git a/bin/loader/hardware.h b/bin/loader/hardware.h
new file mode 100644
index 0000000..47c34d2
--- /dev/null
+++ b/bin/loader/hardware.h
@@ -0,0 +1,28 @@
+/*
+ * hardware.h
+ *
+ * Copyright (C) 2007  Red Hat, Inc.  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 as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef LOADERHW_H
+#define LOADERHW_H
+
+#include "modules.h"
+
+int earlyModuleLoad(int justProbe);
+int busProbe(int justProbe);
+
+#endif
diff --git a/bin/loader/hdinstall.c b/bin/loader/hdinstall.c
new file mode 100644
index 0000000..4bb31a8
--- /dev/null
+++ b/bin/loader/hdinstall.c
@@ -0,0 +1,496 @@
+/*
+ * hdinstall.c - code to set up hard drive installs
+ *
+ * Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003  Red Hat, Inc.
+ * 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 as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ *
+ * Author(s): Erik Troan <ewt@xxxxxxxxxx>
+ *            Matt Wilson <msw@xxxxxxxxxx>
+ *            Michael Fulbright <msf@xxxxxxxxxx>
+ *            Jeremy Katz <katzj@xxxxxxxxxx>
+ */
+
+#include <ctype.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <newt.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/mount.h>
+#include <unistd.h>
+#include <glib.h>
+
+#include "driverdisk.h"
+#include "hdinstall.h"
+#include "getparts.h"
+#include "kickstart.h"
+#include "loader.h"
+#include "loadermisc.h"
+#include "lang.h"
+#include "modules.h"
+#include "method.h"
+#include "mediacheck.h"
+#include "cdinstall.h"
+#include "windows.h"
+
+#include "../isys/imount.h"
+#include "../isys/isys.h"
+#include "../isys/eddsupport.h"
+#include "../isys/log.h"
+
+/* boot flags */
+extern uint64_t flags;
+
+/* given a partition device and directory, tries to mount hd install image */
+static char * setupIsoImages(char * device, char * dirName, char * location) {
+    int rc = 0;
+    char *url = NULL, *dirspec, *updpath, *path;
+
+    logMessage(INFO, "mounting device %s for hard drive install", device);
+
+    if (doPwMount(device, "/mnt/isodir", "auto", "ro", NULL))
+        return NULL;
+
+    checked_asprintf(&dirspec, "/mnt/isodir%.*s",
+                     (int) (strrchr(dirName, '/') - dirName), dirName);
+    checked_asprintf(&path, "/mnt/isodir%s", dirName);
+
+    if (path) {
+        logMessage(INFO, "Path to stage2 image is %s", path);
+
+        rc = copyFile(path, "/tmp/install.img");
+        rc = mountStage2("/tmp/install.img");
+
+        free(path);
+
+        if (rc) {
+            umountLoopback("/mnt/runtime", "/dev/loop0");
+            umount("/mnt/isodir");
+            goto err;
+        }
+
+        checked_asprintf(&updpath, "%s/updates.img", dirspec);
+
+        logMessage(INFO, "Looking for updates for HD in %s", updpath);
+        copyUpdatesImg(updpath);
+        free(updpath);
+
+        checked_asprintf(&updpath, "%s/product.img", dirspec);
+
+        logMessage(INFO, "Looking for product for HD in %s", updpath);
+        copyProductImg(updpath);
+
+        free(updpath);
+        free(dirspec);
+        umount("/mnt/isodir");
+
+        checked_asprintf(&url, "hd:%s:/%s", device,
+                         dirName ? dirName : ".");
+
+        return url;
+    } else {
+        free(dirspec);
+        free(path);
+
+        if (rc) {
+            umount("/mnt/isodir");
+            return NULL;
+        }
+    }
+
+err:
+    newtWinMessage(_("Error"), _("OK"),
+                   _("An error occured finding the installation image "
+                     "on your hard drive.  Please check your images and "
+                     "try again."));
+    return NULL;
+}
+
+/* setup hard drive based install from a partition with a filesystem and
+ * ISO images on that filesystem
+ */
+char * mountHardDrive(struct installMethod * method,
+		      char * location, struct loaderData_s * loaderData) {
+    int rc;
+    int i;
+
+    newtComponent listbox, label, dirEntry, form, okay, back, text;
+    struct newtExitStruct es;
+    newtGrid entryGrid, grid, buttons;
+
+    int done = 0;
+    char * dir = g_strdup("");
+    char * tmpDir;
+    char * url = NULL;
+    char * buf;
+    int numPartitions;
+
+    char **partition_list;
+    char *selpart;
+    char *kspartition = NULL, *ksdirectory = NULL;
+    char *imgpath = "/images/install.img";
+
+    /* handle kickstart/stage2= data first if available */
+    if (loaderData->method == METHOD_HD && loaderData->stage2Data) {
+        kspartition = ((struct hdInstallData *)loaderData->stage2Data)->partition;
+        if (kspartition) {
+            kspartition = g_strdup(kspartition);
+        }
+
+        ksdirectory = ((struct hdInstallData *)loaderData->stage2Data)->directory;
+        if (ksdirectory) {
+            if (g_str_has_suffix(ksdirectory, ".img")) {
+                ksdirectory = g_strdup(ksdirectory);
+            } else {
+                ksdirectory = g_strconcat(ksdirectory, imgpath, NULL);
+            }
+        } else {
+            ksdirectory = g_strdup(imgpath);
+        }
+
+        logMessage(INFO, "partition is %s, dir is %s", kspartition, ksdirectory);
+
+        if (!kspartition || !ksdirectory) {
+            logMessage(ERROR, "missing partition or directory specification");
+            loaderData->method = -1;
+
+            if (loaderData->inferredStage2)
+                loaderData->invalidRepoParam = 1;
+        } else {
+            /* if we start with /dev, strip it (#121486) */
+            char *kspart = kspartition;
+            if (!strncmp(kspart, "/dev/", 5))
+                kspart = kspart + 5;
+
+            url = setupIsoImages(kspart, ksdirectory, location);
+            if (!url) {
+                logMessage(ERROR, "unable to find %s installation images on hd",
+                           getProductName());
+                loaderData->method = -1;
+
+                if (loaderData->inferredStage2)
+                    loaderData->invalidRepoParam = 1;
+            } else {
+                g_free(kspartition);
+                g_free(ksdirectory);
+                return url;
+            }
+        }
+    } else {
+        kspartition = NULL;
+        ksdirectory = NULL;
+    }
+
+    /* if we're here its either because this is interactive, or the */
+    /* hd kickstart directive was faulty and we have to prompt for  */
+    /* location of harddrive image                                  */
+
+    partition_list = NULL;
+    while (!done) {
+        /* if we're doing another pass free this up first */
+        if (partition_list)
+            freePartitionsList(partition_list);
+
+        partition_list = getPartitionsList(NULL);
+        numPartitions = lenPartitionsList(partition_list);
+
+        /* no partitions found, try to load a device driver disk for storage */
+        if (!numPartitions) {
+            rc = newtWinChoice(_("Hard Drives"), _("Yes"), _("Back"),
+                               _("You don't seem to have any hard drives on "
+                                 "your system! Would you like to configure "
+                                 "additional devices?"));
+            if (rc == 2) {
+                loaderData->stage2Data = NULL;
+                return NULL;
+            }
+
+            rc = loadDriverFromMedia(DEVICE_DISK, loaderData, 0, 0, NULL);
+            continue;
+        }
+
+        /* now find out which partition has the stage2 image */
+        checked_asprintf(&buf, _("What partition and directory on that "
+                                 "partition holds the installation image "
+                                 "for %s?  If you don't see the disk drive "
+                                 "you're using listed here, press F2 to "
+                                 "configure additional devices."),
+                         getProductName());
+
+        text = newtTextboxReflowed(-1, -1, buf, 62, 5, 5, 0);
+        free(buf);
+
+        listbox = newtListbox(-1, -1, numPartitions > 5 ? 5 : numPartitions,
+                              NEWT_FLAG_RETURNEXIT | 
+                              (numPartitions > 5 ? NEWT_FLAG_SCROLL : 0));
+
+        for (i = 0; i < numPartitions; i++)
+            newtListboxAppendEntry(listbox,partition_list[i],partition_list[i]);
+
+        /* if we had ks data around use it to prime entry, then get rid of it*/
+        if (kspartition) {
+            newtListboxSetCurrentByKey(listbox, kspartition);
+            g_free(kspartition);
+            kspartition = NULL;
+        }
+
+        label = newtLabel(-1, -1, _("Directory holding image:"));
+
+        dirEntry = newtEntry(28, 11, dir, 28, (const char **) &tmpDir,
+                             NEWT_ENTRY_SCROLL);
+
+        /* if we had ks data around use it to prime entry, then get rid of it*/
+        if (ksdirectory) {
+            newtEntrySet(dirEntry, ksdirectory, 1);
+            g_free(ksdirectory);
+            ksdirectory = NULL;
+        }
+
+        entryGrid = newtGridHStacked(NEWT_GRID_COMPONENT, label,
+                                     NEWT_GRID_COMPONENT, dirEntry,
+                                     NEWT_GRID_EMPTY);
+
+        buttons = newtButtonBar(_("OK"), &okay, _("Back"), &back, NULL);
+
+        grid = newtCreateGrid(1, 4);
+        newtGridSetField(grid, 0, 0, NEWT_GRID_COMPONENT, text,
+                         0, 0, 0, 1, 0, 0);
+        newtGridSetField(grid, 0, 1, NEWT_GRID_COMPONENT, listbox,
+                         0, 0, 0, 1, 0, 0);
+        newtGridSetField(grid, 0, 2, NEWT_GRID_SUBGRID, entryGrid,
+                         0, 0, 0, 1, 0, 0);
+        newtGridSetField(grid, 0, 3, NEWT_GRID_SUBGRID, buttons,
+                         0, 0, 0, 0, 0, NEWT_GRID_FLAG_GROWX);
+
+        newtGridWrappedWindow(grid, _("Select Partition"));
+
+        form = newtForm(NULL, NULL, 0);
+        newtFormAddHotKey(form, NEWT_KEY_F2);
+        newtFormAddHotKey(form, NEWT_KEY_F12);
+
+        newtGridAddComponentsToForm(grid, form, 1);
+        newtGridFree(grid, 1);
+
+        newtFormRun(form, &es);
+
+        selpart = newtListboxGetCurrent(listbox);
+
+        g_free(dir);
+        if (tmpDir && *tmpDir) {
+            /* Protect from form free. */
+            dir = g_strdup(tmpDir);
+        } else  {
+            dir = g_strdup("");
+        }
+
+        newtFormDestroy(form);
+        newtPopWindow();
+
+        if (es.reason == NEWT_EXIT_COMPONENT && es.u.co == back) {
+            loaderData->stage2Data = NULL;
+            return NULL;
+        } else if (es.reason == NEWT_EXIT_HOTKEY && es.u.key == NEWT_KEY_F2) {
+            rc = loadDriverFromMedia(DEVICE_DISK, loaderData, 0, 0, NULL);
+            continue;
+        }
+
+        logMessage(INFO, "partition %s selected", selpart);
+
+        /* If the user-provided URL points at a repo instead of a stage2
+         * image, fix that up now.
+         */
+        if (!g_str_has_suffix(dir, ".img")) {
+            char *tmp = g_strconcat(dir, imgpath, NULL);
+            g_free(dir);
+            dir = tmp;
+        }
+
+        loaderData->invalidRepoParam = 1;
+
+        url = setupIsoImages(selpart, dir, location);
+        if (!url) {
+            newtWinMessage(_("Error"), _("OK"), 
+                           _("Device %s does not appear to contain "
+                             "an installation image."), selpart, getProductName());
+            continue;
+        }
+
+        done = 1; 
+    }
+
+    g_free(dir);
+
+    return url;
+}
+
+void setKickstartHD(struct loaderData_s * loaderData, int argc,
+                     char ** argv) {
+    char *p;
+    gchar *biospart = NULL, *partition = NULL, *dir = NULL;
+    GOptionContext *optCon = g_option_context_new(NULL);
+    GError *optErr = NULL;
+    GOptionEntry ksHDOptions[] = {
+        { "biospart", 0, 0, G_OPTION_ARG_STRING, &biospart, NULL, NULL },
+        { "partition", 0, 0, G_OPTION_ARG_STRING, &partition, NULL, NULL },
+        { "dir", 0, 0, G_OPTION_ARG_STRING, &dir, NULL, NULL },
+        { NULL },
+    };
+
+    logMessage(INFO, "kickstartFromHD");
+
+    g_option_context_set_help_enabled(optCon, FALSE);
+    g_option_context_add_main_entries(optCon, ksHDOptions, NULL);
+
+    if (!g_option_context_parse(optCon, &argc, &argv, &optErr)) {
+        startNewt();
+        newtWinMessage(_("Kickstart Error"), _("OK"),
+                       _("Bad argument to HD kickstart method "
+                         "command: %s"), optErr->message);
+        g_error_free(optErr);
+        g_option_context_free(optCon);
+        return;
+    }
+
+    g_option_context_free(optCon);
+
+    if (biospart) {
+        char * dev;
+
+        p = strchr(biospart,'p');
+        if(!p){
+            logMessage(ERROR, "Bad argument for --biospart");
+            return;
+        }
+        *p = '\0';
+        dev = getBiosDisk(biospart);
+        if (dev == NULL) {
+            logMessage(ERROR, "Unable to location BIOS partition %s", biospart);
+            return;
+        }
+        partition = malloc(strlen(dev) + strlen(p + 1) + 2);
+        sprintf(partition, "%s%s", dev, p + 1);
+    }
+
+    loaderData->method = METHOD_HD;
+    loaderData->stage2Data = calloc(sizeof(struct hdInstallData *), 1);
+    if (partition)
+        ((struct hdInstallData *)loaderData->stage2Data)->partition = partition;
+    if (dir)
+        ((struct hdInstallData *)loaderData->stage2Data)->directory = dir;
+
+    logMessage(INFO, "results of hd ks, partition is %s, dir is %s", partition,
+               dir);
+}
+
+int kickstartFromHD(char *kssrc) {
+    int rc;
+    char *p, *np = NULL, *tmpstr, *ksdev, *kspath;
+
+    logMessage(INFO, "getting kickstart file from harddrive");
+
+    /* format is hd:[device]:/path/to/ks.cfg */
+    /* split up pieces */
+    tmpstr = strdup(kssrc);
+    p = strchr(tmpstr, ':');
+    if (p)
+        np = strchr(p+1, ':');
+    
+    /* no second colon, assume its the old format of                     */
+    /*        hd:[device]/path/to/ks.cfg                                 */
+    /* this format is bad however because some devices have '/' in them! */
+    if (!np)
+        np = strchr(p+1, '/');
+
+    if (!p || !np) {
+        logMessage(WARNING, "Format of command line is ks=hd:[device]:/path/to/ks.cfg");
+        free(tmpstr);
+        return 1;
+    }
+
+    *np = '\0';
+    ksdev = p+1;
+    kspath = np+1;
+
+    logMessage(INFO, "Loading ks from device %s on path %s", ksdev, kspath);
+    if ((rc=getKickstartFromBlockDevice(ksdev, kspath))) {
+        if (rc == 3) {
+            startNewt();
+            newtWinMessage(_("Error"), _("OK"),
+                           _("Cannot find kickstart file on hard drive."));
+        }
+        return 1;
+    }
+
+    return 0;
+}
+
+
+int kickstartFromBD(char *kssrc) {
+    int rc;
+    char *p, *np = NULL, *r = NULL, *tmpstr, *ksdev, *kspath, *biosksdev;
+
+    logMessage(INFO, "getting kickstart file from biosdrive");
+
+    /* format is bd:[device]:/path/to/ks.cfg */
+    /* split of pieces */
+    tmpstr = strdup(kssrc);
+    p = strchr(tmpstr, ':');
+    if (p)
+        np = strchr(p+1, ':');
+    
+    if (!p || !np) {
+        logMessage(WARNING, "Format of command line is ks=bd:device:/path/to/ks.cfg");
+        free(tmpstr);
+        return 1;
+    }
+
+    *np = '\0';
+    kspath = np+1;
+
+    r = strchr(p+1,'p');
+    if(!r){
+        logMessage(INFO, "Format of biosdisk is 80p1");
+        free(tmpstr);
+        return 1;
+    }                                                          
+
+    *r = '\0';
+    biosksdev = getBiosDisk((p + 1));
+    if(!biosksdev){
+        startNewt();
+        newtWinMessage(_("Error"), _("OK"),
+                       _("Cannot find hard drive for BIOS disk %s"),
+                       p + 1);
+        return 1;
+    }
+
+
+    ksdev = malloc(strlen(biosksdev) + 3);
+    sprintf(ksdev, "%s%s", biosksdev, r + 1);
+    logMessage(INFO, "Loading ks from device %s on path %s", ksdev, kspath);
+    if ((rc=getKickstartFromBlockDevice(ksdev, kspath))) {
+        if (rc == 3) {
+            startNewt();
+            newtWinMessage(_("Error"), _("OK"),
+                           _("Cannot find kickstart file on hard drive."));
+        }
+        return 1;
+    }
+
+    return 0;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4: */
diff --git a/bin/loader/hdinstall.h b/bin/loader/hdinstall.h
new file mode 100644
index 0000000..44351a3
--- /dev/null
+++ b/bin/loader/hdinstall.h
@@ -0,0 +1,38 @@
+/*
+ * hdinstall.h
+ *
+ * Copyright (C) 2007  Red Hat, Inc.  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 as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef H_HDINSTALL
+#define H_HDINSTALL
+
+#include "method.h"
+
+struct hdInstallData {
+    char * partition;
+    char * directory;
+};
+
+
+void setKickstartHD(struct loaderData_s * loaderData, int argc,
+		    char ** argv);
+char * mountHardDrive(struct installMethod * method,
+                      char * location, struct loaderData_s * loaderData);
+int kickstartFromHD(char *kssrc);
+int kickstartFromBD(char *kssrc);
+
+#endif
diff --git a/bin/loader/ibft.c b/bin/loader/ibft.c
new file mode 100644
index 0000000..b3a3827
--- /dev/null
+++ b/bin/loader/ibft.c
@@ -0,0 +1,105 @@
+/*
+   File name: ibft.c
+   Date:      2008/09/02
+   Author:    Martin Sivak <msivak@xxxxxxxxxx>
+
+   Copyright (C) 2008 Red Hat
+
+   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; either version 2 of the
+   License, or (at your option) any later version.
+
+   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
+   in a file called COPYING along with this program; if not, write to
+   the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA
+   02139, USA.
+*/
+
+
+#include <stddef.h>
+#include <stdio.h>
+#include <string.h>
+
+#include <libiscsi.h>
+#include "ibft.h"
+
+struct libiscsi_network_config ibft_context;
+int ibft_ispresent = 0;
+int ibft_initialized = 0;
+
+int ibft_init(void)
+{
+  int ret;
+
+  memset(&ibft_context, 0, sizeof(ibft_context));
+
+  ret = libiscsi_get_firmware_network_config(&ibft_context);
+
+  /* ret == 0 -> OK */
+  ibft_ispresent = !ret;
+  ibft_initialized = 1;
+
+  return ibft_initialized;
+}
+
+/* Is iBFT available on this system */
+int ibft_present()
+{
+  if(!ibft_initialized)
+    ibft_init();
+
+  return ibft_ispresent;
+}
+
+/* Is the iBFT network configured to use DHCP */
+int ibft_iface_dhcp()
+{
+  if(!ibft_initialized)
+    ibft_init();
+
+  if(!ibft_present())
+    return -1;
+
+  return ibft_context.dhcp;
+}
+
+#define ibft_iface_charfunc(name, var) char* ibft_iface_##name()\
+{\
+  if(!ibft_initialized)\
+    ibft_init();\
+\
+  if(!ibft_present())\
+    return NULL;\
+\
+  if(!strlen(ibft_context.var))\
+    return NULL;\
+\
+  return ibft_context.var;\
+}
+
+
+/* Get the iBFT MAC address */
+ibft_iface_charfunc(mac, mac_address)
+
+/* Get the iBFT ip address */
+ibft_iface_charfunc(ip, ip_address)
+
+/* Get the iBFT subnet mask */
+ibft_iface_charfunc(mask, netmask)
+
+/* Get the iBFT gateway */
+ibft_iface_charfunc(gw, gateway)
+
+/* Get the iBFT iface name */
+ibft_iface_charfunc(iface, iface_name)
+
+/* Get the iBFT dns servers */
+ibft_iface_charfunc(dns1, primary_dns)
+ibft_iface_charfunc(dns2, secondary_dns)
+
diff --git a/bin/loader/ibft.h b/bin/loader/ibft.h
new file mode 100644
index 0000000..a922c91
--- /dev/null
+++ b/bin/loader/ibft.h
@@ -0,0 +1,45 @@
+/*
+   File name: ibft.h
+   Date:      2008/09/02
+   Author:    Martin Sivak
+
+   Copyright (C) 2008 Red Hat
+
+   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; either version 2 of the
+   License, or (at your option) any later version.
+
+   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
+   in a file called COPYING along with this program; if not, write to
+   the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA
+   02139, USA.
+*/
+
+
+#ifndef __IBFT_H__
+#define __IBFT_H__
+
+
+int ibft_init();
+int ibft_present();
+
+int ibft_iface_dhcp();
+
+char* ibft_iface_mac();
+char* ibft_iface_ip();
+char* ibft_iface_mask();
+char* ibft_iface_gw();
+char* ibft_iface_iface();
+char* ibft_iface_dns1();
+char* ibft_iface_dns2();
+
+
+#endif
+
+/* end of ibft.h */
diff --git a/bin/loader/init.c b/bin/loader/init.c
new file mode 100644
index 0000000..1a38df3
--- /dev/null
+++ b/bin/loader/init.c
@@ -0,0 +1,798 @@
+/*
+ * init.c: This is the install type init
+ *
+ * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004
+ * Red Hat, Inc.  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 as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ *
+ * Author(s): Erik Troan (ewt@xxxxxxxxxx)
+ *            Jeremy Katz (katzj@xxxxxxxxxx)
+ */
+
+#if USE_MINILIBC
+#include "minilibc.h"
+#ifndef SOCK_STREAM
+# define SOCK_STREAM 1
+#endif 
+#define klogctl syslog
+#else
+#include <ctype.h>
+#include <dirent.h>
+#include <errno.h>
+#include <execinfo.h>
+#include <fcntl.h>
+#include <net/if.h>
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/ioctl.h>
+#include <sys/klog.h>
+#include <sys/mount.h>
+#include <sys/socket.h>
+#include <sys/stat.h>
+#include <sys/swap.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#include <sys/un.h>
+#include <sys/wait.h>
+#include <unistd.h>
+#include <sys/ioctl.h>
+#include <sys/reboot.h>
+#include <linux/vt.h>
+#include <termios.h>
+#include <libgen.h>
+#include <glib.h>
+
+#include "init.h"
+#include "copy.h"
+#include "devt.h"
+#include "devices.h"
+
+#endif
+
+#include <asm/types.h>
+#include <linux/serial.h>
+
+#ifndef MS_REMOUNT
+#define MS_REMOUNT          32
+#endif
+
+#define ENV_PATH            0
+#define ENV_LD_LIBRARY_PATH 1
+#define ENV_HOME            2
+#define ENV_TERM            3
+#define ENV_DEBUG           4
+#define ENV_TERMINFO        5
+#define ENV_PYTHONPATH      6
+#define ENV_MALLOC_CHECK    7
+#define ENV_MALLOC_PERTURB  8
+
+char * env[] = {
+    "PATH=/usr/bin:/bin:/sbin:/usr/sbin:/mnt/sysimage/bin:"
+    "/mnt/sysimage/usr/bin:/mnt/sysimage/usr/sbin:/mnt/sysimage/sbin:"
+    "/mnt/sysimage/usr/X11R6/bin",
+
+    /* we set a nicer ld library path specifically for bash -- a full
+       one makes anaconda unhappy */
+#if defined(__x86_64__) || defined(__s390x__) || defined(__powerpc64__) || (defined(__sparc__) && defined(__arch64__))
+    "LD_LIBRARY_PATH=/lib64:/usr/lib64:/lib:/usr/lib",
+#else
+    "LD_LIBRARY_PATH=/lib:/usr/lib",
+#endif
+    "HOME=/",
+    "TERM=linux",
+    "DEBUG=",
+    "TERMINFO=/etc/linux-terminfo",
+    "PYTHONPATH=/tmp/updates",
+    "MALLOC_CHECK_=2",
+    "MALLOC_PERTURB_=204",
+    NULL
+};
+
+/* 
+ * this needs to handle the following cases:
+ *
+ *	1) run from a CD root filesystem
+ *	2) run from a read only nfs rooted filesystem
+ *      3) run from a floppy
+ *	4) run from a floppy that's been loaded into a ramdisk 
+ *
+ */
+
+void shutDown(int doKill, reboot_action rebootAction);
+static int getKillPolicy(void);
+static void getSyslog(char*);
+struct termios ts;
+
+static int expected_exit = 0;
+
+static void doExit(int) __attribute__ ((noreturn));
+static void doExit(int result)
+{
+    expected_exit = 1;
+    exit(result);
+}
+
+static void printstr(char * string) {
+    int ret;
+    ret = write(1, string, strlen(string));
+}
+
+static void fatal_error(int usePerror) {
+    printf("failed.\n");
+
+    printf("\nI can't recover from this.\n");
+#if !defined(__s390__) && !defined(__s390x__)
+    while (1) ;
+#endif
+}
+
+/* sets up and launches syslog */
+static void startSyslog(void) {
+    int conf_fd;
+    int ret;
+    char addr[128];
+    char forwardtcp[] = "*.* @@";
+    
+    /* update the config file with command line arguments first */
+    getSyslog(addr);
+    if (strlen(addr) > 0) {
+        conf_fd = open("/etc/rsyslog.conf", O_WRONLY|O_APPEND);
+        if (conf_fd < 0) {
+            printf("error opening /etc/rsyslog.conf: %d\n", errno);
+            printf("syslog forwarding will not be enabled\n");
+            sleep(5);
+        } else {
+            ret = write(conf_fd, forwardtcp, strlen(forwardtcp));
+            ret = write(conf_fd, addr, strlen(addr));
+            ret = write(conf_fd, "\n", 1);
+            close(conf_fd);
+        }
+    }
+
+    /* rsyslog is going to take care of things, so disable console logging */
+    klogctl(8, NULL, 1);
+    /* now we really start the daemon. */
+    int status;
+    status = system("/sbin/rsyslogd -c 4");
+    if (status < 0 || 
+        !WIFEXITED(status) || 
+        WEXITSTATUS(status)  != 0) {
+        printf("Unable to start syslog daemon.\n");
+        fatal_error(1);
+    }
+}
+
+static int setupTerminal(int fd) {
+    struct winsize winsize;
+    int fdn, len;
+    char buf[65535];
+
+    if (ioctl(fd, TIOCGWINSZ, &winsize)) {
+        printf("failed to get winsize");
+        fatal_error(1);
+    }
+
+    winsize.ws_row = 24;
+    winsize.ws_col = 80;
+
+    if (ioctl(fd, TIOCSWINSZ, &winsize)) {
+        printf("failed to set winsize");
+        fatal_error(1);
+    }
+
+    if (!strcmp(ttyname(fd), "/dev/hvc0")) {
+        /* using an HMC on a POWER system, use vt320 */
+        env[ENV_TERM] = "TERM=vt320";
+    } else {
+        /* use the no-advanced-video vt100 definition */
+        env[ENV_TERM] = "TERM=vt100-nav";
+
+        /* unless the user specifies that they want utf8 */
+        if ((fdn = open("/proc/cmdline", O_RDONLY, 0)) != -1) {
+            len = read(fdn, buf, sizeof(buf) - 1);
+            close(fdn);
+            if (len > 0 && strstr(buf, "utf8"))
+                env[ENV_TERM] = "TERM=vt100";
+        }
+    }
+
+    return 0;
+}
+#if defined(__sparc__)
+static int termcmp(struct termios *a, struct termios *b) {
+    if (a->c_iflag != b->c_iflag || a->c_oflag != b->c_oflag ||
+    a->c_cflag != b->c_cflag || a->c_lflag != b->c_lflag)
+    return 1;
+    return memcmp(a->c_cc, b->c_cc, sizeof(a->c_cc));
+}
+#endif
+
+#if !defined(__s390__) && !defined(__s390x__) && !defined(__sparc__)
+static int termcmp(struct termios *a, struct termios *b) {
+    if (a->c_iflag != b->c_iflag || a->c_oflag != b->c_oflag ||
+        a->c_cflag != b->c_cflag || a->c_lflag != b->c_lflag ||
+        a->c_ispeed != b->c_ispeed || a->c_ospeed != b->c_ospeed)
+        return 1;
+    return memcmp(a->c_cc, b->c_cc, sizeof(a->c_cc));
+}
+#endif
+
+static void createDevices(void) {
+    int i;
+
+    /*	unset the umask so devices are created with correct perms
+	and not complemented by the previous umask call */
+
+    mode_t previous_umask = umask(0); 
+
+    for (i = 0; devnodes[i].devname != NULL; i++) {
+        char devname[64];
+        int type = -1;
+
+        snprintf(devname, 63, "/dev/%s", devnodes[i].devname);
+        switch (devnodes[i].type) {
+        case DIRTYPE:
+            if (mkdir(devname, devnodes[i].perms) < 0) {
+                fprintf(stderr, "Unable to create directory %s: %m\n",
+                        devname);
+            }
+            break;
+        case CHARDEV:
+            type = S_IFCHR;
+            break;
+        case BLOCKDEV:
+            type = S_IFBLK;
+            break;
+        }
+        if (type == -1) continue;
+
+        if (mknod(devname, type | devnodes[i].perms, 
+                  makedev(devnodes[i].major, devnodes[i].minor)) < 0)
+            fprintf(stderr, "Unable to create device %s: %m\n", devname);
+    }
+
+    /* Hurray for hacks, this stops /lib/udev/rules.d/65-md-incremental.rules
+       from medling with mdraid sets. */
+    i = creat("/dev/.in_sysinit", 0644);
+    close(i);
+
+    /* Restore umask for minimal side affects */
+    umask(previous_umask); 
+}
+
+static void termReset(void) {
+    /* change to tty1 */
+    ioctl(0, VT_ACTIVATE, 1);
+    /* reset terminal */
+    tcsetattr(0, TCSANOW, &ts);
+    /* Shift in, default color, move down 100 lines */
+    /* ^O        ^[[0m          ^[[100E */
+    printf("\017\033[0m\033[100E\n");
+}
+
+/* reboot handler */
+static void sigintHandler(int signum) {
+    termReset();
+    shutDown(getKillPolicy(), REBOOT);
+}
+
+/* halt handler */
+static void sigUsr1Handler(int signum) {
+    termReset();
+    shutDown(getKillPolicy(), HALT);
+}
+
+/* poweroff handler */
+static void sigUsr2Handler(int signum) {
+    termReset();
+    shutDown(getKillPolicy(), POWEROFF);
+}
+
+static int getKillPolicy(void) {
+    int fd;
+    int len;
+    char buf[1024];
+
+    /* look through /proc/cmdline for special options */
+    if ((fd = open("/proc/cmdline", O_RDONLY,0)) > 0) {
+        len = read(fd, buf, sizeof(buf) - 1);
+        close(fd);
+        if ((len > 0) && strstr(buf, "nokill"))
+            return 0;
+    }
+    return 1;
+}
+
+/* Looks through /proc/cmdline for remote syslog paramters. */
+static void getSyslog(char *addr) {
+    int fd;
+    int len;
+    char buf[1024];
+
+    /* assume nothing gets found */
+    addr[0] = '\0';
+    if ((fd = open("/proc/cmdline", O_RDONLY,0)) <= 0) {
+        return;
+    }
+    len = read(fd, buf, sizeof(buf) - 1);
+    close(fd);
+    buf[len] = '\0';
+    
+    /* Parse the command line into argument vector using glib */
+    int i;
+    int argc;
+    char** argv;
+    GError* err = NULL;
+    if (!g_shell_parse_argv(buf, &argc, &argv, &err )) {
+        g_error_free(err);
+        return;
+    }
+    for (i = 0; i < argc; ++i) {
+        /* find what we are looking for */
+        if (!strncmp(argv[i], "syslog=", 7)) {
+            strncpy(addr, argv[i] + 7, 127);
+            addr[127] = '\0';
+            break;
+        }
+    }
+    g_strfreev(argv);
+
+    /* address can be either a hostname or IPv4 or IPv6, with or without port;
+       thus we only allow the following characters in the address: letters and
+       digits, dots, colons, slashes, dashes and square brackets */
+    if (!g_regex_match_simple("^[\\w.:/\\-\\[\\]]*$", addr, 0, 0)) {
+        /* the parameter is malformed, disable its use */
+        addr[0] = '\0';
+        printf("The syslog= command line parameter is malformed and will be\n");
+        printf("ignored by the installer.\n");
+        sleep(5);
+    }
+
+}
+
+static int getInitPid(void) {
+    int fd = 0, pid = -1, ret;
+    char * buf = calloc(1, 10);
+
+    fd = open("/var/run/init.pid", O_RDONLY);
+    if (fd < 0) {
+        fprintf(stderr, "Unable to find pid of init!!!\n");
+        return -1;
+    }
+    ret = read(fd, buf, 9);
+    close(fd);
+    ret = sscanf(buf, "%d", &pid);
+    return pid;
+}
+
+static void copyErrorFn (char *msg) {
+    printf(msg);
+}
+
+void initSegvHandler(int signum) {
+    void *array[30];
+    size_t i;
+    const char const * const errmsgs[] = {
+        "init received SIG",
+        "!  Backtrace:\n",
+        "init exited unexpectedly!  Backtrace:\n",
+    };
+
+    /* XXX This should really be in a glibc header somewhere... */
+    extern const char *const sys_sigabbrev[NSIG];
+
+    signal(signum, SIG_DFL); /* back to default */
+
+    if (signum == 0) {
+        i = write(STDERR_FILENO, errmsgs[2], strlen(errmsgs[2]));
+    } else {
+        i = write(STDERR_FILENO, errmsgs[0], strlen(errmsgs[0]));
+        i = write(STDERR_FILENO, sys_sigabbrev[signum],
+                strlen(sys_sigabbrev[signum]));
+        i = write(STDERR_FILENO, errmsgs[1], strlen(errmsgs[1]));
+    }
+
+    i = backtrace (array, 30);
+    backtrace_symbols_fd(array, i, STDERR_FILENO);
+    _exit(1);
+}
+
+void initExitHandler(void)
+{
+    if (expected_exit)
+        return;
+
+    initSegvHandler(0);
+}
+
+static void setupBacktrace(void)
+{
+    void *array;
+
+    signal(SIGSEGV, initSegvHandler);
+    signal(SIGABRT, initSegvHandler);
+    atexit(initExitHandler);
+
+    /* Turns out, there's an initializer at the top of backtrace() that
+     * (on some arches) calls dlopen(). dlopen(), unsurprisingly, calls
+     * malloc(). So, call backtrace() early in signal handler setup so
+     * we can later safely call it from the signal handler itself. */
+    backtrace(&array, 1);
+}
+
+int main(int argc, char **argv) {
+    pid_t installpid, childpid;
+    int waitStatus;
+    int fd = -1;
+    int doShutdown =0;
+    reboot_action shutdown_method = HALT;
+    int isSerial = 0;
+    char * console = NULL;
+    int doKill = 1;
+    char * argvc[15];
+    char ** argvp = argvc;
+    char twelve = 12;
+    struct serial_struct si;
+    int i, disable_keys;
+
+    if (!strncmp(basename(argv[0]), "poweroff", 8)) {
+        printf("Running poweroff...\n");
+        fd = getInitPid();
+        if (fd > 0)
+            kill(fd, SIGUSR2);
+        doExit(0);
+    } else if (!strncmp(basename(argv[0]), "halt", 4)) {
+        printf("Running halt...\n");
+        fd = getInitPid();
+        if (fd > 0)
+            kill(fd, SIGUSR1);
+        doExit(0);
+    } else if (!strncmp(basename(argv[0]), "reboot", 6)) {
+        printf("Running reboot...\n");
+        fd = getInitPid();
+        if (fd > 0)
+            kill(fd, SIGINT);
+        doExit(0);
+    }
+
+    /* turn off screen blanking */
+    printstr("\033[9;0]");
+    printstr("\033[8]");
+
+    umask(022);
+
+    /* set up signal handler */
+    setupBacktrace();
+
+    printstr("\nGreetings.\n");
+
+    printf("anaconda installer init version %s starting\n", VERSION);
+
+    printf("mounting /proc filesystem... "); 
+    if (mount("/proc", "/proc", "proc", 0, NULL))
+        fatal_error(1);
+    printf("done\n");
+
+    printf("creating /dev filesystem... "); 
+    if (mount("/dev", "/dev", "tmpfs", 0, NULL))
+        fatal_error(1);
+    createDevices();
+    printf("done\n");
+    printf("starting udev...");
+    if ((childpid = fork()) == 0) {
+        execl("/sbin/udevd", "/sbin/udevd", "--daemon", NULL);
+        exit(1);
+    }
+    
+    /* wait at least until the udevd process that we forked exits */
+    do {
+        pid_t retpid;
+        int waitstatus;
+
+        retpid = wait(&waitstatus);
+        if (retpid == -1) {
+            if (errno == EINTR)
+                continue;
+            /* if the child exited before we called waitpid, we can get
+             * ECHILD without anything really being wrong; we just lost
+             * the race.*/
+            if (errno == ECHILD)
+                break;
+            printf("init: error waiting on udevd: %m\n");
+            exit(1);
+        } else if ((retpid == childpid) && WIFEXITED(waitstatus)) {
+            break;
+        }
+    } while (1);
+    
+    if (fork() == 0) {
+        execl("/sbin/udevadm", "udevadm", "control", "--env=ANACONDA=1", NULL);
+        exit(1);
+    }
+    printf("done\n");
+
+    printf("mounting /dev/pts (unix98 pty) filesystem... "); 
+    if (mount("/dev/pts", "/dev/pts", "devpts", 0, NULL))
+        fatal_error(1);
+    printf("done\n");
+
+    printf("mounting /sys filesystem... "); 
+    if (mount("/sys", "/sys", "sysfs", 0, NULL))
+        fatal_error(1);
+    printf("done\n");
+
+    /* these args are only for testing from commandline */
+    for (i = 1; i < argc; i++) {
+        if (!strcmp (argv[i], "serial")) {
+            isSerial = 1;
+            break;
+        }
+    }
+
+    doKill = getKillPolicy();
+
+#if !defined(__s390__) && !defined(__s390x__)
+    static struct termios orig_cmode;
+    struct termios cmode, mode;
+    int cfd;
+    
+    cfd =  open("/dev/console", O_RDONLY);
+    tcgetattr(cfd,&orig_cmode);
+    close(cfd);
+
+    cmode = orig_cmode;
+    cmode.c_lflag &= (~ECHO);
+
+    cfd = open("/dev/console", O_WRONLY);
+    tcsetattr(cfd,TCSANOW,&cmode);
+    close(cfd);
+
+    /* handle weird consoles */
+#if defined(__powerpc__)
+    char * consoles[] = { "/dev/hvc0", /* hvc for JS20 */
+
+                          "/dev/hvsi0", "/dev/hvsi1",
+                          "/dev/hvsi2", /* hvsi for POWER5 */
+                          NULL };
+#elif defined (__ia64__)
+    char * consoles[] = { "/dev/ttySG0", "/dev/xvc0", "/dev/hvc0", NULL };
+#elif defined (__i386__) || defined (__x86_64__)
+    char * consoles[] = { "/dev/xvc0", "/dev/hvc0", NULL };
+#else
+    char * consoles[] = { NULL };
+#endif
+    for (i = 0; consoles[i] != NULL; i++) {
+        if ((fd = open(consoles[i], O_RDWR)) >= 0 && !tcgetattr(fd, &mode) && !termcmp(&cmode, &mode)) {
+            printf("anaconda installer init version %s using %s as console\n",
+                   VERSION, consoles[i]);
+            isSerial = 3;
+            console = strdup(consoles[i]);
+            break;
+        }
+        close(fd);
+    }
+
+    cfd = open("/dev/console", O_WRONLY);
+    tcsetattr(cfd,TCSANOW,&orig_cmode);
+    close(cfd); 
+
+    if ((fd < 0) && (ioctl (0, TIOCLINUX, &twelve) < 0)) {
+        isSerial = 2;
+
+        if (ioctl(0, TIOCGSERIAL, &si) == -1) {
+            isSerial = 0;
+        }
+    }
+
+    if (isSerial && (isSerial != 3)) {
+        char *device = "/dev/ttyS0";
+
+        printf("anaconda installer init version %s using a serial console\n", 
+               VERSION);
+
+        if (isSerial == 2)
+            device = "/dev/console";
+        fd = open(device, O_RDWR, 0);
+        if (fd < 0)
+            device = "/dev/tts/0";
+
+        if (fd < 0) {
+            printf("failed to open %s\n", device);
+            fatal_error(1);
+        }
+
+        setupTerminal(fd);
+    } else if (isSerial == 3) {
+        setupTerminal(fd);
+    } else if (fd < 0)  {
+        fd = open("/dev/tty1", O_RDWR, 0);
+        if (fd < 0)
+            fd = open("/dev/vc/1", O_RDWR, 0);
+
+        if (fd < 0) {
+            printf("failed to open /dev/tty1 and /dev/vc/1");
+            fatal_error(1);
+        }
+    }
+
+    setsid();
+    if (ioctl(0, TIOCSCTTY, NULL)) {
+        printf("could not set new controlling tty\n");
+    }
+
+    dup2(fd, 0);
+    dup2(fd, 1);
+    dup2(fd, 2);
+    if (fd > 2)
+        close(fd);
+#else
+    dup2(0, 1);
+    dup2(0, 2);
+#endif
+
+    /* disable Ctrl+Z, Ctrl+C, etc ... but not in rescue mode */
+    disable_keys = 1;
+    if (argc > 1)
+        if (strstr(argv[1], "rescue"))
+            disable_keys = 0;
+
+    if (disable_keys) {
+        tcgetattr(0, &ts);
+        ts.c_iflag &= ~BRKINT;
+        ts.c_iflag |= IGNBRK;
+        ts.c_iflag &= ~ISIG;
+        tcsetattr(0, TCSANOW, &ts);
+    }
+
+    int ret;
+    ret = sethostname("localhost.localdomain", 21);
+    /* the default domainname (as of 2.0.35) is "(none)", which confuses 
+     glibc */
+    ret = setdomainname("", 0);
+
+    printf("trying to remount root filesystem read write... ");
+    if (mount("/", "/", "ext2", MS_REMOUNT | MS_MGC_VAL, NULL)) {
+        fatal_error(1);
+    }
+    printf("done\n");
+
+    /* we want our /tmp to be tmpfs, but we also want to let people hack
+     * their initrds to add things like a ks.cfg, so this has to be a little
+     * tricky */
+    rename("/tmp", "/oldtmp");
+    mkdir("/tmp", 0755);
+
+    printf("mounting /tmp as tmpfs... ");
+    if (mount("none", "/tmp", "tmpfs", 0, "size=250m"))
+        fatal_error(1);
+    printf("done\n");
+
+    copyDirectory("/oldtmp", "/tmp", copyErrorFn, copyErrorFn);
+    unlink("/oldtmp");
+
+    /* Now we have some /tmp space set up, and /etc and /dev point to
+       it. We should be in pretty good shape. */
+    startSyslog();
+
+    /* write out a pid file */
+    if ((fd = open("/var/run/init.pid", O_WRONLY|O_CREAT, 0644)) > 0) {
+        char * buf = malloc(10);
+        int ret;
+
+        snprintf(buf, 9, "%d", getpid());
+        ret = write(fd, buf, strlen(buf));
+        close(fd);
+        free(buf);
+    } else {
+        printf("unable to write init.pid (%d): %m\n", errno);
+        sleep(2);
+    }
+
+    /* D-Bus */
+    if (fork() == 0) {
+        execl("/sbin/dbus-uuidgen", "/sbin/dbus-uuidgen", "--ensure", NULL);
+        doExit(1);
+    }
+
+    if (fork() == 0) {
+        execl("/sbin/dbus-daemon", "/sbin/dbus-daemon", "--system", NULL);
+        doExit(1);
+    }
+
+    sleep(2);
+
+    /* Go into normal init mode - keep going, and then do a orderly shutdown
+       when:
+
+       1) /bin/install exits
+       2) we receive a SIGHUP 
+    */
+
+    printf("running install...\n"); 
+
+    setsid();
+
+    if (!(installpid = fork())) {
+        /* child */
+        *argvp++ = "/sbin/loader";
+
+        if (isSerial == 3) {
+            *argvp++ = "--virtpconsole";
+            *argvp++ = console;
+        }
+
+        *argvp++ = NULL;
+
+        printf("running %s\n", argvc[0]);
+        execve(argvc[0], argvc, env);
+
+        shutDown(1, HALT);
+    }
+
+    /* signal handlers for halt/poweroff */
+    signal(SIGUSR1, sigUsr1Handler);
+    signal(SIGUSR2, sigUsr2Handler);
+
+    /* set up the ctrl+alt+delete handler to kill our pid, not pid 1 */
+    signal(SIGINT, sigintHandler);
+    if ((fd = open("/proc/sys/kernel/cad_pid", O_WRONLY)) != -1) {
+        char buf[7];
+        size_t count;
+        sprintf(buf, "%d", getpid());
+        count = write(fd, buf, strlen(buf));
+        close(fd);
+        /* if we succeeded in writing our pid, turn off the hard reboot
+           ctrl-alt-del handler */
+        if (count == strlen(buf) &&
+            (fd = open("/proc/sys/kernel/ctrl-alt-del", O_WRONLY)) != -1) {
+            int ret;
+
+            ret = write(fd, "0", 1);
+            close(fd);
+        }
+    }
+    
+    while (!doShutdown) {
+        pid_t childpid;
+        childpid = wait(&waitStatus);
+
+        if (childpid == installpid) {
+            doShutdown = 1;
+            ioctl(0, VT_ACTIVATE, 1);
+        }
+    }
+
+    if (!WIFEXITED(waitStatus) ||
+        (WIFEXITED(waitStatus) && WEXITSTATUS(waitStatus))) {
+        shutdown_method = DELAYED_REBOOT;
+        printf("install exited abnormally [%d/%d] ", WIFEXITED(waitStatus),
+                                                     WEXITSTATUS(waitStatus));
+        if (WIFSIGNALED(waitStatus)) {
+            printf("-- received signal %d", WTERMSIG(waitStatus));
+        }
+        printf("\n");
+    } else {
+        shutdown_method = REBOOT;
+    }
+
+    shutDown(doKill, shutdown_method);
+
+    return 0;
+}
+
+/* vim:tw=78:ts=4:et:sw=4
+ */
diff --git a/bin/loader/init.h b/bin/loader/init.h
new file mode 100644
index 0000000..e1e5b70
--- /dev/null
+++ b/bin/loader/init.h
@@ -0,0 +1,31 @@
+/*
+ * init.h
+ *
+ * Copyright (C) 2009  Red Hat, Inc.  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 as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ */
+#ifndef INIT_H
+#define INIT_H
+
+typedef enum {
+	REBOOT,
+	POWEROFF,
+	HALT,
+        /* gives user a chance to read the trace before scrolling the text out
+           with disk unmounting and termination info */
+        DELAYED_REBOOT
+} reboot_action;
+
+#endif /* INIT_H */
diff --git a/bin/loader/kbd.c b/bin/loader/kbd.c
new file mode 100644
index 0000000..b94f920
--- /dev/null
+++ b/bin/loader/kbd.c
@@ -0,0 +1,164 @@
+/*
+ * kbd.c - keyboard handling
+ *
+ * Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002  Red Hat, Inc.
+ * 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 as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ *
+ * Author(s): Erik Troan <ewt@xxxxxxxxxx>
+ *            Matt Wilson <msw@xxxxxxxxxx>
+ *            Michael Fulbright <msf@xxxxxxxxxx>
+ *            Jeremy Katz <katzj@xxxxxxxxxx>
+ */
+
+#include <alloca.h>
+#include <errno.h>
+#include <newt.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "loader.h"
+#include "loadermisc.h"
+#include "lang.h"
+#include "windows.h"
+
+#include "../isys/stubs.h"
+#include "../isys/lang.h"
+#include "../isys/log.h"
+
+/* boot flags */
+extern uint64_t flags;
+
+int chooseKeyboard(struct loaderData_s * loaderData, char ** kbdtypep) {
+    int num = -1;
+    int rc;
+    gzFile f;
+    struct kmapHeader hdr;
+    struct kmapInfo * infoTable;
+    struct langInfo * languages;
+    int numLanguages;
+    char ** kbds;
+    char buf[16384]; 			/* I hope this is big enough */
+    int i;
+    char * defkbd = loaderData->kbd ? loaderData->kbd : NULL;
+    char *lang;
+
+#if defined(__s390__) || defined(__s390x__)
+    return LOADER_NOOP;
+#endif
+
+    if (FL_SERIAL (flags) || FL_VIRTPCONSOLE(flags)) return LOADER_NOOP;
+
+    numLanguages = getLangInfo(&languages);
+
+    lang = getenv("LANG");
+    if (!lang)
+       lang = loaderData->lang;
+
+    if (!defkbd && lang) {
+	for (i = 0; i < numLanguages; i++) {
+	    if (!strncmp(languages[i].lc_all, lang, 2)) {
+		defkbd = languages[i].keyboard;
+		break;
+	    }
+	}
+    }
+
+    if (!defkbd)
+	defkbd = "us";
+
+    f = gunzip_open("/etc/keymaps.gz");
+    if (!f) {
+	errorWindow("cannot open /etc/keymaps.gz: %s");
+	return LOADER_ERROR;
+    }
+
+    if (gunzip_read(f, &hdr, sizeof(hdr)) != sizeof(hdr)) {
+	errorWindow("failed to read keymaps header: %s");
+	gunzip_close(f);
+	return LOADER_ERROR;
+    }
+
+    logMessage(INFO, "%d keymaps are available", hdr.numEntries);
+
+    i = hdr.numEntries * sizeof(*infoTable);
+    infoTable = alloca(i);
+    if (gunzip_read(f, infoTable, i) != i) {
+	errorWindow("failed to read keymap information: %s");
+	gunzip_close(f);
+	return LOADER_ERROR;
+    }
+
+    if (num == -1 ) {
+	kbds = alloca(sizeof(*kbds) * (hdr.numEntries + 1));
+	for (i = 0; i < hdr.numEntries; i++)  {
+	    kbds[i] = infoTable[i].name;
+	}
+
+	kbds[i] = NULL;
+	qsort(kbds, i, sizeof(*kbds), simpleStringCmp);
+
+	for (i = 0; i < hdr.numEntries; i++) 
+	    if (!strcmp(kbds[i], defkbd)) 
+		num = i;
+
+	rc = newtWinMenu(_("Keyboard Type"), 
+			_("What type of keyboard do you have?"),
+		        40, 5, 5, 8, kbds, &num, _("OK"), _("Back"), NULL);
+	if (rc == 2) return LOADER_BACK;
+
+	/* num needs to index the right keyboard infoTable */
+	for (i = 0; i < hdr.numEntries; i++)
+	    if (!strcmp(kbds[num], infoTable[i].name)) break;
+	num = i;
+    }
+
+    rc = 0;
+
+    for (i = 0; i < num; i++) {
+	if (gunzip_read(f, buf, infoTable[i].size) != infoTable[i].size) {
+	    logMessage(ERROR, "error reading %d bytes from file: %m",
+		       infoTable[i].size);
+	    gunzip_close(f);
+	    rc = LOADER_ERROR;
+	}
+    }
+
+    if (!rc) rc = loadKeymap(f);
+
+    /* normalize the error condition */
+    /* MSWFIXME - do we want to warn the user that setting the
+       keyboard didn't work?
+    */
+    if (rc != 0)
+	rc = LOADER_ERROR;
+    else
+        gunzip_close(f);
+
+    loaderData->kbd = strdup(infoTable[num].name);
+
+    return rc;
+}
+
+void setKickstartKeyboard(struct loaderData_s * loaderData, int argc, 
+                          char ** argv) {
+    if (argc < 2) {
+        logMessage(ERROR, "no argument passed to keyboard kickstart command");
+        return;
+    }
+
+    loaderData->kbd = argv[1];
+    loaderData->kbd_set = 1;
+}
diff --git a/bin/loader/kbd.h b/bin/loader/kbd.h
new file mode 100644
index 0000000..26c7111
--- /dev/null
+++ b/bin/loader/kbd.h
@@ -0,0 +1,27 @@
+/*
+ * kbd.h
+ *
+ * Copyright (C) 2007  Red Hat, Inc.  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 as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef H_KBD
+#define H_KBD
+
+int chooseKeyboard(struct loaderData_s * loaderData, char ** kbdtypep);
+void setKickstartKeyboard(struct loaderData_s * loaderData, int argc, 
+                          char ** argv);
+
+#endif
diff --git a/bin/loader/keymaps-i386 b/bin/loader/keymaps-i386
new file mode 100644
index 0000000000000000000000000000000000000000..93f2e58d10c66c2586ad2f42deccdecaec16b177
GIT binary patch
literal 12173
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
V7~sRTFNEiTfZ~fQc(x<}`9D*L!)E{h

literal 0
HcmV?d00001

diff --git a/bin/loader/keymaps-ppc b/bin/loader/keymaps-ppc
new file mode 100644
index 0000000000000000000000000000000000000000..914f4bfd6a36a0b42c8fb5f61284a4c15ee26b8d
GIT binary patch
literal 12871
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

literal 0
HcmV?d00001

diff --git a/bin/loader/keymaps-x86_64 b/bin/loader/keymaps-x86_64
new file mode 100644
index 0000000000000000000000000000000000000000..93f2e58d10c66c2586ad2f42deccdecaec16b177
GIT binary patch
literal 12173
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
V7~sRTFNEiTfZ~fQc(x<}`9D*L!)E{h

literal 0
HcmV?d00001

diff --git a/bin/loader/kickstart.c b/bin/loader/kickstart.c
new file mode 100644
index 0000000..26c4aab
--- /dev/null
+++ b/bin/loader/kickstart.c
@@ -0,0 +1,559 @@
+/*
+ * kickstart.c - kickstart file handling
+ *
+ * Copyright (C) 1999, 2000, 2001, 2002, 2003  Red Hat, Inc.
+ * 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 as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ *
+ * Author(s): Erik Troan <ewt@xxxxxxxxxx>
+ *            Matt Wilson <msw@xxxxxxxxxx>
+ *            Michael Fulbright <msf@xxxxxxxxxx>
+ *            Jeremy Katz <katzj@xxxxxxxxxx>
+ */
+
+#include <alloca.h>
+#include <ctype.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <newt.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <glib.h>
+
+#include "loader.h"
+#include "loadermisc.h"
+#include "lang.h"
+#include "kickstart.h"
+#include "modules.h"
+
+#include "kbd.h"
+#include "driverdisk.h"
+#include "net.h"
+#include "method.h"
+
+#include "nfsinstall.h"
+#include "urlinstall.h"
+#include "cdinstall.h"
+#include "hdinstall.h"
+
+#include "../isys/imount.h"
+#include "../isys/isys.h"
+#include "../isys/log.h"
+
+/* boot flags */
+extern uint64_t flags;
+
+struct ksCommandNames {
+    int code;
+    char * name;
+    void (*setupData) (struct loaderData_s *loaderData,
+                       int argc, char ** argv);
+} ;
+
+struct ksCommand {
+    int code, argc;
+    char ** argv;
+};
+
+static void setTextMode(struct loaderData_s * loaderData, int argc, 
+                        char ** argv);
+static void setGraphicalMode(struct loaderData_s * loaderData, int argc, 
+                             char ** argv);
+static void setCmdlineMode(struct loaderData_s * loaderData, int argc, 
+                           char ** argv);
+static void setSELinux(struct loaderData_s * loaderData, int argc, 
+                       char ** argv);
+static void setPowerOff(struct loaderData_s * loaderData, int argc, 
+                        char ** argv);
+static void setHalt(struct loaderData_s * loaderData, int argc, 
+                    char ** argv);
+static void setShutdown(struct loaderData_s * loaderData, int argc, 
+                        char ** argv);
+static void setMediaCheck(struct loaderData_s * loaderData, int argc, 
+                          char ** argv);
+static void setUpdates(struct loaderData_s * loaderData, int argc,
+                       char ** argv);
+static void setVnc(struct loaderData_s * loaderData, int argc,
+                       char ** argv);
+
+struct ksCommandNames ksTable[] = {
+    { KS_CMD_NFS, "nfs", setKickstartNfs },
+    { KS_CMD_CDROM, "cdrom", setKickstartCD },
+    { KS_CMD_HD, "harddrive", setKickstartHD },
+    { KS_CMD_TEXT, "text", setTextMode },
+    { KS_CMD_GRAPHICAL, "graphical", setGraphicalMode },
+    { KS_CMD_URL, "url", setKickstartUrl },
+    { KS_CMD_NETWORK, "network", setKickstartNetwork },
+    { KS_CMD_KEYBOARD, "keyboard", setKickstartKeyboard },
+    { KS_CMD_LANG, "lang", setKickstartLanguage },
+    { KS_CMD_DD, "driverdisk", useKickstartDD },
+    { KS_CMD_DEVICE, "device", loadKickstartModule },
+    { KS_CMD_CMDLINE, "cmdline", setCmdlineMode },
+    { KS_CMD_SELINUX, "selinux", setSELinux },
+    { KS_CMD_POWEROFF, "poweroff", setPowerOff },
+    { KS_CMD_HALT, "halt", setHalt },
+    { KS_CMD_SHUTDOWN, "shutdown", setShutdown },
+    { KS_CMD_MEDIACHECK, "mediacheck", setMediaCheck },
+    { KS_CMD_UPDATES, "updates", setUpdates },
+    { KS_CMD_VNC, "vnc", setVnc },
+    { KS_CMD_NONE, NULL, NULL }
+};
+
+struct ksCommand * commands = NULL;
+int numCommands = 0;
+
+int ksReadCommands(char * cmdFile) {
+    int fd;
+    char * buf;
+    struct stat sb;
+    char * start, * end, * chptr;
+    char oldch;
+    int line = 0;
+    gint argc = 0;
+    gchar **argv = NULL;
+    GError *optErr = NULL;
+    int inSection = 0; /* in a section such as %post, %pre or %packages */
+    struct ksCommandNames * cmd;
+    int commandsAlloced = 5;
+
+    if ((fd = open(cmdFile, O_RDONLY)) < 0) {
+        startNewt();
+        newtWinMessage(_("Kickstart Error"), _("OK"),
+                       _("Error opening kickstart file %s: %m"),
+                       cmdFile);
+        return LOADER_ERROR;
+    }
+
+    fstat(fd, &sb);
+    buf = alloca(sb.st_size + 1);
+    if (read(fd, buf, sb.st_size) != sb.st_size) {
+        startNewt();
+        newtWinMessage(_("Kickstart Error"), _("OK"),
+                       _("Error reading contents of kickstart file %s: %m"),
+                       cmdFile);
+        close(fd);
+        return LOADER_ERROR;
+    }
+
+    close(fd);
+
+    buf[sb.st_size] = '\0';
+
+    commands = malloc(sizeof(*commands) * commandsAlloced);
+
+    start = buf;
+    while (*start && !inSection) {
+        line++;
+        if (!(end = strchr(start, '\n')))
+            end = start + strlen(start);
+
+        oldch = *end;
+        *end = '\0';
+
+        while (*start && isspace(*start)) start++;
+
+        chptr = end - 1;
+        while (chptr > start && isspace(*chptr)) chptr--;
+        
+        if (isspace(*chptr)) 
+            *chptr = '\0';
+        else
+            *(chptr + 1) = '\0';
+
+        if (!*start || *start == '#' || !strncmp(start, "%include", 8)) {
+            /* keep parsing the file */
+        } else if (*start == '%') {
+            /* assumed - anything starting with %something is a section */
+            inSection = 1;
+        } else if  (*chptr == '\\') {
+            /* JKFIXME: this should be handled better, but at least we 
+             * won't segfault now */
+        } else {
+            if (!g_shell_parse_argv(start, &argc, &argv, &optErr) && argc) {
+                newtWinMessage(_("Kickstart Error"), _("OK"),
+                               _("Error in %s on line %d of kickstart "
+                                 "file %s."), argv[0], line, cmdFile);
+                g_error_free(optErr);
+            } else if (!argc) {
+                newtWinMessage(_("Kickstart Error"), _("OK"),
+                               _("Missing options on line %d of kickstart "
+                                 "file %s."), line, cmdFile);
+            } else {
+                for (cmd = ksTable; cmd->name; cmd++)
+                    if (!strcmp(cmd->name, argv[0])) break;
+                
+                if (cmd->name) {
+                    if (numCommands == commandsAlloced) {
+                        commandsAlloced += 5;
+                        commands = realloc(commands,
+                                           sizeof(*commands) * commandsAlloced);
+                    }
+                    
+                    commands[numCommands].code = cmd->code;
+                    commands[numCommands].argc = argc;
+                    commands[numCommands].argv = argv;
+                    numCommands++;
+                }
+            }
+        }
+        
+        if (oldch)
+            start = end + 1;
+        else
+            start = end;
+    }
+    
+    return 0;
+}
+
+
+int ksHasCommand(int cmd) {
+    int i;
+
+    for(i = 0; i < numCommands; i++)
+	if (commands[i].code == cmd) return 1;
+
+    return 0;
+}
+
+int ksGetCommand(int cmd, char ** last, int * argc, char *** argv) {
+    int i = 0;
+    
+    if (last) {
+        for (i = 0; i < numCommands; i++) {
+            if (commands[i].argv == last) break;
+        }
+        
+        i++;
+    }
+
+    for (; i < numCommands; i++) {    
+        if (commands[i].code == cmd) {
+            if (argv) *argv = commands[i].argv;
+            if (argc) *argc = commands[i].argc;
+            return 0;
+        }
+    }
+    
+    return 1;
+}
+
+int kickstartFromRemovable(char *kssrc) {
+    struct device ** devices;
+    char *p, *kspath;
+    int i, rc;
+
+    logMessage(INFO, "doing kickstart from removable media");
+    devices = getDevices(DEVICE_DISK);
+    /* usb can take some time to settle, even with the various hacks we
+     * have in place. some systems use portable USB CD-ROM drives, try to
+     * make sure there really isn't one before bailing. */
+    for (i = 0; !devices && i < 10; ++i) {
+        logMessage(INFO, "sleeping to wait for a USB disk");
+        sleep(2);
+        devices = getDevices(DEVICE_DISK);
+    }
+    if (!devices) {
+        logMessage(ERROR, "no disks");
+        return 1;
+    }
+
+    for (i = 0; devices[i]; i++) {
+        if (devices[i]->priv.removable == 1) {
+            logMessage(INFO, "first removable media is %s", devices[i]->device);
+            break;
+        }
+    }
+
+    if (!devices[i] || (devices[i]->priv.removable == 0)) {
+        logMessage(ERROR, "no removable devices");
+        return 1;
+    }
+
+    /* format is floppy:[/path/to/ks.cfg] */
+    kspath = "";
+    p = strchr(kssrc, ':');
+    if (p)
+	kspath = p + 1;
+
+    if (!p || strlen(kspath) < 1)
+	kspath = "/ks.cfg";
+
+    if ((rc=getKickstartFromBlockDevice(devices[i]->device, kspath))) {
+	if (rc == 3) {
+	    startNewt();
+	    newtWinMessage(_("Error"), _("OK"),
+			   _("Cannot find ks.cfg on removable media."));
+	}
+	return 1;
+    }
+
+    return 0;
+}
+
+
+/* given a device name (w/o '/dev' on it), try to get ks file */
+/* Error codes: 
+      1 - could not create device node
+      2 - could not mount device as ext2, vfat, or iso9660
+      3 - kickstart file named path not there
+*/
+int getKickstartFromBlockDevice(char *device, char *path) {
+    return getFileFromBlockDevice(device, path, "/tmp/ks.cfg");
+}
+
+static char *newKickstartLocation(const char *origLocation) {
+    const char *location;
+    char *retval = NULL;
+    newtComponent f, okay, cancel, answer, locationEntry;
+    newtGrid grid, buttons;
+
+    startNewt();
+
+    locationEntry = newtEntry(-1, -1, NULL, 60, &location, NEWT_FLAG_SCROLL);
+    newtEntrySet(locationEntry, origLocation, 1);
+
+    /* button bar at the bottom of the window */
+    buttons = newtButtonBar(_("OK"), &okay, _("Cancel"), &cancel, NULL);
+
+    grid = newtCreateGrid(1, 3);
+
+    newtGridSetField(grid, 0, 0, NEWT_GRID_COMPONENT,
+                     newtTextboxReflowed(-1, -1, _("Unable to download the kickstart file.  Please modify the kickstart parameter below or press Cancel to proceed as an interactive installation."), 60, 0, 0, 0),
+                     0, 0, 0, 0, NEWT_ANCHOR_LEFT, 0);
+    newtGridSetField(grid, 0, 1, NEWT_GRID_COMPONENT, locationEntry,
+                     0, 1, 0, 0, NEWT_ANCHOR_LEFT, 0);
+    newtGridSetField(grid, 0, 2, NEWT_GRID_SUBGRID, buttons,
+                     0, 1, 0, 0, 0, NEWT_GRID_FLAG_GROWX);
+
+    f = newtForm(NULL, NULL, 0);
+    newtGridAddComponentsToForm(grid, f, 1);
+    newtGridWrappedWindow(grid, _("Error downloading kickstart file"));
+    newtGridFree(grid, 1);
+
+    /* run the form */
+    answer = newtRunForm(f);
+
+    if (answer != cancel)
+        retval = strdup(location);
+
+    newtFormDestroy(f);
+    newtPopWindow();
+
+    return retval;
+}
+
+int isKickstartFileRemote(char *ksFile) {
+    char *location = NULL;
+
+    if (ksFile == NULL) {
+        return 0;
+    }
+
+    if (!strcmp(ksFile, "ks")) {
+       return 1;
+    } else if (!strncmp(ksFile, "ks=", 3)) {
+        location = ksFile + 3;
+    }
+
+    if (!strncmp(location, "http", 4) ||
+        !strncmp(location, "ftp://";, 6) ||
+        !strncmp(location, "nfs:", 4)) {
+        return 1;
+    } else {
+        return 0;
+    }
+}
+
+void getKickstartFile(struct loaderData_s *loaderData) {
+    char *c;
+    int rc = 1;
+
+    /* Chop off the parameter name, if given. */
+    if (!strncmp(loaderData->ksFile, "ks=", 3))
+        c = loaderData->ksFile+3;
+    else
+        c = loaderData->ksFile;
+
+    while (rc != 0) {
+        if (!strncmp(c, "ks", 2)) {
+            rc = kickstartFromNfs(NULL, loaderData);
+            loaderData->ksFile = strdup("/tmp/ks.cfg");
+        } else if (!strncmp(c, "http", 4) || !strncmp(c, "ftp://";, 6)) {
+            rc = kickstartFromUrl(c, loaderData);
+            loaderData->ksFile = strdup("/tmp/ks.cfg");
+        } else if (!strncmp(c, "nfs:", 4)) {
+            rc = kickstartFromNfs(c+4, loaderData);
+            loaderData->ksFile = strdup("/tmp/ks.cfg");
+        } else if (!strncmp(c, "floppy", 6)) {
+            rc = kickstartFromRemovable(c);
+            loaderData->ksFile = strdup("/tmp/ks.cfg");
+        } else if (!strncmp(c, "hd:", 3)) {
+            rc = kickstartFromHD(c);
+            loaderData->ksFile = strdup("/tmp/ks.cfg");
+        } else if (!strncmp(c, "bd:", 3)) {
+            rc = kickstartFromBD(c);
+            loaderData->ksFile = strdup("/tmp/ks.cfg");
+        } else if (!strncmp(c, "cdrom", 5)) {
+            rc = kickstartFromCD(c);
+            loaderData->ksFile = strdup("/tmp/ks.cfg");
+        } else if (!strncmp(c, "file:", 5)) {
+            loaderData->ksFile = c+5;
+            break;
+        }
+
+        if (rc != 0) {
+            char *newLocation;
+
+            if (!strcmp(c, "ks"))
+                newLocation = newKickstartLocation("");
+            else
+                newLocation = newKickstartLocation(c);
+
+            if (loaderData->ksFile != NULL)
+                free(loaderData->ksFile);
+
+            if (newLocation != NULL) {
+               loaderData->ksFile = strdup(newLocation);
+               free(newLocation);
+               return getKickstartFile(loaderData);
+            }
+            else
+               return;
+        }
+    }
+
+    flags |= LOADER_FLAGS_KICKSTART;
+    return;
+}
+
+static void setVnc(struct loaderData_s * loaderData, int argc,
+                   char ** argv) {
+    logMessage(INFO, "kickstart forcing graphical mode over vnc");
+    flags |= LOADER_FLAGS_GRAPHICAL | LOADER_FLAGS_EARLY_NETWORKING;
+    return;
+}
+
+static void setUpdates(struct loaderData_s * loaderData, int argc,
+                       char ** argv) {
+   if (argc == 1)
+      flags |= LOADER_FLAGS_UPDATES;
+   else if (argc == 2)
+      loaderData->updatessrc = strdup(argv[1]);
+   else
+      logMessage(WARNING, "updates command given with incorrect arguments");
+}
+
+static void setTextMode(struct loaderData_s * loaderData, int argc, 
+                        char ** argv) {
+    logMessage(INFO, "kickstart forcing text mode");
+    flags |= LOADER_FLAGS_TEXT;
+    return;
+}
+
+static void setGraphicalMode(struct loaderData_s * loaderData, int argc, 
+                        char ** argv) {
+    logMessage(INFO, "kickstart forcing graphical mode");
+    flags |= LOADER_FLAGS_GRAPHICAL;
+    return;
+}
+
+static void setCmdlineMode(struct loaderData_s * loaderData, int argc, 
+                           char ** argv) {
+    logMessage(INFO, "kickstart forcing cmdline mode");
+    flags |= LOADER_FLAGS_CMDLINE;
+    return;
+}
+
+static void setSELinux(struct loaderData_s * loaderData, int argc, 
+                       char ** argv) {
+    flags |= LOADER_FLAGS_SELINUX;
+    return;
+}
+
+static void setPowerOff(struct loaderData_s * loaderData, int argc, 
+                        char ** argv) {
+    if (!FL_NOKILL(flags))
+        flags |= LOADER_FLAGS_POWEROFF;
+    return;
+}
+
+static void setHalt(struct loaderData_s * loaderData, int argc, 
+                    char ** argv) {
+    if (!FL_NOKILL(flags))
+        flags |= LOADER_FLAGS_HALT;
+    return;
+}
+
+static void setShutdown(struct loaderData_s * loaderData, int argc, 
+                    char ** argv) {
+    gint eject = 0, reboot = 0, halt = 0, poweroff = 0;
+    GOptionContext *optCon = g_option_context_new(NULL);
+    GError *optErr = NULL;
+    GOptionEntry ksOptions[] = {
+        { "eject", 'e', 0, G_OPTION_ARG_INT, &eject, NULL, NULL },
+        { "reboot", 'r', 0, G_OPTION_ARG_INT, &reboot, NULL, NULL },
+        { "halt", 'h', 0, G_OPTION_ARG_INT, &halt, NULL, NULL },
+        { "poweroff", 'p', 0, G_OPTION_ARG_INT, &poweroff, NULL, NULL },
+        { NULL },
+    };
+
+    g_option_context_set_help_enabled(optCon, FALSE);
+    g_option_context_add_main_entries(optCon, ksOptions, NULL);
+
+    if (!g_option_context_parse(optCon, &argc, &argv, &optErr)) {
+        startNewt();
+        newtWinMessage(_("Kickstart Error"), _("OK"),
+                       _("Bad argument to shutdown kickstart method "
+                         "command: %s"), optErr->message);
+        g_error_free(optErr);
+        g_option_context_free(optCon);
+        return;
+    }
+
+    g_option_context_free(optCon);
+
+    if (FL_NOKILL(flags)) {
+        flags |= LOADER_FLAGS_HALT;
+    } else  {
+        if (poweroff)
+            flags |= LOADER_FLAGS_POWEROFF;
+        if ((!poweroff && !reboot) || (halt))
+            flags |= LOADER_FLAGS_HALT;
+    }
+}
+
+static void setMediaCheck(struct loaderData_s * loaderData, int argc, 
+                          char ** argv) {
+    flags |= LOADER_FLAGS_MEDIACHECK;
+    return;
+}
+
+void runKickstart(struct loaderData_s * loaderData) {
+    struct ksCommandNames * cmd;
+    int argc;
+    char ** argv;
+
+    logMessage(INFO, "setting up kickstart");
+    for (cmd = ksTable; cmd->name; cmd++) {
+        if ((!ksGetCommand(cmd->code, NULL, &argc, &argv)) && cmd->setupData) {
+            cmd->setupData(loaderData, argc, argv);
+        }
+    }
+}
+
+/* vim:set sw=4 sts=4 et: */
diff --git a/bin/loader/kickstart.h b/bin/loader/kickstart.h
new file mode 100644
index 0000000..574026b
--- /dev/null
+++ b/bin/loader/kickstart.h
@@ -0,0 +1,54 @@
+/*
+ * kickstart.h
+ *
+ * Copyright (C) 2007  Red Hat, Inc.  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 as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef H_KICKSTART
+
+#include "loader.h"
+
+#define KS_CMD_NONE	    0
+#define KS_CMD_NFS	    1
+#define KS_CMD_CDROM	    2
+#define KS_CMD_HD	    3
+#define KS_CMD_URL	    4
+#define KS_CMD_NETWORK      5
+#define KS_CMD_TEXT         6
+#define KS_CMD_KEYBOARD     7
+#define KS_CMD_LANG         8
+#define KS_CMD_DD           9
+#define KS_CMD_DEVICE      10
+#define KS_CMD_CMDLINE     11
+#define KS_CMD_GRAPHICAL   12
+#define KS_CMD_SELINUX     13
+#define KS_CMD_POWEROFF    14
+#define KS_CMD_HALT        15
+#define KS_CMD_SHUTDOWN    16
+#define KS_CMD_MEDIACHECK  17
+#define KS_CMD_UPDATES     18
+#define KS_CMD_VNC         19
+
+int ksReadCommands(char * cmdFile);
+int ksGetCommand(int cmd, char ** last, int * argc, char *** argv);
+int ksHasCommand(int cmd);
+
+int isKickstartFileRemote(char *ksFile);
+void getKickstartFile(struct loaderData_s * loaderData);
+void runKickstart(struct loaderData_s * loaderData);
+int getKickstartFromBlockDevice(char *device, char *path);
+
+#endif
diff --git a/bin/loader/lang.c b/bin/loader/lang.c
new file mode 100644
index 0000000..31749fc
--- /dev/null
+++ b/bin/loader/lang.c
@@ -0,0 +1,399 @@
+/*
+ * lang.c - determines language, handles translations
+ *
+ * Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003  Red Hat, Inc.
+ * 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 as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ *
+ * Author(s): Erik Troan <ewt@xxxxxxxxxx>
+ *            Matt Wilson <msw@xxxxxxxxxx>
+ *            Michael Fulbright <msf@xxxxxxxxxx>
+ *            Jeremy Katz <katzj@xxxxxxxxxx>
+ */
+
+#include <alloca.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <netinet/in.h>
+#include <newt.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/ioctl.h>
+#include <unistd.h>
+#include <wchar.h>
+
+#include "loader.h"
+#include "lang.h"
+#include "loadermisc.h"
+#include "windows.h"
+
+#include "../isys/stubs.h"
+#include "../isys/cpio.h"
+#include "../isys/lang.h"
+#include "../isys/isys.h"
+#include "../isys/log.h"
+
+/* boot flags */
+extern uint64_t flags;
+
+struct aString {
+    unsigned int hash;
+    short length;
+    char * str;
+} ;
+
+struct aString * strings = NULL;
+int numStrings = 0, allocedStrings = 0;
+
+static int english = 0;
+
+static char * topLineWelcome = N_("Welcome to %s for %s");
+static char * topLineWelcomeRescue = N_("Welcome to %s for %s - Rescue Mode");
+static char * bottomHelpLine = N_("  <Tab>/<Alt-Tab> between elements  | <Space> selects | <F12> next screen ");
+
+static int aStringCmp(const void * a, const void * b) {
+    const struct aString * first = a;
+    const struct aString * second = b;
+
+    if (first->hash < second->hash)
+        return -1;
+    else if (first->hash == second->hash)
+        return 0;
+
+    return 1;
+}
+
+char * translateString(char * str) {
+    unsigned int sum = 0, xor = 0;
+    int len = 0;
+    char * chptr;
+    struct aString * match;
+    struct aString key;
+
+    for (chptr = str; *chptr; chptr++) {
+        sum += *chptr;
+        xor ^= *chptr;
+        len++;
+    }
+
+    key.hash = (sum << 16) | ((xor & 0xFF) << 8) | (len & 0xFF);
+    match = bsearch(&key, strings, numStrings, sizeof(*strings), aStringCmp);
+    if (!match)
+        return str;
+
+    return match->str;
+}
+
+static struct langInfo * languages = NULL;
+static int numLanguages = 0;
+
+static void loadLanguageList(void) {
+    char * file = "/etc/lang-table";
+    FILE * f;
+    char line[256];
+    char name[256], key[256], font[256], code[256],
+        keyboard[256], timezone[256];
+    int lineNum = 0;
+
+    wcwidth(0);
+    f = fopen(file, "r");
+    if (!f) {
+        newtWinMessage(_("Error"), _("OK"), "cannot open %s: %m", file);
+        return;
+    }
+
+    while (fgets(line, sizeof(line), f)) {
+        lineNum++;
+        languages = realloc(languages, sizeof(*languages) * (numLanguages + 1));
+        if (sscanf(line, "%[^\t]\t%[^\t]\t%[^\t]\t%[^\t]\t%[^\t]\t%[^\t]\n",
+                   name, key, font, code, keyboard, timezone) != 6) {
+            printf("bad line %d in lang-table", lineNum);
+            logMessage(WARNING, "bad line %d in lang-table", lineNum);
+        } else {
+            languages[numLanguages].lang = strdup(name);
+            languages[numLanguages].key = strdup(key);
+            languages[numLanguages].font = strdup(font);
+            languages[numLanguages].lc_all = strdup(code);
+            languages[numLanguages++].keyboard = strdup(keyboard);
+        }
+    }
+    fclose(f);
+}
+
+int getLangInfo(struct langInfo ** langs) {
+    if (!languages)
+        loadLanguageList();
+
+    *langs = languages;
+    return numLanguages;
+}
+
+void loadLanguage (char * file) {
+    char filename[200];
+    gzFile stream;
+    int fd, hash, rc;
+    char * key = getenv("LANGKEY");
+
+    if (strings) {
+	free(strings), strings = NULL;
+	numStrings = allocedStrings = 0;
+    }
+    
+    /* english requires no files */
+    if (!strcmp(key, "en"))
+        return;
+
+    if (!file) {
+        file = filename;
+        sprintf(filename, "/etc/loader.tr");
+    }
+
+    stream = gunzip_open(file);
+
+    if (!stream) {
+        newtWinMessage("Error", "OK", "Translation for %s is not available.  "
+                       "The Installation will proceed in English.", key);
+        return ;
+    }
+    
+    sprintf(filename, "%s.tr", key);
+
+    rc = installCpioFile(stream, filename, "/tmp/translation", 1);
+    gunzip_close(stream);
+
+    if (rc || access("/tmp/translation", R_OK)) {
+        newtWinMessage("Error", "OK", "Cannot get translation file %s.\n", 
+                        filename);
+        return;
+    }
+    
+    fd = open("/tmp/translation", O_RDONLY);
+    if (fd < 0) {
+        newtWinMessage("Error", "OK", "Failed to open /tmp/translation: %m\n");
+        return;
+    }
+
+    while (read(fd, &hash, 4) == 4) {
+        if (allocedStrings == numStrings) {
+            allocedStrings += 10;
+            strings = realloc(strings, sizeof(*strings) * allocedStrings);
+        }
+
+        strings[numStrings].hash = ntohl(hash);
+        rc = read(fd, &strings[numStrings].length, 2);
+        strings[numStrings].length = ntohs(strings[numStrings].length);
+        strings[numStrings].str = malloc(strings[numStrings].length + 1);
+        rc = read(fd, strings[numStrings].str, strings[numStrings].length);
+        strings[numStrings].str[strings[numStrings].length] = '\0';
+        numStrings++;
+    }
+
+    close(fd);
+    unlink("/tmp/translation");
+
+    qsort(strings, numStrings, sizeof(*strings), aStringCmp);
+}
+
+
+/* give the index of the language to set to -- sets the appropriate
+ * lang variables if we have a font.
+ *
+ * ASSUMPTION: languages exists
+ */
+static void setLangEnv (int i) {
+    if (i > numLanguages)
+        return;
+
+    if (strcmp(languages[i].font, "latarcyrheb-sun16"))
+        return;
+    logMessage(INFO, "setting language to %s", languages[i].lc_all);
+
+    setenv("LANG", languages[i].lc_all, 1);
+    setenv("LANGKEY", languages[i].key, 1);
+    setenv("LINGUAS", languages[i].lang, 1);
+    loadLanguage (NULL);
+}
+
+/* choice is the index of the chosen language in languages */
+static int setupLanguage(int choice, int forced) {
+    char * buf;
+    int i;
+
+    logMessage(DEBUGLVL, "going to set language to %s", languages[choice].lc_all);
+    /* load the language only if it is displayable.  if they're using
+     * a serial console or iSeries vioconsole, we hope it's smart enough */
+    if ((strcmp(languages[choice].font, "latarcyrheb-sun16") && !FL_SERIAL(flags) && 
+         !FL_VIRTPCONSOLE(flags) && !isVioConsole())) {
+        if (forced == 1) return 0;
+
+	newtWinMessage("Language Unavailable", "OK", 
+		       "%s display is unavailable in text mode.  The "
+		       "installation will continue in English until the "
+		       "display of %s is possible.", languages[choice].lang,
+		       languages[choice].lang);
+        setLangEnv(english);
+	return 0;
+    }
+    
+    setLangEnv (choice);
+    isysLoadFont();
+
+    /* clear out top line */
+    buf = alloca(81); /* reserve one byte for \0 */
+    for (i=0; i < 80; i++)
+	buf[i] = ' ';
+    buf[80] = 0; /* and set the \0 */
+    newtDrawRootText(0, 0, buf);
+
+    char *fmt = FL_RESCUE(flags) ? _(topLineWelcomeRescue) : _(topLineWelcome);
+    checked_asprintf(&buf, fmt, getProductName(), getProductArch());
+
+    newtDrawRootText(0, 0, buf);
+    free(buf);
+    newtPopHelpLine();
+    newtPushHelpLine(_(bottomHelpLine));
+
+    return 0;
+
+}
+
+/* this is pretty simple.  we want to break down the language specifier
+ * into its short form (eg, en_US)
+ */
+static char * getLangShortForm(char * oldLang) {
+    char * lang;
+    char * c;
+    
+    lang = strdup(oldLang);
+
+    c = strchr(lang, '@');
+    if (c) {
+        *c = '\0';
+    }
+
+    c = strchr(lang, '.');
+    if (c) {
+        *c = '\0';
+    }
+
+    return lang;
+}
+
+/* return the nick of a language -- eg en_US -> en */
+static char * getLangNick(char * oldLang) {
+    char * lang;
+    char * c;
+    
+    lang = strdup(oldLang);
+
+    c = strchr(lang, '_');
+    if (c) {
+        *c = '\0';
+    }
+
+    return lang;
+}
+
+int setLanguage (char * key, int forced) {
+    int i;
+
+    if (!languages) loadLanguageList();
+
+    for (i = 0; i < numLanguages; i++) {
+        if (!strcmp(languages[i].lc_all, key)) {
+            return setupLanguage(i, forced | !FL_KICKSTART(flags));
+        }
+    }
+
+    /* we didn't specify anything that's exactly in the lang-table.  check
+     * against short forms and nicks */
+    for (i = 0; i < numLanguages; i++) {
+        if (!strcmp(getLangShortForm(languages[i].lc_all), key)) {
+            return setupLanguage(i, forced | !FL_KICKSTART(flags));
+        }
+    }
+
+    for (i = 0; i < numLanguages; i++) {
+        if (!strcmp(getLangNick(languages[i].lc_all), key)) {
+            return setupLanguage(i, forced | !FL_KICKSTART(flags));
+        }
+    }
+
+    logMessage(ERROR, "unable to set to requested language %s", key);
+    return -1;
+}
+
+int chooseLanguage(char ** lang) {
+    int choice = 0;
+    char ** langs;
+    int i;
+    int current = -1;
+    char * currentLangName = getenv("LANG");
+    int numLangs = 0;
+    char * langPicked;
+
+    if (!languages) loadLanguageList();
+
+    langs = alloca(sizeof(*langs) * (numLanguages + 1)); 
+
+    for (i = 0; i < numLanguages; i++) {
+        if (!strncmp(languages[i].key, "en", 2))
+            english = numLangs;
+        if (currentLangName &&
+            !strcmp(languages[i].lang, currentLangName))
+            current = numLangs;
+
+        langs[numLangs++] = languages[i].lang;
+    }
+
+    langs[numLangs] = NULL;
+
+    if (current >= 0)
+        choice = current;
+    else
+        choice = english;
+
+    if (!FL_CMDLINE(flags))
+        newtWinMenu(_("Choose a Language"),
+                    _("What language would you like to use during the "
+                      "installation process?"), 40, 5, 5, 8,
+                    langs, &choice, _("OK"), NULL);
+
+    langPicked = langs[choice];
+    for (i = 0; i < numLanguages; i++) {
+        if (!strcmp(langPicked, languages[i].lang)) {
+            *lang = languages[i].lc_all;
+            choice = i;
+            break;
+        }
+    }
+
+    /* this can't happen */
+    if (i == numLanguages) abort();
+
+    return setupLanguage(choice, 0);
+}
+
+void setKickstartLanguage(struct loaderData_s * loaderData, int argc, 
+                          char ** argv) {
+    if (argc < 2) {
+        logMessage(ERROR, "no argument passed to lang kickstart command");
+        return;
+    }
+
+    loaderData->lang = argv[1];
+    loaderData->lang_set = 1;
+}
diff --git a/bin/loader/lang.h b/bin/loader/lang.h
new file mode 100644
index 0000000..965f5a0
--- /dev/null
+++ b/bin/loader/lang.h
@@ -0,0 +1,41 @@
+/*
+ * lang.h
+ *
+ * Copyright (C) 2007  Red Hat, Inc.  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 as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _LANG_H_
+#define _LANG_H_
+
+#include "loader.h"
+
+#define _(x) translateString (x)
+#define N_(foo) (foo)
+
+struct langInfo {
+    char * lang, * key, * font, * lc_all, * keyboard;
+} ;
+
+
+int chooseLanguage(char ** lang);
+char * translateString(char * str);
+int setLanguage (char * key, int forced);
+int getLangInfo(struct langInfo **langs);
+
+void setKickstartLanguage(struct loaderData_s * loaderData, int argc, 
+                          char ** argv);
+
+#endif /* _LANG_H_ */
diff --git a/bin/loader/linuxrc.s390 b/bin/loader/linuxrc.s390
new file mode 100644
index 0000000..814dd32
--- /dev/null
+++ b/bin/loader/linuxrc.s390
@@ -0,0 +1,3118 @@
+#! /bin/bash
+
+# linuxrc.s390: init process of Red Hat's installer initrd for s390(x)
+# Copyright (C) 2000-2004 by
+#        Bernhard Rosenkraenzer <bero@xxxxxxxxxx>
+#        Oliver Paukstadt <opaukstadt@xxxxxxxxxxxx>
+#        Karsten Hopp <karsten@xxxxxxxxx>
+#        Florian La Roche <laroche@xxxxxxxxxx>
+#        Nils Philippsen <nils@xxxxxxxxx>
+#        Helge Deller <hdeller@xxxxxxxxx>
+#        David Sainty <dsainty@xxxxxxxxxx>
+# Copyright (C) IBM Corp. 2008,2009
+#        Author: Steffen Maier <maier@xxxxxxxxxx>
+#
+#    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; either version 2 of the License, or
+#    (at your option) any later version.
+#
+#    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
+#
+
+# prerequisites of this script to run inside the installer initrd:
+# - udevadm and udevd need to be there
+# - have /etc/udev/udev.conf with at least one comment line as content
+# - if necessary, have udev rules
+# - lsznet.raw and znetcontrolunits from s390utils-base in /lib/s390-tools
+# - pack kernel modules and module-init-tools (no longer use busybox for that)
+# - "multi on" in /etc/host.conf [RH bugs 486457,486461,483244]
+
+# TODOs:
+# - make sure driver modules get loaded automatically
+# - udev rule for lcs/ctcm vs. cu3088
+
+# debug: set -x
+
+if [ "${0##*/}" = "reboot" ]; then
+    kill -USR2 1
+elif [ "${0##*/}" = "halt" ]; then
+    kill -USR1 1
+fi
+
+VERSION=1.2
+
+export TEXTDOMAIN=s390installer
+export TEXTDOMAINDIR=/usr/lib/locale
+
+# helper function to execute command in arguments and print command on stdout
+function debug() {
+    # uncomment the following echo "$*" to enable debug output
+    #echo "$*"
+    $*
+}
+
+# FIXME: maybe change to "$$" for production use, in case it wouldn't be init
+declare -r INITPID="1"
+
+unset testing
+[ "$$" != "$INITPID" ] && testing="1"
+# uncomment the following test="1" to never execute sensitive commands
+#testing="1"
+
+if [ "$RUNKS" = "0" ]; then
+    RUNKS=""
+fi
+
+# ping command to use to test host availability (for gateway & dns servers)
+PINGOPTS="-c 3 -w 30"
+PING="ping $PINGOPTS"
+PING6="ping6 $PINGOPTS"
+
+# helper function to disable commands while running outside the initrd
+function tv() {
+    if [ -z "$testing" ]; then
+        $*
+    else
+        return 0
+    fi
+}
+
+function checkipv6()
+{
+    local ip=$1
+    [ -z "$ip" ] && return 1
+    /sbin/ipcalc -c -6 "$ip" >/dev/null 2>&1
+    return $?
+}
+
+function checkipv4()
+{
+    local ip=$1
+    [ -z "$ip" ] && return 1
+    /sbin/ipcalc -c -4 "$ip" >/dev/null 2>&1
+    return $?
+}
+
+function doshutdown()
+{
+    echo $"about to exec shutdown"
+    exec /sbin/shutdown
+    exit 0
+}
+
+function doreboot()
+{
+    if [ -e "/sys/firmware/reipl" ]; then
+        read REIPL_TYPE < /sys/firmware/reipl/reipl_type
+        echo "reipl_type=$REIPL_TYPE"
+        pushd /sys/firmware/reipl/$REIPL_TYPE >/dev/null 2>&1
+        for i in *; do
+            echo "$i=`cat $i`"
+        done
+        popd >/dev/null 2>&1
+    fi
+
+    echo $"about to exec shutdown -r"
+    exec /sbin/shutdown -r
+    exit 0
+}
+
+function sysecho () {
+    file=$1
+    shift
+    local i=1
+    while [ $i -le 10 ] ; do
+        if [ ! -f "$file" ]; then
+            sleep 1
+            i=$((i+1))
+        else
+            break
+        fi
+    done
+    [ -f "$file" ] && echo $* > $file
+}
+
+function dasd_settle() {
+    local dasd_status=/sys/bus/ccw/devices/$1/status
+    if [ ! -f $dasd_status ]; then
+        return 1
+    fi
+    local i=1
+    while [ $i -le 30 ] ; do
+        local status
+        read status < $dasd_status
+        case $status in
+            online|unformatted)
+                return 0 ;;
+            *)
+                sleep 0.1
+                i=$((i+1)) ;;
+        esac
+    done
+    return 1
+}
+
+function dasd_settle_all() {
+    for dasdccw in $(cut -d '(' -f 1 /proc/dasd/devices) ; do
+        if ! dasd_settle $dasdccw ; then
+            echo $"Could not access DASD $dasdccw in time"
+            return 1
+        fi
+    done
+    return 0
+}
+
+function startinetd()
+{
+    echo
+    echo $"Starting sshd to allow login over the network."
+    if [ -z "$testing" ]; then
+        echo $"Welcome to the anaconda install environment $VERSION for $S390ARCH" > /etc/issue.net
+        echo $"Welcome to the anaconda install environment $VERSION for $S390ARCH" > /etc/motd
+        echo >> /etc/motd
+    fi # testing
+
+    /sbin/sshd -f /etc/ssh/sshd_config.anaconda
+    if [ -z "$RUNKS" ]; then
+        echo
+        echo $"Connect now to $IPADDR and log in as user install to start the installation."
+        echo $"E.g. using: ssh -x install@$IPADDR"
+        echo $"You may log in as the root user to start an interactive shell."
+        read
+        while : ; do
+            /bin/sh --login
+            [ $? = 0 ] || break
+        done
+    fi
+}
+
+# prints a canonocalized device bus ID for a given devno of any format
+function canonicalize_devno()
+{
+    case ${#1} in
+        3) echo "0.0.0${1}" ;;
+        4) echo "0.0.${1}" ;;
+        *) echo "${1}" ;;
+    esac
+    return 0
+}
+
+# read file from CMS and write it to /tmp
+function readcmsfile() # $1=dasdport $2=filename
+{
+    local dev
+    if [ $# -ne 2 ]; then return; fi
+    # precondition: udevd created dasda block device node
+    if ! sysecho /proc/cio_ignore "free $1"; then
+        echo $"DASD $1 could not be cleared from device blacklist"
+        return 1
+    fi
+    # /proc/cio_ignore won't block on freeing devices until resensing
+    # has been completed, so wait until the udev event queue depletes
+    # (without udevadm settle we could wait 2 seconds unconditionally)
+    #debug ls -laF /dev/.udev
+    udevadm settle
+    # even though the device might now be online, some of its
+    # sysfs attributes might not yet be available
+    sleep 1
+    # precondition: dasd_eckd_mod driver incl. dependencies loaded,
+    #               dasd_mod must be loaded without setting any DASD online
+    dev=$(canonicalize_devno $1)
+    if ! sysecho /sys/bus/ccw/devices/$dev/online 1; then
+        echo $"DASD $dev could not be set online"
+        return 1
+    fi
+    udevadm settle
+    if ! dasd_settle $dev ; then
+        echo $"Could not access DASD $dev in time"
+        return 1
+    fi
+    udevadm settle
+    if ! cmsfscat -d /dev/dasda -a $2 > /tmp/$2; then
+        echo $"Could not read conf file $2 on CMS DASD $1."
+    fi
+    if ! sysecho /sys/bus/ccw/devices/$dev/online 0; then
+        echo $"DASD $dev could not be set offline again"
+        return 1
+    fi
+    udevadm settle
+    # consequences of no more module unload: loader can no longer
+    # use DASD module option to online DASDs and set other DASD parameters!
+}
+
+# adaption of the same function in init.c (udevd gets started later)
+function createDevices()
+{
+    awk '{ printf("mknod /dev/%s %s %s %s\n", $1, $2, $3, $4);
+      printf("chmod %s /dev/%s\n", $5, $1);
+      printf("chown %s /dev/%s\n", $6, $1);
+    }' <<EOF | sh
+console c 5 1 600 root:root
+null c 1 3 666 root:root
+zero c 1 5 666 root:root
+mem c 1 1 600 root:root
+ptmx c 5 2 666 root:root
+tty  c 5 0 666 root:root
+tty0 c 4 0 600 root:tty
+tty1 c 4 1 600 root:tty
+random c 1 8 644 root:root
+urandom c 1 9 644 root:root
+rtc c 10 135 644 root:root
+EOF
+    # tty handling is different from init.c since s390 does not have all
+    for i in 2 3 4 5 6 7 8 9 ; do
+        ln -s console /dev/tty$i
+    done
+    mkdir /dev/pts
+    ln -s /proc/self/fd /dev/fd
+}
+
+# approximately the main() function of init.c
+function init_main() {
+    S390ARCH=$(uname -m)
+    if [ "$S390ARCH" = "s390" ]; then
+        export S390ARCH="S/390"
+    else
+        export S390ARCH="zSeries"
+    fi
+
+    echo
+    echo $"Starting the $S390ARCH initrd to configure networking. Version is $VERSION"
+
+    # set up env vars as we do in init.c
+    if [ $(uname -m) = "s390x" ]; then
+        LD_LIBRARY_PATH=/lib64:/usr/lib64:/usr/X11R6/lib64:/usr/kerberos/lib64:/lib:/usr/lib:/usr/X11R6/lib:/usr/kerberos/lib
+    else
+        LD_LIBRARY_PATH=/lib:/usr/lib:/usr/X11R6/lib:/usr/kerberos/lib
+    fi
+    export LD_LIBRARY_PATH
+
+    PATH="$PATH:/usr/bin:/bin:/sbin:/usr/sbin:/mnt/sysimage/bin:/mnt/sysimage/usr/bin:/mnt/sysimage/usr/sbin:/mnt/sysimage/sbin:/mnt/sysimage/usr/X11R6/bin"
+    export PATH
+    HOME=/
+    export HOME
+    PYTHONPATH=/tmp/updates
+    export PYTHONPATH
+
+    if [ -z "$testing" ]; then
+
+        mount -t proc none /proc
+
+        mount -t tmpfs none /dev
+        createDevices
+        # udevd req'd by udevadm settle (/dev/.udev/queue)
+        # in readcmsfile, dialog_network_table, semantic_check_subchannels.
+        # (important: start udevd at the right time, e.g. after setup of /dev)
+        echo $"Starting udev..."
+        udevd --daemon
+        # debug: udevadm control --log-priority=debug
+
+        udevadm control --env=ANACONDA=1
+
+        mount -t devpts /dev/pts /dev/pts
+        mount -t sysfs none /sys
+
+        # remount root fs rw
+        mount /dev/root /  -o remount,rw
+
+        # limit output on 3270 console
+        # (console_loglevel of 4 is just right to not get driver info,
+        #  e.g. from qeth, since that would mix up with the user dialog)
+        echo "4 4 1 7" > /proc/sys/kernel/printk
+
+        # make /tmp/ramfs
+        mount -t ramfs none /tmp
+
+        ifconfig lo 127.0.0.1 netmask 255.0.0.0
+        route add -host 127.0.0.1 dev lo
+
+        echo -e "127.0.0.1\tlocalhost.localdomain localhost localhost4 localhost4.localdomain4" > /etc/hosts
+        echo -e     "::1\t\tlocalhost.localdomain localhost localhost6 localhost6.localdomain6" >> /etc/hosts
+
+        /sbin/dbus-uuidgen --ensure &
+        [ $? != 0 ] && echo "error on calling /sbin/dbus-uuidgen --ensure"
+        /sbin/dbus-daemon --system &
+        [ $? != 0 ] && echo "error on calling /sbin/dbus-daemon --system"
+
+    fi # testing
+}
+
+# trigger udev to automatically load device drivers
+function udev_setup() {
+    if [ -z "$testing" ]; then
+       # debug: udevadm monitor &
+       udevadm trigger
+       udevadm settle
+    fi # testing
+}
+
+# from here on accesses to sysfs try to follow
+# linux/Documentation/sysfs-rules.txt
+
+### lsznet.raw integration
+
+declare -a nettable
+
+function read_lsznet_output() {
+    count=0
+    local line
+    while read line; do
+        nettable[$count]="$line"
+        count=$((count + 1))
+    # using the more sophisticated process substitution instead of temp file
+    # requires the symlink /dev/fd -> /proc/self/fd => createDevices
+    done < <(/lib/s390-tools/lsznet.raw)
+}
+
+function print_nettable() {
+    local fmtstring="%3s %-14s %-7s %-5s %-4s %-6s %-7s %s\n"
+    printf "$fmtstring" \
+        "NUM" "CARD" "CU" "CHPID" "TYPE" "DRIVER" "IF" "DEVICES"
+    local i
+    for ((i=0; i < count; i++)); do
+        local item cutype chp chpidtype devdrv devname chlist cardtype
+        read item cutype chp chpidtype devdrv devname chlist cardtype <<< ${nettable[$i]}
+        printf "$fmtstring" \
+            $item "$cardtype" $cutype $chp "$chpidtype" $devdrv $devname $chlist
+    done
+}
+
+function clear_screen() {
+    # FIXME: find a way to clear screen despite 3215 line mode terminal
+    echo
+}
+
+function dialog_network_table() {
+    while : ; do
+        echo $"Scanning for available network devices..."
+        # This may take a long time so we show "progress":
+        #( while true; do echo -n "."; sleep 1; done ) &
+        #local childpid=$!
+        read_lsznet_output
+        #kill $childpid
+        #echo
+        echo $"Autodetection found ${count} devices."
+        # count==0: there might still be a blacklist the user wants to clear.
+        # do not flood user with long list if there are many devices
+        if [ "$count" -le 15 ]; then
+            # Show list
+            answer=s
+        else # [ $count -gt 15 ]
+            echo
+            while : ; do
+                echo $"s) show all, m) manual config:"
+                local answer
+                read answer
+                case $answer in
+                    s|m) break ;;
+                esac
+            done
+        fi
+        [ "$answer" = "m" ] && break
+        # show network table to select network hardware configuration from
+        if [ "$count" -gt 0 ]; then
+            clear_screen
+            print_nettable
+            echo
+        fi
+        # account for possibly ignored common I/O devices
+        # cio_wc_bytes is NOT local so it can be re-used outside this function
+        cio_wc_bytes=0
+        local cio_wc_filename cio_wc_foo
+        if [ -f /proc/cio_ignore ]; then
+            local cio_wc=$(wc -c /proc/cio_ignore)
+            read cio_wc_bytes cio_wc_filename cio_wc_foo <<< "$cio_wc"
+            if [ "$cio_wc_bytes" != "0" ]; then
+                echo $"Note: There is a device blacklist active! (Clearing might take long)"
+                #cat /proc/cio_ignore | tr '\n' ','
+                #echo
+            else
+                if [ "$count" -eq 0 ]; then
+                    # count==0 AND no device blacklist => manual mode
+                    echo $"Entering manual configuration mode."
+                    break
+                fi
+            fi
+        fi
+        # selection dialog
+        while : ; do
+            [ "$count" -gt 0 ] && echo -n $"<num>) use config, "
+            [ "$cio_wc_bytes" != "0" ] && echo -n $"c) clear blacklist, "
+            echo $"m) manual config, r) rescan, s) shell:"
+            local choice
+            read choice
+            [ -z "$choice" ] && continue
+            if [ "$choice" = "s" ]; then
+                echo $"Enter 'exit' at the shell prompt to get back to the installation dialog."
+                /bin/bash
+                continue 2
+            fi
+            [ "$choice" = "m" ] && break
+            [ "$choice" = "r" ] && continue 2
+            [ "$cio_wc_bytes" != "0" -a "$choice" = "c" ] && break
+            [[ "$choice" =~ ^[[:digit:]]+$ ]]
+            case $? in
+                0)
+                    # string matched the pattern
+                    [ "$choice" -ge 1 -a "$choice" -le "$count"  ] && break
+                    ;;
+                1)
+                    # string did not match the pattern
+                    continue
+                    ;;
+                2)
+                    echo "l.$LINENO: syntax error in regex of match operator =~, code needs to be fixed" 1>&2
+                    ;;
+                *)
+                    echo "l.$LINENO: unexpected return code of regex match operator =~, code needs to be fixed" 1>&2
+                    ;;
+            esac
+        done
+        if [ "$choice" = "c" ]; then
+            echo $"Clearing device blacklist..."
+            if sysecho /proc/cio_ignore "free all"; then
+                cio_wc_bytes=0
+                # /proc/cio_ignore won't block on freeing devices
+                # until resensing has been completed, so wait until
+                # the udev event queue depletes.
+                # This may take a long time so we show "progress":
+                #( while true; do echo -n "."; sleep 3; done ) &
+                #local childpid=$!
+                #debug ls -laF /dev/.udev
+                udevadm settle
+                # (virtual) CTC/A takes some more time to appear in sysfs
+                # FIXME: how long to wait? 3 seconds seems to be enough.
+                sleep 3
+                #kill $childpid
+                #echo
+                continue
+            else
+                echo $"Device blacklist could not be cleared"
+            fi
+        fi
+        [ "$choice" = "m" ] && break
+        # finally extract config info from selected item
+        # array nettable starts at index zero, user input starts at index one
+        choice=$((choice - 1))
+        local item cutype chp chpidtype devdrv devname chlist cardtype
+        read item cutype chp chpidtype devdrv devname chlist cardtype <<< ${nettable[$choice]}
+        # $NETTYPE happens to be exactly the network driver name
+        if [ "$devdrv" = "ctcm" ]; then
+            NETTYPE="ctc"
+        else
+            NETTYPE=$devdrv
+        fi
+        SUBCHANNELS=$chlist
+        break
+    done
+    echo
+}
+
+declare -r PREFIXFORMAT=[[:xdigit:]]*
+declare -r SSIDFORMAT=[0-3]
+declare -r BUSIDFORMAT=[[:xdigit:]][[:xdigit:]][[:xdigit:]][[:xdigit:]]
+declare -r IDFORMAT=$PREFIXFORMAT.$SSIDFORMAT.$BUSIDFORMAT
+declare -r SUBCHANNEL_TYPE_IO=0
+
+. /lib/s390-tools/znetcontrolunits
+
+function cardtype2cleartext() {
+    local cardtype=$1
+    case $cardtype in
+        OSD_10GIG)        echo "OSA card in OSD mode, 10 Gigabit Ethernet" ;;
+        OSD_1000)         echo "OSA card in OSD mode, Gigabit Ethernet" ;;
+        OSD_100)          echo "OSA card in OSD mode, Fast Ethernet" ;;
+        OSD_GbE_LANE)     echo "OSA card in OSD mode, Gigabit Ethernet, LAN Emulation" ;;
+        OSD_FE_LANE)      echo "OSA card in OSD mode, Fast Ethernet, LAN Emulation" ;;
+        OSD_TR_LANE)      echo "OSA card in OSD mode, Token Ring, LAN Emulation" ;;
+        OSD_ATM_LANE)     echo "OSA card in OSD mode, ATM, LAN Emulation" ;;
+        OSD_Express)      echo "OSA card in OSD mode, unknown link type" ;;
+        HSTR)             echo "OSA card in OSD mode, High Speed Token Ring" ;;
+        OSN)              echo "OSA for NCP, ESCON/CDLC bridge" ;;
+        HiperSockets)     echo "HiperSockets with CHPID type IQD" ;;
+        "GuestLAN QDIO")  echo "GuestLAN based on OSA (QDIO)" ;;
+        "GuestLAN Hiper") echo "GuestLAN based on HiperSockets" ;;
+        unknown)          echo "other" ;;
+        *) echo "unknown"
+            echo "l.$LINENO: found unknown card_type, code needs to be fixed" 1>&2
+            ;;
+    esac
+}
+
+# returns true iff running under z/VM
+function isVM() {
+    local cpu_version=$(cat /proc/cpuinfo |grep "^processor " | head -n1 | sed 's/.*version = \([[:xdigit:]][[:xdigit:]]\).*/\1/' | tr '[:lower:]' '[:upper:]')
+    if [ "$cpu_version" = "FF" ]; then
+        return 0
+    else
+        return 1
+    fi
+}
+
+# watch out: potential error message as side effect
+function isLayer2Default() {
+    # Read default from sysfs because according to device
+    # drivers book there are differences in the default between
+    # OSA (l2), hipersockets (l3).
+    # This only works here in installer where nobody has overwritten
+    # the default setting with another custom value already!
+    if [ ! -f /sys/devices/${NETTYPE}/$SCH_R_DEVBUSID/layer2 ]; then
+        echo $"Could not read layer mode from sysfs"
+        return 1
+    fi
+    local layer2
+    read layer2 < /sys/devices/${NETTYPE}/$SCH_R_DEVBUSID/layer2
+    if [ "$layer2" = "1" ]; then
+        return 0
+    else
+        return 1
+    fi
+}
+
+# returns true iff either LAYER2 has been set to 1 or is the default
+# watch out: potential error message as side effect
+function isLayer2() {
+    case "x$LAYER2" in
+        x0) return 1 ;; # layer 3
+        x1) return 0 ;; # layer 2
+        x)  # LAYER2 is unset or empty => qeth driver default applies.
+            isLayer2Default
+            return $?
+            ;;
+        *) echo "l.$LINENO: unknown value \"$LAYER2\" for LAYER2, code needs to be fixed" 1>&2
+            return 2 ;;
+    esac
+}
+
+# returns true iff qeth device $SCH_R_DEVBUSID
+# is capable of supporting IPv6
+# watch out: potential error message as side effect
+function ipv6_capable() {
+    [ "$NETTYPE" = "qeth" ] || return 1
+    case $cardtype in
+        OSD_10GIG|OSD_1000|OSD_100|OSD_Express|HiperSockets|"GuestLAN QDIO")
+            return 0 ;;
+        OSD_GbE_LANE|OSD_FE_LANE|OSD_TR_LANE|OSD_ATM_LANE) return 1 ;;
+        HSTR|OSN|unknown) return 1 ;;
+        "GuestLAN Hiper") return 1 ;;
+        *) echo $"Unknown card_type to determine IPv6 support"
+            return 1 ;;
+    esac
+}
+
+# sets device online _and_ retrieves DEVICE at the same time
+function set_device_online() {
+    echo $"Activating network device..."
+    local sysnettype
+    case "${NETTYPE}" in
+        qeth|lcs) sysnettype=${NETTYPE} ;;
+        ctc) sysnettype=ctcm ;;
+    esac
+    if ! [ -f /sys/devices/${sysnettype}/$SCH_R_DEVBUSID/online ]; then
+        echo $"Sysfs path to set device online does not exist."
+        return 1
+    fi
+    if ! sysecho /sys/devices/${sysnettype}/$SCH_R_DEVBUSID/online "1"; then
+        echo $"Could not set device ($SUBCHANNELS) online"
+        return 1
+    fi
+    udevadm settle
+    local i=1
+    while : ; do
+        local online
+        read online < /sys/devices/${sysnettype}/$SCH_R_DEVBUSID/online
+        [ "$online" == "1" ] && break
+        sleep 1
+        i=$((i+1))
+        if [ "$i" -gt 10 ]; then
+            echo $"Could not set device ($SUBCHANNELS) online within timeout"
+            return 1
+        fi
+    done
+    if [ "$NETTYPE" = "lcs" -o "$NETTYPE" = "ctc" ]; then
+        # KH FIXME: Workaround for missing sysfs interface
+        #   DEVICE=$(cat /sys/devices/lcs/${SUBCHANNELS//,*/}/if_name)
+        # replaced with flexible solution:
+        # https://bugzilla.redhat.com/show_bug.cgi?id=204803#c9
+        # "sys/bus/ccwgroup/devices/${SUBCHANNEL}/net\:*
+        # for lcs after setting online"
+        if [ ! -h /sys/devices/${sysnettype}/$SCH_R_DEVBUSID/net:* ]; then
+            echo $"Device $SUBCHANNELS does not have required sysfs attribute 'net:*'"
+            return 1
+        fi
+        DEVICE=$(echo /sys/devices/${sysnettype}/$SCH_R_DEVBUSID/net:*)
+        DEVICE=${DEVICE//*:/}
+        if [ "$DEVICE" = "" ]; then
+            echo $"Could not get device name for $SUBCHANNELS"
+            return 1
+        fi
+    else # qeth
+        if [ ! -f /sys/devices/qeth/$SCH_R_DEVBUSID/if_name ]; then
+            echo $"Device $SUBCHANNELS does not have required sysfs attribute 'if_name'"
+            return 1
+        fi
+        # (device needs to be online to read if_name from sysfs attribute!)
+        read DEVICE < /sys/devices/qeth/$SCH_R_DEVBUSID/if_name
+        if [ "$DEVICE" = "" ]; then
+            echo $"Could not get device name for $SUBCHANNELS"
+            return 1
+        fi
+        if [ -f /sys/devices/qeth/$SCH_R_DEVBUSID/card_type ]; then
+            read cardtype < /sys/devices/qeth/$SCH_R_DEVBUSID/card_type
+            #debug echo "$cardtype"
+            # device is now online and link type will be known
+            echo -n $"Detected: "
+            cardtype2cleartext "$cardtype"
+        else
+            echo $"Could not read qeth network card type from sysfs."
+        fi
+    fi
+}
+
+# sets device up and blocks until device appears to be up
+function set_device_up() {
+    if [ -z "$DEVICE" ]; then
+        echo $"Could not determine interface name to bring up device $SUBCHANNELS"
+        return 1
+    fi
+    # Device does not come up fast enough to use "ip" to configure, so block.
+    # While OSA come up themselves after setting online,
+    # e.g. HiperSockets won't => set them up explicitly for the following check
+    debug ip link set up $DEVICE
+    local i=1
+    while : ; do
+        local tst=$(ip -o link show up dev $DEVICE)
+        [ -n "$tst" ] && break
+        sleep 1
+        i=$((i+1))
+        if [ "$i" -gt 10 ]; then
+            echo $"Could not bring up device $DEVICE within timeout"
+            return 1
+        fi
+    done
+    return 0
+}
+
+function syntax_check_domainname() {
+    # - match against regex adopted from RFC1035,sec.2.3.1 or RFC1034,sec.3.5
+    #   (Internationalized Domain Names in Applications (IDNA) [RFC4690]
+    #    have to be entered after encoding by punycode [RFC3492])
+    [[ "$1" =~ ^[[:alpha:]]([[:alnum:]-]{0,61}[[:alnum:]])?(\.[[:alpha:]]([[:alnum:]-]{0,61}[[:alnum:]])?)*$ ]]
+    case $? in
+        0)
+            # string matched the pattern
+            return 0
+            ;;
+        1)
+            # string did not match the pattern
+            echo "$2"
+            ;;
+        2)
+            echo "l.$LINENO: syntax error in regex of match operator =~, code needs to be fixed" 1>&2
+            ;;
+        *)
+            echo "l.$LINENO: unexpected return code of regex match operator =~, code needs to be fixed" 1>&2
+            ;;
+    esac
+    return 1
+}
+
+function modprobe_alias() {
+    if [ ":$NETTYPE" = ":ctc" ]; then
+        echo "alias $DEVICE ctcm" >> /tmp/modprobe.conf
+    else
+        echo "alias $DEVICE $NETTYPE" >> /tmp/modprobe.conf
+    fi
+    if [ $? -ne 0 ]; then
+        echo $"Could not append alias for network device $DEVICE to modprobe.conf"
+        return 1
+    fi
+    return 0
+}
+
+function disable_ipv6_autoconf() {
+    sysctl -w net.ipv6.conf.all.accept_ra=0 > /dev/null
+    sysctl -w net.ipv6.conf.all.accept_redirects=0 > /dev/null
+    sysctl -w net.ipv6.conf.all.autoconf=0 > /dev/null
+    sysctl -w net.ipv6.conf.default.accept_ra=0 > /dev/null
+    sysctl -w net.ipv6.conf.default.accept_redirects=0 > /dev/null
+    sysctl -w net.ipv6.conf.default.autoconf=0 > /dev/null
+}
+
+function configure_ipv6_address() {
+    # device needs to be online
+    # arp flag needs to be on for ipv6 over osa because of ndisc.
+    # happens automatically by the driver. do NOT mess with default setting.
+    #NO#debug ip link set dev $DEVICE arp on
+    if ! debug ip -6 address add $IPADDR/$NETMASK dev $DEVICE; then
+        echo $"Could net set IPv6 address $IPADDR/$NETMASK for device $DEVICE"
+        return 1
+    fi
+    # network route has been set by above "ip address add" already
+    # take care of MTU, which is bundled with ifconfig in the other IPv4 cases
+    if [ -n "$MMTU" ]; then
+        if ! debug ip link set $DEVICE $MMTU; then
+            echo $"Could net set maximum transfer unit ($MMTU) for device $DEVICE"
+            return 1
+        fi
+    fi
+    return 0
+}
+
+function configure_ipv4_address() {
+    # it's IPv4 and we can make use of ipcalc for better usability
+    if ipcalc -bmnp $ipcalc_arg > /tmp/ipcalc.$$.out 2> /dev/null; then
+        . /tmp/ipcalc.$$.out
+    else
+        echo $"Could not calculate network address and broadcast address from"
+        echo $" IPv4 address $IPADDR and netmask $NETMASK"
+        return 1
+    fi
+    rm /tmp/ipcalc.$$.out
+    # device needs to be online
+    if ! debug ifconfig $DEVICE $IPADDR $MMTU netmask $NETMASK broadcast $BROADCAST; then
+        echo $"Could not set IPv4 address $IPADDR for device $DEVICE"
+        echo $" with network mask $NETMASK and broadcast address $BROADCAST"
+        [ -n "$MMTU" ] && echo $" and maximum transfer unit: $MMTU"
+        return 1
+    fi
+    # This network route is already there after ifconfig!
+    #if ! debug route add -net $NETWORK netmask $NETMASK dev $DEVICE; then
+    #    echo $"Could not add network route to $NETWORK/$NETMASK on device $DEVICE"
+    #    return 1
+    #fi
+    return 0
+}
+
+function handle_mtu() {
+    # don't ask for MTU, but use it if it has been set in the .parm file
+    # don't overwrite MMTU if it has been set for CTC
+    [ -n "$MTU" -a -z "$MMTU" ] && MMTU="mtu $MTU"
+}
+
+function rollback_config() {
+    # each transaction to roll back may fail, if previous setup has not
+    # made progress that far to reach a certain transation
+    # => error output is misleading and should be avoided
+    [ -n "$DEVICE" ] && tv ip -4 route flush default dev $DEVICE
+    [ -n "$DEVICE" ] && tv ip -6 route flush default dev $DEVICE
+    # address flush seems to be effective for all address families
+    [ -n "$DEVICE" ] && ip address flush dev $DEVICE
+    if [ -n "$NETTYPE" ]; then
+        if [ -n "$SCH_R_DEVBUSID" ]; then
+            local sysnettype
+            case "${NETTYPE}" in
+                qeth|lcs) sysnettype=${NETTYPE} ;;
+                ctcm) sysnettype=ctcm ;;
+            esac
+            [ -f /sys/devices/${sysnettype}/$SCH_R_DEVBUSID/online ] && \
+                sysecho /sys/devices/${sysnettype}/$SCH_R_DEVBUSID/online "0"
+            udevadm settle
+            [ -f /sys/devices/${sysnettype}/$SCH_R_DEVBUSID/ungroup ] && \
+                sysecho /sys/devices/${sysnettype}/$SCH_R_DEVBUSID/ungroup "1"
+            udevadm settle
+        fi
+    fi
+    [ -z "$mtu_was_set" ] && unset MTU
+    [ -z "$mmtu_was_set" ] && unset MMTU
+    [ -z "$vswitch_was_set" ] && unset VSWITCH
+    # prevent possible reuse of an old DEVICE on restarting dialog
+    unset DEVICE
+    # set activated DASDs offline again
+    local dasd
+    while read dasd < /proc/dasd/devices; do
+        dasd=${dasd%%(*}
+        sysecho /sys/bus/ccw/devices/$dasd/online 0
+    done
+    udevadm settle
+}
+
+### workflow helper functions
+
+# workflow ideas:
+# - setting/applying single configuration steps right away save us explicit
+#   syntactical & semantic checks PLUS we get direct feedback on error
+# - check error level of forked external programs and react on errors
+
+unset reenter
+unset redoitem
+unset interaction_happened
+
+function reenter() {
+    [ -z "$reenter" ] && return 1
+    # reenter menu should only be shown if NOT redoing item
+    if [ -n "$redoitem" ]; then
+        # unset redoitem # wrong => do NOT do this here
+        return 1
+    fi
+    return 0
+}
+
+function reenter_menu() {
+    local oldvalue=$1
+    interaction_happened="yes"
+    # unsetting input here is not sufficient, since reenter_menu
+    # is not called for predefined parameters
+    # which then might get assigned a previous old input of another parameter!
+    #unset input
+    reenter || return 0
+    # don't present reenter menu for empty parameters
+    # (currently ignoring parameters that are allowed to be empty!)
+    # this could be improved by checking if variable has been set/defined
+    #[ -z "$1" ] && return 0
+    while : ; do
+        if [ -n "$helptext" ]; then
+            echo $"0) default is previous \"$oldvalue\", 1) new value, ?) help"
+        else
+            echo $"0) default is previous \"$oldvalue\", 1) new value"
+        fi
+        # uncoded alternative: 2) skip parameter
+        local answer
+        read answer
+        [ -z "$answer" ] && return 1
+        case $answer in
+            0) return 1 ;;
+            1)  # Deciding to enter new value gets user out of reenter-mode
+                # temporarily for this parameter.
+                # To put it differently: redoing does NOT present old values.
+                redoitem="yes"
+                echo -n $"new value: "
+                return 0
+                ;;
+            "?") input="?"
+                return 1
+                ;;
+        esac
+    done
+}
+
+function workflow_item_menu() {
+    local noredo=$1
+    # default is to continue if running kickstart to prevent interaction
+    [ -n "$RUNKS" ] && return 0
+    interaction_happened="yes"
+    while : ; do
+        unset redoitem
+        if [ "$noredo" = "noredo" ]; then
+            echo $"1) continue, 2) restart dialog, 3) halt, 4) shell"
+        else
+            echo $"0) redo this parameter, 1) continue, 2) restart dialog, 3) halt, 4) shell"
+        fi
+        local answer
+        read answer
+        case $answer in
+            0) [ "$noredo" = "noredo" ] && continue
+                redoitem="yes"
+                continue 2
+                ;;
+            1) return 0 ;; # can be used to break at caller on ignore
+            2) reenter="yes"
+                rollback_config
+                continue 3
+                ;;
+            3) tv doshutdown
+                exit 0
+                ;;
+            4) echo $"Enter 'exit' at the shell prompt to get back to the installation dialog."
+                /bin/bash
+                if [ "$noredo" != "noredo" ] && [ -n "$question_prefix" ]; then
+                    $question_prefix
+                    echo
+                fi
+                ;; # stay in workflow item menu
+        esac
+    done
+}
+
+# input variables: PARMNAME, question_prefix, question_choices,
+#                  "options" ...
+# output variables: $question_prefix, $helptext
+# modifies: the variable named $PARMNAME, $OPTIND
+function ask() {
+    [ $# -lt 3 ] && echo "l.$LINENO: too few arguments (<3), please fix calling code." 1>&2
+    local PARMNAME=$1
+    shift
+    question_prefix=$1
+    shift
+    local question_choices=$1
+    shift
+    local exception
+    local syntax_check
+    unset helptext
+    local handle
+    local finish
+    local optname
+    OPTIND=1
+    while getopts ":e:s:h:c:f:" optname; do
+        case $optname in
+            e) exception=$OPTARG ;;
+            s) syntax_check=$OPTARG ;;
+            h) helptext=$OPTARG ;;
+            c) handle=$OPTARG ;;
+            f) finish=$OPTARG ;;
+            "?") ;; # ignore invalid option
+            :) echo "l.$LINENO: Missing parameter to option -$OPTARG" 1>&2 ;;
+        esac
+    done
+    while : ; do
+        unset input
+        local input
+        # actually ask question if one of the following is true:
+        # - $PARMNAME parameter has not been set yet, e.g. not in parm file
+        # - on 2nd and further attempts, i.e. redoing the parameter
+        # - on having restarted the whole dialog
+        # describing the same from another viewpoint:
+        # - if $PARMNAME has been set, try to check syntax and apply
+        # - on redo, $PARMNAME has been set and reenter is false,
+        #   but still ask question again
+        # - on reenter, $PARMNAME might have been set, but still ask question
+        if [ -z "${!PARMNAME}" -o -n "$redoitem" -o -n "$reenter" ]; then
+            # one empty line to separate parameter questions from each other
+            echo
+            $question_prefix
+            if reenter; then
+                echo
+            else
+                $question_choices
+            fi
+            # on reenter, give choice between old value and entering new one
+            reenter_menu ${!PARMNAME} && read input \
+                && [ "$input" != "?" ] && eval ${PARMNAME}=\$input
+            # escaping the $ in the RHS of the eval statement makes it safe
+        fi
+        if [ -n "$helptext" ] && [ "$input" = "?" ]; then
+            $helptext
+            continue
+        fi
+        # optional: default or exceptional handling
+        [ -n "$exception" ] && $exception
+        if [ -n "$syntax_check" -a -z "$handle" ]; then
+            # some parameters have only syntax check (and deferred config):
+            if $syntax_check; then
+                break
+            else
+                workflow_item_menu && break
+            fi
+        elif [ -n "$syntax_check" -a -n "$handle" ]; then
+            # most common parameters have syntax and configuration:
+            # user might still continue on syntax error
+            $syntax_check || workflow_item_menu
+            # optional: actual configuration
+            if $handle; then
+                # parmname has been configured successfully
+                break
+            else
+                # user might still continue on configuration failure
+                workflow_item_menu && break
+            fi
+        elif [ -n "$finish" ]; then
+            # few parameters need special handling done by their own function:
+            $finish
+        else
+            echo $"Unsupported calling of ask function, please fix calling code"
+        fi
+    done # PARMNAME
+    # disable potential temporary redoing-mode during reenter-mode
+    unset redoitem
+}
+
+### NETTYPE
+
+function syntax_check_nettype() {
+    # - NETTYPE \in {qeth,lcs,ctc}
+    [[ "$NETTYPE" =~ (^qeth$)|(^lcs$)|(^ctc$) ]]
+    case $? in
+        0)
+            # string matched the pattern
+            return 0
+            ;;
+        1)
+            # string did not match the pattern
+            ;;
+        2)
+            echo "l.$LINENO: syntax error in regex of match operator =~, code needs to be fixed" 1>&2
+            ;;
+        *)
+            echo "l.$LINENO: unexpected return code of regex match operator =~, code needs to be fixed" 1>&2
+            ;;
+    esac
+    echo $"Incorrect format or value for network type (NETTYPE): $NETTYPE"
+    return 1
+}
+
+function question_prefix_nettype() {
+    echo -n $"Network type"
+}
+
+function question_choices_nettype() {
+    echo $" (qeth, lcs, ctc, ? for help). Default is qeth:"
+}
+
+function helptext_nettype() {
+    echo $" Help text for network type:"
+    echo $"  qeth: OSA-Express Fast Ethernet, Gigabit Ethernet (including 1000Base-T),"
+    echo $"        High Speed Token Ring, Hipersockets, and ATM (running Ethernet LAN emulation)"
+    echo $"        features in QDIO mode."
+    echo $"        [default]"
+    echo $"  lcs:  OSA-2 Ethernet/Token Ring, OSA-Express Fast Ethernet in non-QDIO mode,"
+    echo $"        OSA-Express High Speed Token Ring in non-QDIO mode and Gigabit Ethernet"
+    echo $"        in non-QDIO mode."
+    echo $"  ctc:  Deprecated, useful for migration."
+}
+
+function exception_nettype() {
+    # - default is qeth since it should be common
+    if [ -z "$NETTYPE" ]; then
+        NETTYPE=qeth
+        break
+    fi
+}
+
+function finish_nettype() {
+    if syntax_check_nettype; then
+        break
+    else
+        # necessary parts which would otherwise be done by workflow_item_menu
+        interaction_happened="yes"
+        redoitem="yes"
+    fi
+}
+
+function do_nettype() {
+    ask NETTYPE \
+        question_prefix_nettype question_choices_nettype \
+        -h helptext_nettype -e exception_nettype -f finish_nettype
+}
+
+### CHANDEV
+
+function do_chandev() {
+    echo
+    echo $"The CHANDEV variable isn't used anymore, please update your "
+    echo $".parm or the .conf file to use NETTYPE, SUBCHANNELS, etc. instead."
+    echo
+}
+
+### SUBCHANNELS
+
+function syntax_check_subchannels() {
+    SUBCHANNELS=$(echo $SUBCHANNELS | tr ABCDEF abcdef)
+    # - make subchannel question dependent on NETTYPE (2 vs. 3 subchannels)
+    if [ "$NETTYPE" = "qeth" ]; then
+        # - match against regex, depending on qeth
+        [[ "$SUBCHANNELS" =~ ^[[:xdigit:]]+\.[0-3]\.[[:xdigit:]]{4},[[:xdigit:]]+\.[0-3]\.[[:xdigit:]]{4},[[:xdigit:]]+\.[0-3]\.[[:xdigit:]]{4}$ ]]
+    else
+        # - match against regex, depending on lcs/ctc
+        [[ "$SUBCHANNELS" =~ ^[[:xdigit:]]+\.[0-3]\.[[:xdigit:]]{4},[[:xdigit:]]+\.[0-3]\.[[:xdigit:]]{4}$ ]]
+    fi
+    case $? in
+        0)
+            # string matched the pattern
+            return 0
+            ;;
+        1)
+            # string did not match the pattern
+            echo $"Incorrect format for channels (SUBCHANNELS): $SUBCHANNELS"
+            ;;
+        2)
+            echo "l.$LINENO: syntax error in regex of match operator =~, code needs to be fixed" 1>&2
+            ;;
+        *)
+            echo "l.$LINENO: unexpected return code of regex match operator =~, code needs to be fixed" 1>&2
+            ;;
+    esac
+    return 1
+}
+
+function semantic_check_subchannels() {
+    local subch_count
+    if [ "$NETTYPE" = "qeth" ]; then
+        subch_count=3
+    else
+        subch_count=2
+    fi
+    # done: make subchannel handling more robust by not relying on REMATCH
+    local -a subch_array
+    IFS=,
+    read -a subch_array <<< "indexzero,$SUBCHANNELS"
+    unset IFS
+    local i
+    local all_subch_good=0
+    for ((i=1; i <= $subch_count; i++)); do
+        local devbusid=${subch_array[$i]}
+        # remember first subchannel for potential undo of ccwgroup
+        # (via /sys/devices/qeth/$SCH_R_DEVBUSID/ungroup)
+        [ "$i" -eq 1 ] && SCH_R_DEVBUSID=$devbusid
+        local prefix ssid devno foo
+        IFS=.
+        read prefix ssid devno foo <<< "$devbusid"
+        unset IFS
+        local dev_p=$(echo /sys/devices/css$prefix/$IDFORMAT/$devbusid)
+        # - check for existence of devnos in sysfs
+        if [ ! -d "$dev_p" -a "$cio_wc_bytes" != "0" ]; then
+            # - try to free from /proc/cio_ignore if they don't exist
+            echo $"Device $devbusid not present, trying to clear from blacklist and resense..."
+            if sysecho /proc/cio_ignore "free $devbusid"; then
+                # /proc/cio_ignore won't block on freeing devices
+                # until resensing has been completed, so wait until
+                # the udev event queue depletes (without udevadm settle we
+                # could wait 2 seconds unconditionally)
+                #debug ls -laF /dev/.udev
+                udevadm settle
+                # even though the device might now be online, some of its
+                # sysfs attributes (e.g. cutype) might not yet be available
+                sleep 1
+            else
+                echo $"Device $devbusid could not be cleared from device blacklist"
+            fi
+        fi
+        # reevaluate since globbing might not have worked before device existed
+        dev_p=$(echo /sys/devices/css$prefix/$IDFORMAT/$devbusid)
+        if [ ! -d "$dev_p" ]; then
+            echo $"Device $devbusid does not exist"
+            all_subch_good=1
+            continue
+        fi
+        # devno does exist now
+        local subch_p=${dev_p%/*}
+        local subch=${subch_p##*/}
+        # filter definitely unusable subchannels ...
+        # - check for subchannel type I/O
+        if [ -f $subch_p/type ]; then
+            local type
+            read type < $subch_p/type
+            if [ "$type" != "$SUBCHANNEL_TYPE_IO" ]; then
+                echo $"Channel $subch (device $devbusid) is not of type I/O"
+                all_subch_good=1
+                continue
+            fi
+        fi
+        # - check for correct CU type/model, depending on qeth/lcs/ctc
+        if [ ! -f $dev_p/cutype ]; then
+            echo $"Device $devbusid does not have required sysfs attribute 'cutype'"
+            all_subch_good=1
+            continue
+        fi
+        local cutype
+        read cutype < $dev_p/cutype
+        if search_cu $cutype; then
+            local driver
+            if [ "$NETTYPE" = "ctc" ]; then
+                driver="ctcm"
+            else
+                driver=$NETTYPE
+            fi
+            if [ "${CU_DEVDRV[$cu_idx]}" != "$driver" ]; then
+                echo $"Device $devbusid has control unit type $cutype,"
+                echo $" which does not match your selected network type $NETTYPE"
+                all_subch_good=1
+                continue
+            fi
+        else
+            echo $"Device $devbusid has control unit type $cutype which is unknown"
+            all_subch_good=1
+            continue
+        fi
+        # read CHPIDs information about subchannels
+        if [ ! -f $subch_p/chpids ]; then
+            echo $"Channel $subch (device $devbusid) does not have required sysfs attribute 'chpids'"
+            all_subch_good=1
+            continue
+        fi
+        local chpid_list
+        read chpid_list < $subch_p/chpids
+        local -a chpids
+        read -a chpids <<< "$chpid_list"
+        if [ ${#chpids[@]} -ne 8 ]; then
+            echo $"sysfs reported ${#chpids[@]} CHPIDs instead of expected 8, code needs fix"
+        fi
+        if [ ! -f $subch_p/pimpampom ]; then
+            echo $"Channel $subch (device $devbusid) does not have required sysfs attribute 'pimpampom'"
+            all_subch_good=1
+            continue
+        fi
+        local pim pam pom foo
+        read pim pam pom foo < $subch_p/pimpampom
+        local pimchpidZ=""
+        for ((chp=0; chp < 8; chp++)); do
+            local mask=$((0x80 >> chp))
+            if (( 0x$pim & $mask )); then
+                pimchpidZ=${pimchpidZ}${chpids[chp]}
+            else
+                pimchpidZ=${pimchpidZ}"ZZ"
+            fi
+        done
+        local pimchpids=${pimchpidZ//ZZ/}
+        if [ "x$pimchpids" == "x" ]; then
+            echo $"Channel $subch (device $devbusid) does not have any installed channel path"
+            all_subch_good=1
+            continue
+        fi
+        # compare parts of different subchannels for required matches
+        if [ "$i" -eq 1 ]; then
+            # remember parts of first subchannel for comparison
+            local sch_r_prefix=$prefix
+            local sch_r_ssid=$ssid
+            local sch_r_devno=$devno
+            local sch_r_pimchipidZ=$pimchpidZ
+            local sch_r_cutype=$cutype
+        else
+            local comparison=0
+            # $sch_r_... might be empty if first channel was wrong
+            # => be sure to quote all variable accesses in test statements.
+            # - all subchannels must be of same CU type/model
+            if [ "$cutype" != "$sch_r_cutype" ]; then
+                echo $"Device $devbusid does not have the same control unit type as device $SCH_R_DEVBUSID"
+                comparison=1
+            fi
+            # - all subchannels must have same CHPIDs
+            if [ "$pimchpidZ" != "$sch_r_pimchipidZ" ]; then
+                echo $"Device $devbusid does not have the same CHPIDs as device $SCH_R_DEVBUSID"
+                comparison=1
+            fi
+            # - all subchannels should have same prefix & ssid ?
+            if [ "$prefix" != "$sch_r_prefix" \
+                -o "$ssid" != "$sch_r_ssid" ]; then
+                echo $"Device $devbusid does not have the same prefix and subchannel set ID as device $SCH_R_DEVBUSID"
+                comparison=1
+            fi
+            if [ "$i" -eq 2 ]; then
+                local sch_w_devbusid=$devbusid
+                local sch_w_devno=$devno
+                # TODO: not true for CTCM => relax
+                # - write_devbusid == read_devbusid+1
+                if [ $((0x$devno)) -ne $((0x$sch_r_devno + 1)) ]; then
+                    echo $"Device bus ID of write channel (dev $devbusid) must be one larger than"
+                    echo $" that of read channel (dev $SCH_R_DEVBUSID)"
+                    comparison=1
+                fi
+            elif [ "$i" -eq 3 ]; then
+                # check data subchannel unequal to read/write subchannel
+                # (also seems to be handled by ccwgroup kernel subsystem)
+                if [ "$devbusid" = "$sch_w_devbusid" \
+                    -o "$devbusid" = "$SCH_R_DEVBUSID" ]; then
+                    echo $"Device bus ID of data channel (dev $devbusid) must be different to that of"
+                    echo $" read channel ($SCH_R_DEVBUSID) and write channel ($sch_w_devbusid)"
+                    comparison=1
+                fi
+            fi
+            if [ "$comparison" != 0 ]; then
+                all_subch_good=1
+                continue
+            fi
+        fi
+        # filter potentially good subchannels ...
+        if [ -h $dev_p/group_device ]; then
+            echo $"Device $devbusid is already in a ccwgroup and thus unavailable"
+            all_subch_good=1
+            continue
+        fi
+        if [ ! -f $dev_p/online ]; then
+            echo $"Device $devbusid does not have required sysfs attribute 'online'"
+            all_subch_good=1
+            continue
+        fi
+        local online
+        read online < $dev_p/online
+        if [ "$online" = "1" ]; then
+            echo $"Device $devbusid is already in use and thus unavailable"
+            all_subch_good=1
+            continue
+        fi
+        # - check availability
+        if [ ! -f $dev_p/availability ]; then
+            echo $"Device $devbusid does not have required sysfs attribute 'availability'"
+            all_subch_good=1
+            continue
+        fi
+        local availability
+        read availability < $dev_p/availability
+        if [ "$availability" != "good" ]; then
+            echo $"Device $devbusid is not available but '$availiability'"
+            all_subch_good=1
+            continue
+        fi
+
+    done # for ((i=1; i <= $subch_count; i++))
+    if [ "$all_subch_good" = "0" ]; then
+        return 0
+    fi
+    return 1
+}
+
+function handle_subchannels() {
+    # - try to establish ccwgroup right here and fail out on error
+    local driver
+    if [ "$NETTYPE" = "ctc" ]; then
+        driver="ctcm"
+    else
+        driver=$NETTYPE
+    fi
+    if sysecho /sys/bus/ccwgroup/drivers/${driver}/group "$SUBCHANNELS"; then
+        udevadm settle
+        case "$NETTYPE" in
+            qeth)
+                # Just preliminary card_type info until device goes online!
+                # In fact it seems enough to separate OSA from HiperSockets.
+                if [ -f /sys/devices/qeth/$SCH_R_DEVBUSID/card_type ]; then
+                    read cardtype < /sys/devices/qeth/$SCH_R_DEVBUSID/card_type
+                else
+                    echo $"Could not read qeth network card type from sysfs."
+                fi
+                ;;
+            ctc|lcs)
+                if [ -f /sys/devices/$driver/$SCH_R_DEVBUSID/type ]; then
+                    local type
+                    read type < /sys/devices/$driver/$SCH_R_DEVBUSID/type
+                    [ "$type" = "CTC/A" ] && \
+                        type="channel-to-channel adapter (CTC/A)"
+                    echo $"Detected: $type"
+                else
+                    echo $"Could not read ctc network card type from sysfs."
+                fi
+                ;;
+        esac
+        return 0
+    else
+        echo $"Channels $SUBCHANNELS could not be grouped"
+    fi
+    return 1
+}
+
+function question_prefix_subchannels() {
+    if [ "$NETTYPE" = "qeth" ]; then
+        echo -n $"Read,write,data channel"
+    else
+        echo -n $"Read,write channel"
+    fi
+}
+
+function question_choices_subchannels() {
+    if [ "$NETTYPE" = "qeth" ]; then
+        echo $" (e.g. 0.0.0300,0.0.0301,0.0.0302 or ? for help)."
+    else
+        echo $" (e.g. 0.0.0600,0.0.0601 or ? for help)"
+    fi
+}
+
+function helptext_subchannels() {
+    if [ "$NETTYPE" = "qeth" ]; then
+        echo $" Help text for qeth channels:"
+        echo $"  Enter the device bus ID of your CCW devices."
+        echo $"  QETH needs three channels for read, write, and data,"
+        echo $"  e.g. 0.0.0300,0.0.0301,0.0.0302"
+    else
+        echo $" Help text for lcs/ctc channels:"
+        echo $"  Enter the device bus ID of your CCW devices."
+        echo $"  CTC/ESCON and LCS need two channels for read and write,"
+        echo $"  e.g. 0.0.0600,0.0.0601 will configure the CTC or ESCON interface"
+        echo $"  with the channels 0x600 and 0x601"
+    fi
+}
+
+function finish_subchannels() {
+    syntax_check_subchannels || workflow_item_menu
+    # continuing on syntax error is doomed to fail,
+    # since handle_subchannels relies on the regex-based strict parsing
+    # in syntax_check_subchannels which does not match anything then
+    # news: relaxed by splitting semantic check and actual handling
+    semantic_check_subchannels || workflow_item_menu
+    if handle_subchannels; then
+        break
+    else
+        workflow_item_menu && break
+    fi
+}
+
+function do_subchannels() {
+    ask SUBCHANNELS \
+        question_prefix_subchannels question_choices_subchannels \
+        -h helptext_subchannels -f finish_subchannels
+}
+
+### PORTNAME (qeth)
+
+function syntax_check_portname() {
+    # - 1-8 characters, we convert it to upper case
+    PORTNAME=$(echo $PORTNAME | tr '[:lower:]' '[:upper:]')
+    local portname_len=${#PORTNAME}
+    if [ "$portname_len" -ge 1 -a "$portname_len" -le 8 ]; then
+        return 0
+    fi
+    echo $"Incorrect string length [1..8] for portname (PORTNAME): $PORTNAME"
+    return 1
+}
+
+function handle_portname() {
+    [ -n "$PORTNAME" ] || return 0
+    # - try to set portname right here w/ error handling
+    if sysecho /sys/devices/${NETTYPE}/$SCH_R_DEVBUSID/portname "$PORTNAME"; then
+        return 0
+    else
+        echo $"Portname '$PORTNAME' could not be configured for $SUBCHANNELS"
+    fi
+    return 1
+}
+
+function hint_portname() {
+    if [ -f /sys/devices/${NETTYPE}/$SCH_R_DEVBUSID/portname ]; then
+        local pname_hint
+        read pname_hint < /sys/devices/${NETTYPE}/$SCH_R_DEVBUSID/portname
+        if [ "$pname_hint" = "no portname required" ]; then
+            echo $"  * Your configuration does not require a portname. *"
+        fi
+    fi
+}
+
+function question_prefix_portname(){
+    echo -n $"Portname"
+}
+
+function question_choices_portname(){
+    echo $" (1..8 characters, or ? for help). Default is no portname:"
+}
+
+function helptext_portname(){
+    echo $" Help text for portname:"
+    # updated text describing when portname is obsolete;
+    # taken from:
+    # SA22-7935-09, Open Systems Adapter-Express Customer's
+    #   Guide and Reference, 10th ed. May 2008, IBM, p.17f.
+    # SC33-8411-00, Device Drivers, Features, and Commands,
+    #   1st ed. May 2008, IBM, p.116.
+    echo $"  Portname of the OSA-Express feature in QDIO mode and z/VM Guest LAN."
+    echo $"  This parameter is optional with:"
+    echo $"   - z/VM 4.4.0 or z/VM 4.3.0 with APARs VM63308 and PQ73878"
+    echo $"   - z800, z900 with >= Driver 3G - EC stream J11204, MCL032 (OSA level 3.33)"
+    echo $"   - z890, z990, z9, z10 mainframes"
+    hint_portname
+    echo $"  If portname is used, all operating systems sharing port must use same name."
+    echo $"  Input empty string if you don't want to enter a portname. [default]"
+}
+
+function exception_portname(){
+    [ -z "$PORTNAME" ] && break
+}
+
+function do_portname() {
+    ask PORTNAME \
+        question_prefix_portname question_choices_portname \
+        -h helptext_portname \
+        -e exception_portname -s syntax_check_portname -c handle_portname
+}
+
+### PORTNO (qeth)
+
+function syntax_check_qeth_portno() {
+    case $PORTNO in
+        0|1)
+            return 0
+            ;;
+    esac
+    echo $"Incorrect format or value for relative port number (PORTNO): $PORTNO"
+    return 1
+}
+
+function handle_qeth_portno() {
+    if sysecho /sys/devices/qeth/$SCH_R_DEVBUSID/portno "$PORTNO"; then
+        return 0
+    fi
+    echo $"Could not configure relative port number $PORTNO for $SUBCHANNELS"
+    return 1
+}
+
+function question_prefix_portno() {
+    echo -n $"Relative port number for OSA"
+}
+
+function question_choices_portno() {
+    echo $" (0, 1, or ? for help). Default is 0:"
+}
+
+function helptext_portno() {
+    echo $" Help text for relative port number for OSA with 2 ports per CHPID:"
+    echo $"  This applies to:"
+    echo $"   - OSA-Express3 Gigabit Ethernet on z10 systems"
+    echo $"   - OSA-Express ATM on zSeries 800 and 900 systems"
+    echo $"  0 for relative port number 0 [default]"
+    echo $"  1 for relative port number 1"
+    echo $"  Input empty string to not modify the default configuration."
+}
+
+function exception_portno() {
+    # Writing portno of e.g. hipersockets device fails.
+    # Therefore, do not configure on empty default value.
+    [ -z "$PORTNO" ] && break
+}
+
+function do_portno() {
+    ask PORTNO \
+        question_prefix_portno question_choices_portno \
+        -h helptext_portno -e exception_portno \
+        -s syntax_check_qeth_portno -c handle_qeth_portno
+}
+
+### LAYER2
+
+function syntax_check_layer2() {
+    # - $LAYER2 \in {0,1}
+    case $LAYER2 in
+        0|1)
+            return 0
+            ;;
+    esac
+    echo $"Incorrect format or value for layer2 mode (LAYER2): $LAYER2"
+    return 1
+}
+
+function handle_layer2() {
+    [ "$NETTYPE" == "qeth" ] || return 0
+    [ -n "$LAYER2" ] || return 0
+    # - try to set layer2 mode right here w/ error handling
+    if sysecho /sys/devices/${NETTYPE}/$SCH_R_DEVBUSID/layer2 "$LAYER2"; then
+        return 0
+    else
+        echo $"Layer2 mode '$LAYER2' could not be configured for $SUBCHANNELS"
+    fi
+    return 1
+}
+
+function question_prefix_layer2() {
+    echo -n $"Layer mode"
+}
+
+function question_choices_layer2() {
+    echo -n $" (0 for layer3, 1 for layer2, or ? for help)."
+    if [ "$isLayer2Default" = "yes" ]; then
+        echo $" Default is 1:"
+    else
+        echo $" Default is 0:"
+    fi
+}
+
+function helptext_layer2() {
+    echo $" Help text for OSA mode of operation: layer 2 vs. layer 3"
+    if [ "$isLayer2Default" = "yes" ]; then
+        echo $"  0 for layer 3 mode (may not work with dhcp, tcpdump, etc.)"
+        echo $"  1 for layer 2 mode [default]"
+    else
+        echo $"  0 for layer 3 mode [default] (may not work with dhcp, tcpdump, etc.)"
+        echo $"  1 for layer 2 mode"
+    fi
+}
+
+function exception_layer2() {
+    if [ -z "$LAYER2" ]; then
+        isLayer2Default && LAYER2=1 || LAYER2=0
+        # do not break, always apply, default may differ from online layer mode
+        #break
+    fi
+}
+
+function do_layer2() {
+    isLayer2Default && isLayer2Default=yes || isLayer2Default=no
+    ask LAYER2 \
+        question_prefix_layer2 question_choices_layer2 \
+        -h helptext_layer2 -e exception_layer2 \
+        -s syntax_check_layer2 -c handle_layer2
+}
+
+### MACADDR
+
+function syntax_check_macaddr() {
+    # - match against regex
+    [[ "$MACADDR" =~ ^[[:xdigit:]][[:xdigit:]]:[[:xdigit:]][[:xdigit:]]:[[:xdigit:]][[:xdigit:]]:[[:xdigit:]][[:xdigit:]]:[[:xdigit:]][[:xdigit:]]:[[:xdigit:]][[:xdigit:]]$ ]]
+    case $? in
+        0)
+            # string matched the pattern
+            return 0
+            ;;
+        1)
+            # string did not match the pattern
+            echo $"Incorrect format for mac address (MACADDR): $MACADDR"
+            ;;
+        2)
+            echo "l.$LINENO: syntax error in regex of match operator =~, code needs to be fixed" 1>&2
+            ;;
+        *)
+            echo "l.$LINENO: unexpected return code of regex match operator =~, code needs to be fixed" 1>&2
+            ;;
+    esac
+    return 1
+}
+
+function handle_macaddr() {
+    # - try to set macaddr right here w/ error handlg.
+    # device needs to be online
+    if debug ifconfig $DEVICE hw ether $MACADDR; then
+        return 0
+    fi
+    echo $"MAC address $MACADDR could not be configured for"
+    echo $" $SUBCHANNELS (network device $DEVICE)"
+    return 1
+}
+
+function question_prefix_macaddr() {
+    echo -n $"Unique MAC address"
+}
+
+function question_choices_macaddr() {
+    macaddr_default=$(ifconfig $DEVICE | grep 'HWaddr' | sed 's/.*HWaddr \([[:xdigit:]][[:xdigit:]]:[[:xdigit:]][[:xdigit:]]:[[:xdigit:]][[:xdigit:]]:[[:xdigit:]][[:xdigit:]]:[[:xdigit:]][[:xdigit:]]:[[:xdigit:]][[:xdigit:]]\).*/\1/')
+    echo $" (e.g. 02:00:00:00:00:00, ? for help). Default is $macaddr_default:"
+}
+
+function helptext_macaddr() {
+    echo $" Help text for MAC address:"
+    if [ -z "${cardtype//OSD_*/}" ]; then
+        echo $"  For real OSA in layer 2 mode, a random MAC address is automatically assigned."
+    else
+        echo $"  If connecting to a layer 2 VSWITCH, a MAC address is automatically assigned."
+    fi
+    echo $"  You may accept the automatic MAC address with an empty input. [default]"
+    echo $"  If the automatic address is not unique, please provide a MAC address."
+    [ -z "${cardtype//OSD_*/}" ] && \
+        echo $"  For real OSA, the provided address must be different from that of the OSA."
+    echo $"  You may override the automatic MAC address with non-empty input."
+    echo $"  An example MAC address would be: 02:00:00:00:00:00"
+}
+
+function exception_macaddr() {
+    if [ -z "$MACADDR" ]; then
+        if [ -z "${cardtype//OSD_*/}" ]; then
+            # keep random default MAC address of real OSA,
+            # so the OSA comes up with the same MAC each time in the future
+            MACADDR=$macaddr_default
+        else
+            # virtual OSA in layer2 is GuestLAN or VSWITCH
+            VSWITCH=1
+        fi
+        break
+    fi
+}
+
+function do_macaddr() {
+    ask MACADDR \
+        question_prefix_macaddr question_choices_macaddr \
+        -h helptext_macaddr -e exception_macaddr \
+        -s syntax_check_macaddr -c handle_macaddr
+}
+
+### CTCPROT
+
+function syntax_check_ctcprot() {
+    case "x$CTCPROT" in
+        x|x0)
+            unset CTCPROT
+            return 0
+            ;;
+        x1|x3)
+            return 0
+            ;;
+        x2)
+            echo $"CTC tty's are not usable for this installation (CTCPROT)"
+            ;;
+        *)
+            echo $"Incorrect format or value for CTC protocol (CTCPROT): $CTCPROT"
+            ;;
+    esac
+    return 1
+}
+
+function handle_ctcprot() {
+    [ -n "$CTCPROT" ] || return 0
+    if sysecho /sys/devices/ctcm/${SCH_R_DEVBUSID}/protocol "$CTCPROT"; then
+        return 0
+    fi
+    echo $"Could not configure CTC protocol $CTCPROT for $SUBCHANNELS"
+    return 1
+}
+
+function question_prefix_ctcprot() {
+    echo -n $"CTC protocol"
+}
+
+function question_choices_ctcprot() {
+    echo $" (0, 1, 3, or ? for help). Default is 0:"
+}
+
+function helptext_ctcprot() {
+    echo $" Help text for CTC protocol:"
+    echo $"  Protocol which should be used for the CTC interface"
+    echo $"  0 for compatibility with p.e. VM TCP service machine [default]"
+    echo $"  1 for enhanced package checking for Linux peers"
+    echo $"  3 for compatibility with OS/390 or z/OS peers"
+}
+
+function do_ctcprot() {
+    ask CTCPROT \
+        question_prefix_ctcprot question_choices_ctcprot \
+        -h helptext_ctcprot -s syntax_check_ctcprot -c handle_ctcprot
+}
+
+### PORTNAME (LCS portno)
+
+function syntax_check_lcs_portno() {
+    [[ "$PORTNAME" =~ ^[[:digit:]]+$ ]]
+    case $? in
+        0)
+            # string matched the pattern
+            return 0
+            ;;
+        1)
+            # string did not match the pattern
+            ;;
+        2)
+            echo "l.$LINENO: syntax error in regex of match operator =~, code needs to be fixed" 1>&2
+            ;;
+        *)
+            echo "l.$LINENO: unexpected return code of regex match operator =~, code needs to be fixed" 1>&2
+            ;;
+    esac
+    echo $"Incorrect format for LCS port number (PORTNAME): $PORTNAME"
+    return 1
+}
+
+function handle_lcs_portno() {
+    [ -n "$PORTNAME" ] || return 0
+    if sysecho /sys/devices/lcs/$SCH_R_DEVBUSID/portno "$PORTNAME"; then
+        return 0
+    fi
+    echo $"Could not configure relative port number $PORTNAME for $SUBCHANNELS"
+    return 1
+}
+
+function question_prefix_lcs_portno() {
+    echo -n $"Relative port number of your LCS device"
+}
+
+function question_choices_lcs_portno() {
+    echo $" (number or ? for help). Default is 0:"
+}
+
+function helptext_lcs_portno() {
+    echo $" Help text for relative port number of LCS device:"
+    echo $"  Required for OSA-Express ATM cards only."
+}
+
+function exception_lcs_portno() {
+    [ -z "$PORTNAME" ] && break
+}
+
+function do_lcs_portno() {
+    # LCS portno and QETH portname share the parameter variable PORTNAME.
+    # For compatibility with existing parm files we keep this scheme.
+    ask PORTNAME \
+        question_prefix_lcs_portno question_choices_lcs_portno \
+        -e exception_lcs_portno \
+        -h helptext_lcs_portno -s syntax_check_lcs_portno -c handle_lcs_portno
+}
+
+### HOSTNAME
+
+function syntax_check_hostname() {
+    syntax_check_domainname "$HOSTNAME" "Incorrect format for hostname (HOSTNAME): $HOSTNAME"
+}
+
+function handle_hostname() {
+    if ! hostname $HOSTNAME; then
+        echo $"Could not configure hostname $HOSTNAME"
+        return 1
+    fi
+    return 0
+}
+
+function question_prefix_hostname() {
+    echo -n $"Hostname of your new Linux guest"
+}
+
+function question_choices_hostname() {
+    echo $" (FQDN e.g. s390.redhat.com or ? for help):"
+}
+
+function helptext_hostname() {
+    echo $" Help text for hostname:"
+    echo $"  Enter the full qualified domain name of your host."
+}
+
+function do_hostname() {
+    ask HOSTNAME \
+        question_prefix_hostname question_choices_hostname \
+        -h helptext_hostname -s syntax_check_hostname -c handle_hostname
+}
+
+### IPADDR
+
+function syntax_check_ipaddr() {
+    unset ipv4
+    unset ipv6
+    if checkipv4 $IPADDR; then
+        ipv4="yes"
+        return 0
+    elif [ "$ipv6_capable" = "yes" ] && checkipv6 $IPADDR; then
+        ipv6="yes"
+        return 0
+    fi
+    echo $"Incorrect format for IP address (IPADDR): $IPADDR"
+    return 1
+}
+
+function question_prefix_ipaddr() {
+    echo -n $"IPv4 address"
+    [ "$ipv6_capable" = "yes" ] && echo -n $" / IPv6 addr."
+}
+
+function question_choices_ipaddr() {
+    echo -n $" (e.g. 10.0.0.2"
+    [ "$ipv6_capable" = "yes" ] && echo -n $" / 2001:0DB8::"
+    echo $" or ? for help)"
+}
+
+function helptext_ipaddr() {
+    echo $" Help text for IP address:"
+    echo $"  Enter a valid IPv4 address of your new Linux guest (e.g. 10.0.0.2)"
+    if [ "$ipv6_capable" = "yes" ]; then
+        echo $"  or alternatively a valid IPv6 address without CIDR prefix (e.g. 2001:0DB8::)"
+        echo $"  IPv6 is supported on:"
+        echo $"   - Ethernet interfaces of the OSA-Express adapter running in QDIO mode."
+        echo $"   - HiperSockets interfaces"
+        echo $"   - z/VM guest LAN interfaces running in QDIO mode."
+        echo $"  IPv6 is not supported on HiperSockets guest LAN, OSA-Express Token Ring, ATM."
+    fi
+}
+
+function do_ipaddr() {
+    ipv6_capable && ipv6_capable=yes || ipv6_capable=no
+    ask IPADDR \
+        question_prefix_ipaddr question_choices_ipaddr \
+        -h helptext_ipaddr -s syntax_check_ipaddr
+    if [ "$ipv6" ]; then
+       # qeth_l3 would load ipv6 automatically but not qeth_l2
+       modprobe ipv6
+       tv disable_ipv6_autoconf
+    fi
+
+    # no handling/configuring of IPADDR yet, since more parameters needed
+}
+
+### NETMASK (IPv4)
+
+function syntax_check_netmask_v4() {
+    # also support CIDR prefix
+    if [[ "$NETMASK" =~ ^[[:digit:]]+$ ]]; then
+        if [ "$NETMASK" -ge 1 -a "$NETMASK" -le 32 ]; then
+            ipcalc_arg="$IPADDR/$NETMASK"
+            return 0
+        fi
+        echo $"Incorrect value for network prefix [1..32] (NETMASK): $NETMASK"
+        return 1
+    elif checkipv4 $NETMASK; then
+        ipcalc_arg="$IPADDR $NETMASK"
+        return 0
+    fi
+    echo $"Incorrect format or value for network mask (NETMASK): $NETMASK"
+    return 1
+}
+
+function question_prefix_netmask() {
+    echo -n $"IPv4 netmask or CIDR prefix"
+}
+
+function hint_netmask_v4() {
+    # default based on class a/b/c address
+    local a b c d
+    IFS=.
+    read a b c d <<< "$IPADDR"
+    unset IFS
+    local ip=$(( ( a << 24 ) + ( b << 16 ) + ( c << 8 ) + ( d ) ))
+    # <<EOF convince syntax highlighter that above shifts are no here documents
+    if   [ $(( ip & 0x80000000 )) -eq $(( 0x00000000 )) ]; then
+        # class a
+        echo "255.0.0.0"
+    elif [ $(( ip & 0xC0000000 )) -eq $(( 0x80000000 )) ]; then
+        # class b
+        echo "255.255.0.0"
+    elif [ $(( ip & 0xE0000000 )) -eq $(( 0xC0000000 )) ]; then
+        # class c
+        echo "255.255.255.0"
+    else
+        # some other class that should not be used as host address
+        return 1
+    fi
+    return 0
+}
+
+function question_choices_netmask() {
+    echo -n $" (e.g. 255.255.255.0 or 1..32 or ? for help)"
+    local default=$(hint_netmask_v4)
+    if [ -n "$default" ]; then
+        echo $". Default is $default:"
+    else
+        echo $":"
+        echo $"The IP address you entered previously should probably not be used for a host."
+    fi
+}
+
+function helptext_netmask() {
+    echo $" Help text for IPv4 netmask or CIDR prefix:"
+    echo $"  Enter a valid IPv4 netmask or CIDR prefix (e.g. 255.255.255.0 or 1..32)"
+    local default=$(hint_netmask_v4)
+    if [ -n "$default" ]; then
+        echo $"  Default is $default"
+    else
+        echo $"The IP address you entered previously should probably not be used for a host."
+    fi
+}
+
+function exception_netmask() {
+    if [ -z "$NETMASK" ]; then
+        NETMASK=$(hint_netmask_v4)
+    fi
+}
+
+function do_netmask() {
+    ask NETMASK \
+        question_prefix_netmask question_choices_netmask \
+        -h helptext_netmask \
+        -s syntax_check_netmask_v4 -e exception_netmask
+    # no handling/configuring of NETMASK yet, since more parameters needed
+}
+
+### NETWORK
+
+function do_network() {
+    echo
+    echo $"The NETWORK parameter isn't used anymore and will be ignored."
+    echo $" It is sufficient to specify IPADDR and NETMASK."
+    echo
+}
+
+### BROADCAST
+
+function do_broadcast() {
+    echo
+    echo $"The BROADCAST parameter isn't used anymore and will be ignored."
+    echo $" It is sufficient to specify IPADDR and NETMASK."
+    echo
+}
+
+### NETMASK (IPv6)
+
+function syntax_check_prefix_v6() {
+    if [[ "$NETMASK" =~ ^[[:digit:]]+$ ]]; then
+        if [ "$NETMASK" -ge 1 -a "$NETMASK" -le 128 ]; then
+            return 0
+        fi
+    fi
+    echo $"Incorrect value for network prefix [1..128] (NETMASK): $NETMASK"
+    return 1
+}
+
+function question_prefix_netmask_v6() {
+    echo -n $"CIDR prefix for the IPv6 address"
+}
+
+function question_choices_netmask_v6() {
+    echo $" (1..128):"
+}
+
+function do_netmask_v6() {
+    ask NETMASK \
+        question_prefix_netmask_v6 question_choices_netmask_v6 \
+        -s syntax_check_prefix_v6
+    # no handling/configuring of NETMASK yet, since more parameters needed
+}
+
+### GATEWAY (IPv4)
+
+function configure_ipv4_gateway() {
+    # FIXME:
+    # - Strictly speaking we should first check reachability of gateway
+    #   and then configure the gateway route.
+    #   This would require a new intermediate workflow_item step
+    #   so that the user might continue despite unreachable gateway.
+    # done: Only adding default route might add multiple undesired default
+    # routes on redoing the parameter item, so delete default route
+    # before adding a new one.
+    ip -4 route del default dev $DEVICE >& /dev/null
+    [ -z "$GATEWAY" ] && return 0
+    if ! tv route add default gw $GATEWAY dev $DEVICE; then
+        echo $"Could net set default route on device $DEVICE via gateway $GATEWAY"
+        return 1
+    fi
+    # BH FIXME: Workaround for manual MACADDR, need ping to update arp table
+    echo $"Trying to reach gateway $GATEWAY..."
+    if [ "$NETTYPE" = "ctc" ]; then
+        # (virtual) CTC(/A) seems to need some time to get functional
+        local i=1
+        while : ; do
+            $PING $GATEWAY >& /dev/null && break
+            i=$((i+1))
+            if [ "$i" -gt 3 ]; then
+                echo $"Could not reach gateway $GATEWAY within timeout"
+                return 1
+            fi
+        done
+    else
+        if ! $PING $GATEWAY >& /dev/null; then
+            echo $"Could not reach your default gateway $GATEWAY"
+            return 1
+        fi
+    fi
+    return 0
+}
+
+function hint_ipv4_gateway() {
+    # - provide default suggestion based on network,
+    #   for a class C network this would be either .1 or .254 at the end
+    local a b c d
+    IFS=.
+    read a b c d <<< "$NETWORK"
+    unset IFS
+    local ip=$(( ( a << 24 ) + ( b << 16 ) + ( c << 8 ) + ( d ) ))
+    # <<EOF convince syntax highlighter that above shifts are no here documents
+    local lo=$(( ip | 1 ))
+    local lo_a=$(( (lo & 0xFF000000) >> 24 ))
+    local lo_b=$(( (lo & 0x00FF0000) >> 16 ))
+    local lo_c=$(( (lo & 0x0000FF00) >> 8 ))
+    local lo_d=$(( (lo & 0x000000FF) ))
+    local hi=$(( ip | ( (2**(32 - PREFIX)) - 1 ) ))
+    local hi_a=$(( (hi & 0xFF000000) >> 24 ))
+    local hi_b=$(( (hi & 0x00FF0000) >> 16 ))
+    local hi_c=$(( (hi & 0x0000FF00) >> 8 ))
+    local hi_d=$(( (hi & 0x000000FE) ))
+    echo $"  Depending on your network design patterns, the default gateway"
+    echo $"   might be $lo_a.$lo_b.$lo_c.$lo_d or $hi_a.$hi_b.$hi_c.$hi_d"
+}
+
+function question_prefix_gateway() {
+    echo -n $"IPv4 address of your default gateway"
+}
+
+function question_choices_gateway() {
+    echo $" or ? for help:"
+}
+
+function helptext_gateway() {
+    echo $" Help text for IPv4 default gateway:"
+    echo $"  For HiperSockets with internal traffic only you may want to leave this empty"
+    echo $"  and choose continue afterwards to go on without gateway."
+    hint_ipv4_gateway
+}
+
+function finish_gateway() {
+    if ! checkipv4 $GATEWAY; then
+        # above checkipv4 is silent, so make up for syntax error
+        echo $"Incorrect format for IPv4 address of gateway (GATEWAY): $GATEWAY"
+        workflow_item_menu
+    fi
+    if configure_ipv4_gateway; then
+        break
+    else
+        workflow_item_menu && break
+    fi
+}
+
+# FIXME: allow empty/no gateway?
+
+function do_gateway() {
+    ask GATEWAY \
+        question_prefix_gateway question_choices_gateway \
+        -h helptext_gateway -f finish_gateway
+}
+
+### GATEWAY (IPv6)
+
+function configure_ipv6_gateway() {
+    # FIXME:
+    # - Strictly speaking we should first check reachability of gateway
+    #   and then configure the gateway route.
+    #   This would require a new intermediate workflow_item step
+    #   so that the user might continue despite unreachable gateway.
+    # done: Only adding default route might add multiple undesired default
+    # routes on redoing the parameter item, so delete default route
+    # before adding a new one.
+    ip -6 route del default dev $DEVICE >& /dev/null
+    [ -z "$GATEWAY" ] && return 0
+    # IPv6 http://www.ibiblio.org/pub/Linux/docs/HOWTO/other-formats/html_single/Linux+IPv6-HOWTO.html#AEN1147
+    #       ip -6 route add ::/0 dev $DEVICE via $GATEWAY
+    # (Could also be learned by autoconfiguration on the link:
+    #  after IP address setup and device up,
+    #   see if default route has been learned
+    #   ip -6 route show | grep ^default
+    #  However, we currently use manual IPv6 configuration only.)
+    if ! debug ip -6 route add ::/0 dev $DEVICE via $GATEWAY; then
+        echo $"Could net set default route on device $DEVICE"
+        echo $" via gateway $GATEWAY"
+        return 1
+    fi
+    # BH FIXME: Workaround for manual MACADDR, need ping to update arp table
+    echo $"Trying to reach gateway $GATEWAY..."
+    if ! $PING6 $GATEWAY >& /dev/null; then
+        echo $"Could not reach your default gateway $GATEWAY"
+        return 1
+    fi
+    return 0
+}
+
+function question_prefix_gateway_v6() {
+    echo -n $"IPv6 address of your default gateway"
+}
+
+function question_choices_gateway_v6() {
+    echo $":"
+}
+
+function helptext_gateway_v6() {
+    echo $" Help text for IPv6 default gateway:"
+    echo $"  For HiperSockets with internal traffic only you may want to leave this empty"
+    echo $"  and choose continue afterwards to go on without gateway."
+}
+
+function finish_gateway_v6() {
+    if ! checkipv6 $GATEWAY; then
+        # above checkipv6 is silent, so make up for syntax error
+        echo $"Incorrect format for IPv6 address of gateway (GATEWAY): $GATEWAY"
+        workflow_item_menu
+    fi
+    if configure_ipv6_gateway; then
+        break
+    else
+        workflow_item_menu && break
+    fi
+}
+
+# FIXME: allow empty/no gateway?
+
+function do_gateway_v6() {
+    ask GATEWAY \
+        question_prefix_gateway_v6 question_choices_gateway_v6 \
+        -h helptext_gateway_v6 -f finish_gateway_v6
+}
+
+### GATEWAY (IPv4, point-to-point)
+
+function configure_ipv4_ptp() {
+    # device needs to be online
+    if debug ifconfig $DEVICE $IPADDR $MMTU pointopoint $GATEWAY; then
+        configure_ipv4_gateway
+        return $?
+    fi
+    echo $"Could not set IPv4 address $IPADDR for device $DEVICE"
+    echo $" to peer $GATEWAY"
+    [ -n "$MMTU" ] && echo $" and maximum transfer unit: $MMTU"
+    return 1
+}
+
+function question_prefix_ptp_gateway() {
+    echo -n $"IPv4 address of your point-to-point partner"
+}
+
+function question_choices_ptp_gateway() {
+    echo $" or ? for help:"
+    # no hinting possible here
+}
+
+function helptext_ptp_gateway() {
+    echo $" Help text for point-to-point partner:"
+    echo $"  IPv4 address of your CTC or ESCON point-to-point partner."
+}
+
+function finish_ptp_gateway() {
+    if checkipv4 $GATEWAY; then
+        if [ "$GATEWAY" = "$IPADDR" ]; then
+            echo $"IPv4 address of partner should probably be different from the guest's address"
+            workflow_item_menu && break
+        else
+            break
+        fi
+    else
+        # above checkipv4 is silent, so make up for syntax error
+        echo $"Incorrect format for IPv4 address of partner (GATEWAY): $GATEWAY"
+        workflow_item_menu && break
+    fi
+    # too early to actually configure gateway
+}
+
+function do_ptp_gateway() {
+    ask GATEWAY \
+        question_prefix_ptp_gateway question_choices_ptp_gateway \
+        -h helptext_ptp_gateway -f finish_ptp_gateway
+}
+
+### DNS
+
+function syntax_check_dns() {
+    if [ -z "$DNS" ]; then
+        echo $"You might encounter problems without a nameserver, especially with FTP installs"
+        return 1
+    fi
+    local dnsitem
+    local allgood="yes"
+    if [ "$ipv6" ]; then
+        while read dnsitem; do
+            if ! checkipv6 $dnsitem; then
+                echo $"Not a valid IPv6 address for DNS server: $dnsitem"
+                allgood="no"
+            fi
+        done < <(echo $DNS | sed 's/,/\n/g')
+    else
+         while read dnsitem; do
+           if ! checkipv4 $dnsitem; then
+                echo $"Not a valid IPv4 address for DNS server: $dnsitem"
+                allgood="no"
+            fi
+         done < <(echo $DNS | sed 's/:/\n/g')
+    fi
+    if [ "$allgood" = "yes" ]; then
+        return 0
+    else
+        return 1
+    fi
+}
+
+function handle_dns() {
+    # - foreach DNS try if server is reachable by one ping
+    [ -z "$DNS" ] && return 0
+    local dnsitem
+    local allgood="yes"
+    echo $"Trying to reach DNS servers..."
+    if [ "$ipv6" ]; then
+        while read dnsitem; do
+            if ! $PING6 $dnsitem >& /dev/null; then
+                echo $"Could not ping DNS server (might still serve DNS requests): $dnsitem"
+                allgood="no"
+                # this should not be a hard failure since some network
+                # environments may prevent pings to DNS servers
+                # => prevent workflow_item_menu in kickstart mode
+            fi
+        done < <(echo $DNS | sed 's/,/\n/g')
+    else
+        while read dnsitem; do
+            # Some network environment may prevent a DNS server from being
+            # reachable by ping, so it would make sense to use nslookup.
+            # However, nslookup fails with "Resolver Error 0 (no error)"
+            # at this stage of the setup progress => not useful
+            if ! $PING $dnsitem >& /dev/null; then
+                echo $"Could not ping DNS server: $dnsitem"
+#                if nslookup $dnsitem $dnsitem >& /dev/null; then
+#                    echo $" but could resolve DNS server with itself: $dnsitem"
+#                else
+#                    echo $"Could not resolve DNS server with itself: $dnsitem"
+#                    allgood="no"
+#                fi
+#            elif ! nslookup $dnsitem $dnsitem >& /dev/null; then
+#                echo $"Could not resolve DNS server with itself: $dnsitem"
+                allgood="no"
+            fi
+        done < <(echo $DNS | sed 's/:/\n/g')
+    fi
+    if [ "$allgood" = "yes" ]; then
+        return 0
+    else
+        return 1
+    fi
+}
+
+function question_prefix_dns() {
+    if [ "$ipv6" ]; then
+        echo -n $"IPv6 addresses of DNS servers"
+    else
+        echo -n $"IPv4 addresses of DNS servers"
+    fi
+}
+
+function question_choices_dns() {
+    if [ "$ipv6" ]; then
+        echo $" (separated by commas ',' or ? for help):"
+    else
+        echo $" (separated by colons ':' or ? for help):"
+    fi
+}
+
+function helptext_dns() {
+    echo $" Help text for DNS servers:"
+    if [ "$ipv6" ]; then
+        echo $"  Enter IPv6 addresses of DNS servers separated by commas ','"
+    else
+        echo $"  Enter IPv4 addresses of DNS servers separated by colons ':'"
+    fi
+    echo $"  Default are no DNS servers at all."
+    echo $"  However, you might encounter problems without a nameserver,"
+    echo $"   especially with FTP installs."
+    if [ "$ipv6" ]; then
+        echo $"  An example with 2 servers would be: 2001:0DB8::42,2001:0DB8::BE:AF"
+    else
+        echo $"  An example with 2 servers would be: 10.0.0.250:10.1.1.1"
+    fi
+}
+
+function do_dns() {
+    ask DNS \
+        question_prefix_dns question_choices_dns \
+        -h helptext_dns -s syntax_check_dns -c handle_dns
+}
+
+### SEARCHDNS
+
+function syntax_check_searchdns() {
+    [ -z "$SEARCHDNS" ] && return 0
+    local dnsitem
+    local allgood="yes"
+    while read dnsitem; do
+        syntax_check_domainname "$dnsitem" $"Not a valid DNS search domain: $dnsitem" || allgood="no"
+    done < <(echo $SEARCHDNS | sed 's/:/\n/g')
+    if [ "$allgood" = "yes" ]; then
+        return 0
+    else
+        return 1
+    fi
+}
+
+function question_prefix_searchdns() {
+    echo -n $"DNS search domains"
+}
+
+function question_choices_searchdns() {
+    echo $" (separated by colons ':' or ? for help):"
+}
+
+function helptext_searchdns() {
+    echo $" Help text for DNS search domains:"
+    echo $"  Enter search domains according to hostname syntax separated by colons."
+    echo $"  Default are no DNS search domains at all."
+    echo $"  An example would be: subdomain.domain.com:domain.com"
+}
+
+function do_searchdns() {
+    ask SEARCHDNS \
+        question_prefix_searchdns question_choices_searchdns \
+        -h helptext_searchdns -s syntax_check_searchdns
+}
+
+### DASD
+
+function parse_dasd() {
+    local handle
+    [ "$1" = "-h" ] && handle=yes || unset handle
+    local dasditem
+    local allgood="yes"
+    local cio_wc=$(wc -c /proc/cio_ignore)
+    read cio_wc_bytes cio_wc_filename cio_wc_foo <<< "$cio_wc"
+    if [ "$handle" = "yes" -a "$cio_wc_bytes" != "0" ]; then
+        echo $"Trying to clear specified DASDs from device blacklist..."
+        mkdir -p /etc/modprobe.d
+        echo "options dasd_mod dasd=$DASD" > /etc/modprobe.d/dasd_mod.conf
+        if ! dasd_cio_free; then
+            echo $"Not all specified DASDs could be detected within timeout."
+            allgood="no"
+        fi
+    fi
+    while read dasditem; do
+        unset range features range lo hi rangegood \
+            attrs devno lodevno hidevno devbusid sys
+        case $dasditem in
+            autodetect)
+                [ -z "$handle" ] && continue
+                cio_wc=$(wc -c /proc/cio_ignore)
+                read cio_wc_bytes cio_wc_filename cio_wc_foo <<< "$cio_wc"
+                # above we only freed the devices specified in $DASD,
+                # so there might still be other DASDs in the blacklist
+                if [ "$cio_wc_bytes" != "0" ]; then
+                    echo $"Note: There is a device blacklist active! Only activating visible DASDs."
+                fi
+                local sys
+                while read sys; do
+                    if ! sysecho $sys/online 1; then
+                        echo $"Could not set DASD ${sys##*/} online"
+                    fi
+                done < <(find /sys/bus/ccw/drivers/dasd-eckd/ -name "*.?.????" 2>/dev/null;\
+                    find /sys/bus/ccw/drivers/dasd-fba/ -name "*.?.????" 2>/dev/null)
+                ;;
+            probeonly|nopav|nofcx)
+                if [ -z "$handle" ]; then
+                    echo $"DASD option $dasditem not supported by installer"
+                fi
+                ;;
+            "") continue ;; # empty range
+            *)  local range features rangegood="yes"
+                IFS='('
+                read range features <<< "$dasditem"
+                unset IFS
+                # parse: dev OR dev'-'dev
+                local lo=${range%%-*}
+                [[ "$lo" =~ (^[[:xdigit:]]+\.[0-3]\.[[:xdigit:]]{4}$)|(^[[:xdigit:]]{3,4}$) ]]
+                case $? in
+                    0)  # string matched the pattern
+                        lo=$(canonicalize_devno $lo) ;;
+                    1)  # string did not match the pattern
+                        rangegood="no"
+                        if [ -z "$handle" ]; then
+                            echo $"Incorrect format for lower bound of DASD range $range: $lo"
+                            allgood="no"
+                        fi
+                        ;;
+                    2)  echo "l.$LINENO: syntax error in regex of match operator =~, code needs to be fixed" 1>&2 ;;
+                    *)  echo "l.$LINENO: unexpected return code of regex match operator =~, code needs to be fixed" 1>&2 ;;
+                esac
+                if [ "${range//*-*/}" = "" ]; then
+                    local hi=${range##*-}
+                    [[ "$hi" =~ (^[[:xdigit:]]+\.[0-3]\.[[:xdigit:]]{4}$)|(^[[:xdigit:]]{3,4}$) ]]
+                    case $? in
+                        0)  # string matched the pattern
+                            hi=$(canonicalize_devno $hi)
+                            if [ "${lo%.*}" != "${hi%.*}" ]; then
+                                echo $"Prefixes of DASD range $range do not match: ${lo%.*} != ${hi%.*}"
+                                rangegood="no"
+                                allgood="no"
+                            fi
+                            ;;
+                        1)  # string did not match the pattern
+                            rangegood="no"
+                            if [ -z "$handle" ]; then
+                                echo $"Incorrect format for upper bound of DASD range $range: $hi"
+                                allgood="no"
+                            fi
+                            ;;
+                        2)  echo "l.$LINENO: syntax error in regex of match operator =~, code needs to be fixed" 1>&2 ;;
+                        *)  echo "l.$LINENO: unexpected return code of regex match operator =~, code needs to be fixed" 1>&2 ;;
+                    esac
+                fi
+                if [ "${features//*)/}" != "" ]; then
+                    if [ -z "$handle" ]; then
+                        echo $"Missing closing parenthesis at features of DASD range $range: ($features"
+                        allgood="no"
+                    fi
+                fi
+                local attrs=""
+                if [ -n "$features" ]; then
+                    features="${features%)}"
+                    while read feature; do
+                        case $feature in
+                            ro) attrs=$attrs" readonly" ;;
+                            diag) attrs=$attrs" use_diag" ;;
+                            erplog|failfast) attrs=$attrs" "$feature ;;
+                            *) if [ -z "$handle" ]; then
+                                   echo $"Unknown DASD feature for device range $range: $feature"
+                                   allgood="no"
+                               fi
+                               ;;
+                        esac
+                    done < <(echo $features | sed 's/:/\n/g')
+                fi
+                [ "$rangegood" = "yes" ] || continue
+                [ "$handle" = "yes" ] || continue
+                # now apply $attrs and set DASDs $lo to $hi online
+                [ -z "$hi" ] && hi=$lo
+                local devno lodevno=$((0x${lo##*.})) hidevno=$((0x${hi##*.}))
+                for ((devno=$lodevno; $devno <= $hidevno; ++devno)); do
+                    local devbusid=$(printf "%s.%04x" ${lo%.*} $devno)
+                    local sys="/sys/bus/ccw/devices/"$devbusid
+                    for attr in $attrs; do
+                        if [ "$attr" = "use_diag" ]; then
+                            # diag discipline cannot be auto-loaded
+                            modprobe dasd_diag_mod
+                        fi
+                        if [ ! -f $sys/$attr ]; then
+                            echo $"DASD $devbusid does not provide attribute $attr"
+                            continue
+                        fi
+                        if ! sysecho $sys/$attr 1; then
+                            echo $"Could not set attribute $attr for DASD $devbusid"
+                        fi
+                    done
+                    if [ ! -f $sys/online ]; then
+                        echo $"DASD $devbusid not found"
+                        continue
+                    fi
+                    if ! sysecho $sys/online 1; then
+                        echo $"Could not set DASD $devbusid online"
+                    fi
+                done
+                ;;
+        esac
+    done < <(echo $DASD | sed 's/,/\n/g')
+    if [ "$handle" = "yes" ]; then
+        udevadm settle
+        dasd_settle_all || return 1
+        echo $"Activated DASDs:"
+        cat /proc/dasd/devices | sed -e 's/ at ([^)]*) is//' -e 's/ at/,/'
+    fi
+    if [ "$allgood" = "yes" ]; then
+        return 0
+    else
+        return 1
+    fi
+}
+
+function syntax_check_dasd() {
+    parse_dasd
+    return $?
+}
+
+function handle_dasd() {
+    parse_dasd -h
+    return $?
+}
+
+function question_prefix_dasd() {
+    echo -n $"DASD range"
+}
+
+function question_choices_dasd() {
+    echo $" (e.g. 200-203,205 or ? for help). Default is autoprobing:"
+}
+
+function helptext_dasd() {
+    echo $" Help text for DASD range:"
+    echo $"  Comma separated list of ranges of device bus IDs."
+    echo $"  Default is autoprobing (not recommended)."
+    echo $"  Examples would be: 200-203 or 200,201,202,203 or 0.0.0200-0.0.0203,0.0.0205"
+}
+
+function exception_dasd() {
+    [ -z "$DASD" ] && DASD="autodetect"
+}
+
+function do_dasd() {
+    ask DASD \
+        question_prefix_dasd question_choices_dasd \
+        -h helptext_dasd -e exception_dasd -s syntax_check_dasd -c handle_dasd
+}
+
+### FCP
+
+function syntax_check_fcp() {
+    local allgood="yes"
+    local i
+    for i in ${!FCP_*}; do
+        local -a fcp
+        local devno wwpn lun
+        read -a fcp <<< "${!i}"
+        case ${#fcp[@]} in
+            3)
+                devno=${fcp[0]}
+                wwpn=${fcp[1]}
+                lun=${fcp[2]}
+                ;;
+            5)
+                devno=${fcp[0]}
+                wwpn=${fcp[2]}
+                lun=${fcp[4]}
+                echo $"Deprecated number of FCP arguments (5 instead of 3): "
+                echo $" $i=\"${!i}\""
+                echo $" should instead be: "
+                echo $" $i=\"$devno $wwpn $lun\""
+                ;;
+            *)
+                echo $"Unsupported number of FCP arguments (${#fcp[@]} instead of 3) in:"
+                echo $" $i=\"${!i}\""
+                allgood="no"
+                continue
+                ;;
+        esac
+        [[ "$devno" =~ (^[[:xdigit:]]+\.[0-3]\.[[:xdigit:]]{4}$)|(^[[:xdigit:]]{3,4}$) ]]
+        case $? in
+            0)  ;; # string matched the pattern
+            1)  # string did not match the pattern
+                echo $"Incorrect format for FCP device $devno in:"
+                echo $" $i=\"${!i}\""
+                allgood="no"
+                ;;
+            2)
+                echo "l.$LINENO: syntax error in regex of match operator =~, code needs to be fixed" 1>&2
+                ;;
+            *)
+                echo "l.$LINENO: unexpected return code of regex match operator =~, code needs to be fixed" 1>&2
+                ;;
+        esac
+        # zfcp.py:class ZFCPDevice would also accept WWPN without leading 0x
+        [[ "$wwpn" =~ ^0x[[:xdigit:]]{16}$ ]]
+        case $? in
+            0)  ;; # string matched the pattern
+            1)  # string did not match the pattern
+                echo $"Incorrect format for FCP WWPN $wwpn in:"
+                echo $" $i=\"${!i}\""
+                allgood="no"
+                ;;
+            2)  echo "l.$LINENO: syntax error in regex of match operator =~, code needs to be fixed" 1>&2 ;;
+            *)  echo "l.$LINENO: unexpected return code of regex match operator =~, code needs to be fixed" 1>&2 ;;
+        esac
+        # zfcp.py:class ZFCPDevice would also accept LUN without leading 0x
+        # zfcp.py:class ZFCPDevice would also accept 16 bit LUN and pads with 0
+        [[ "$lun" =~ ^0x[[:xdigit:]]{8}0{8}$ ]]
+        case $? in
+            0)  ;; # string matched the pattern
+            1)  # string did not match the pattern
+                echo $"Incorrect format for FCP LUN $lun in:"
+                echo $" $i=\"${!i}\""
+                allgood="no"
+                ;;
+            2)
+                echo "l.$LINENO: syntax error in regex of match operator =~, code needs to be fixed" 1>&2
+                ;;
+            *)
+                echo "l.$LINENO: unexpected return code of regex match operator =~, code needs to be fixed" 1>&2
+                ;;
+        esac
+    done
+    if [ "$allgood" = "yes" ]; then
+        return 0
+    else
+        return 1
+    fi
+}
+
+###
+
+function show_parms() {
+    # The only issue with this stateless approach to showing parameters based
+    # on their content being non-empty is, that parameters with defaults
+    # such as LAYER2, (PORTNAME,) CTCPROT, PORTNO (,MACADDR) won't be shown
+    # if the user just hit enter, so the parm file would be "incomplete".
+    # However this is not easy to fix in here, since it would require the
+    # inter-parameter dependenies coded below in the main part, e.g. an
+    # empty LAYER2 should only be printed with default value if $NETTYPE=qeth.
+    # For the time being, at least the parameters LAYER2, PORTNAME, and CTCPROT
+    # only get asked on being empty if not running in kickstart mode.
+    cat << EOF
+NETTYPE=$NETTYPE
+IPADDR=$IPADDR
+NETMASK=$NETMASK
+GATEWAY=$GATEWAY
+HOSTNAME=$HOSTNAME
+EOF
+    [ "$SUBCHANNELS" ] && echo "SUBCHANNELS=$SUBCHANNELS"
+    [ "$LAYER2" ] && echo "LAYER2=$LAYER2"
+    [ "$VSWITCH" ] && echo "VSWITCH=$VSWITCH"
+    [ "$MACADDR" ] && echo "MACADDR=$MACADDR"
+    [ "$PORTNAME" ] && echo "PORTNAME=$PORTNAME"
+    [ "$PORTNO" ] && echo "PORTNO=$PORTNO"
+    [ "$PEERID" ] && echo "PEERID=$PEERID"
+    [ "$CTCPROT" ] && echo "CTCPROT=$CTCPROT"
+    if [ -n "$mmtu_was_set" ]; then
+        echo "MMTU=\"$MMTU\""
+    elif [ -n "$mtu_was_set" ]; then
+        echo "MTU=$MTU"
+    fi
+    [ "$DNS" ] && echo "DNS=$DNS"
+    [ "$SEARCHDNS" ] && echo "SEARCHDNS=$SEARCHDNS"
+    [ "$DASD" ] && echo "DASD=$DASD"
+}
+
+function final_check() {
+    # final check && break
+    if [ -z "$interaction_happened" ]; then
+        # if parm file was good enough just continue without interaction
+        break
+        return 0
+    fi
+    while : ; do
+        # optionally consider "continue" as default
+        # but then again the user may inadvertently continue
+        echo
+        echo $"c) continue, p) parm file/configuration, n) network state, r) restart, s) shell"
+        local answer
+        read answer
+        case $answer in
+            c) return 0 ;;
+            p) echo
+                show_parms ;;
+            n) # show interfaces and routing table
+                ifconfig -a
+                if [ "$ipv6" ]; then
+                    #route -n -A inet6
+                    # the following produces more compact output for 80 columns
+                    ip -6 route show | grep -v "^unreachable "
+                else
+                    route -n
+                fi
+                ;;
+            d) # show active DASDs with some useful details
+                echo $"Activated DASDs:"
+                cat /proc/dasd/devices|sed -e 's/ at ([^)]*) is//' -e 's/ at/,/'
+                ;;
+            r) break ;;
+            s) echo $"Enter 'exit' at the shell prompt to get back to the installation dialog."
+                /bin/bash
+                ;;
+    esac
+    done
+    return 1
+}
+
+### MAIN ###
+
+init_main
+udev_setup
+
+# Parse configuration
+if [ -n "$CMSDASD" -a -n "$CMSCONFFILE" ]; then
+    readcmsfile $CMSDASD $CMSCONFFILE
+    source /tmp/$CMSCONFFILE #2>/dev/null
+fi
+
+if [ -r /sys/firmware/ipl/ipl_type ]; then
+    #local ipl_type
+    read ipl_type < /sys/firmware/ipl/ipl_type
+    if [ "$ipl_type" = "fcp" ]; then
+        while : ; do
+            echo $"Your IPL device is set to FCP."
+            echo $"Would you like to perform a CD-ROM/DVD-ROM installation? (y/n)"
+            #local do_cd_install
+            read do_cd_install
+            case $do_cd_install in
+                y|Y|[Yy][Ee][Ss])
+                    # precondition: zfcp driver incl. dependencies loaded
+                    #local CD_DEVICE WWPN LUN
+                    read CD_DEVICE < /sys/firmware/ipl/device
+                    read WWPN < /sys/firmware/ipl/wwpn
+                    read LUN < /sys/firmware/ipl/lun
+                    if sysecho /proc/cio_ignore "free $CD_DEVICE"; then
+                        udevadm settle
+                        # even though device might now be online, some of its
+                        # sysfs attributes might not yet be available
+                        sleep 1
+                    else
+                        echo $"Device $CD_DEVICE could not be cleared from device blacklist"
+                    fi
+                    sysecho /sys/bus/ccw/drivers/zfcp/$CD_DEVICE/online 1 \
+                        || echo $"Could not set FCP device $CD_DEVICE online"
+                    udevadm settle
+                    # port (WWPN) appears automatically
+                    sysecho /sys/bus/ccw/drivers/zfcp/$CD_DEVICE/$WWPN/unit_add $LUN \
+                        || echo $"Could not add LUN $LUN at WWPN $WWPN on FCP device $CD_DEVICE"
+                    udevadm settle
+                    break
+                    ;;
+                n|N|[Nn][Oo])
+                    break
+                    ;;
+                *)
+                    echo
+                    echo $"*** INVALID ANSWER: $do_cd_install"
+                    echo
+                    unset do_cd_install
+                    ;;
+            esac
+        done
+    fi
+fi
+
+# Perform a network installation
+
+[ -n "$MTU" ] && mtu_was_set=$MTU
+[ -n "$MMTU" ] && mmtu_was_set=$MMTU
+[ -n "$VSWITCH" ] && vswitch_was_set=$VSWITCH
+
+[ -n "$CHANDEV" ] && do_chandev
+[ -n "$NETWORK" ] && do_network
+[ -n "$BROADCAST" ] && do_broadcast
+
+# [ -z "${cardtype//OSD_*/}" ] can be used to check for real OSA
+
+# Check for missing parameters, prompt for them if necessary
+while : ; do
+
+    # do not show list of possible network device configurations, if:
+    # - running unattended install with kickstart
+    # - relevant parameters have already been specified in parm file
+    #   (a possible optimization would be matching those parms to table entry)
+    # - dialog has not been restarted
+    [ -n "$reenter" \
+        -o -z "$RUNKS" -a \( -z "$NETTYPE" -o -z "$SUBCHANNELS" \) ] && \
+        dialog_network_table
+    if isVM; then
+        echo $"* NOTE: To enter default or empty values press enter twice. *"
+    fi
+    do_nettype
+
+    # precondition: driver (qeth/lcs/ctcm) loaded incl. dependencies
+    do_subchannels
+    if [ "$NETTYPE" = "qeth" ]; then
+        [ -z "$reenter" -a -n "$RUNKS" -a -z "$PORTNAME" ] || \
+            [ -n "${cardtype//OSD_*/}" ] || do_portname
+        # See also https://bugzilla.redhat.com/show_bug.cgi?id=439461
+        #
+        # If running in kickstart mode (unattended), we assume no
+        # interaction and the user won't get asked for PORTNO.
+        # Otherwise the user will be asked for PORTNO.
+        # If the user specified PORTNO in parm/conf file, PORTNO gets
+        # respected (or the user will be asked if it was wrong).
+        if [ -f /sys/devices/qeth/$SCH_R_DEVBUSID/portno ]; then
+            # driver support exists since RHEL5.2
+            [ -z "$reenter" -a -n "$RUNKS" -a -z "$PORTNO" ] || \
+                [ -n "${cardtype//OSD_*/}" ] || do_portno
+        fi
+        do_layer2
+        # set device online to know the device name
+        # and to know if it's OSD/HiperSockets/GuestLAN BUT do not
+        # try to ifconfig the device up since that requires
+        # setting the mac address before (if applicable).
+        set_device_online || workflow_item_menu noredo
+        # MAC address handling is not part of
+        # https://bugzilla.redhat.com/show_bug.cgi?id=233376
+        # Instead the additions come from
+        # https://bugzilla.redhat.com/show_bug.cgi?id=248049
+        # The new parms VSWITCH and MACADDR are described in
+        # the RHEL 5.1 release notes.
+        if isLayer2; then
+            if [ -z "$VSWITCH" -o "$VSWITCH" == 0 ]; then
+                do_macaddr
+            fi
+        fi
+    elif [ "$NETTYPE" = "ctc" ]; then
+        [ -z "$reenter" -a -n "$RUNKS" -a -z "$CTCPROT" ] || do_ctcprot
+        set_device_online || workflow_item_menu noredo
+    elif [ "$NETTYPE" = "lcs" ]; then
+        [ -n "$RUNKS" -a -z "$PORTNAME" ] && PORTNAME=0
+        do_lcs_portno
+        set_device_online || workflow_item_menu noredo
+    fi
+
+    # device needs to be up before configuring with ifconfig/ip in
+    # configure_ipv6_address/configure_ipv4_address/configure_ipv4_address
+    set_device_up || workflow_item_menu noredo
+
+    [ "$HOSTNAME" = "(none)" ] && unset HOSTNAME
+    do_hostname
+
+    # Note: The workflow_item_menu does a rollback_config on restart
+    # dialog, i.e. hardware config has been reset and it is impossible to
+    # only restart halfway at IPADDR.
+    do_ipaddr
+    if [ "$ipv6" ]; then
+        # this branch is all IPv6 and at the same time also NETTYPE==qeth
+        do_netmask_v6
+        handle_mtu
+        configure_ipv6_address || workflow_item_menu noredo
+        do_gateway_v6
+    else
+        # Consider IPv4 as default, even for unknown IP versions
+        # due to invalid input for IPADDR ignored by the user previously
+        # (neither ipv6 nor ipv4 is set).
+        # Otherwise we would skip things like NETMASK or GATEWAY
+        # and jump forward to DNS which is probably not what we want.
+        if [ "$NETTYPE" = "qeth" ] || [ "$NETTYPE" = "lcs" ]; then
+            do_netmask
+            handle_mtu
+            configure_ipv4_address || workflow_item_menu noredo
+            do_gateway
+        else  # ctc0
+            if [ -z "$NETMASK" ]; then
+                # If the user did not supply netmask, we add the right one.
+                # Netmask MUST be present,
+                # or pumpSetupInterface() blows routes.
+                NETMASK="255.255.255.255"
+            fi
+            # don't ask for MTU, but use it if set in the parm file
+            # don't overwrite MMTU if it has been set for CTC
+            [ "$NETTYPE" = "ctc" -a -z "$MTU" -a -z "$MMTU" ] && \
+                MMTU="mtu 1500"
+            do_ptp_gateway
+            configure_ipv4_ptp || workflow_item_menu noredo
+        fi
+    fi
+
+    modprobe_alias
+    do_dns
+    [ -n "$DNS" ] && do_searchdns
+
+    do_dasd
+
+    echo $"Initial configuration completed."
+    final_check && break
+    rollback_config
+    reenter="yes"
+
+done # outer dialog loop
+
+if [ -z "$testing" ]; then
+
+    # convert to space-separated lists
+    if [ -n "$SEARCHDNS" ]; then
+        SEARCHDNS=$(echo $SEARCHDNS |sed -e 's/:/ /g')
+        for i in "$SEARCHDNS"; do echo "search $i"; done >> /etc/resolv.conf
+    fi
+    if [ -n "$DNS" ]; then
+        if [ "$ipv6" ]; then
+            RESOLVDNS=$(echo $DNS |sed -e 's/,/ /g')
+        else
+            RESOLVDNS=$(echo $DNS |sed -e 's/:/ /g')
+        fi
+        for i in $RESOLVDNS; do echo "nameserver $i"; done >> /etc/resolv.conf
+    fi
+
+    # make sure we have an /etc/hosts file (originally required for telnetd)
+    if [ ! -z "$HOSTNAME" -a ! -z "$IPADDR" ]; then
+        echo -e "$IPADDR\t$HOSTNAME $(echo $HOSTNAME | cut -d '.' -f 1)" >> /etc/hosts
+    fi
+
+fi # testing
+
+# syntax check to give user early feedback on parameters provided in parm file
+# (he probably won't notice the logs written by anaconda later on)
+syntax_check_fcp
+# currently we ignore failed syntax checks since FCP parms are non-interactive
+for i in ${!FCP_*}; do
+    echo "${!i}" >> /tmp/fcpconfig
+done
+# cio_ignore handling for FCP should happen when the content of /tmp/fcpconfig
+# will actually be processed which is in anaconda's zfcp.py ZFCP::readConfig()
+
+# TODO/FIXME: also need to pass IPv6 decision to loader/anaconda
+#    [ "$ipv6" ] && echo "IPV6=yes"
+
+# transfer options into install environment
+cat > /tmp/install.cfg << EOF
+LANG="$LANG"
+S390ARCH="$S390ARCH"
+TEXTDOMAIN="$TEXTDOMAIN"
+TEXTDOMAINDIR="$TEXTDOMAINDIR"
+PORTNAME="$PORTNAME"
+HOSTNAME="$HOSTNAME"
+DEVICE="$DEVICE"
+NETTYPE="$NETTYPE"
+IPADDR="$IPADDR"
+GATEWAY="$GATEWAY"
+MTU="$MTU"
+NETWORK="$NETWORK"
+NETMASK="$NETMASK"
+BROADCAST="$BROADCAST"
+SEARCHDNS="$SEARCHDNS"
+PEERID="$PEERID"
+SUBCHANNELS="$SUBCHANNELS"
+ONBOOT="yes"
+CTCPROT="$CTCPROT"
+EOF
+if [ "$ipv6" ]; then
+    DNS1=$(echo $DNS | cut -d ',' -f 1)
+    echo DNS=\"$DNS1\" >> /tmp/install.cfg
+    echo DNS1=\"$DNS1\" >> /tmp/install.cfg
+    echo DNS2=\"$(echo $DNS | cut -d ',' -f 2)\" >> /tmp/install.cfg
+else
+    DNS1=$(echo $DNS | cut -d ':' -f 1)
+    echo DNS=\"$DNS1\" >> /tmp/install.cfg
+    echo DNS1=\"$DNS1\" >> /tmp/install.cfg
+    echo DNS2=\"$(echo $DNS | cut -d ':' -f 2)\" >> /tmp/install.cfg
+fi
+cat >> /tmp/install.cfg << EOF
+export LANG PORTNAME S390ARCH TEXTDOMAIN TEXTDOMAINDIR
+export HOSTNAME DEVICE NETTYPE IPADDR GATEWAY MTU
+export NETWORK NETMASK BROADCAST DNS DNS1 DNS2 SEARCHDNS
+export PEERID ONBOOT SUBCHANNELS CTCPROT
+EOF
+# immediately read it in again to export these into the shell below
+. /tmp/install.cfg
+if [ -z "$testing" ]; then
+    cat /tmp/install.cfg >> /etc/profile
+fi # testing
+
+NETSCRIPTS="/etc/sysconfig/network-scripts"
+IFCFGFILE="$NETSCRIPTS/ifcfg-$DEVICE"
+if [ ! -d "$NETSCRIPTS" ]; then
+    mkdir -p $NETSCRIPTS
+fi
+
+# to please NetworkManager on startup in loader before loader reconfigures net
+cat > /etc/sysconfig/network << EOF
+HOSTNAME=$HOSTNAME
+EOF
+
+cat > $IFCFGFILE << EOF
+DEVICE=$DEVICE
+ONBOOT=yes
+BOOTPROTO=static
+GATEWAY=$GATEWAY
+BROADCAST=$BROADCAST
+MTU=$MTU
+SUBCHANNELS=$SUBCHANNELS
+EOF
+if [ "$ipv6" ]; then
+    cat >> $IFCFGFILE << EOF
+IPV6INIT=yes
+IPV6_AUTOCONF=no
+IPV6ADDR=$IPADDR/$NETMASK
+IPV6_DEFAULTGW=$GATEWAY
+EOF
+    # FIXME: /etc/sysconfig/network:IPV6_DEFAULTGW=$GATEWAY
+    #        /etc/sysconfig/network:NETWORKING_IPV6=yes
+else
+    cat >> $IFCFGFILE << EOF
+IPADDR=$IPADDR
+NETMASK=$NETMASK
+EOF
+fi
+[ "$DNS1" != "" ] && echo "DNS1=$DNS1" >> $IFCFGFILE
+[ "$DNS2" != "" ] && echo "DNS2=$DNS2" >> $IFCFGFILE
+# colons in SEARCHDNS already replaced with spaces above for /etc/resolv.conf
+[ "$SEARCHDNS" != "" ] && echo "DOMAIN=\"$SEARCHDNS\"" >> $IFCFGFILE
+[ "$NETTYPE" != "" ] && echo "NETTYPE=$NETTYPE" >> $IFCFGFILE
+[ "$PEERID" != "" ] && echo "PEERID=$PEERID" >> $IFCFGFILE
+[ "$PORTNAME" != "" ] && echo "PORTNAME=$PORTNAME" >> $IFCFGFILE
+[ "$CTCPROT" != "" ] && echo "CTCPROT=$CTCPROT" >> $IFCFGFILE
+[ "$MACADDR" != "" ] && echo "MACADDR=$MACADDR" >> $IFCFGFILE
+optstr=""
+for option in LAYER2 PORTNO; do
+    [ -z "${!option}" ] && continue
+    [ -n "$optstr" ] && optstr=${optstr}" "
+    optstr=${optstr}$(echo ${option} | tr [[:upper:]] [[:lower:]])"="${!option}
+done
+# write single quotes since network.py removes double quotes but we need quotes
+echo "OPTIONS='$optstr'" >> $IFCFGFILE
+unset option
+unset optstr
+
+if [ -z "$testing" ]; then
+
+    # so that the vars get propagated into the sshd shells
+    mkdir /.ssh
+    cat >> /.ssh/environment <<EOF
+LD_LIBRARY_PATH=$LD_LIBRARY_PATH
+PATH=$PATH
+HOME=$HOME
+PYTHONPATH=$PYTHONPATH
+EOF
+
+    cat >> /etc/profile <<EOF
+LD_LIBRARY_PATH=$LD_LIBRARY_PATH
+PATH=$PATH
+HOME=$HOME
+PYTHONPATH=$PYTHONPATH
+export LD_LIBRARY_PATH PATH HOME PYTHONPATH
+EOF
+
+    if [ -n "$DISPLAY" ]; then
+        echo "export DISPLAY=$DISPLAY" >> /etc/profile
+    fi
+
+    # I'm tired of typing this out...
+    echo "loader" >> /.bash_history
+
+    echo -n $$ > /var/run/init.pid
+
+    # shutdown (halt) on SIGUSR1
+    trap doshutdown SIGUSR1
+    # reboot on SIGUSR2
+    trap doreboot SIGUSR2
+
+    startinetd
+
+    if [ -n "$RUNKS" ]; then
+        /sbin/loader
+    fi
+
+    doshutdown
+
+fi # testing
+
+# ;;; Local Variables: ***
+# ;;; mode: sh ***
+# ;;; end: ***
diff --git a/bin/loader/loader.c b/bin/loader/loader.c
new file mode 100644
index 0000000..84fd116
--- /dev/null
+++ b/bin/loader/loader.c
@@ -0,0 +1,2378 @@
+/*
+ * loader.c
+ *
+ * This is the installer loader.  Its job is to somehow load the rest
+ * of the installer into memory and run it.  This may require setting
+ * up some devices and networking, etc. The main point of this code is
+ * to stay SMALL! Remember that, live by that, and learn to like it.
+ *
+ * Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
+ * 2006, 2007  Red Hat, Inc.  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 as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ *
+ * Author(s): Erik Troan <ewt@xxxxxxxxxx>
+ *            Matt Wilson <msw@xxxxxxxxxx>
+ *            Michael Fulbright <msf@xxxxxxxxxx>
+ *            Jeremy Katz <katzj@xxxxxxxxxx>
+ */
+
+#include <ctype.h>
+#include <errno.h>
+#include <execinfo.h>
+#include <fcntl.h>
+#include <newt.h>
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <strings.h>
+#include <unistd.h>
+#include <stdint.h>
+#include <dirent.h>
+#include <arpa/inet.h>
+
+#include <sys/ioctl.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/stat.h>
+#include <sys/wait.h>
+#include <sys/utsname.h>
+
+#include <linux/fb.h>
+#include <linux/serial.h>
+#include <linux/vt.h>
+
+#include <glib.h>
+
+#ifdef USE_MTRACE
+#include <mcheck.h>
+#endif
+
+#include "copy.h"
+#include "getparts.h"
+#include "loader.h"
+#include "loadermisc.h" /* JKFIXME: functions here should be split out */
+#include "lang.h"
+#include "fwloader.h"
+#include "kbd.h"
+#include "kickstart.h"
+#include "windows.h"
+
+/* module stuff */
+#include "modules.h"
+#include "moduleinfo.h"
+
+#include "driverdisk.h"
+
+/* hardware stuff */
+#include "hardware.h"
+
+/* install method stuff */
+#include "method.h"
+#include "cdinstall.h"
+#include "nfsinstall.h"
+#include "hdinstall.h"
+#include "urls.h"
+#include "urlinstall.h"
+
+#include "net.h"
+#include "telnetd.h"
+
+#include <selinux/selinux.h>
+#include "selinux.h"
+
+#include "../isys/imount.h"
+#include "../isys/isys.h"
+#include "../isys/stubs.h"
+#include "../isys/lang.h"
+#include "../isys/eddsupport.h"
+#include "../isys/log.h"
+
+/* maximum number of extra arguments that can be passed to the second stage */
+#define MAX_EXTRA_ARGS 128
+static char * extraArgs[MAX_EXTRA_ARGS];
+static int hasGraphicalOverride();
+
+static int newtRunning = 0;
+
+/* boot flags -- we need these in a lot of places */
+uint64_t flags = LOADER_FLAGS_SELINUX;
+
+#ifdef INCLUDE_LOCAL
+#include "cdinstall.h"
+#include "hdinstall.h"
+#endif
+#ifdef INCLUDE_NETWORK
+#include "nfsinstall.h"
+#include "urlinstall.h"
+#endif
+
+int num_link_checks = 5;
+int post_link_sleep = 0;
+
+static pid_t init_pid = 1;
+static int init_sig = SIGUSR1; /* default to shutdown=halt */
+static const char *LANG_DEFAULT = "en_US.UTF-8";
+
+static struct installMethod installMethods[] = {
+    { N_("Local CD/DVD"), 0, DEVICE_CDROM, mountCdromImage },
+    { N_("Hard drive"), 0, DEVICE_DISK, mountHardDrive },
+    { N_("NFS directory"), 1, DEVICE_NETWORK, mountNfsImage },
+    { "URL", 1, DEVICE_NETWORK, mountUrlImage },
+};
+static int numMethods = sizeof(installMethods) / sizeof(struct installMethod);
+
+static int expected_exit = 0;
+
+void doExit(int result)
+{
+    expected_exit = 1;
+    exit(result);
+}
+
+void doSuspend(void) {
+    newtFinished();
+    doExit(1);
+}
+
+void doShell(void) {
+    pid_t child;
+    int status;
+
+    newtSuspend();
+    child = fork();
+
+    if (child == 0) {
+        if (execl("/sbin/bash", "/sbin/bash", "-i", NULL) == -1) {
+            logMessage(ERROR, "%s (%d): %m", __func__, __LINE__);
+            _exit(1);
+        }
+    } else if (child == -1) {
+        logMessage(ERROR, "%s (%d): %m", __func__, __LINE__);
+        newtResume();
+    } else {
+        if (waitpid(child, &status, 0) == -1) {
+            logMessage(ERROR, "%s (%d): %m", __func__, __LINE__);
+        }
+
+        newtResume();
+    }
+}
+
+void doGdbserver(struct loaderData_s *loaderData) {
+    int child, fd;
+    char *pid;
+    iface_t iface;
+
+    /* If gdbserver is found, go ahead and run it on the loader process now
+     * before anything bad happens.
+     */
+    if (loaderData->gdbServer && !access("/usr/bin/gdbserver", X_OK)) {
+        pid_t loaderPid = getpid();
+        iface_init_iface_t(&iface);
+
+        if (kickstartNetworkUp(loaderData, &iface)) {
+            logMessage(ERROR, "can't run gdbserver due to no network");
+            return;
+        }
+
+        checked_asprintf(&pid, "%d", loaderPid);
+
+        if (!(child = fork())) {
+            logMessage(INFO, "starting gdbserver: %s %s %s %s",
+                       "/usr/bin/gdbserver", "--attach", loaderData->gdbServer,
+                       pid);
+
+            fd = open("/dev/null", O_RDONLY);
+            close(STDIN_FILENO);
+            dup2(fd, STDIN_FILENO);
+            close(fd);
+            fd = open("/dev/null", O_WRONLY);
+            close(STDOUT_FILENO);
+            dup2(fd, STDOUT_FILENO);
+            close(STDERR_FILENO);
+            dup2(fd, STDERR_FILENO);
+            close(fd);
+
+            if (execl("/usr/bin/gdbserver", "/usr/bin/gdbserver", "--attach",
+                      loaderData->gdbServer, pid, NULL) == -1)
+                logMessage(ERROR, "error running gdbserver: %m");
+
+            _exit(1);
+        }
+    }
+}
+
+void startNewt(void) {
+    if (!newtRunning) {
+        char *buf;
+        char *arch = getProductArch();
+        checked_asprintf(&buf, _("Welcome to %s for %s"), getProductName(), arch);
+
+        /*
+         * Because currently initrd.img only has got the default English locale
+         * support, pretend for newtInit() it is actually the used LANG so Newt
+         * knows how to compute character widths etc. 
+         */
+        char *lang = getenv("LANG");
+        if (lang) {
+            lang = strdup(lang);
+        }
+        setenv("LANG", LANG_DEFAULT, 1);
+        newtInit();
+        unsetenv("LANG");
+        /* restore the original LANG value */
+        if (lang) {
+            setenv("LANG", lang, 1);
+            free(lang);
+        }
+
+        newtCls();
+        newtDrawRootText(0, 0, buf);
+        free(buf);
+        
+        newtPushHelpLine(_("  <Tab>/<Alt-Tab> between elements  | <Space> selects | <F12> next screen "));
+        
+        newtRunning = 1;
+        if (!access("/bin/sh",  X_OK)) 
+            newtSetSuspendCallback((void *) doShell, NULL);
+    }
+}
+
+void stopNewt(void) {
+    if (newtRunning) newtFinished();
+    newtRunning = 0;
+}
+
+static gchar *productName = NULL;
+static gchar *productPath = NULL;
+static gchar *productArch = NULL;
+
+static void initProductInfo(void) {
+    gchar *contents = NULL;
+    gchar **lines = NULL, **stamp = NULL;
+    GError *fileErr = NULL;
+
+    if (!g_file_get_contents("/.buildstamp", &contents, NULL, &fileErr)) {
+        logMessage(ERROR, "error reading .buildstamp: %s", fileErr->message);
+        g_error_free(fileErr);
+        productName = g_strdup("anaconda");
+        productArch = g_strdup("unknown architecture");
+        productPath = g_strdup("anaconda");
+        return;
+    }
+
+    /* .buildstamp uses the first 3 lines in this format:
+     *     STAMP.productArch
+     *     productName
+     *     productPath
+     */
+    lines = g_strsplit(contents, "\n", 0);
+    g_free(contents);
+
+    if ((lines != NULL) && (g_strv_length(lines) >= 3)) {
+        /* STAMP.productArch */
+        stamp = g_strsplit(lines[0], ".", 0);
+
+        if ((stamp != NULL) && (g_strv_length(stamp) == 2)) {
+            productArch = g_strdup(stamp[1]);
+        } else {
+            productArch = g_strdup("unknown architecture");
+        }
+
+        if (stamp) {
+            g_strfreev(stamp);
+        }
+
+        productName = g_strdup(lines[1]);
+        productPath = g_strdup(lines[2]);
+    } else {
+        productName = g_strdup("anaconda");
+        productArch = g_strdup("unknown architecture");
+        productPath = g_strdup("anaconda");
+    }
+
+    if (lines) {
+        g_strfreev(lines);
+    }
+
+    return;
+}
+
+char * getProductName(void) {
+    if (!productName) {
+       initProductInfo();
+    }
+    return productName;
+}
+
+char * getProductArch(void) {
+    if (!productArch) {
+       initProductInfo();
+    }
+    return productArch;
+}
+
+char * getProductPath(void) {
+    if (!productPath) {
+       initProductInfo();
+    }
+    return productPath;
+}
+
+void initializeConsole() {
+    /* enable UTF-8 console */
+    setenv("LANG", LANG_DEFAULT, 1);
+    printf("\033%%G");
+    fflush(stdout);
+
+    isysLoadFont();
+    isysSetUnicodeKeymap();
+}
+
+/* fbcon is buggy and resets our color palette if we allocate a terminal
+ * after initializing it, so we initialize 9 of them before we need them.
+ * If it doesn't work, the user gets to suffer through having an ugly palette,
+ * but things are still usable. */
+static void initializeTtys(void) {
+    int fd, n;
+    char dev[] = "/dev/ttyX";
+
+    for (n = 9; n > 0; n--) {
+	sprintf(dev, "/dev/tty%d", n);
+	mknod(dev, 0600 | S_IFCHR, makedev(4, n));
+	fd = open(dev, O_RDWR|O_NOCTTY);
+	if (fd >= 0) {
+	    ioctl(fd, VT_ACTIVATE, n);
+	    if (n == 1)
+		ioctl(fd, VT_WAITACTIVE, n);
+	    close(fd);
+	} else
+	    logMessage(ERROR, "failed to initialize %s", dev);
+    }
+}
+
+static void spawnShell(void) {
+    pid_t pid;
+
+    if (FL_SERIAL(flags) || FL_NOSHELL(flags)) {
+        logMessage(INFO, "not spawning a shell");
+        return;
+    } else if (access("/bin/sh",  X_OK))  {
+        logMessage(ERROR, "cannot open shell - /bin/sh doesn't exist");
+        return;
+    }
+
+    if (!(pid = fork())) {
+	int fd;
+
+    	fd = open("/dev/tty2", O_RDWR|O_NOCTTY);
+    	if (fd < 0) {
+            logMessage(ERROR, "cannot open /dev/tty2 -- no shell will be provided");
+	    return;
+	}
+
+        dup2(fd, 0);
+        dup2(fd, 1);
+        dup2(fd, 2);
+        
+        close(fd);
+        setsid();
+
+	/* enable UTF-8 console */
+	printf("\033%%G");
+	fflush(stdout);
+	isysLoadFont();
+	
+        if (ioctl(0, TIOCSCTTY, NULL)) {
+            logMessage(ERROR, "could not set new controlling tty");
+        }
+        
+        signal(SIGINT, SIG_DFL);
+        signal(SIGTSTP, SIG_DFL);
+
+        if (!access("/tmp/updates/pyrc.py", R_OK|X_OK))
+            setenv("PYTHONSTARTUP", "/tmp/updates/pyrc.py", 1);
+        else if (!access("/usr/share/anaconda/pyrc.py", R_OK|X_OK))
+            setenv("PYTHONSTARTUP", "/usr/share/anaconda/pyrc.py", 1);
+        setenv("LD_LIBRARY_PATH", LIBPATH, 1);
+        setenv("LANG", "C", 1);
+        
+        if (execl("/bin/sh", "-/bin/sh", NULL) == -1) {
+            logMessage(CRITICAL, "exec of /bin/sh failed: %m");
+            exit(1);
+        }
+    }
+
+    return;
+}
+
+
+static void copyWarnFn (char *msg) {
+   logMessage(WARNING, msg);
+}
+
+static void copyErrorFn (char *msg) {
+   newtWinMessage(_("Error"), _("OK"), _(msg));
+}
+
+void loadUpdates(struct loaderData_s *loaderData) {
+    char *device = NULL, *part = NULL, *buf;
+    char **devNames = NULL;
+    enum { UPD_DEVICE, UPD_PART, UPD_PROMPT, UPD_LOAD, UPD_DONE } stage = UPD_DEVICE;
+    int rc, num = 0;
+    int dir = 1;
+
+    while (stage != UPD_DONE) {
+        switch (stage) {
+        case UPD_DEVICE: {
+            rc = getRemovableDevices(&devNames);
+            if (rc == 0)
+                return;
+
+            /* we don't need to ask which to use if they only have one */
+            if (rc == 1) {
+                device = strdup(devNames[0]);
+                free(devNames);
+                devNames = NULL;
+                if (dir == -1)
+                    return;
+
+                stage = UPD_PART;
+                break;
+            }
+            dir = 1;
+
+            startNewt();
+            rc = newtWinMenu(_("Update Disk Source"),
+                             _("You have multiple devices which could serve "
+                               "as sources for an update disk.  Which would "
+                               "you like to use?"), 40, 10, 10,
+                             rc < 6 ? rc : 6, devNames,
+                             &num, _("OK"), _("Cancel"), NULL);
+
+            if (rc == 2) {
+                free(devNames);
+                devNames = NULL;
+                return;
+            }
+
+            device = strdup(devNames[num]);
+            free(devNames);
+            devNames = NULL;
+            stage = UPD_PART;
+        }
+
+        case UPD_PART: {
+            char ** part_list = getPartitionsList(device);
+            int nump = 0, num = 0;
+
+            if (part != NULL) {
+                free(part);
+                part = NULL;
+            }
+
+            if ((nump = lenPartitionsList(part_list)) == 0) {
+                if (dir == -1) {
+                    stage = UPD_DEVICE;
+                } else {
+                    checked_asprintf(&part, "/dev/%s", device);
+                    stage = UPD_PROMPT;
+                }
+
+                break;
+            }
+            dir = 1;
+
+            startNewt();
+            rc = newtWinMenu(_("Update Disk Source"),
+                             _("There are multiple partitions on this device "
+                               "which could contain the update disk image.  "
+                               "Which would you like to use?"), 40, 10, 10,
+                             nump < 6 ? nump : 6, part_list, &num, _("OK"),
+                             _("Back"), NULL);
+
+            if (rc == 2) {
+                freePartitionsList(part_list);
+                stage = UPD_DEVICE;
+                dir = -1;
+                break;
+            }
+
+            part = strdup(part_list[num]);
+            stage = UPD_LOAD;
+        }
+
+        case UPD_PROMPT:
+            checked_asprintf(&buf, _("Insert your updates disk into %s and "
+                                     "press \"OK\" to continue."), part);
+
+            rc = newtWinChoice(_("Updates Disk"), _("OK"), _("Back"), buf);
+            free(buf);
+            buf = NULL;
+
+            if (rc == 2) {
+                stage = UPD_PART;
+                dir = -1;
+                break;
+            }
+
+            stage = UPD_LOAD;
+            break;
+
+        case UPD_LOAD:
+            logMessage(INFO, "UPDATES device is %s", part);
+
+            if (doPwMount(part, "/tmp/update-disk", "auto", "ro", NULL)) {
+                newtWinMessage(_("Error"), _("OK"),
+                               _("Failed to mount updates disk"));
+                stage = UPD_PROMPT;
+                break;
+            } else {
+                /* Copy everything to /tmp/updates so we can unmount the disk  */
+                winStatus(40, 3, _("Updates"), _("Reading anaconda updates"));
+                if (!copyDirectory("/tmp/update-disk", "/tmp/updates", copyWarnFn,
+                                   copyErrorFn)) {
+                    dir = 1;
+                    stage = UPD_DONE;
+                }
+
+                newtPopWindow();
+                umount("/tmp/update-disk");
+            }
+
+        case UPD_DONE:
+            break;
+        }
+    }
+
+    return;
+}
+
+static char *newUpdatesLocation(const char *origLocation) {
+    const char *location;
+    char *retval = NULL;
+    newtComponent f, okay, cancel, answer, locationEntry;
+    newtGrid grid, buttons;
+
+    startNewt();
+
+    locationEntry = newtEntry(-1, -1, NULL, 60, &location, NEWT_FLAG_SCROLL);
+    newtEntrySet(locationEntry, origLocation, 1);
+
+    /* button bar at the bottom of the window */
+    buttons = newtButtonBar(_("OK"), &okay, _("Cancel"), &cancel, NULL);
+
+    grid = newtCreateGrid(1, 3);
+
+    newtGridSetField(grid, 0, 0, NEWT_GRID_COMPONENT,
+                     newtTextboxReflowed(-1, -1, _("Unable to download the updates image.  Please modify the updates location below or press Cancel to proceed without updates.."), 60, 0, 0, 0),
+                     0, 0, 0, 0, NEWT_ANCHOR_LEFT, 0);
+    newtGridSetField(grid, 0, 1, NEWT_GRID_COMPONENT, locationEntry,
+                     0, 1, 0, 0, NEWT_ANCHOR_LEFT, 0);
+    newtGridSetField(grid, 0, 2, NEWT_GRID_SUBGRID, buttons,
+                     0, 1, 0, 0, 0, NEWT_GRID_FLAG_GROWX);
+
+    f = newtForm(NULL, NULL, 0);
+    newtGridAddComponentsToForm(grid, f, 1);
+    newtGridWrappedWindow(grid, _("Error downloading updates image"));
+    newtGridFree(grid, 1);
+
+    /* run the form */
+    answer = newtRunForm(f);
+
+    if (answer != cancel)
+        retval = strdup(location);
+
+    newtFormDestroy(f);
+    newtPopWindow();
+
+    return retval;
+}
+
+static int loadUpdatesFromRemote(char * url, struct loaderData_s * loaderData) {
+    int rc = getFileFromUrl(url, "/tmp/updates.img", loaderData);
+
+    if (rc != 0) {
+        char *newLocation = newUpdatesLocation(url);
+
+        if (!newLocation)
+           return rc;
+        else
+           return loadUpdatesFromRemote(newLocation, loaderData);
+    }
+
+    copyUpdatesImg("/tmp/updates.img");
+    unlink("/tmp/updates.img");
+    return 0;
+}
+
+static void writeVNCPasswordFile(char *pfile, char *password) {
+    FILE *f;
+
+    f = fopen(pfile, "w+");
+    fprintf(f, "%s\n", password);
+    fclose(f);
+}
+
+/* read information from /etc/sysconfig/network-scripts/ifcfg-$INTERFACE
+ * (written by linuxrc), the linuxrc mess should be firing up NM too
+ */
+static void readNetInfo(struct loaderData_s ** ld) {
+    struct loaderData_s * loaderData = *ld;
+    char *cfgfile = NULL;
+    gchar *contents = NULL;
+    gchar **lines = NULL, **line = NULL;
+    GError *e = NULL;
+
+    /* when this function is called, the DEVICE environment variable
+     * contains the device name whose ifcfg file we want to read
+     */
+    if (!getenv("DEVICE")) {
+        return;
+    }
+
+    checked_asprintf(&cfgfile, "/etc/sysconfig/network-scripts/ifcfg-%s",
+                     getenv("DEVICE"));
+
+    /* make sure everything is NULL before we begin copying info */
+    loaderData->ipv4 = NULL;
+    loaderData->netmask = NULL;
+    loaderData->gateway = NULL;
+    loaderData->dns = NULL;
+    loaderData->peerid = NULL;
+    loaderData->subchannels = NULL;
+    loaderData->portname = NULL;
+    loaderData->nettype = NULL;
+    loaderData->ctcprot = NULL;
+    loaderData->layer2 = NULL;
+    loaderData->portno = NULL;
+    loaderData->macaddr = NULL;
+#ifdef ENABLE_IPV6
+    loaderData->ipv6 = NULL;
+    loaderData->gateway6 = NULL;
+#endif
+
+    /*
+     * The ifcfg file is written out by /sbin/init on s390x (which is
+     * really the linuxrc.s390 script).  It's a shell-sourcable file with
+     * various system settings needing for the system instance.
+     *
+     * The goal of this function is to read in only the network settings
+     * and populate the loaderData structure.
+     */
+    if (!g_file_get_contents(cfgfile, &contents, NULL, &e)) {
+        logMessage(ERROR, "error reading %s: %s", cfgfile, e->message);
+        g_error_free(e);
+        return;
+    }
+
+    line = lines = g_strsplit(contents, "\n", 0);
+    g_free(contents);
+
+    while (*line != NULL) {
+        gchar *tmp = g_strdup(*line);
+        gchar **pair = NULL;
+
+        if (!strstr(tmp, "=")) {
+            g_free(tmp);
+            line++;
+            continue;
+        }
+
+        tmp = g_strstrip(tmp);
+        pair = g_strsplit(tmp, "=", 0);
+
+        if (g_strv_length(pair) == 2) {
+            gchar *val = g_shell_unquote(pair[1], &e);
+
+            if (e != NULL) {
+                logMessage(WARNING,
+                           "error reading %s from %s (line=%s): %s",
+                           pair[0], cfgfile, tmp, e->message);
+                g_error_free(e);
+            } else {
+                if (!g_strcmp0(pair[0], "IPADDR")) {
+                    loaderData->ipv4 = strdup(val);
+                } else if (!g_strcmp0(pair[0], "NETMASK")) {
+                    loaderData->netmask = strdup(val);
+                } else if (!g_strcmp0(pair[0], "GATEWAY")) {
+                    loaderData->gateway = strdup(val);
+                } else if (!g_strcmp0(pair[0], "DNS")) {
+                    loaderData->dns = strdup(val);
+                } else if (!g_strcmp0(pair[0], "MTU")) {
+                    errno = 0;
+                    loaderData->mtu = strtol(val, NULL, 10);
+
+                    if ((errno == ERANGE && (loaderData->mtu == LONG_MIN ||
+                                             loaderData->mtu == LONG_MAX)) ||
+                        (errno != 0 && loaderData->mtu == 0)) {
+                        logMessage(ERROR, "%s: %d: %m", __func__, __LINE__);
+                        abort();
+                    }
+                } else if (!g_strcmp0(pair[0], "PEERID")) {
+                    loaderData->peerid = strdup(val);
+                } else if (!g_strcmp0(pair[0], "SUBCHANNELS")) {
+                    loaderData->subchannels = strdup(val);
+                } else if (!g_strcmp0(pair[0], "PORTNAME")) {
+                    loaderData->portname = strdup(val);
+                } else if (!g_strcmp0(pair[0], "NETTYPE")) {
+                    loaderData->nettype = strdup(val);
+                } else if (!g_strcmp0(pair[0], "CTCPROT")) {
+                    loaderData->ctcprot = strdup(val);
+                } else if (!g_strcmp0(pair[0], "LAYER2")) {
+                    loaderData->layer2 = strdup(val);
+                } else if (!g_strcmp0(pair[0], "PORTNO")) {
+                    loaderData->portno = strdup(val);
+                } else if (!g_strcmp0(pair[0], "MACADDR")) {
+                    loaderData->macaddr = strdup(val);
+                } else if (!g_strcmp0(pair[0], "HOSTNAME")) {
+                    loaderData->hostname = strdup(val);
+                }
+            }
+
+            g_free(val);
+        }
+
+        g_strfreev(pair);
+        g_free(tmp);
+        line++;
+    }
+
+    if (loaderData->ipv4 && loaderData->netmask) {
+        flags |= LOADER_FLAGS_HAVE_CMSCONF;
+    }
+
+    free(cfgfile);
+    g_strfreev(lines);
+    return;
+}
+
+/* parse anaconda or pxelinux-style ip= arguments
+ * pxelinux format: ip=<client-ip>:<boot-server-ip>:<gw-ip>:<netmask>
+ * anaconda format: ip=<client-ip> netmask=<netmask> gateway=<gw-ip>
+*/
+static void parseCmdLineIp(struct loaderData_s * loaderData, char *argv)
+{
+    /* Detect pxelinux */
+    if (strstr(argv, ":") != NULL) {
+        char *start, *end;
+
+        /* IP */
+        start = argv + 3;
+        end = strstr(start, ":");
+        loaderData->ipv4 = strndup(start, end-start);
+        loaderData->ipinfo_set = 1;
+
+        /* Boot server */
+        if (end + 1 == '\0')
+            return;
+        start = end + 1;
+        end = strstr(start, ":");
+        if (end == NULL)
+            return;
+
+        /* Gateway */
+        if (end + 1 == '\0')
+            return;
+        start = end + 1;
+        end = strstr(start, ":");
+        if (end == NULL) {
+            loaderData->gateway = strdup (start);
+            return;
+        } else {
+            loaderData->gateway = strndup(start, end-start);
+        }
+
+        /* Netmask */
+        if (end + 1 == '\0')
+            return;
+        start = end + 1;
+        loaderData->netmask = strdup(start);
+    } else {
+        loaderData->ipv4 = strdup(argv + 3);
+        loaderData->ipinfo_set = 1;
+    }
+
+    if (loaderData->ipinfo_set)
+        flags |= LOADER_FLAGS_IP_PARAM;
+}
+
+#ifdef ENABLE_IPV6
+/*
+ * parse anaconda ipv6= arguments
+ */
+static void parseCmdLineIpv6(struct loaderData_s * loaderData, char *argv)
+{
+    /* right now we only accept ipv6= arguments equal to:
+     *     dhcp     DHCPv6 call
+     *     auto     RFC 2461 neighbor discovery
+     */
+    loaderData->ipv6 = NULL;
+
+    if (!strncasecmp(argv, "ipv6=dhcp", 9)) {
+        loaderData->ipv6 = strdup("dhcp");
+    } else if (!strncasecmp(argv, "ipv6=auto", 9)) {
+        loaderData->ipv6 = strdup("auto");
+    }
+
+    if (loaderData->ipv6 != NULL) {
+        loaderData->ipv6info_set = 1;
+        flags |= LOADER_FLAGS_IPV6_PARAM;
+    }
+
+    return;
+}
+#endif
+
+static long argToLong(char *arg, int offset) {
+    long retval;
+
+    errno = 0;
+
+    retval = strtol(arg+offset, NULL, 10);
+    if ((errno == ERANGE && (retval == LONG_MIN || retval == LONG_MAX)) ||
+        (errno != 0 && retval == 0)) {
+        logMessage(ERROR, "%s: %d: %m", __func__, __LINE__);
+        abort();
+    }
+
+    return retval;
+}
+
+/* parses /proc/cmdline for any arguments which are important to us.  
+ * NOTE: in test mode, can specify a cmdline with --cmdline
+ */
+static void parseCmdLineFlags(struct loaderData_s * loaderData,
+                              char * cmdLine) {
+    int fd;
+    char buf[1024];
+    int len;
+    gint argc = 0;
+    gchar **argv = NULL;
+    GError *optErr = NULL;
+    int numExtraArgs = 0;
+    int i;
+    char *front;
+
+    /* we want to default to graphical and allow override with 'text' */
+    flags |= LOADER_FLAGS_GRAPHICAL;
+
+    /* if we have any explicit cmdline (probably test mode), we don't want
+     * to parse /proc/cmdline */
+    if (!cmdLine) {
+        if ((fd = open("/proc/cmdline", O_RDONLY)) < 0) return;
+        len = read(fd, buf, sizeof(buf) - 1);
+        close(fd);
+        if (len <= 0) {
+            logMessage(INFO, "kernel command line was empty");
+            return;
+        }
+        
+        buf[len] = '\0';
+        cmdLine = buf;
+    }
+
+    logMessage(INFO, "kernel command line: %s", cmdLine);
+    
+    if (!g_shell_parse_argv(cmdLine, &argc, &argv, &optErr)) {
+        g_error_free(optErr);
+        return;
+    }
+
+    for (i=0; i < argc; i++) {
+        if (!strcasecmp(argv[i], "askmethod"))
+            flags |= LOADER_FLAGS_ASKMETHOD;
+        else if (!strcasecmp(argv[i], "asknetwork"))
+            flags |= LOADER_FLAGS_ASKNETWORK;
+        else if (!strcasecmp(argv[i], "noshell"))
+            flags |= LOADER_FLAGS_NOSHELL;
+        else if (!strcasecmp(argv[i], "nokill"))
+            flags |= LOADER_FLAGS_NOKILL;
+        else if (!strcasecmp(argv[i], "mediacheck"))
+            flags |= LOADER_FLAGS_MEDIACHECK;
+        else if (!strcasecmp(argv[i], "allowwireless"))
+            flags |= LOADER_FLAGS_ALLOW_WIRELESS;
+        else if (!strcasecmp(argv[i], "telnet"))
+            flags |= LOADER_FLAGS_TELNETD;
+        else if (!strcasecmp(argv[i], "noprobe"))
+            flags |= LOADER_FLAGS_NOPROBE;
+        else if (!strcasecmp(argv[i], "text")) {
+            logMessage(INFO, "text mode forced from cmdline");
+            flags |= LOADER_FLAGS_TEXT;
+            flags &= ~LOADER_FLAGS_GRAPHICAL;
+        }
+        else if (!strcasecmp(argv[i], "graphical")) {
+            logMessage(INFO, "graphical mode forced from cmdline");
+            flags |= LOADER_FLAGS_GRAPHICAL;
+        } else if (!strcasecmp(argv[i], "cmdline")) {
+            logMessage(INFO, "cmdline mode forced from cmdline");
+            flags |= LOADER_FLAGS_CMDLINE;
+        } else if (!strncasecmp(argv[i], "updates=", 8))
+            loaderData->updatessrc = strdup(argv[i] + 8);
+        else if (!strncasecmp(argv[i], "updates", 7))
+            flags |= LOADER_FLAGS_UPDATES;
+        else if (!strncasecmp(argv[i], "dogtail=", 8))
+            loaderData->dogtailurl = strdup(argv[i] + 8);
+        else if (!strncasecmp(argv[i], "dd=", 3) || 
+                 !strncasecmp(argv[i], "driverdisk=", 11)) {
+            loaderData->ddsrc = strdup(argv[i] + 
+                                       (argv[i][1] == 'r' ? 11 : 3));
+        }
+        else if (!strcasecmp(argv[i], "dd") || 
+                 !strcasecmp(argv[i], "driverdisk"))
+            flags |= LOADER_FLAGS_MODDISK;
+        else if (!strcasecmp(argv[i], "dlabel=on"))
+            flags |= LOADER_FLAGS_AUTOMODDISK;
+        else if (!strcasecmp(argv[i], "dlabel=off"))
+            flags &= ~LOADER_FLAGS_AUTOMODDISK;
+        else if (!strcasecmp(argv[i], "rescue"))
+            flags |= LOADER_FLAGS_RESCUE;
+        else if (!strcasecmp(argv[i], "nopass"))
+            flags |= LOADER_FLAGS_NOPASS;
+        else if (!strcasecmp(argv[i], "serial")) 
+            flags |= LOADER_FLAGS_SERIAL;
+        else if (!strcasecmp(argv[i], "noipv4"))
+            flags |= LOADER_FLAGS_NOIPV4;
+#ifdef ENABLE_IPV6
+        else if (!strcasecmp(argv[i], "noipv6"))
+            flags |= LOADER_FLAGS_NOIPV6;
+#endif
+        else if (!strcasecmp(argv[i], "kssendmac"))
+            flags |= LOADER_FLAGS_KICKSTART_SEND_MAC;
+        else if (!strcasecmp(argv[i], "kssendsn"))
+            flags |= LOADER_FLAGS_KICKSTART_SEND_SERIAL;
+        /* deprecated hardware bits */
+        else if (!strcasecmp(argv[i], "nousbstorage"))
+            mlAddBlacklist("usb-storage");
+        else if (!strcasecmp(argv[i], "nousb")) {
+            mlAddBlacklist("ehci-hcd");
+            mlAddBlacklist("ohci-hcd");
+            mlAddBlacklist("uhci-hcd");
+        } else if (!strcasecmp(argv[i], "nofirewire"))
+            mlAddBlacklist("firewire-ohci");
+        else if (!strncasecmp(argv[i], "loglevel=", 9)) {
+            if (!strcasecmp(argv[i]+9, "debug")) {
+                loaderData->logLevel = strdup(argv[i]+9);
+                setLogLevel(DEBUGLVL);
+            }
+            else if (!strcasecmp(argv[i]+9, "info")) {
+                loaderData->logLevel = strdup(argv[i]+9);
+                setLogLevel(INFO);
+            }
+            else if (!strcasecmp(argv[i]+9, "warning")) {
+                loaderData->logLevel = strdup(argv[i]+9);
+                setLogLevel(WARNING);
+            }
+            else if (!strcasecmp(argv[i]+9, "error")) {
+                loaderData->logLevel = strdup(argv[i]+9);
+                setLogLevel(ERROR);
+            }
+            else if (!strcasecmp(argv[i]+9, "critical")) {
+                loaderData->logLevel = strdup(argv[i]+9);
+                setLogLevel(CRITICAL);
+            }
+        }
+        else if (!strncasecmp(argv[i], "ksdevice=", 9)) {
+            loaderData->netDev = strdup(argv[i] + 9);
+            loaderData->netDev_set = 1;
+        }
+        else if (!strncmp(argv[i], "BOOTIF=", 7)) {
+            /* +10 so that we skip over the leading 01- */
+            loaderData->bootIf = strdup(argv[i] + 10);
+
+            /* scan the BOOTIF value and replace '-' with ':' */
+            front = loaderData->bootIf;
+            if (front) {
+                while (*front != '\0') {
+                    if (*front == '-')
+                        *front = ':';
+                    front++;
+                }
+            }
+
+            loaderData->bootIf_set = 1;
+        } else if (!strncasecmp(argv[i], "dhcpclass=", 10)) {
+            loaderData->netCls = strdup(argv[i] + 10);
+            loaderData->netCls_set = 1;
+        }
+        else if (!strcasecmp(argv[i], "ks") || !strncasecmp(argv[i], "ks=", 3))
+            loaderData->ksFile = strdup(argv[i]);
+        else if (!strncasecmp(argv[i], "display=", 8))
+            setenv("DISPLAY", argv[i] + 8, 1);
+        else if ((!strncasecmp(argv[i], "lang=", 5)) && 
+                 (strlen(argv[i]) > 5))  {
+            loaderData->lang = strdup(argv[i] + 5);
+            loaderData->lang_set = 1;
+        }
+        else if (!strncasecmp(argv[i], "keymap=", 7) &&
+                   (strlen(argv[i]) > 7)) {
+            loaderData->kbd = strdup(argv[i] + 7);
+            loaderData->kbd_set = 1;
+        }
+        else if (!strncasecmp(argv[i], "method=", 7)) {
+            logMessage(WARNING, "method= is deprecated.  Please use repo= instead.");
+            loaderData->instRepo = strdup(argv[i] + 7);
+        }
+        else if (!strncasecmp(argv[i], "repo=", 5))
+            loaderData->instRepo = strdup(argv[i] + 5);
+        else if (!strncasecmp(argv[i], "stage2=", 7))
+            setStage2LocFromCmdline(argv[i] + 7, loaderData);
+        else if (!strncasecmp(argv[i], "hostname=", 9))
+            loaderData->hostname = strdup(argv[i] + 9);
+        else if (!strncasecmp(argv[i], "ip=", 3))
+            parseCmdLineIp(loaderData, argv[i]);
+#ifdef ENABLE_IPV6
+        else if (!strncasecmp(argv[i], "ipv6=", 5))
+            parseCmdLineIpv6(loaderData, argv[i]);
+#endif
+        else if (!strncasecmp(argv[i], "netmask=", 8))
+            loaderData->netmask = strdup(argv[i] + 8);
+        else if (!strncasecmp(argv[i], "gateway=", 8))
+            loaderData->gateway = strdup(argv[i] + 8);
+        else if (!strncasecmp(argv[i], "dns=", 4))
+            loaderData->dns = strdup(argv[i] + 4);
+        else if (!strncasecmp(argv[i], "ethtool=", 8))
+            loaderData->ethtool = strdup(argv[i] + 8);
+        else if (!strncasecmp(argv[i], "essid=", 6))
+            loaderData->essid = strdup(argv[i] + 6);
+        else if (!strncasecmp(argv[i], "mtu=", 4))
+            loaderData->mtu = argToLong(argv[i], 4);
+        else if (!strncasecmp(argv[i], "wepkey=", 7))
+            loaderData->wepkey = strdup(argv[i] + 7);
+        else if (!strncasecmp(argv[i], "linksleep=", 10))
+            num_link_checks = argToLong(argv[i], 10);
+        else if (!strncasecmp(argv[i], "nicdelay=", 9))
+            post_link_sleep = argToLong(argv[i], 9);
+        else if (!strncasecmp(argv[i], "dhcptimeout=", 12))
+            loaderData->dhcpTimeout = argToLong(argv[i], 12);
+        else if (!strncasecmp(argv[i], "selinux=0", 9))
+            flags &= ~LOADER_FLAGS_SELINUX;
+        else if (!strncasecmp(argv[i], "selinux", 7))
+            flags |= LOADER_FLAGS_SELINUX;
+        else if (!strncasecmp(argv[i], "gdb=", 4))
+            loaderData->gdbServer = strdup(argv[i] + 4);
+        else if (!strncasecmp(argv[i], "proxy=", 6))
+            splitProxyParam(argv[i]+6, &loaderData->proxyUser,
+                            &loaderData->proxyPassword, &loaderData->proxy);
+        else if (numExtraArgs < (MAX_EXTRA_ARGS - 1)) {
+            /* go through and append args we just want to pass on to */
+            /* the anaconda script, but don't want to represent as a */
+            /* LOADER_FLAGS_XXX since loader doesn't care about these */
+            /* particular options.                                   */
+            /* do vncpassword case first */
+            if (!strncasecmp(argv[i], "vncpassword=", 12)) {
+                writeVNCPasswordFile("/tmp/vncpassword.dat", argv[i]+12);
+            }
+            else if (!strncasecmp(argv[i], "resolution=", 11) ||
+                     !strncasecmp(argv[i], "nomount", 7) ||
+                     !strncasecmp(argv[i], "vnc", 3) ||
+                     !strncasecmp(argv[i], "vncconnect=", 11) ||
+                     !strncasecmp(argv[i], "headless", 8) ||
+                     !strncasecmp(argv[i], "usefbx", 6) ||
+                     !strncasecmp(argv[i], "mpath", 6) ||
+                     !strncasecmp(argv[i], "nompath", 8) ||
+                     !strncasecmp(argv[i], "dmraid", 6) ||
+                     !strncasecmp(argv[i], "nodmraid", 8) ||
+                     !strncasecmp(argv[i], "xdriver=", 8) ||
+                     !strncasecmp(argv[i], "vesa", 4) ||
+                     !strncasecmp(argv[i], "syslog=", 7)) { 
+
+                /* vnc implies graphical */
+                if (!strncasecmp(argv[i], "vnc", 3)) {
+                    logMessage(INFO, "vnc forced graphical mode from cmdline");
+                    flags |= LOADER_FLAGS_GRAPHICAL;
+                }
+
+                /* the following things require networking to be configured
+                 * by loader, so an active connection is ready once we get
+                 * to anaconda
+                 */
+                if (!strncasecmp(argv[i], "syslog", 6) ||
+                    !strncasecmp(argv[i], "vnc", 3)) {
+                    logMessage(INFO, "early networking required for %s",
+                               argv[i]);
+                    flags |= LOADER_FLAGS_EARLY_NETWORKING;
+                }
+                if (isKickstartFileRemote(loaderData->ksFile)) {
+                    logMessage(INFO, "early networking required for remote kickstart configuration");
+                    flags |= LOADER_FLAGS_EARLY_NETWORKING;
+                }
+
+                if (!strncasecmp(argv[i], "vesa", 4)) {
+                    checked_asprintf(&extraArgs[numExtraArgs],
+                                     "--xdriver=vesa");
+
+                    logMessage(WARNING, "\"vesa\" command line argument is deprecated.  use \"xdriver=vesa\".");
+                } else {
+                    checked_asprintf(&extraArgs[numExtraArgs],"--%s",
+                                     argv[i]);
+                }
+
+                numExtraArgs += 1;
+
+                if (numExtraArgs > (MAX_EXTRA_ARGS - 2)) {
+                     logMessage(WARNING, "Too many command line arguments (max "
+                                "allowed is %d), rest will be dropped.",
+                                MAX_EXTRA_ARGS);
+                }
+            }
+        }
+    }
+
+    readNetInfo(&loaderData);
+
+    /* NULL terminates the array of extra args */
+    extraArgs[numExtraArgs] = NULL;
+
+    return;
+}
+
+/* make sure they have enough ram */
+static void checkForRam(void) {
+    if (totalMemory() < MIN_RAM) {
+        char *buf;
+
+        checked_asprintf(&buf, _("You do not have enough RAM to install %s "
+                                 "on this machine."), getProductName());
+
+        startNewt();
+        newtWinMessage(_("Error"), _("OK"), buf);
+        free(buf);
+        stopNewt();
+        doExit(0);
+    }
+}
+
+static int haveDeviceOfType(int type) {
+    struct device ** devices;
+
+    devices = getDevices(type);
+    if (devices) {
+        return 1;
+    }
+    return 0;
+}
+
+static char *doLoaderMain(struct loaderData_s *loaderData,
+                          moduleInfoSet modInfo) {
+    enum { STEP_LANG, STEP_KBD, STEP_METHOD, STEP_DRIVER,
+           STEP_DRIVERDISK, STEP_NETWORK, STEP_IFACE,
+           STEP_IP, STEP_STAGE2, STEP_DONE } step;
+
+    char *url = NULL, *ret = NULL, *devName = NULL, *kbdtype = NULL;
+    static iface_t iface;
+    int i, rc = LOADER_NOOP, dir = 1;
+    int needsNetwork = 0, class = -1;
+    int skipMethodDialog = 0, skipLangKbd = 0;
+
+    char *installNames[10];
+    int numValidMethods = 0;
+    int validMethods[10];
+
+    for (i = 0; i < numMethods; i++, numValidMethods++) {
+        installNames[numValidMethods] = installMethods[i].name;
+        validMethods[numValidMethods] = i;
+    }
+    installNames[numValidMethods] = NULL;
+
+    /* Before anything else, see if there's a CD/DVD with a stage2 image on
+     * it.  However if stage2= was given, use that value as an override here.
+     * That will also then bypass any method selection UI in loader.
+     */
+    if (!FL_ASKMETHOD(flags)) {
+        url = findAnacondaCD("/mnt/stage2");
+        if (url) {
+            setStage2LocFromCmdline(url, loaderData);
+            skipMethodDialog = 1;
+
+            logMessage(INFO, "Detected stage 2 image on CD (url: %s)", url);
+            winStatus(50, 3, _("Media Detected"),
+                      _("Found local installation media"), 0);
+            sleep(3);
+            newtPopWindow();
+
+            skipLangKbd = 1;
+            flags |= LOADER_FLAGS_NOPASS;
+        } else if (!loaderData->stage2Data && loaderData->instRepo) {
+            /* If no CD/DVD with a stage2 image was found and we were given a
+             * repo=/method= parameter, try to piece together a valid setting
+             * for the stage2= parameter based on that.
+             */
+            char *tmp;
+
+            checked_asprintf(&tmp, "%s/images/install.img",
+                             loaderData->instRepo);
+
+            logMessage(INFO, "no stage2= given, assuming %s", tmp);
+            setStage2LocFromCmdline(tmp, loaderData);
+            free(tmp);
+
+            /* If we had to infer a stage2= location, but the repo= parameter
+             * we based this guess on was wrong, we need to correct the typo
+             * in both places.  Unfortunately we can't really know what the
+             * user meant, so the best we can do is take the results of
+             * running stage2= through the UI and chop off any /images/whatever
+             * path that's at the end of it.
+             */
+            loaderData->inferredStage2 = 1;
+            if (loaderData->method != -1) {
+                skipMethodDialog = 1;
+            }
+        } else if (loaderData->stage2Data) {
+            skipMethodDialog = 1;
+        }
+    } else {
+        /* Needed because they have already been set when parsing cmdline.
+         * (Leaks a little.)
+         */
+        loaderData->method = -1;
+        loaderData->stage2Data = NULL;
+    }
+
+    i = 0;
+    step = STEP_LANG;
+
+    while (step != STEP_DONE) {
+        switch(step) {
+            case STEP_LANG: {
+                if (loaderData->lang && (loaderData->lang_set == 1))
+                    setLanguage(loaderData->lang, 1);
+                else if (FL_RESCUE(flags) || !skipLangKbd)
+                    chooseLanguage(&loaderData->lang);
+
+                step = STEP_KBD;
+                dir = 1;
+                break;
+            }
+
+            case STEP_KBD: {
+                if (loaderData->kbd && (loaderData->kbd_set == 1)) {
+                    /* JKFIXME: this is broken -- we should tell of the 
+                     * failure; best by pulling code out in kbd.c to use */
+                    if (isysLoadKeymap(loaderData->kbd)) {
+                        logMessage(WARNING, "requested keymap %s is not valid, asking",
+                                   loaderData->kbd);
+                        loaderData->kbd = NULL;
+                        loaderData->kbd_set = 0;
+                        break;
+                    }
+                    rc = LOADER_NOOP;
+                } else if (FL_RESCUE(flags) || !skipLangKbd) {
+                    /* JKFIXME: should handle kbdtype, too probably... but it 
+                     * just matters for sparc */
+                    if (!FL_CMDLINE(flags))
+                        rc = chooseKeyboard(loaderData, &kbdtype);
+                    else
+                       rc = LOADER_NOOP;
+                } else {
+                    step = STEP_METHOD;
+                    dir = 1;
+                }
+
+                if (rc == LOADER_NOOP) {
+                    if (dir == -1)
+                        step = STEP_LANG;
+                    else
+                        step = STEP_METHOD;
+
+                    break;
+                }
+
+                if (rc == LOADER_BACK) {
+                    step = STEP_LANG;
+                    dir = -1;
+                } else {
+                    step = STEP_METHOD;
+                    dir = 1;
+                }
+
+                break;
+            }
+
+            case STEP_METHOD: {
+                if (loaderData->method != -1)
+                    skipMethodDialog = 1;
+                else if (FL_CMDLINE(flags)) {
+                    fprintf(stderr, "No method given for cmdline mode, aborting\n");
+                    doExit(EXIT_FAILURE);
+                }
+
+                /* If we already found a stage2 image, skip the prompt. */
+                if (skipMethodDialog) {
+                    if (dir == 1)
+                        rc = 1;
+                    else
+                        rc = -1;
+                } else {
+                    /* we need to set these each time through so that we get
+                     * updated for language changes (#83672) */
+                    for (i = 0; i < numMethods; i++) {
+                        installNames[i] = _(installMethods[i].name);
+                    }
+                    installNames[i] = NULL;
+
+                    rc = newtWinMenu(FL_RESCUE(flags) ? _("Rescue Method") :
+                                     _("Installation Method"),
+                                     FL_RESCUE(flags) ?
+                                     _("What type of media contains the rescue "
+                                       "image?") :
+                                     _("What type of media contains the installation "
+                                       "image?"),
+                                     30, 10, 20, 6, installNames, &loaderData->method,
+                                     _("OK"), _("Back"), NULL);
+                    if (rc == 2) {
+                        loaderData->method = -1;
+                    }
+                }
+
+                if (rc && (rc != 1)) {
+                    step = STEP_KBD;
+                    dir = -1;
+                } else {
+                    class = installMethods[validMethods[loaderData->method]].type;
+                    step = STEP_DRIVER;
+                    dir = 1;
+                }
+                break;
+            }
+
+            case STEP_DRIVER: {
+                if ((FL_EARLY_NETWORKING(flags) && haveDeviceOfType(DEVICE_NETWORK)) ||
+                    (class == -1 || haveDeviceOfType(class))) {
+                    step = STEP_NETWORK;
+                    dir = 1;
+                    class = -1;
+                    break;
+                }
+
+                if (skipLangKbd) {
+                    skipLangKbd = 0;
+                    step = STEP_KBD;
+                    break;
+                }
+
+                rc = newtWinTernary(_("No driver found"), _("Select driver"),
+                                    _("Use a driver disk"), _("Back"),
+                                    _("Unable to find any devices of the type "
+                                      "needed for this installation type.  "
+                                      "Would you like to manually select your "
+                                      "driver or use a driver disk?"));
+                if (rc == 2) {
+                    step = STEP_DRIVERDISK;
+                    dir = 1;
+                    break;
+                } else if (rc == 3) {
+                    step = STEP_METHOD;
+                    loaderData->method = -1;
+                    dir = -1;
+                    break;
+                }
+
+                chooseManualDriver(installMethods[validMethods[loaderData->method]].type,
+                                   loaderData);
+                /* it doesn't really matter what we return here; we just want
+                 * to reprobe and make sure we have the driver */
+                step = STEP_DRIVER;
+                break;
+            }
+
+            case STEP_DRIVERDISK: {
+                if (skipLangKbd) {
+                    skipLangKbd = 0;
+                    step = STEP_KBD;
+                    break;
+                }
+
+                rc = loadDriverFromMedia(class, loaderData, 0, 0, NULL);
+                if (rc == LOADER_BACK) {
+                    step = STEP_DRIVER;
+                    dir = -1;
+                    break;
+                }
+
+                /* need to come back to driver so that we can ensure that we found
+                 * the right kind of driver after loading the driver disk */
+                step = STEP_DRIVER;
+                break;
+            }
+
+            case STEP_NETWORK: {
+                if (((installMethods[validMethods[loaderData->method]].type !=
+                       DEVICE_NETWORK) && (!hasGraphicalOverride()) &&
+                      !FL_ASKNETWORK(flags) &&
+                      !FL_EARLY_NETWORKING(flags)) ||
+                     (is_nm_connected())) {
+                    needsNetwork = 0;
+                    if (dir == 1) 
+                        step = STEP_STAGE2;
+                    else if (dir == -1)
+                        step = STEP_METHOD;
+                    break;
+                }
+
+                needsNetwork = 1;
+                if (!haveDeviceOfType(DEVICE_NETWORK)) {
+                    class = DEVICE_NETWORK;
+                    step = STEP_DRIVER;
+                    break;
+                }
+                logMessage(INFO, "need to set up networking");
+
+                memset(&iface, 0, sizeof(iface));
+
+                /* fall through to interface selection */
+            }
+
+            case STEP_IFACE: {
+                logMessage(INFO, "going to pick interface");
+
+                /* skip configureTCPIP() screen for kickstart (#260621) */
+                if (loaderData->ksFile)
+                    flags |= LOADER_FLAGS_IS_KICKSTART;
+
+                if (FL_HAVE_CMSCONF(flags)) {
+                    loaderData->ipinfo_set = 1;
+#ifdef ENABLE_IPV6
+                    loaderData->ipv6info_set = 1;
+#endif
+                }
+
+                rc = chooseNetworkInterface(loaderData);
+                if ((rc == LOADER_BACK) || (rc == LOADER_ERROR) ||
+                    ((dir == -1) && (rc == LOADER_NOOP))) {
+                    /* don't skip method dialog iff we don't have url from ks or boot params */
+                    if (!loaderData->stage2Data) {
+                        loaderData->method = -1;
+                    }
+                    step = STEP_METHOD;
+                    dir = -1;
+                    break;
+                }
+
+                devName = loaderData->netDev;
+                strcpy(iface.device, devName);
+
+                /* continue to ip config */
+                step = STEP_IP;
+                dir = 1;
+                break;
+            }
+
+            case STEP_IP: {
+                if (!needsNetwork || dir == -1) {
+                    step = STEP_METHOD; /* only hit going back */
+                    break;
+                }
+
+                if ((ret = malloc(INET6_ADDRSTRLEN+1)) == NULL) {
+                    logMessage(ERROR, "malloc failure for ret in STEP_IP");
+                    doExit(EXIT_FAILURE);
+                }
+
+                logMessage(INFO, "going to do getNetConfig");
+
+                /* s390 provides all config info by way of the CMS conf file */
+                if (FL_HAVE_CMSCONF(flags)) {
+                    loaderData->ipinfo_set = 1;
+#ifdef ENABLE_IPV6
+                    loaderData->ipv6info_set = 1;
+#endif
+                }
+
+                /* populate netDev based on any kickstart data */
+                setupIfaceStruct(&iface, loaderData);
+                rc = readNetConfig(devName, &iface, loaderData->netCls, loaderData->method);
+
+                /* set the hostname if we have that */
+                if (loaderData->hostname) {
+                    if (sethostname(loaderData->hostname,
+                                    strlen(loaderData->hostname))) {
+                        logMessage(ERROR, "error setting hostname to %s",
+                                   loaderData->hostname);
+                    }
+                }
+
+                free(ret);
+                ret = NULL;
+
+                if ((rc == LOADER_BACK) ||
+                    ((dir == -1) && (rc == LOADER_NOOP))) {
+                    needsNetwork = 1;
+                    step = STEP_IFACE;
+                    dir = -1;
+                    break;
+                }
+                /* retry */
+                if (rc == LOADER_ERROR) {
+                    needsNetwork = 1;
+                    break;
+                }
+
+                writeEnabledNetInfo(&iface);
+                step = STEP_STAGE2;
+                dir = 1;
+                break;
+            }
+
+            case STEP_STAGE2: {
+                if (url) {
+                    logMessage(INFO, "stage2 url is %s", url);
+                    return url;
+                }
+
+                logMessage(INFO, "starting STEP_STAGE2");
+                url = installMethods[validMethods[loaderData->method]].mountImage(
+                                          installMethods + validMethods[loaderData->method],
+                                          "/mnt/stage2", loaderData);
+                if (!url) {
+                    step = STEP_IP;
+                    loaderData->ipinfo_set = 0;
+#ifdef ENABLE_IPV6
+                    loaderData->ipv6info_set = 0;
+#endif
+                    loaderData->method = -1;
+                    skipMethodDialog = 0;
+                    dir = -1;
+                } else {
+                    logMessage(INFO, "got stage2 at url %s", url);
+                    step = STEP_DONE;
+                    dir = 1;
+
+                    if (loaderData->invalidRepoParam) {
+                        char *newInstRepo;
+
+                        /* Doesn't contain /images?  Let's not even try. */
+                        if (strstr(url, "/images") == NULL)
+                            break;
+                        
+                        checked_asprintf(&newInstRepo, "%.*s",
+                                         (int) (strstr(url, "/images")-url), url);
+
+                        free(loaderData->instRepo);
+                        loaderData->instRepo = newInstRepo;
+                        logMessage(INFO, "reset repo= parameter to %s",
+                                   loaderData->instRepo);
+                    }
+                }
+
+                break;
+            }
+
+            case STEP_DONE:
+                break;
+        }
+    }
+
+    return url;
+}
+static int manualDeviceCheck(struct loaderData_s *loaderData) {
+    char ** devices;
+    int i, j, rc, num = 0;
+    unsigned int width = 40;
+    char * buf;
+
+    do {
+        /* FIXME */
+        devices = malloc(1 * sizeof(*devices));
+        j = 0;
+        devices[j] = NULL;
+
+        if (width > 70)
+            width = 70;
+
+        if (j > 0) {
+            buf = _("The following devices have been found on your system.");
+        } else {
+            buf = _("No device drivers have been loaded for your system.  "
+                    "Would you like to load any now?");
+        }
+
+        rc = newtWinMenu(_("Devices"), buf, width, 10, 20, 
+                         (j > 6) ? 6 : j, devices, &num, _("Done"), 
+                         _("Add Device"), NULL);
+
+        /* no leaky */
+        for (i = 0; i < j; i++)
+            free(devices[j]);
+        free(devices);
+
+        if (rc != 2)
+            break;
+
+        chooseManualDriver(DEVICE_ANY, loaderData);
+    } while (1);
+    return 0;
+}
+
+/* JKFIXME: I don't really like this, but at least it isolates the ifdefs */
+/* Either move dirname to %s_old or unlink depending on arch (unlink on all
+ * !s390{,x} arches).  symlink to /mnt/runtime/dirname.  dirname *MUST* start
+ * with a '/' */
+static void migrate_runtime_directory(char * dirname) {
+    char * runtimedir;
+    int ret;
+
+    checked_asprintf(&runtimedir, "/mnt/runtime%s", dirname);
+
+    if (!access(runtimedir, X_OK)) {
+        if (unlink(dirname) == -1) {
+            char * olddir;
+            
+            checked_asprintf(&olddir, "%s_old", dirname);
+
+            ret = rename(dirname, olddir);
+            free(olddir);
+        }
+        ret = symlink(runtimedir, dirname);
+    }
+    free(runtimedir);
+}
+
+
+static int hasGraphicalOverride() {
+    int i;
+
+    if (getenv("DISPLAY"))
+        return 1;
+
+    for (i = 0; extraArgs[i] != NULL; i++) {
+        if (!strncasecmp(extraArgs[i], "--vnc", 5))
+            return 1;
+    }
+    return 0;
+}
+
+void loaderSegvHandler(int signum) {
+    void *array[30];
+    size_t i;
+    const char const * const errmsgs[] = {
+        "loader received SIG",
+        "!  Backtrace:\n",
+        "Loader exited unexpectedly!  Backtrace:\n",
+    };
+
+    /* XXX This should really be in a glibc header somewhere... */
+    extern const char *const sys_sigabbrev[NSIG];
+
+    signal(signum, SIG_DFL); /* back to default */
+
+    newtFinished();
+    if (signum == 0) {
+        i = write(STDERR_FILENO, errmsgs[2], strlen(errmsgs[2]));
+    } else {
+        i = write(STDERR_FILENO, errmsgs[0], strlen(errmsgs[0]));
+        i = write(STDERR_FILENO, sys_sigabbrev[signum],
+                strlen(sys_sigabbrev[signum]));
+        i = write(STDERR_FILENO, errmsgs[1], strlen(errmsgs[1]));
+    }
+
+    i = backtrace (array, 30);
+    backtrace_symbols_fd(array, i, STDERR_FILENO);
+    _exit(1);
+}
+
+void loaderExitHandler(void)
+{
+    if (expected_exit)
+        return;
+
+    loaderSegvHandler(0);    
+}
+
+static void setupBacktrace(void)
+{
+    void *array;
+
+    signal(SIGSEGV, loaderSegvHandler);
+    signal(SIGABRT, loaderSegvHandler);
+    atexit(loaderExitHandler);
+
+    /* Turns out, there's an initializer at the top of backtrace() that
+     * (on some arches) calls dlopen(). dlopen(), unsurprisingly, calls
+     * malloc(). So, call backtrace() early in signal handler setup so
+     * we can later safely call it from the signal handler itself. */
+    backtrace(&array, 1);
+}
+
+void loaderUsrXHandler(int signum) {
+    logMessage(INFO, "Remembering signal %d\n", signum);
+    init_sig = signum;
+}
+
+static int anaconda_trace_init(void) {
+#ifdef USE_MTRACE
+    setenv("MALLOC_TRACE","/malloc",1);
+    mtrace();
+#endif
+    /* We have to do this before we init bogl(), which doLoaderMain will do
+     * when setting fonts for different languages.  It's also best if this
+     * is well before we might take a SEGV, so they'll go to tty8 */
+    initializeTtys();
+
+    /* set up signal handler */
+    setupBacktrace();
+
+    return 0;
+}
+
+static void add_to_path_env(const char *env, const char *val)
+{
+    char *oldenv, *newenv;
+
+    oldenv = getenv(env);
+    if (oldenv) {
+        checked_asprintf(&newenv, "%s:%s", val, oldenv);
+
+        oldenv = strdupa(newenv);
+        free(newenv);
+        newenv = oldenv;
+    } else {
+        newenv = strdupa(val);
+    }
+
+    setenv(env, newenv, 1);
+}
+
+static void loadScsiDhModules(void)
+{
+    struct utsname utsname;
+    char *modules = NULL;
+    char *tmp = NULL;
+    struct dirent *ent = NULL;
+
+    uname(&utsname);
+    checked_asprintf(&tmp,
+        "/lib/modules/%s/kernel/drivers/scsi/device_handler", utsname.release);
+
+    DIR *dir = opendir(tmp);
+    free(tmp);
+    if (!dir)
+        return;
+
+    int fd = dirfd(dir);
+    while ((ent = readdir(dir)) != NULL) {
+        struct stat sb;
+
+        if (fstatat(fd, ent->d_name, &sb, 0) < 0)
+            continue;
+
+        size_t len = strlen(ent->d_name) - 3;
+        if (strcmp(ent->d_name+len, ".ko"))
+            continue;
+
+        if (S_ISREG(sb.st_mode)) {
+            char modname[len+1];
+            strncpy(modname, ent->d_name, len);
+	    modname[len] = '\0';
+
+            if (modules && modules[0]) {
+                checked_asprintf(&tmp, "%s:%s", modules, modname);
+            } else {
+                checked_asprintf(&tmp, "%s", modname);
+            }
+
+            free(modules);
+            modules = tmp;
+        }
+    }
+    closedir(dir);
+
+    mlLoadModuleSet(modules);
+    free(modules);
+}
+
+int main(int argc, char ** argv) {
+    int rc, ret, pid, status;
+
+    struct stat sb;
+    struct serial_struct si;
+    char * arg;
+    FILE *f;
+
+    char twelve = 12;
+
+    moduleInfoSet modInfo;
+    iface_t iface;
+
+    char *url = NULL;
+
+    char ** argptr, ** tmparg;
+    char * anacondaArgs[50];
+
+    struct loaderData_s loaderData;
+
+    char *path, *fmt;
+    GSList *dd, *dditer;
+    GTree *moduleState;
+
+    gchar *cmdLine = NULL, *ksFile = NULL, *virtpcon = NULL;
+    gboolean mediacheck = FALSE;
+    gchar **remaining = NULL;
+    GOptionContext *optCon = g_option_context_new(NULL);
+    GError *optErr = NULL;
+    GOptionEntry optionTable[] = {
+        { "cmdline", 0, 0, G_OPTION_ARG_STRING, &cmdLine, NULL, NULL },
+        { "ksfile", 0, 0, G_OPTION_ARG_STRING, &ksFile, NULL, NULL },
+        { "mediacheck", 0, 0, G_OPTION_ARG_NONE, &mediacheck, NULL, NULL },
+        { "virtpconsole", 0, 0, G_OPTION_ARG_STRING, &virtpcon, NULL, NULL },
+        { G_OPTION_REMAINING, 0, 0, G_OPTION_ARG_STRING_ARRAY, &remaining,
+          NULL, NULL },
+        { NULL },
+    };
+
+    /* get init PID if we have it */
+    if ((f = fopen("/var/run/init.pid", "r")) != NULL) {
+        char linebuf[256];
+
+        while (fgets(linebuf, sizeof(linebuf), f) != NULL) {
+            errno = 0;
+            init_pid = strtol(linebuf, NULL, 10);
+            if (errno == EINVAL || errno == ERANGE) {
+                logMessage(ERROR, "%s (%d): %m", __func__, __LINE__);
+                init_pid = 1;
+            }
+        }
+
+        fclose(f);
+    }
+
+    signal(SIGUSR1, loaderUsrXHandler);
+    signal(SIGUSR2, loaderUsrXHandler);
+
+    /* Make sure sort order is right. */
+    setenv ("LC_COLLATE", "C", 1);	
+
+    /* Very first thing, set up tracebacks and debug features. */
+    rc = anaconda_trace_init();
+
+    /* now we parse command line options */
+    g_option_context_set_help_enabled(optCon, FALSE);
+    g_option_context_add_main_entries(optCon, optionTable, NULL);
+
+    if (!g_option_context_parse(optCon, &argc, &argv, &optErr)) {
+        fprintf(stderr, "bad option: %s\n", optErr->message);
+        g_error_free(optErr);
+        g_option_context_free(optCon);
+        doExit(1);
+    }
+
+    g_option_context_free(optCon);
+
+    if (remaining) {
+        fprintf(stderr, "unexpected argument: %s\n", remaining[0]);
+        g_strfreev(remaining);
+        doExit(1);
+    }
+
+    g_strfreev(remaining);
+
+    if (!access("/var/run/loader.run", R_OK)) {
+        printf(_("loader has already been run.  Starting shell.\n"));
+        execl("/bin/sh", "-/bin/sh", NULL);
+        doExit(0);
+    }
+
+    f = fopen("/var/run/loader.run", "w+");
+    fprintf(f, "%d\n", getpid());
+    fclose(f);
+
+    /* The fstat checks disallows serial console if we're running through
+       a pty. This is handy for Japanese. */
+    fstat(0, &sb);
+    if (major(sb.st_rdev) != 3 && major(sb.st_rdev) != 136 && 
+        (virtpcon == NULL)){
+        if ((ioctl (0, TIOCLINUX, &twelve) < 0) && 
+            (ioctl(0, TIOCGSERIAL, &si) != -1))
+            flags |= LOADER_FLAGS_SERIAL;
+    }
+
+    if (mediacheck) flags |= LOADER_FLAGS_MEDIACHECK;
+    if (ksFile) flags |= LOADER_FLAGS_KICKSTART;
+    if (virtpcon) flags |= LOADER_FLAGS_VIRTPCONSOLE;
+
+    /* uncomment to send mac address in ks=http:/ header by default*/
+    flags |= LOADER_FLAGS_KICKSTART_SEND_MAC;
+
+    /* JKFIXME: I do NOT like this... it also looks kind of bogus */
+#if defined(__s390__) || defined(__s390x__)
+    flags |= LOADER_FLAGS_NOSHELL;
+#endif
+
+    openLog();
+    
+    /* XXX if RHEL, enable the AUTODD feature by default,
+     * but we should come with more general way how to control this */
+    if (!strncmp(getProductName(), "Red Hat", 7)) {
+        flags |= LOADER_FLAGS_AUTOMODDISK;
+    }
+
+    memset(&loaderData, 0, sizeof(loaderData));
+    loaderData.method = -1;
+    loaderData.fw_loader_pid = -1;
+    loaderData.fw_search_pathz_len = -1;
+    loaderData.dhcpTimeout = -1;
+
+    extraArgs[0] = NULL;
+    parseCmdLineFlags(&loaderData, cmdLine);
+
+    logMessage(INFO, "anaconda version %s on %s starting", VERSION, getProductArch());
+
+    if ((FL_SERIAL(flags) || FL_VIRTPCONSOLE(flags)) && 
+        !hasGraphicalOverride()) {
+        logMessage(INFO, "text mode forced due to serial/virtpconsole");
+        flags |= LOADER_FLAGS_TEXT;
+    }
+    set_fw_search_path(&loaderData, "/firmware:/lib/firmware");
+    start_fw_loader(&loaderData);
+
+    arg = "/lib/modules/module-info";
+    modInfo = newModuleInfoSet();
+    if (readModuleInfo(arg, modInfo, NULL, 0)) {
+        fprintf(stderr, "failed to read %s\n", arg);
+        sleep(5);
+        stop_fw_loader(&loaderData);
+        doExit(1);
+    }
+    initializeConsole();
+
+    checkForRam();
+
+    /* iSeries vio console users will be ssh'ing in to the primary
+       partition, so use a terminal type that is appripriate */
+    if (isVioConsole())
+        setenv("TERM", "vt100", 1);
+
+    mlLoadModuleSet("cramfs:squashfs:iscsi_tcp");
+
+    loadScsiDhModules();
+
+#if !defined(__s390__) && !defined(__s390x__)
+    mlLoadModuleSet("floppy:edd:pcspkr:iscsi_ibft");
+#endif
+
+#ifdef ENABLE_IPV6
+    if (!FL_NOIPV6(flags))
+        mlLoadModule("ipv6", NULL);
+#endif
+
+    /* now let's do some initial hardware-type setup */
+#if defined(__powerpc__)
+    mlLoadModule("spufs", NULL);
+#endif
+
+    if (loaderData.lang && (loaderData.lang_set == 1)) {
+        setLanguage(loaderData.lang, 1);
+    }
+
+    /* FIXME: this is a bit of a hack */
+    loaderData.modInfo = modInfo;
+
+    /* If there is /.rundepmod file present, rerun depmod */
+    if (!access("/.rundepmod", R_OK)){
+        if (system("depmod -a")) {
+            /* this is not really fatal error, it might still work, log it */
+            logMessage(ERROR, "Error running depmod -a for initrd overlay");
+        }
+    }
+
+    /* this allows us to do an early load of modules specified on the
+     * command line to allow automating the load order of modules so that
+     * eg, certain scsi controllers are definitely first.
+     * FIXME: this syntax is likely to change in a future release
+     *        but is done as a quick hack for the present.
+     */
+    if (!mlInitModuleConfig()) {
+        logMessage(ERROR, "unable to initialize kernel module loading");
+        abort();
+    }
+
+    earlyModuleLoad(0);
+
+    /* Save list of preloaded modules so we can restore the state */
+    moduleState = mlSaveModuleState();
+
+    /* Load all known devices */
+    busProbe(FL_NOPROBE(flags));
+
+    if (FL_AUTOMODDISK(flags)) {
+        /* Load all autodetected DDs */
+        logMessage(INFO, "Trying to detect vendor driver discs");
+        dd = findDriverDiskByLabel();
+        dditer = dd;
+        while(dditer) {
+            /* load the DD */
+            if (loadDriverDiskFromPartition(&loaderData, (char*)(dditer->data))) {
+                logMessage(ERROR, "Automatic driver disk loader failed for %s.", (char*)(dditer->data));
+            }
+            else {
+                logMessage(INFO, "Automatic driver disk loader succeeded for %s.", (char*)(dditer->data));
+
+                /* Unload all devices and load them again to use the updated modules */
+                mlRestoreModuleState(moduleState);
+                busProbe(0);
+            }
+            
+            /* clean the device record */
+            free((char*)(dditer->data));
+            dditer->data = NULL;
+
+            /* next DD */
+            dditer = g_slist_next(dditer);
+        }
+        g_slist_free(dd);
+    }
+
+    if (FL_MODDISK(flags)) {
+        startNewt();
+        loadDriverDisks(DEVICE_ANY, &loaderData, moduleState);
+    }
+
+    if (!access("/dd.img", R_OK)) {
+        logMessage(INFO, "found /dd.img, loading drivers");
+        getDDFromSource(&loaderData, "path:/dd.img", moduleState);
+    }
+    
+    /* Reset depmod & modprobe to normal mode and get the rest of drivers*/
+    mlFreeModuleState(moduleState);
+    busProbe(FL_NOPROBE(flags));
+
+    /* Disable all network interfaces in NetworkManager by default */
+#if !defined(__s390__) && !defined(__s390x__)
+    int i;
+
+    if ((i = writeDisabledNetInfo()) != 0) {
+        logMessage(ERROR, "writeDisabledNetInfo failure: %d", i);
+    }
+#endif
+
+    /* Start NetworkManager now so it's always available to talk to. */
+    if (iface_start_NetworkManager())
+        logMessage(INFO, "failed to start NetworkManager");
+
+    if (!FL_CMDLINE(flags))
+        startNewt();
+
+    /* can't run gdbserver until after network modules are loaded */
+    doGdbserver(&loaderData);
+
+    /* JKFIXME: we'd really like to do this before the busprobe, but then
+     * we won't have network devices available (and that's the only thing
+     * we support with this right now */
+    if (loaderData.ddsrc != NULL) {
+        getDDFromSource(&loaderData, loaderData.ddsrc, NULL);
+    }
+
+    /* JKFIXME: loaderData->ksFile is set to the arg from the command line,
+     * and then getKickstartFile() changes it and sets FL_KICKSTART.  
+     * kind of weird. */
+    if (loaderData.ksFile || ksFile) {
+        logMessage(INFO, "getting kickstart file");
+
+        if (!ksFile)
+            getKickstartFile(&loaderData);
+        if (FL_KICKSTART(flags) && 
+            (ksReadCommands((ksFile)?ksFile:loaderData.ksFile)!=LOADER_ERROR)) {
+            runKickstart(&loaderData);
+        }
+    }
+
+    if (FL_EARLY_NETWORKING(flags)) {
+        kickstartNetworkUp(&loaderData, &iface);
+    }
+
+    if (FL_TELNETD(flags))
+        startTelnetd(&loaderData);
+
+    url = doLoaderMain(&loaderData, modInfo);
+
+    /* unlink dirs and link to the ones in /mnt/runtime */
+    migrate_runtime_directory("/usr");
+    migrate_runtime_directory("/lib");
+    migrate_runtime_directory("/lib64");
+    ret = symlink("/mnt/runtime/etc/selinux", "/etc/selinux");
+    copyDirectory("/mnt/runtime/etc","/etc", NULL, copyErrorFn);
+    copyDirectory("/mnt/runtime/var","/var", NULL, copyErrorFn);
+
+    /* now load SELinux policy before exec'ing anaconda and the shell
+     * (if we're using SELinux) */
+    if (FL_SELINUX(flags)) {
+        if (mount("/selinux", "/selinux", "selinuxfs", 0, NULL)) {
+            logMessage(ERROR, "failed to mount /selinux: %m, disabling SELinux");
+            flags &= ~LOADER_FLAGS_SELINUX;
+        } else {
+            if (loadpolicy() == 0) {
+                setexeccon(ANACONDA_CONTEXT);
+            } else {
+                logMessage(ERROR, "failed to load policy, disabling SELinux");
+                flags &= ~LOADER_FLAGS_SELINUX;
+            }
+        }
+    }
+
+    logMessage(INFO, "getting ready to spawn shell now");
+
+    spawnShell();  /* we can attach gdb now :-) */
+
+    if (FL_NOPROBE(flags) && !loaderData.ksFile) {
+        startNewt();
+        manualDeviceCheck(&loaderData);
+    }
+
+    if (loaderData.updatessrc)
+        loadUpdatesFromRemote(loaderData.updatessrc, &loaderData);
+    else if (FL_UPDATES(flags))
+        loadUpdates(&loaderData);
+
+    /* make sure /tmp/updates exists so that magic in anaconda to */
+    /* symlink rhpl/ will work                                    */
+    if (access("/tmp/updates", F_OK))
+        mkdirChain("/tmp/updates");
+
+    add_fw_search_dir(&loaderData, "/tmp/updates/firmware");
+    add_fw_search_dir(&loaderData, "/tmp/product/firmware");
+
+    add_to_path_env("PYTHONPATH", "/tmp/updates");
+    add_to_path_env("PYTHONPATH", "/tmp/updates/iw");
+    add_to_path_env("PYTHONPATH", "/tmp/updates/textw");
+    add_to_path_env("PYTHONPATH", "/tmp/product");
+    add_to_path_env("LD_LIBRARY_PATH", "/tmp/updates");
+    add_to_path_env("LD_LIBRARY_PATH", "/tmp/product");
+    add_to_path_env("PATH", "/tmp/updates");
+    add_to_path_env("PATH", "/tmp/product");
+
+    stop_fw_loader(&loaderData);
+    start_fw_loader(&loaderData);
+
+    mlLoadModuleSet("raid0:raid1:raid5:raid6:raid456:raid10:linear:dm-mod:dm-zero:dm-mirror:dm-snapshot:dm-multipath:dm-round-robin:dm-crypt:cbc:sha256:lrw:xts");
+
+    if (!access("/mnt/runtime/usr/lib/libunicode-lite.so.1", R_OK))
+        setenv("LD_PRELOAD", "/mnt/runtime/usr/lib/libunicode-lite.so.1", 1);
+    if (!access("/mnt/runtime/usr/lib64/libunicode-lite.so.1", R_OK))
+        setenv("LD_PRELOAD", "/mnt/runtime/usr/lib64/libunicode-lite.so.1", 1);
+
+    argptr = anacondaArgs;
+
+    path = getenv("PATH");
+    while (path && path[0]) {
+        int n = strcspn(path, ":");
+        char c, *binpath;
+
+        c = path[n];
+        path[n] = '\0';
+        checked_asprintf(&binpath, "%s/anaconda", path);
+        path[n] = c;
+
+        if (!access(binpath, X_OK)) {
+            *argptr++ = strdupa(binpath);
+            free(binpath);
+            break;
+        }
+        free(binpath);
+        path += n + 1;
+    }
+
+    logMessage(INFO, "Running anaconda script %s", *(argptr-1));
+
+    *argptr++ = "--stage2";
+    if (strncmp(url, "ftp:", 4)) {
+        *argptr++ = url;
+    } else {
+        int fd, ret;
+
+        fd = open("/tmp/ftp-stage2", O_CREAT | O_TRUNC | O_RDWR, 0600);
+        ret = write(fd, url, strlen(url));
+        ret = write(fd, "\r", 1);
+        close(fd);
+        *argptr++ = "@/tmp/ftp-stage2";
+    }
+
+    /* add extra args - this potentially munges extraArgs */
+    tmparg = extraArgs;
+    while (*tmparg) {
+        char *idx;
+
+        logMessage(DEBUGLVL, "adding extraArg %s", *tmparg);
+        idx = strchr(*tmparg, '=');
+        if (idx &&  ((idx-*tmparg) < strlen(*tmparg))) {
+            *idx = '\0';
+            *argptr++ = *tmparg;
+            *argptr++ = idx+1;
+        } else {
+            *argptr++ = *tmparg;
+        }
+
+        tmparg++;
+    }
+
+    if (FL_AUTOMODDISK(flags))
+        *argptr++ = "--dlabel";
+
+    if (FL_NOIPV4(flags))
+        *argptr++ = "--noipv4";
+
+#ifdef ENABLE_IPV6
+    if (FL_NOIPV6(flags))
+        *argptr++ = "--noipv6";
+#endif
+
+#if defined(__s390__) || defined(__s390x__)
+    *argptr++ = "--headless";
+#endif
+
+    if (FL_KICKSTART(flags)) {
+        *argptr++ = "--kickstart";
+        *argptr++ = loaderData.ksFile;
+    }
+
+    if (FL_SERIAL(flags))
+        *argptr++ = "--serial";
+
+    if (FL_RESCUE(flags)) {
+        *argptr++ = "--rescue";
+    } else {
+        if (FL_TEXT(flags))
+            *argptr++ = "-T";
+        else if (FL_GRAPHICAL(flags))
+            *argptr++ = "--graphical";
+        if (FL_CMDLINE(flags))
+            *argptr++ = "-C";
+        if (!FL_SELINUX(flags))
+            *argptr++ = "--noselinux";
+        else if (FL_SELINUX(flags))
+            *argptr++ = "--selinux";
+
+        if (FL_VIRTPCONSOLE(flags)) {
+            *argptr++ = "--virtpconsole";
+            *argptr++ = virtpcon;
+        }
+
+        if (loaderData.updatessrc && FL_UPDATES(flags)) {
+            *argptr++ = "--updates";
+            *argptr++ = loaderData.updatessrc;
+        }
+
+        if (loaderData.dogtailurl) {
+            *argptr++ = "--dogtail";
+            *argptr++ = loaderData.dogtailurl;
+        }
+
+        if ((loaderData.lang) && !FL_NOPASS(flags)) {
+            *argptr++ = "--lang";
+            *argptr++ = loaderData.lang;
+        }
+
+        if ((loaderData.kbd) && !FL_NOPASS(flags)) {
+            *argptr++ = "--keymap";
+            *argptr++ = loaderData.kbd;
+        }
+
+        if (loaderData.logLevel) {
+            *argptr++ = "--loglevel";
+            *argptr++ = loaderData.logLevel;
+        }
+
+        if (loaderData.instRepo) {
+           *argptr++ = "--repo";
+            if (strncmp(loaderData.instRepo, "ftp:", 4)) {
+                *argptr++ = loaderData.instRepo;
+            } else {
+                int fd, ret;
+
+                fd = open("/tmp/ftp-repo", O_CREAT | O_TRUNC | O_RDWR, 0600);
+                ret = write(fd, loaderData.instRepo, strlen(loaderData.instRepo));
+                ret = write(fd, "\r", 1);
+                close(fd);
+                *argptr++ = "@/tmp/ftp-repo";
+            }
+        }
+
+        if (loaderData.proxy && strcmp("", loaderData.proxy)) {
+            *argptr++ = "--proxy";
+
+            *argptr++ = strdup(loaderData.proxy);
+
+            if (loaderData.proxyUser && strcmp(loaderData.proxyUser, "")) {
+                int fd, ret;
+
+                fd = open("/tmp/proxy", O_CREAT|O_TRUNC|O_RDWR, 0600);
+                ret = write(fd, loaderData.proxyUser, strlen(loaderData.proxyUser));
+                ret = write(fd, "\r\n", 2);
+
+                if (loaderData.proxyPassword && strcmp(loaderData.proxyPassword, "")) {
+                    ret = write(fd, loaderData.proxyPassword, strlen(loaderData.proxyPassword));
+                    ret = write(fd, "\r\n", 2);
+                }
+
+                close(fd);
+
+                *argptr++ = "--proxyAuth";
+                *argptr++ = "/tmp/proxy";
+            }
+        }
+    }
+    
+    *argptr = NULL;
+    
+    stopNewt();
+    closeLog();
+
+    if (FL_RESCUE(flags)) {
+        fmt = _("Running anaconda %s, the %s rescue mode - please wait.\n");
+    } else {
+        fmt = _("Running anaconda %s, the %s system installer - please wait.\n");
+    }
+    printf(fmt, VERSION, getProductName());
+
+    if (!(pid = fork())) {
+        if (execv(anacondaArgs[0], anacondaArgs) == -1) {
+           fprintf(stderr,"exec of anaconda failed: %m\n");
+           doExit(1);
+        }
+    }
+
+    waitpid(pid, &status, 0);
+
+    if (!WIFEXITED(status) || (WIFEXITED(status) && WEXITSTATUS(status))) {
+        rc = 1;
+    } else {
+        rc = 0;
+    }
+
+    if ((rc == 0) && (FL_POWEROFF(flags) || FL_HALT(flags))) {
+        if (!(pid = fork())) {
+            char * cmd = (FL_POWEROFF(flags) ? strdup("/sbin/poweroff") :
+                          strdup("/sbin/halt"));
+            if (execl(cmd, cmd, NULL) == -1) {
+                fprintf(stderr, "exec of poweroff failed: %m\n");
+                doExit(1);
+            }
+        }
+        waitpid(pid, &status, 0);
+    }
+
+    stop_fw_loader(&loaderData);
+#if defined(__s390__) || defined(__s390x__)
+    /* at the latest possibility signal init=linuxrc.s390 to reboot/halt */
+    logMessage(INFO, "Sending signal %d to process %d\n",
+               init_sig, init_pid);
+    kill(init_pid, init_sig);
+#endif
+    doExit(rc);
+
+    doExit(1);
+}
+
+/* vim:set sw=4 sts=4 et: */
diff --git a/bin/loader/loader.h b/bin/loader/loader.h
new file mode 100644
index 0000000..c64c475
--- /dev/null
+++ b/bin/loader/loader.h
@@ -0,0 +1,193 @@
+/*
+ * loader.h
+ *
+ * Copyright (C) 2007  Red Hat, Inc.  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 as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <stdint.h>
+
+#ifndef LOADER_H
+#define LOADER_H
+
+#define LOADER_OK 0
+#define LOADER_BACK 1
+#define LOADER_NOOP 2
+#define LOADER_ERROR -1
+
+/* #0 unused */
+/* #1 unused */
+#define LOADER_FLAGS_TEXT               (((uint64_t) 1) << 2)
+#define LOADER_FLAGS_RESCUE             (((uint64_t) 1) << 3)
+#define LOADER_FLAGS_KICKSTART          (((uint64_t) 1) << 4)
+#define LOADER_FLAGS_KICKSTART_SEND_MAC (((uint64_t) 1) << 5)
+#define LOADER_FLAGS_POWEROFF           (((uint64_t) 1) << 6)
+#define LOADER_FLAGS_NOPROBE              (((uint64_t) 1) << 7)
+#define LOADER_FLAGS_MODDISK            (((uint64_t) 1) << 8)
+#define LOADER_FLAGS_EARLY_NETWORKING   (((uint64_t) 1) << 9)
+#define LOADER_FLAGS_SERIAL             (((uint64_t) 1) << 10)
+#define LOADER_FLAGS_UPDATES            (((uint64_t) 1) << 11)
+#define LOADER_FLAGS_KSFILE             (((uint64_t) 1) << 12)
+#define LOADER_FLAGS_HALT               (((uint64_t) 1) << 13)
+#define LOADER_FLAGS_SELINUX            (((uint64_t) 1) << 14)
+#define LOADER_FLAGS_VIRTPCONSOLE       (((uint64_t) 1) << 15)
+/* #16 unused */
+#define LOADER_FLAGS_NOSHELL            (((uint64_t) 1) << 17)
+/* #18 unused */
+#define LOADER_FLAGS_TELNETD            (((uint64_t) 1) << 19)
+#define LOADER_FLAGS_NOPASS             (((uint64_t) 1) << 20)
+/* #21 unused */
+#define LOADER_FLAGS_MEDIACHECK         (((uint64_t) 1) << 22)
+/* #23 unused */
+#define LOADER_FLAGS_ASKMETHOD          (((uint64_t) 1) << 24)
+#define LOADER_FLAGS_ASKNETWORK         (((uint64_t) 1) << 25)
+/* #26 unused */
+/* #27 unused */
+#define LOADER_FLAGS_CMDLINE            (((uint64_t) 1) << 28)
+#define LOADER_FLAGS_GRAPHICAL          (((uint64_t) 1) << 29)
+#define LOADER_FLAGS_NOIPV4             (((uint64_t) 1) << 31)
+#ifdef ENABLE_IPV6
+#define LOADER_FLAGS_NOIPV6             (((uint64_t) 1) << 32)
+#endif
+#define LOADER_FLAGS_IP_PARAM           (((uint64_t) 1) << 33)
+#ifdef ENABLE_IPV6
+#define LOADER_FLAGS_IPV6_PARAM         (((uint64_t) 1) << 34)
+#endif
+#define LOADER_FLAGS_IS_KICKSTART       (((uint64_t) 1) << 35)
+#define LOADER_FLAGS_ALLOW_WIRELESS     (((uint64_t) 1) << 36)
+#define LOADER_FLAGS_HAVE_CMSCONF       (((uint64_t) 1) << 37)
+#define LOADER_FLAGS_NOKILL		(((uint64_t) 1) << 38)
+#define LOADER_FLAGS_KICKSTART_SEND_SERIAL   (((uint64_t) 1) << 39)
+#define LOADER_FLAGS_AUTOMODDISK        (((uint64_t) 1) << 40)
+
+#define FL_TEXT(a)               ((a) & LOADER_FLAGS_TEXT)
+#define FL_RESCUE(a)             ((a) & LOADER_FLAGS_RESCUE)
+#define FL_KICKSTART(a)          ((a) & LOADER_FLAGS_KICKSTART)
+#define FL_KICKSTART_SEND_MAC(a) ((a) & LOADER_FLAGS_KICKSTART_SEND_MAC)
+#define FL_POWEROFF(a)           ((a) & LOADER_FLAGS_POWEROFF)
+#define FL_NOPROBE(a)            ((a) & LOADER_FLAGS_NOPROBE)
+#define FL_MODDISK(a)            ((a) & LOADER_FLAGS_MODDISK)
+#define FL_EARLY_NETWORKING(a)   ((a) & LOADER_FLAGS_EARLY_NETWORKING)
+#define FL_SERIAL(a)             ((a) & LOADER_FLAGS_SERIAL)
+#define FL_UPDATES(a)            ((a) & LOADER_FLAGS_UPDATES)
+#define FL_KSFILE(a)             ((a) & LOADER_FLAGS_KSFILE)
+#define FL_NOSHELL(a)            ((a) & LOADER_FLAGS_NOSHELL)
+#define FL_TELNETD(a)            ((a) & LOADER_FLAGS_TELNETD)
+#define FL_NOPASS(a)             ((a) & LOADER_FLAGS_NOPASS)
+#define FL_MEDIACHECK(a)         ((a) & LOADER_FLAGS_MEDIACHECK)
+#define FL_ASKMETHOD(a)          ((a) & LOADER_FLAGS_ASKMETHOD)
+#define FL_GRAPHICAL(a)          ((a) & LOADER_FLAGS_GRAPHICAL)
+#define FL_CMDLINE(a)            ((a) & LOADER_FLAGS_CMDLINE)
+#define FL_HALT(a)               ((a) & LOADER_FLAGS_HALT)
+#define FL_SELINUX(a)            ((a) & LOADER_FLAGS_SELINUX)
+#define FL_VIRTPCONSOLE(a)       ((a) & LOADER_FLAGS_VIRTPCONSOLE)
+#define FL_ASKNETWORK(a)         ((a) & LOADER_FLAGS_ASKNETWORK)
+#define FL_NOIPV4(a)             ((a) & LOADER_FLAGS_NOIPV4)
+#ifdef ENABLE_IPV6
+#define FL_NOIPV6(a)             ((a) & LOADER_FLAGS_NOIPV6)
+#endif
+#define FL_IP_PARAM(a)           ((a) & LOADER_FLAGS_IP_PARAM)
+#ifdef ENABLE_IPV6
+#define FL_IPV6_PARAM(a)         ((a) & LOADER_FLAGS_IPV6_PARAM)
+#endif
+#define FL_IS_KICKSTART(a)       ((a) & LOADER_FLAGS_IS_KICKSTART)
+#define FL_ALLOW_WIRELESS(a)     ((a) & LOADER_FLAGS_ALLOW_WIRELESS)
+#define FL_HAVE_CMSCONF(a)       ((a) & LOADER_FLAGS_HAVE_CMSCONF)
+#define FL_NOKILL(a)		 ((a) & LOADER_FLAGS_NOKILL)
+#define FL_KICKSTART_SEND_SERIAL(a) ((a) & LOADER_FLAGS_KICKSTART_SEND_SERIAL)
+#define FL_AUTOMODDISK(a)        ((a) & LOADER_FLAGS_AUTOMODDISK)
+
+void doExit(int) __attribute__ ((noreturn));
+void startNewt(void);
+void stopNewt(void);
+char * getProductName(void);
+char * getProductPath(void);
+char * getProductArch(void);
+
+#include "moduleinfo.h"
+#include "../isys/devices.h"
+/* JKFIXME: I don't like all of the _set attribs, but without them,
+ * we can't tell if it was explicitly set by kickstart/cmdline or 
+ * if we just got it going through the install.   */
+struct loaderData_s {
+    char * lang;
+    int lang_set;
+    char * kbd;
+    int kbd_set;
+    char * netDev;
+    int netDev_set;
+    char * bootIf;
+    int bootIf_set;
+    char * netCls;
+    int netCls_set;
+    char *ipv4, *netmask, *gateway, *dns, *hostname, *peerid, *ethtool, *subchannels, *portname, *essid, *wepkey, *nettype, *ctcprot, *layer2, *portno, *macaddr;
+#ifdef ENABLE_IPV6
+    char *ipv6;
+    int ipv6info_set;
+    char *gateway6;
+#endif
+    int mtu;
+    int noDns;
+    int dhcpTimeout;
+    int ipinfo_set;
+    char * ksFile;
+    int method;
+    char * ddsrc;
+    void * stage2Data;
+    char * logLevel;
+    char * updatessrc;
+    char * dogtailurl;
+    char * gdbServer;
+    char * instRepo;
+
+    pid_t fw_loader_pid;
+    char *fw_search_pathz;
+    size_t fw_search_pathz_len;
+
+    moduleInfoSet modInfo;
+
+    int inferredStage2, invalidRepoParam;
+
+    /* Proxy info needs to be in the loaderData so we can get these
+     * settings off the command line, too.
+     */
+    char *proxy;
+    char *proxyUser;
+    char *proxyPassword;
+};
+
+/* 64 bit platforms, definitions courtesy of glib */
+#if defined (__x86_64__) || defined(__ia64__) || defined(__alpha__) || defined(__powerpc64__) || defined(__s390x__) || (defined(__sparc__) && defined(__arch64__))
+#define POINTER_TO_INT(p)  ((int) (long) (p))
+#define INT_TO_POINTER(i)  ((void *) (long) (i))
+#else
+#define POINTER_TO_INT(p)  ((int) (p))
+#define INT_TO_POINTER(i)  ((void *) (i))
+#endif
+
+/* library paths */
+#if defined(__x86_64__) || defined(__s390x__) || defined(__powerpc64__)
+#define LIBPATH "/lib64:/usr/lib64:/usr/X11R6/lib64:/usr/kerberos/lib64:/mnt/usr/lib64:/mnt/sysimage/lib64:/mnt/sysimage/usr/lib64"
+#else
+#define LIBPATH "/lib:/usr/lib:/usr/X11R6/lib:/usr/kerberos/lib:/mnt/usr/lib:/mnt/sysimage/lib:/mnt/sysimage/usr/lib"
+#endif
+
+#define checked_asprintf(...)                                       \
+    if (asprintf( __VA_ARGS__ ) == -1) {                            \
+        logMessage(CRITICAL, "%s: %d: %m", __func__, __LINE__);     \
+        abort();                                                    \
+    }
+
+#endif
diff --git a/bin/loader/loadermisc.c b/bin/loader/loadermisc.c
new file mode 100644
index 0000000..64e80a2
--- /dev/null
+++ b/bin/loader/loadermisc.c
@@ -0,0 +1,150 @@
+/*
+ * loadermisc.c - miscellaneous loader functions that don't seem to fit
+ * anywhere else (yet)  (was misc.c)
+ * JKFIXME: need to break out into reasonable files based on function
+ *
+ * Copyright (C) 1999, 2000, 2001, 2002  Red Hat, Inc.  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 as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ *
+ * Author(s): Erik Troan <ewt@xxxxxxxxxx>
+ *            Matt Wilson <msw@xxxxxxxxxx>
+ *            Michael Fulbright <msf@xxxxxxxxxx>
+ *            Jeremy Katz <katzj@xxxxxxxxxx>
+ */
+
+#include <ctype.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <string.h>
+#include <unistd.h>
+#include <stdarg.h>
+#include <stdlib.h>
+
+#include "../isys/log.h"
+
+#include "windows.h"
+
+int copyFileFd(int infd, char * dest, progressCB pbcb,
+               struct progressCBdata *data, long long total) {
+    int outfd;
+    char buf[4096];
+    int i;
+    int rc = 0;
+    long long count = 0;
+
+    outfd = open(dest, O_CREAT | O_RDWR, 0666);
+
+    if (outfd < 0) {
+        logMessage(ERROR, "failed to open %s: %m", dest);
+        return 1;
+    }
+
+    while ((i = read(infd, buf, sizeof(buf))) > 0) {
+        if (write(outfd, buf, i) != i) {
+            rc = 1;
+            break;
+        }
+
+        count += i;
+
+        if (pbcb && data && total) {
+            pbcb(data, count, total);
+        }
+    }
+
+    close(outfd);
+
+    return rc;
+}
+
+int copyFile(char * source, char * dest) {
+    int infd = -1;
+    int rc;
+
+    infd = open(source, O_RDONLY);
+
+    if (infd < 0) {
+        logMessage(ERROR, "failed to open %s: %m", source);
+        return 1;
+    }
+
+    rc = copyFileFd(infd, dest, NULL, NULL, 0);
+
+    close(infd);
+
+    return rc;
+}
+
+int simpleStringCmp(const void * a, const void * b) {
+    const char * first = *((const char **) a);
+    const char * second = *((const char **) b);
+
+    return strverscmp(first, second);
+}
+
+/* look for available memory.  note: won't ever report more than the 
+ * 900 megs or so supported by the -BOOT kernel due to not using e820 */
+int totalMemory(void) {
+    int fd;
+    int bytesRead;
+    char buf[4096];
+    char * chptr, * start;
+    int total = 0;
+
+    fd = open("/proc/meminfo", O_RDONLY);
+    if (fd < 0) {
+        logMessage(ERROR, "failed to open /proc/meminfo: %m");
+        return 0;
+    }
+
+    bytesRead = read(fd, buf, sizeof(buf) - 1);
+    if (bytesRead < 0) {
+        logMessage(ERROR, "failed to read from /proc/meminfo: %m");
+        close(fd);
+        return 0;
+    }
+
+    close(fd);
+    buf[bytesRead] = '\0';
+
+    chptr = buf;
+    while (*chptr && !total) {
+        if (strncmp(chptr, "MemTotal:", 9)) {
+            chptr++;
+            continue;
+        }
+
+        start = ++chptr ;
+        while (*chptr && *chptr != '\n') chptr++;
+
+        *chptr = '\0';
+
+        while (!isdigit(*start) && *start) start++;
+        if (!*start) {
+            logMessage(WARNING, "no number appears after MemTotal tag");
+            return 0;
+        }
+
+        chptr = start;
+        while (*chptr && isdigit(*chptr)) {
+            total = (total * 10) + (*chptr - '0');
+            chptr++;
+        }
+    }
+
+    logMessage(INFO, "%d kB are available", total);
+
+    return total;
+}
diff --git a/bin/loader/loadermisc.h b/bin/loader/loadermisc.h
new file mode 100644
index 0000000..23ebf4a
--- /dev/null
+++ b/bin/loader/loadermisc.h
@@ -0,0 +1,33 @@
+/*
+ * loadermisc.h
+ *
+ * Copyright (C) 2007  Red Hat, Inc.  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 as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef H_LOADER_MISC_H
+#define H_LOADER_MISC_H
+#include <stdio.h>
+#include <stdarg.h>
+
+#include "windows.h"
+
+int copyFile(char * source, char * dest);
+int copyFileFd(int infd, char * dest, progressCB pbcb,
+               struct progressCBdata *data, long long total);
+int simpleStringCmp(const void * a, const void * b);
+int totalMemory(void);
+
+#endif
diff --git a/bin/loader/mediacheck.c b/bin/loader/mediacheck.c
new file mode 100644
index 0000000..4bec1c8
--- /dev/null
+++ b/bin/loader/mediacheck.c
@@ -0,0 +1,115 @@
+/*
+ * simple program to check implanted md5sum in an iso 9660 image
+ *
+ * Copyright (C) 2001, 2005  Red Hat, Inc.  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 as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ *
+ * Author(s): Michael Fulbright <msf@xxxxxxxxxx>
+ *            Dustin Kirkland <dustin.kirkland@xxxxxxxxx>
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <string.h>
+#include <newt.h>
+#include <libcheckisomd5.h>
+
+#include "../isys/log.h"
+
+#include "lang.h"
+#include "windows.h"
+
+int doMediaCheck(char *file, char *descr) {
+    struct progressCBdata data;
+    newtComponent t, f, scale, label;
+    int rc;
+    int dlen;
+    int llen;
+    char tmpstr[1024];
+
+    if (access(file, R_OK) < 0) {
+	newtWinMessage(_("Error"), _("OK"), _("Unable to find install image "
+					      "%s"), file);
+	return -1;
+    }
+
+    if (descr)
+	snprintf(tmpstr, sizeof(tmpstr), _("Checking \"%s\"."), descr);
+    else
+	snprintf(tmpstr, sizeof(tmpstr), _("Checking media."));
+
+    dlen = strlen(tmpstr);
+    if (dlen > 65)
+	dlen = 65;
+
+    newtCenteredWindow(dlen+8, 6, _("Media Check"));
+    t = newtTextbox(1, 1, dlen+4, 3, NEWT_TEXTBOX_WRAP);
+
+    newtTextboxSetText(t, tmpstr);
+    llen = strlen(tmpstr);
+
+    label = newtLabel(llen+1, 1, "-");
+    f = newtForm(NULL, NULL, 0);
+    newtFormAddComponent(f, t);
+    scale = newtScale(3, 3, dlen, 100);
+    newtFormAddComponent(f, scale);
+
+    newtDrawForm(f);
+    newtRefresh();
+
+    data.scale = scale;
+    data.label = label;
+
+    rc = mediaCheckFile(file, progressCallback, &data);
+
+    newtFormDestroy(f);
+    newtPopWindow();
+
+    if (rc == ISOMD5SUM_CHECK_NOT_FOUND) {
+	logMessage(WARNING, "mediacheck: %s (%s) has no checksum info", file, descr);
+	newtWinMessage(_("Error"), _("OK"),
+		       _("Unable to find the checksum in the "
+			 "image.  This probably "
+			 "means the disc was created without adding the "
+			 "checksum."));
+    } else if (rc == ISOMD5SUM_FILE_NOT_FOUND) {
+        logMessage(WARNING, "mediacheck: %s (%s) open failed", file, descr);
+        newtWinMessage(_("Error"), _("OK"),
+                       _("Unable to open the image."));
+    } else if (rc == ISOMD5SUM_CHECK_FAILED) {
+        logMessage(ERROR, "mediacheck: %s (%s) FAILED", file, descr);
+        newtWinMessage(_("Error"), _("OK"),
+                       _("The image which was just tested has errors. "
+                         "This could be due to a "
+                         "corrupt download or a bad disc.  "
+                         "If applicable, please clean the disc "
+                         "and try again.  If this test continues to fail you "
+                         "should not continue the install."));
+    } else if (rc == ISOMD5SUM_CHECK_PASSED) {
+        logMessage(INFO, "mediacheck: %s (%s) PASSED", file, descr);
+        newtWinMessage(_("Success"), _("OK"),
+                       _("The image which was just tested was successfully "
+                         "verified.  It should be OK to install from this "
+                         "media.  Note that not all media/drive errors can "
+                         "be detected by the media check."));
+    }
+
+
+    return rc;
+}
diff --git a/bin/loader/mediacheck.h b/bin/loader/mediacheck.h
new file mode 100644
index 0000000..ab2f887
--- /dev/null
+++ b/bin/loader/mediacheck.h
@@ -0,0 +1,25 @@
+/*
+ * mediacheck.h
+ *
+ * Copyright (C) 2007  Red Hat, Inc.  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 as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef MEDIACHECK_H
+#define MEDIACHECK_H
+
+int doMediaCheck(char *file, char *descr);
+
+#endif
diff --git a/bin/loader/method.c b/bin/loader/method.c
new file mode 100644
index 0000000..3ca669f
--- /dev/null
+++ b/bin/loader/method.c
@@ -0,0 +1,570 @@
+/*
+ * method.c - generic install method setup functions
+ *
+ * Copyright (C) 2002  Red Hat, Inc.  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 as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ *
+ * Author(s): Erik Troan <ewt@xxxxxxxxxx>
+ *            Matt Wilson <msw@xxxxxxxxxx>
+ *            Michael Fulbright <msf@xxxxxxxxxx>
+ *            Jeremy Katz <katzj@xxxxxxxxxx>
+ */
+
+#include <ctype.h>
+#include <dirent.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <inttypes.h>
+#include <libgen.h>
+#include <newt.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/ioctl.h>
+#include <sys/mount.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <unistd.h>
+#include <libgen.h>
+
+#include "copy.h"
+#include "loader.h"
+#include "loadermisc.h"
+#include "lang.h"
+#include "mediacheck.h"
+#include "method.h"
+
+#include "../isys/imount.h"
+#include "../isys/isys.h"
+#include "../isys/cpio.h"
+#include "../isys/log.h"
+
+#include "devt.h"
+
+#include "nfsinstall.h"
+#include "hdinstall.h"
+#include "urlinstall.h"
+
+/* boot flags */
+extern uint64_t flags;
+
+static void stripTrailingSlash(char *path) {
+    size_t len = strlen(path);
+
+    if (len == 0)
+        return;
+    if (path[len-1] == '/')
+        path[len-1] = '\0';
+}
+
+int umountLoopback(char * mntpoint, char * device) {
+    int loopfd;
+
+    umount(mntpoint);
+
+    logMessage(INFO, "umounting loopback %s %s", mntpoint, device);
+
+    loopfd = open(device, O_RDONLY);
+
+    if (ioctl(loopfd, LOOP_CLR_FD, 0) == -1)
+        logMessage(ERROR, "LOOP_CLR_FD failed for %s %s: %m", mntpoint, device);
+
+    close(loopfd);
+
+    return 0;
+}
+
+int mountLoopback(char *fsystem, char *mntpoint, char *device) {
+    char *opts, *err = NULL;
+
+    if (device == NULL) {
+        logMessage(ERROR, "no loopback device given");
+        return LOADER_ERROR;
+    }
+
+    if (access(fsystem, F_OK) != 0) {
+       logMessage(ERROR, "file %s is not accessible", fsystem);
+       return LOADER_ERROR;
+    }
+
+    checked_asprintf(&opts, "ro,loop=%s", device);
+
+    if (doPwMount(fsystem, mntpoint, "auto", opts, &err)) {
+        logMessage(ERROR, "failed to mount loopback device %s on %s as %s: %s",
+                   device, mntpoint, fsystem, err);
+        return LOADER_ERROR;
+    }
+
+    logMessage(INFO, "mounted loopback device %s on %s as %s", mntpoint, device, fsystem);
+
+    return 0;
+}
+
+/* returns the *absolute* path (malloced) to the #1 iso image */
+/* get timestamp and description of ISO image from stamp file */
+/* returns 0 on success, -1 otherwise                         */
+int readStampFileFromIso(char *file, char **timestamp, char **releasedescr) {
+    DIR * dir;
+    FILE *f;
+    struct dirent * ent;
+    struct stat sb;
+    char *stampfile;
+    char *descr, *tstamp;
+    char tmpstr[1024];
+    int  filetype;
+    int  rc;
+
+    lstat(file, &sb);
+    if (S_ISBLK(sb.st_mode)) {
+	filetype = 1;
+	if (doPwMount(file, "/tmp/testmnt", "iso9660", "ro", NULL)) {
+	    logMessage(ERROR, "Failed to mount device %s to get description",
+                       file);
+	    return -1;
+	}
+    } else if (S_ISREG(sb.st_mode)) {
+	filetype = 2;
+	if (mountLoopback(file, "/tmp/testmnt", "/dev/loop6")) {
+	    logMessage(ERROR, "Failed to mount iso %s to get description",
+                       file);
+	    return -1;
+	}
+    } else {
+	    logMessage(ERROR, "Unknown type of file %s to get description",
+                       file);
+	    return -1;
+    }
+
+    if (!(dir = opendir("/tmp/testmnt"))) {
+	umount("/tmp/testmnt");
+	if (filetype == 2)
+	    umountLoopback("/tmp/testmnt", "/dev/loop6");
+	return -1;
+    }
+
+    errno = 0;
+    stampfile = NULL;
+    while ((ent = readdir(dir))) {
+	if (!strncmp(ent->d_name, ".discinfo", 9)) {
+	    stampfile = strdup(".discinfo");
+	    break;
+	}
+    }
+
+    closedir(dir);
+    descr = NULL;
+    tstamp = NULL;
+    if (stampfile) {
+	snprintf(tmpstr, sizeof(tmpstr), "/tmp/testmnt/%s", stampfile);
+	f = fopen(tmpstr, "r");
+	if (f) {
+	    char *tmpptr;
+
+	    /* readtime stamp line */
+	    tmpptr = fgets(tmpstr, sizeof(tmpstr), f);
+	    
+	    if (tmpptr)
+		tstamp = strdup(tmpstr);
+
+	    /* now read OS description line */
+	    if (tmpptr)
+		tmpptr = fgets(tmpstr, sizeof(tmpstr), f);
+
+	    if (tmpptr)
+		descr = strdup(tmpstr);
+
+	    /* skip over arch */
+	    if (tmpptr)
+		tmpptr = fgets(tmpstr, sizeof(tmpstr), f);
+
+	    /* now get the CD number */
+	    if (tmpptr) {
+		unsigned int len;
+		char *p, *newstr;
+
+		tmpptr = fgets(tmpstr, sizeof(tmpstr), f);
+		
+		/* nuke newline from end of descr, stick number on end*/
+		for (p=descr+strlen(descr); p != descr && !isspace(*p); p--);
+
+		*p = '\0';
+		len = strlen(descr) + strlen(tmpstr) + 10;
+		newstr = malloc(len);
+		strncpy(newstr, descr, len-1);
+		strncat(newstr, " ", len-1);
+
+		/* is this a DVD or not?  If disc id has commas, like */
+		/* "1,2,3", its a DVD                                 */
+		if (strchr(tmpstr, ','))
+		    strncat(newstr, "DVD\n", len-1);
+		else {
+		    strncat(newstr, "disc ", len-1);
+		    strncat(newstr, tmpstr, len-1);
+		}
+
+		free(descr);
+		descr = newstr;
+	    }
+
+	    fclose(f);
+	}
+    }
+
+    free(stampfile);
+
+    umount("/tmp/testmnt");
+    if (filetype == 2)
+	umountLoopback("/tmp/testmnt", "/dev/loop6");
+
+    if (descr != NULL && tstamp != NULL) {
+	descr[strlen(descr)-1] = '\0';
+	*releasedescr = descr;
+
+	tstamp[strlen(tstamp)-1] = '\0';
+	*timestamp = tstamp;
+
+	rc = 0;
+    } else {
+	rc = 1;
+    }	
+
+    return rc;
+}
+
+/* XXX this ignores "location", which should be fixed
+ *
+ * Given a starting isoFile, will offer choice to mediacheck it and
+ * all other ISO images in the same directory with the same stamp
+ */
+void queryIsoMediaCheck(char *isoFile) {
+    DIR * dir;
+    struct dirent * ent;
+    char *isoDir;
+    char isoImage[1024];
+    char tmpmessage[1024];
+    char *master_timestamp;
+    char *tmpstr;
+    int rc, first;
+
+    /* dont bother to test in automated installs */
+    if (FL_KICKSTART(flags) && !FL_MEDIACHECK(flags))
+	return;
+
+    /* if they did not specify to mediacheck explicitely then return */
+    if (!FL_MEDIACHECK(flags))
+	return;
+
+    /* check that file is actually an iso */
+    if (!fileIsIso(isoFile))
+	return;
+
+    /* get stamp of isoFile, free descr since we dont care */
+    readStampFileFromIso(isoFile, &master_timestamp, &tmpstr);
+    free(tmpstr);
+    
+    /* get base path from isoFile */
+    tmpstr = strdup(isoFile);
+    isoDir = strdup(dirname(tmpstr));
+    free(tmpstr);
+
+    logMessage(DEBUGLVL, "isoFile = %s", isoFile);
+    logMessage(DEBUGLVL, "isoDir  = %s", isoDir);
+    logMessage(DEBUGLVL, "Master Timestemp = %s", master_timestamp);
+
+    if (!(dir = opendir(isoDir))) {
+	newtWinMessage(_("Error"), _("OK"), 
+		       _("Failed to read directory %s: %m"),
+		       isoDir);
+	free(isoDir);
+	free(master_timestamp);
+	return;
+    }
+
+    /* Walk through the directories looking for a CD images. */
+    errno = 0;
+    first = 0;
+    while (1) {
+	char *nextname;
+	char *tdescr, *tstamp;
+
+	if (first) {
+	    first = 1;
+	    nextname = isoFile;
+	} else {
+	    ent = readdir(dir);
+	    if (!ent)
+		break;
+
+	    nextname = ent->d_name;
+	}
+
+	/* synthesize name of iso from isoDir and file entry */
+	snprintf(isoImage, sizeof(isoImage), "%s/%s", isoDir, nextname);
+
+	/* see if this is an iso image */
+	if (!fileIsIso(isoImage)) {
+	    errno = 0;
+	    continue;
+	}
+
+	/* see if its part of the current CD set */
+	readStampFileFromIso(isoImage, &tstamp, &tdescr);
+	if (strcmp(tstamp, master_timestamp)) {
+	    errno = 0;
+	    continue;
+	}
+	    
+	/* found a valid candidate, proceed */
+	snprintf(tmpmessage, sizeof(tmpmessage),
+		 _("Would you like to perform a checksum "
+		   "test of the ISO image:\n\n   %s?"), isoImage);
+
+	rc = newtWinChoice(_("Checksum Test"), _("Test"), _("Skip"),
+			   tmpmessage);
+
+	if (rc == 2) {
+	    logMessage(INFO, "mediacheck: skipped checking of %s", isoImage);
+	    if (tdescr)
+		free(tdescr);
+	    continue;
+	} else {
+	    doMediaCheck(isoImage, tdescr);
+	    if (tdescr)
+		free(tdescr);
+
+	    continue;
+	}
+    }
+
+    free(isoDir);
+    free(master_timestamp);
+    closedir(dir);
+}
+
+static void copyWarnFn (char *msg) {
+   logMessage(WARNING, msg);
+}
+
+static void copyErrorFn (char *msg) {
+   newtWinMessage(_("Error"), _("OK"), _(msg));
+}
+
+/* 
+ * unpack a gzipped cpio ball into a tree rooted at rootDir
+ * returns 0 on success, 1 on failure
+ */
+int unpackCpioBall(char * ballPath, char * rootDir) {
+    gzFile fd;
+    char *buf, *cwd;
+    int rc = 1;
+
+    if (access(ballPath, R_OK))
+        return 1;
+
+    if (access(rootDir, R_OK))
+        mkdirChain(rootDir);
+
+    buf = (char *)malloc(PATH_MAX);
+    cwd = getcwd(buf, PATH_MAX);
+    if ((rc = chdir(rootDir)) == 0) {
+        fd = gunzip_open(ballPath);
+        if (fd) {
+            if (!installCpioFile(fd, NULL, NULL, 0)) {
+                logMessage(INFO, "copied contents of %s into %s", ballPath,
+                           rootDir);
+                rc = chdir(cwd);
+                return 0;
+            }
+            gunzip_close(fd);
+        }
+        rc = chdir(cwd);
+    }
+
+    return 1;
+}
+
+void copyUpdatesImg(char * path) {
+    if (!access(path, R_OK)) {
+        if (!mountLoopback(path, "/tmp/update-disk", "/dev/loop7")) {
+            copyDirectory("/tmp/update-disk", "/tmp/updates", copyWarnFn,
+                          copyErrorFn);
+            umountLoopback("/tmp/update-disk", "/dev/loop7");
+            unlink("/tmp/update-disk");
+        } else {
+            unpackCpioBall(path, "/tmp/updates");
+        }
+    }
+}
+
+void copyProductImg(char * path) {
+    if (!access(path, R_OK)) {
+        if (!mountLoopback(path, "/tmp/product-disk", "/dev/loop7")) {
+            copyDirectory("/tmp/product-disk", "/tmp/product", copyWarnFn,
+                          copyErrorFn);
+            umountLoopback("/tmp/product-disk", "/dev/loop7");
+            unlink("/tmp/product-disk");
+        }
+    }
+}
+
+/** Bind the uncompressed second stage to /mnt/runtime.
+ *
+ * return 0 on success, 1 on failure to mount.
+ */
+int mountStage2Direct(char *stage2Path) {
+    if (access(stage2Path, R_OK)) {
+        return 1;
+    }
+
+    char *target = "/mnt/runtime";
+    char *error = NULL;
+    if (doBindMount(stage2Path, target, &error)) {
+        logMessage(ERROR, "failed to bind %s to %s: %s",
+                   stage2Path, target, error);
+        free(error);
+        return 1;
+    }
+    logMessage(INFO, "successfully bound %s to %s", stage2Path, target);
+    return 0;
+}
+
+/* mount a second stage, verify the stamp file, copy updates 
+ * Returns 0 on success, 1 on failure to mount, -1 on bad stamp */
+int mountStage2(char *stage2path) {
+    if (access(stage2path, R_OK)) {
+        return 1;
+    }
+
+    if (mountLoopback(stage2path, "/mnt/runtime", "/dev/loop0")) {
+        return 1;
+    }
+
+    return 0;
+}
+
+
+/* copies a second stage from fd to dest and mounts on mntpoint */
+int copyFileAndLoopbackMount(int fd, char * dest, char * device, char * mntpoint,
+                             progressCB pbcb, struct progressCBdata *data,
+                             long long total) {
+    int rc;
+    struct stat sb;
+
+    rc = copyFileFd(fd, dest, pbcb, data, total);
+    stat(dest, &sb);
+    logMessage(DEBUGLVL, "copied %" PRId64 " bytes to %s (%s)", sb.st_size, dest, 
+               ((rc) ? " incomplete" : "complete"));
+    
+    if (rc) {
+	/* just to make sure */
+	unlink(dest);
+	return 1;
+    }
+
+    if (mountLoopback(dest, mntpoint, device)) {
+        /* JKFIXME: this used to be fatal, but that seems unfriendly */
+        logMessage(ERROR, "Error mounting %s on %s: %m", device, mntpoint);
+        return 1;
+    }
+
+    return 0;
+}
+
+/* given a device name (w/o '/dev' on it), try to get a file */
+/* Error codes: 
+      1 - could not create device node
+      2 - could not mount device as ext2, vfat, or iso9660
+      3 - file named path not there
+*/
+int getFileFromBlockDevice(char *device, char *path, char * dest) {
+    int rc, i;
+    char file[4096];
+
+    logMessage(INFO, "getFileFromBlockDevice(%s, %s)", device, path);
+
+    /* some USB thumb drives and hard drives are slow to initialize */
+    /* retry up to 5 times or 31 seconds */
+    rc = doPwMount(device, "/tmp/mnt", "auto", "ro", NULL);
+    for (i = 0; mountMightSucceedLater(rc) && i < 5; ++i) {
+        logMessage(INFO, "sleeping to wait for USB storage devices");
+        sleep(1 << i);
+        rc = doPwMount(device, "/tmp/mnt", "auto", "ro", NULL);
+        logMessage(ERROR, "error code: %d", rc);
+    }
+    if (rc) {
+        logMessage(ERROR, "failed to mount /dev/%s: %m", device);
+        return 2;
+    }
+
+    snprintf(file, sizeof(file), "/tmp/mnt/%s", path);
+    logMessage(INFO, "Searching for file on path %s", file);
+    
+    if (access(file, R_OK)) {
+	rc = 3;
+    } else {
+	copyFile(file, dest);
+	rc = 0;
+	logMessage(INFO, "file copied to %s", dest);
+    }    
+
+    umount("/tmp/mnt");
+    unlink("/tmp/mnt");
+    return rc;
+}
+
+void setStage2LocFromCmdline(char * arg, struct loaderData_s * ld) {
+    if (!strncmp(arg, "nfs:", 4)) {
+        ld->method = METHOD_NFS;
+        ld->stage2Data = calloc(sizeof(struct nfsInstallData *), 1);
+
+        parseNfsHostPathOpts(arg + 4,
+          &(((struct nfsInstallData *)ld->stage2Data)->host),
+          &(((struct nfsInstallData *)ld->stage2Data)->directory),
+          &(((struct nfsInstallData *)ld->stage2Data)->mountOpts));
+        stripTrailingSlash(((struct nfsInstallData *)ld->stage2Data)->directory);
+    } else if (!strncmp(arg, "nfsiso:", 7)) {
+        ld->method = METHOD_NFS;
+        ld->stage2Data = calloc(sizeof(struct nfsInstallData *), 1);
+
+        parseNfsHostPathOpts(arg + 7,
+          &(((struct nfsInstallData *)ld->stage2Data)->host),
+          &(((struct nfsInstallData *)ld->stage2Data)->directory),
+          &(((struct nfsInstallData *)ld->stage2Data)->mountOpts));
+    } else if (!strncmp(arg, "ftp:", 4) ||
+               !strncmp(arg, "http", 4)) {
+        ld->method = METHOD_URL;
+        ld->stage2Data = calloc(sizeof(struct urlInstallData *), 1);
+        ((urlInstallData *)ld->stage2Data)->url = strdup(arg);
+    } else if (!strncmp(arg, "cdrom:", 6)) {
+        ld->method = METHOD_CDROM;
+    } else if (!strncmp(arg, "harddrive:", 10) ||
+               !strncmp(arg, "hd:", 3)) {
+        size_t offset;
+
+	arg += strcspn(arg, ":");
+	if (!*arg || !*(arg+1))
+	    return;
+	arg += 1;
+        offset = strcspn(arg, ":");
+
+        ld->method = METHOD_HD;
+        ld->stage2Data = calloc(sizeof(struct hdInstallData *), 1);
+        ((struct hdInstallData *)ld->stage2Data)->partition = strndup(arg, offset);
+	arg += offset;
+	if (*arg && *(arg+1))
+            ((struct hdInstallData *)ld->stage2Data)->directory = strdup(arg+1);
+        else
+            ((struct hdInstallData *)ld->stage2Data)->directory = NULL;
+    }
+}
diff --git a/bin/loader/method.h b/bin/loader/method.h
new file mode 100644
index 0000000..cabd1c2
--- /dev/null
+++ b/bin/loader/method.h
@@ -0,0 +1,60 @@
+/*
+ * method.h
+ *
+ * Copyright (C) 2007  Red Hat, Inc.  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 as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef H_METHOD
+#define H_METHOD
+
+#include "loader.h"
+#include "windows.h"
+
+/* method identifiers, needs to match struct installMethod order in loader.c */
+enum {
+    METHOD_CDROM,
+    METHOD_HD,
+    METHOD_NFS,
+    METHOD_URL
+};
+
+struct installMethod {
+    char * name;
+    int network;
+    enum deviceType type;
+    char * (*mountImage)(struct installMethod * method,
+                         char * location, struct loaderData_s * loaderData);
+};
+
+int umountLoopback(char * mntpoint, char * device);
+int mountLoopback(char * fsystem, char * mntpoint, char * device);
+
+int readStampFileFromIso(char *file, char **descr, char **timestamp);
+void queryIsoMediaCheck(char * isoDir);
+
+int mountStage2(char *stage2path);
+int mountStage2Direct(char *stage2path);
+int copyFileAndLoopbackMount(int fd, char *dest, char *device, char *mntpoint,
+                             progressCB pbcb, struct progressCBdata *data, long long total);
+int getFileFromBlockDevice(char *device, char *path, char * dest);
+
+int unpackCpioBall(char * ballPath, char * rootDir);
+void copyUpdatesImg(char * path);
+void copyProductImg(char * path);
+
+void setStage2LocFromCmdline(char * arg, struct loaderData_s * ld);
+
+#endif
diff --git a/bin/loader/mkctype.c b/bin/loader/mkctype.c
new file mode 100644
index 0000000..12eaba0
--- /dev/null
+++ b/bin/loader/mkctype.c
@@ -0,0 +1,76 @@
+/*
+ * mkctype.c
+ *
+ * Copyright (C) 2007  Red Hat, Inc.  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 as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <ctype.h>
+#include <stdio.h>
+
+#if __GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ > 2)
+# define __ctype_b (*__ctype_b_loc())
+# define __ctype_tolower (*__ctype_tolower_loc())
+# define __ctype_toupper (*__ctype_toupper_loc())
+#endif
+
+int main(int argc, char ** argv) {
+    int i;
+
+    printf("#include <sys/types.h>\n\n");
+
+    printf("static const unsigned short int __ctype_b_internal[] = {");
+
+    for (i = -128; i < 256; i++) {
+	if (!(i % 8)) {
+	    printf("\n");
+	}
+
+	printf("\t0x%x,", __ctype_b[i]);
+    }
+
+    printf("\n};\n\n");
+    printf("const unsigned short int * __ctype_b = __ctype_b_internal + 128;\n\n");
+
+    printf("const int __ctype_toupper_internal[] = {");
+    for (i = -128; i < 256; i++) {
+	if (!(i % 8)) {
+	    printf("\n");
+	}
+
+	printf("\t0x%x,", __ctype_toupper[i]);
+    }
+
+    printf("\n};\n\n");
+    printf("const int * __ctype_toupper = __ctype_toupper_internal + 128;\n\n");
+
+    printf("const int __ctype_tolower_internal[] = {");
+    for (i = -128; i < 256; i++) {
+	if (!(i % 8)) {
+	    printf("\n");
+	}
+
+	printf("\t0x%x,", __ctype_tolower[i]);
+    }
+
+    printf("\n};\n\n");
+    printf("const int * __ctype_tolower = __ctype_tolower_internal + 128;\n\n");
+
+    printf ("const unsigned short int **__ctype_b_loc (void) { return &__ctype_b; }\n");
+    printf ("const int **__ctype_toupper_loc (void) { return &__ctype_toupper; }\n");
+    printf ("const int **__ctype_tolower_loc (void) { return &__ctype_tolower; }\n\n");
+
+    return 0;
+};
diff --git a/bin/loader/moduleinfo.c b/bin/loader/moduleinfo.c
new file mode 100644
index 0000000..2e0ab77
--- /dev/null
+++ b/bin/loader/moduleinfo.c
@@ -0,0 +1,276 @@
+/*
+ * moduleinfo.c - module info functionality
+ *
+ * Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002  Red Hat, Inc.
+ * 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 as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ *
+ * Author(s): Erik Troan <ewt@xxxxxxxxxx>
+ *            Matt Wilson <msw@xxxxxxxxxx>
+ */
+
+#include <alloca.h>
+#include <ctype.h>
+#include <fcntl.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/stat.h>
+#include <unistd.h>
+
+#include <stdio.h>
+
+#include "moduleinfo.h"
+
+struct moduleInfo * getModuleList(moduleInfoSet mis, 
+                                  enum driverMajor major) {
+    struct moduleInfo * miList, * next;
+    int i;
+
+    next = miList = malloc(sizeof(*miList) * mis->numModules + 1);
+    for (i = 0; i < mis->numModules; i++) {
+        if (mis->moduleList[i].major == major || major == DRIVER_NONE) {
+            *next = mis->moduleList[i];
+            next++;
+        }
+    }
+
+    if (next == miList) {
+        free(next);
+        return NULL;
+    }
+
+    next->moduleName = NULL;
+    next++;
+
+    miList = realloc(miList, sizeof(*miList) * (next - miList));
+    return miList;
+}
+
+struct moduleInfo * findModuleInfo(moduleInfoSet mis, 
+                                   const char * moduleName) {
+    int i;
+    struct moduleInfo * found = NULL;
+
+    for (i = 0; i < mis->numModules; i++) {
+        if (!strcmp(moduleName, mis->moduleList[i].moduleName)) {
+            if (!found)
+                found = mis->moduleList + i;
+            else if (found->locationID && !mis->moduleList[i].locationID)
+                ;
+            else
+                found = mis->moduleList + i;
+        }
+    }
+
+    return found;
+}
+
+moduleInfoSet newModuleInfoSet(void) {
+    return calloc(sizeof(struct moduleInfoSet_s), 1);
+}
+
+/* filename: file to read module-info from
+ * mis: moduleInfoSet
+ * location: moduleBallLocation struct describing the location of 
+ *           these modules.  (may be NULL)
+ * override: 1 if modules from this module ball should override old ones
+ *           of the same name.
+ */
+int readModuleInfo(const char * filename, moduleInfoSet mis, 
+                   void * location, int override) {
+    int fd, isIndented;
+    char * buf, * start, * next = NULL, * chptr;
+    struct stat sb;
+    char oldch;
+    struct moduleInfo * nextModule;
+    int modulesAlloced;
+    int i;
+    int found = 0, skipModule = 0;
+
+    fd = open(filename, O_RDONLY);
+    if (fd < 0) return -1;
+ 
+    fstat(fd, &sb);
+    buf = alloca(sb.st_size + 1);
+    i = read(fd, buf, sb.st_size);
+    buf[sb.st_size] = '\0';
+    close(fd);
+
+    if (i != sb.st_size)
+        return -1;
+
+    nextModule = NULL;
+    modulesAlloced = mis->numModules;
+
+    if (strncmp(buf, "Version 0\n", 10)) return -1;
+
+    start = buf + 10;
+    while (start && *start) {
+        chptr = strchr(start, '\n');
+        if (chptr) {
+            /* slice and dice */
+            next = chptr + 1;
+        } else {
+            chptr += strlen(start) - 1;
+        }
+
+        chptr--;
+        while (isspace(*chptr)) chptr--;
+        chptr++;
+        *chptr = '\0';
+
+        isIndented = 0;
+        if (isspace(*start)) {
+            while (isspace(*start) && *start != '\n') start++;
+            isIndented = 1;
+        }
+
+        if (*start != '\n' && *start && *start != '#') {
+            if (!isIndented) {
+                if (nextModule && nextModule->moduleName &&
+                    nextModule == (mis->moduleList + mis->numModules)) {
+                        mis->numModules++; 
+                }
+
+                if (mis->numModules == modulesAlloced) {
+                    modulesAlloced += 5;
+                    mis->moduleList = realloc(mis->moduleList,
+                        modulesAlloced * sizeof(*mis->moduleList));
+                }
+
+                nextModule = NULL;
+                found = 0;
+                skipModule = 0;
+                for (i = 0; i < mis->numModules; i++) {
+                    if (!strcmp(mis->moduleList[i].moduleName, start)) {
+                        if (override) 
+                            nextModule = mis->moduleList + i;
+                        else
+                            skipModule = 1;
+                        found = 1;
+                        break;
+                    }
+                }
+
+                if (!found && !nextModule) {
+                    nextModule = mis->moduleList + mis->numModules;
+
+                    nextModule->moduleName = strdup(start);
+                } 
+
+                if (nextModule) {
+                    nextModule->major = DRIVER_NONE;
+                    nextModule->minor = DRIVER_MINOR_NONE;
+                    nextModule->description = NULL;
+                    nextModule->flags = 0;
+                    nextModule->args = NULL;
+                    nextModule->numArgs = 0;
+                    nextModule->locationID = location;
+                }
+            } else if (!nextModule && skipModule) {
+                /* we're skipping this one (not overriding), do nothing */
+            } else if (!nextModule && skipModule) {
+                /* ACK! syntax error */
+                fprintf(stderr, "module-info syntax error in %s\n", filename);
+                return 1;
+            } else if (nextModule->major == DRIVER_NONE) {
+                chptr = start + strlen(start) - 1;
+                while (!isspace(*chptr) && chptr > start) chptr--;
+                if (chptr != start) chptr++;
+
+                if (!strcmp(chptr, "eth")) {
+                    nextModule->major = DRIVER_NET;
+                    nextModule->minor = DRIVER_MINOR_ETHERNET;
+                } else if (!strcmp(chptr, "tr")) {
+                    nextModule->major = DRIVER_NET;
+                    nextModule->minor = DRIVER_MINOR_TR;
+                } else if (!strcmp(chptr, "scsi_hostadapter") ||
+                           !strcmp(chptr, "scsi")) {
+                    nextModule->major = DRIVER_SCSI;
+                } else if (!strcmp(chptr, "pcmcia")) {
+                    nextModule->major = DRIVER_PCMCIA;
+                } else if (!strcmp(chptr, "fs")) {
+                    nextModule->major = DRIVER_FS;
+                } else if (!strcmp(chptr, "cdrom")) {
+                    nextModule->major = DRIVER_CDROM;
+                } else if (!strcmp(chptr, "ide")) {
+                    nextModule->major = DRIVER_IDE;
+                } else {
+                    nextModule->major = DRIVER_OTHER;
+                }
+            } else if (!nextModule->description) {
+                chptr = start + strlen(start) - 1;
+                if (*start == '"' && *chptr == '"') {
+                    start++;
+                    *chptr = '\0';
+                    nextModule->description = strdup(start);
+                }
+            } else {
+                nextModule->args = realloc(nextModule->args,
+                        sizeof(*nextModule->args) * (nextModule->numArgs + 1));
+                chptr = start;
+                while (!isspace(*chptr) && *chptr) chptr++;
+                if (*chptr) {
+                    oldch = *chptr;
+                    *chptr = '\0';
+                    nextModule->args[nextModule->numArgs].arg = strdup(start);
+
+                    start = chptr + 1;
+                    while (*start && isspace(*start)) start++;
+
+                    if (*start == '"') {
+                        start++;
+                        chptr = strchr(start, '"');
+                        if (chptr) {
+                            *chptr = '\0';
+                            nextModule->args[nextModule->numArgs].description = 
+                                strdup(start);
+                            nextModule->numArgs++;
+                        }
+                    }
+                }
+            }
+        }
+
+        start = next;
+    }
+
+    /* do we need to add in this last module? */
+    if (nextModule && ((nextModule - mis->moduleList) == mis->numModules))
+        mis->numModules++;
+
+    return 0;
+}
+
+void freeModuleInfoSet(moduleInfoSet mis) {
+    int i, j;
+
+    for (i = 0; i < mis->numModules; i++) {
+        if (mis->moduleList[i].moduleName) 
+            free(mis->moduleList[i].moduleName);
+
+        if (mis->moduleList[i].description) 
+            free(mis->moduleList[i].description);
+
+        for (j = 0; i < mis->moduleList[i].numArgs; j++) {
+            if (mis->moduleList[i].args[j].arg) 
+                free(mis->moduleList[i].args[j].arg) ;
+            if (mis->moduleList[i].args[j].description) 
+                free(mis->moduleList[i].args[j].description) ;
+        }
+    }
+
+    free(mis);
+}
diff --git a/bin/loader/moduleinfo.h b/bin/loader/moduleinfo.h
new file mode 100644
index 0000000..72f6d71
--- /dev/null
+++ b/bin/loader/moduleinfo.h
@@ -0,0 +1,78 @@
+/*
+ * moduleinfo.h
+ *
+ * Copyright (C) 2007  Red Hat, Inc.  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 as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef MODULEINFO_H
+#define MODULEINFO_H
+
+enum driverMajor { DRIVER_NONE = 0, DRIVER_SCSI, DRIVER_NET, DRIVER_CDROM,
+		   DRIVER_PCMCIA, DRIVER_FS, DRIVER_IDE, DRIVER_OTHER = 1000,
+                   DRIVER_ANY = 5000 };
+enum driverMinor { DRIVER_MINOR_NONE = 0, DRIVER_MINOR_ETHERNET,
+		   DRIVER_MINOR_TR };
+
+struct moduleArg {
+    char * arg;
+    char * description;
+};
+
+#define MI_FLAG_NOMISCARGS	(1 << 0)
+
+struct moduleInfo {
+    char * moduleName;
+    char * description;
+    enum driverMajor major;
+    enum driverMinor minor;
+    int numArgs;
+    struct moduleArg * args;
+    int flags;
+    void * locationID;
+};
+
+struct moduleInfoSet_s {
+    struct moduleInfo * moduleList;
+    int numModules;
+};
+
+struct moduleBallLocation {
+    char * path; /* path to module ball that this driver is from. if NULL,
+                  * implies /modules/modules.cgz */
+    char * title; /* title used for driver disk -- may be NULL */
+    int version;  /* module ball version, used to determine layout */
+};
+#define CURRENT_MODBALLVER 1
+
+/* valid moduleball versions
+ * 0: old single-arch module ball, modules are in uname.release
+ * 1: multi-arch, modules are in uname.release/arch
+ */
+
+typedef struct moduleInfoSet_s * moduleInfoSet;
+
+moduleInfoSet newModuleInfoSet(void);
+void freeModuleInfoSet(moduleInfoSet mis);
+int readModuleInfo(const char * filename, moduleInfoSet mis, void * path, int override);
+struct moduleInfo * findModuleInfo(moduleInfoSet mis, 
+				   const char * moduleName);
+
+/* NULL moduleName indicates the end of the list; the list must be freed() */
+struct moduleInfo * getModuleList(moduleInfoSet mis, 
+				  enum driverMajor major);
+
+
+#endif
diff --git a/bin/loader/modules.c b/bin/loader/modules.c
new file mode 100644
index 0000000..89f956c
--- /dev/null
+++ b/bin/loader/modules.c
@@ -0,0 +1,530 @@
+/*
+ * modules.c - module loading functionality
+ *
+ * Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007,
+ *               2008, 2009  Red Hat, Inc.
+ * 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 as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ *
+ * Author(s): Erik Troan <ewt@xxxxxxxxxx>
+ *            Matt Wilson <msw@xxxxxxxxxx>
+ *            Michael Fulbright <msf@xxxxxxxxxx>
+ *            Jeremy Katz <katzj@xxxxxxxxxx>
+ *            David Cantrell <dcantrell@xxxxxxxxxx>
+ */
+#include <ctype.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <newt.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <sys/mman.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <sys/utsname.h>
+#include <sys/wait.h>
+#include <unistd.h>
+#include <glib.h>
+#include <glib/gprintf.h>
+#include <assert.h>
+
+#include "../isys/log.h"
+
+#include "loader.h"
+#include "modules.h"
+#include "windows.h"
+
+/* boot flags */
+extern uint64_t flags;
+
+static GSList *modopts = NULL;
+static GSList *blacklist = NULL;
+
+static gboolean _isValidModule(gchar *module) {
+    gint fd = -1, i = 0;
+    gchar *path = NULL, *buf = NULL, *modname = NULL;
+    gchar *ends[] = { ".ko.gz:", ".ko:", NULL };
+    struct utsname utsbuf;
+    struct stat sbuf;
+
+    if (uname(&utsbuf) == -1) {
+        logMessage(ERROR, "%s (%d): %m", __func__, __LINE__);
+        return FALSE;
+    }
+
+    if (asprintf(&path, "/lib/modules/%s/modules.dep", utsbuf.release) == -1) {
+        logMessage(ERROR, "%s (%d): %m", __func__, __LINE__);
+        return FALSE;
+    }
+
+    if (stat(path, &sbuf) == -1) {
+        logMessage(ERROR, "%s (%d): %m", __func__, __LINE__);
+        free(path);
+        return FALSE;
+    }
+
+    if ((fd = open(path, O_RDONLY)) == -1) {
+        logMessage(ERROR, "%s (%d): %m", __func__, __LINE__);
+        free(path);
+        return FALSE;
+    } else {
+        free(path);
+    }
+
+    buf = mmap(0, sbuf.st_size, PROT_READ, MAP_SHARED, fd, 0);
+    if (!buf || buf == MAP_FAILED) {
+        close(fd);
+        return FALSE;
+    }
+
+    close(fd);
+
+    while (ends[i] != NULL) {
+        if (asprintf(&modname, "/%s%s", module, ends[i]) == -1) {
+            logMessage(ERROR, "%s (%d): %m", __func__, __LINE__);
+            return FALSE;
+        }
+
+        if (g_strstr_len(buf, -1, modname) != NULL) {
+            munmap(buf, sbuf.st_size);
+            free(modname);
+            return TRUE;
+        }
+
+        free(modname);
+        modname = NULL;
+        i++;
+    }
+
+    munmap(buf, sbuf.st_size);
+    return FALSE;
+}
+
+static void _addOption(const gchar *module, const gchar *option) {
+    gboolean found = FALSE;
+    GSList *iterator = modopts;
+    module_t *modopt = NULL;
+    gchar *tmpopt = g_strdup(option);
+
+    while (iterator != NULL) {
+        modopt = (module_t *) iterator->data;
+
+        if (!strncmp(modopt->name, module, strlen(modopt->name))) {
+            found = TRUE;
+            break;
+        }
+
+        iterator = g_slist_next(iterator);
+    }
+
+    if (found) {
+        modopt->options = g_slist_append(modopt->options, tmpopt);
+    } else {
+        if ((modopt = g_malloc0(sizeof(module_t))) == NULL) {
+            logMessage(ERROR, "%s (%d): %m", __func__, __LINE__);
+            abort();
+        }
+
+        modopt->name = g_strdup(module);
+        modopt->options = NULL;
+        modopt->options = g_slist_append(modopt->options, tmpopt);
+        modopts = g_slist_append(modopts, modopt);
+    }
+
+    return;
+}
+
+static gboolean _writeModulesConf(gchar *conf) {
+    gint fd = -1, rc = 0, len = 0;
+    GSList *iterator = modopts;
+    GString *buf = g_string_new("# Module options and blacklists written by anaconda\n");
+
+    if (conf == NULL) {
+        /* XXX: should this use mkstemp() ? */
+        conf = "/tmp/modprobe.conf";
+    }
+
+    if ((fd = open(conf, O_WRONLY | O_CREAT, 0644)) == -1) {
+        logMessage(ERROR, "error opening to %s: %m", conf);
+        return FALSE;
+    }
+
+    while (iterator != NULL) {
+        module_t *modopt = iterator->data;
+        GSList *optiterator = modopt->options;
+        g_string_append_printf(buf, "options %s", modopt->name);
+
+        while (optiterator != NULL) {
+            gchar *option = (gchar *) optiterator->data;
+            g_string_append_printf(buf, " %s", option);
+            optiterator = g_slist_next(optiterator);
+        }
+
+        g_string_append(buf, "\n");
+        iterator = g_slist_next(iterator);
+    }
+
+    iterator = blacklist;
+
+    while (iterator != NULL) {
+        gchar *module = (gchar *) iterator->data;
+        g_string_append_printf(buf, "blacklist %s\n", module);
+        iterator = g_slist_next(iterator);
+    }
+
+    len = buf->len;
+    rc = write(fd, buf->str, len);
+    close(fd);
+    g_string_free(buf, TRUE);
+
+    return (rc == len);
+}
+
+static gboolean _doLoadModule(const gchar *module, gchar **args) {
+    gint child;
+    gint status;
+
+    if (!(child = fork())) {
+        gint i, rc;
+        gchar **argv = NULL;
+        gint fd = -1;
+
+        if ((argv = g_malloc0(3 * sizeof(*argv))) == NULL) {
+            logMessage(ERROR, "%s (%d): %m", __func__, __LINE__);
+            abort();
+        }
+
+        if ((fd = open("/dev/tty3", O_RDWR)) == -1) {
+            logMessage(ERROR, "%s (%d): %m", __func__, __LINE__);
+        } else {
+            dup2(fd, 0);
+            dup2(fd, 1);
+            dup2(fd, 2);
+            close(fd);
+        }
+
+        argv[0] = "/sbin/modprobe";
+        argv[1] = g_strdup(module);
+        argv[2] = NULL;
+
+        if (args) {
+            for (i = 0; args[i] ; i++) {
+                _addOption(module, args[i]);
+            }
+            _writeModulesConf(MODULES_CONF);
+        }
+
+        rc = execv("/sbin/modprobe", argv);
+        g_strfreev(argv);
+        _exit(rc);
+    }
+
+    waitpid(child, &status, 0);
+
+    if (!WIFEXITED(status) || (WIFEXITED(status) && WEXITSTATUS(status))) {
+        return TRUE;
+    } else {
+        return FALSE;
+    }
+}
+
+gboolean mlInitModuleConfig(void) {
+    gint i = 0;
+    gchar *cmdline = NULL;
+    gchar **options = NULL;
+    GError *readErr = NULL;
+
+    /* read module options out of /proc/cmdline and into a structure */
+    if (!g_file_get_contents("/proc/cmdline", &cmdline, NULL, &readErr)) {
+        logMessage(ERROR, "unable to read /proc/cmdline: %s", readErr->message);
+        g_error_free(readErr);
+        return _writeModulesConf(MODULES_CONF);
+    }
+
+    cmdline = g_strchomp(cmdline);
+    options = g_strsplit(cmdline, " ", 0);
+    g_free(cmdline);
+
+    if (options == NULL) {
+        return _writeModulesConf(MODULES_CONF);
+    }
+
+    while (options[i] != NULL) {
+        gchar *tmpmod = NULL;
+        gchar **fields = NULL;
+
+        if (g_strstr_len(options[i], -1, "=") == NULL) {
+            i++;
+            continue;
+        }
+
+        if (!strncmp(options[i], "blacklist=", 10)) {
+            if ((fields = g_strsplit(options[i], "=", 0)) != NULL) {
+                if (g_strv_length(fields) == 2) {
+                    tmpmod = g_strdup(fields[1]);
+                    blacklist = g_slist_append(blacklist, tmpmod);
+                }
+            }
+        } else if ((fields = g_strsplit(options[i], ".", 0)) != NULL) {
+            if (g_strv_length(fields) == 2) {
+                if (_isValidModule(fields[0])) {
+                    _addOption(fields[0], fields[1]);
+                }
+            }
+        }
+
+        if (fields != NULL) {
+            g_strfreev(fields);
+        }
+
+        i++;
+    }
+
+    if (options != NULL) {
+        g_strfreev(options);
+    }
+
+    return _writeModulesConf(MODULES_CONF);
+}
+
+/* load a module with a given list of arguments */
+gboolean mlLoadModule(const gchar *module, gchar **args) {
+    return _doLoadModule(module, args);
+}
+
+/* loads a : separated list of modules */
+gboolean mlLoadModuleSet(const gchar *modNames) {
+    gchar **mods = NULL, **iterator = NULL;
+    gboolean rc = FALSE;
+
+    if (modNames == NULL) {
+        return FALSE;
+    }
+
+    if ((mods = g_strsplit(modNames, ":", 0)) != NULL) {
+        iterator = mods;
+
+        while (*iterator != NULL) {
+            rc |= _doLoadModule(*iterator, NULL);
+            iterator++;
+        }
+    } else {
+        return FALSE;
+    }
+
+    g_strfreev(mods);
+    return rc;
+}
+
+gboolean mlAddBlacklist(gchar *module) {
+    gchar *tmpmod = NULL;
+
+    if (module == NULL) {
+        return FALSE;
+    }
+
+    tmpmod = g_strdup(module);
+    blacklist = g_slist_append(blacklist, tmpmod);
+    return _writeModulesConf(MODULES_CONF);
+}
+
+gboolean mlRemoveBlacklist(gchar *module) {
+    GSList *iterator = blacklist;
+
+    if (module == NULL) {
+        return FALSE;
+    }
+
+    while (iterator != NULL) {
+        if (!strcmp((gchar *) iterator->data, module)) {
+            iterator = g_slist_delete_link(blacklist, iterator);
+            continue;
+        } else {
+            iterator = g_slist_next(iterator);
+        }
+    }
+
+    return TRUE;
+}
+
+void loadKickstartModule(struct loaderData_s * loaderData,
+                         int argc, char **argv) {
+    gchar *opts = NULL;
+    gchar *module = NULL;
+    gchar **args = NULL, **remaining = NULL;
+    gboolean rc;
+    GOptionContext *optCon = g_option_context_new(NULL);
+    GError *optErr = NULL;
+    GOptionEntry ksDeviceOptions[] = {
+        { "opts", 0, 0, G_OPTION_ARG_STRING, &opts, NULL, NULL },
+        { G_OPTION_REMAINING, 0, 0, G_OPTION_ARG_STRING_ARRAY, &remaining,
+          NULL, NULL },
+        { NULL },
+    };
+
+    g_option_context_set_help_enabled(optCon, FALSE);
+    g_option_context_add_main_entries(optCon, ksDeviceOptions, NULL);
+
+    if (!g_option_context_parse(optCon, &argc, &argv, &optErr)) {
+        startNewt();
+        newtWinMessage(_("Kickstart Error"), _("OK"),
+                       _("Bad argument to device kickstart method "
+                         "command: %s"), optErr->message);
+        g_error_free(optErr);
+        g_option_context_free(optCon);
+        return;
+    }
+
+    g_option_context_free(optCon);
+
+    if ((remaining != NULL) && (g_strv_length(remaining) == 1)) {
+        module = remaining[0];
+    }
+
+    if (!module) {
+        startNewt();
+        newtWinMessage(_("Kickstart Error"), _("OK"),
+                       _("A module name must be specified for "
+                         "the kickstart device command."));
+        return;
+    }
+
+    if (opts) {
+        args = g_strsplit(opts, " ", 0);
+    }
+
+    rc = mlLoadModule(module, args);
+    g_strfreev(args);
+    return;
+}
+
+inline gint gcmp(gconstpointer a, gconstpointer b, gpointer userptr)
+{
+    return g_strcmp0(a, b);
+}
+
+int processModuleLines(GTree *data, int (*f)(gchar**, GTree*)){
+    char *line = NULL;
+    size_t linesize = 0;
+    gchar** lineparts = NULL;
+    int count = 0;
+
+    FILE *file = fopen("/proc/modules", "r");
+    if (file == NULL)
+        return -1;
+
+    while (1) {
+        if (getline(&line, &linesize, file) < 0)
+            break;
+
+        if (*line == NULL)
+            break;
+
+        lineparts = g_strsplit_set(line, " ", 4);
+
+        free(line);
+        line = NULL;
+
+        int ret = f(lineparts, data);
+        g_strfreev(lineparts);
+
+        if (ret < 0)
+            break;
+        count+=ret;
+    }
+
+    fclose(file);
+    return count;
+}
+
+inline int cb_savestate(gchar** parts, GTree *data)
+{
+    logMessage(DEBUGLVL, "Saving module %s", parts[0]);
+    g_tree_insert(data, g_strdup(parts[0]), (gchar*)1);
+    return 1;
+}
+
+GTree* mlSaveModuleState()
+{
+    GTree *state = NULL;
+
+    state = g_tree_new_full(gcmp, NULL, g_free, NULL);
+    if(!state)
+        return NULL;
+
+    processModuleLines(state, cb_savestate);
+
+    return state;
+}
+
+inline int cb_restorestate(gchar** parts, GTree *data)
+{
+    pid_t pid;
+    int status;
+
+    /* this module has to stay loaded */
+    if (g_tree_lookup(data, parts[0])){
+        return 0;
+    }
+
+    /* this module is still required */
+    if (parts[2][0] != '0') {
+        return 0;
+    }
+
+    /* rmmod parts[0] */
+    pid = fork();
+    if (pid == 0) {
+        execl("/sbin/rmmod", "-f", parts[0], NULL);
+        _exit(1);
+    }
+    else if (pid < 0) {
+        logMessage(ERROR, "Module %s removal FAILED", parts[0]);
+        return 0;
+    }
+
+    waitpid(pid, &status, 0);
+    if (WEXITSTATUS(status)) {
+        logMessage(DEBUGLVL, "Module %s was NOT removed", parts[0]);
+        return 0;
+    }
+    else{
+        logMessage(DEBUGLVL, "Module %s was removed", parts[0]);
+        return 1;
+    }
+    
+    return 0;
+}
+
+void mlRestoreModuleState(GTree *state)
+{
+    if(!state)
+        return;
+
+    logMessage(INFO, "Restoring module state...");
+
+    /* repeat until we can't remove anything else */
+    while (processModuleLines(state, cb_restorestate) > 0)
+        /* noop */;
+}
+
+void mlFreeModuleState(GTree *state)
+{
+    if(!state)
+        return;
+
+    g_tree_destroy(state);
+}
diff --git a/bin/loader/modules.h b/bin/loader/modules.h
new file mode 100644
index 0000000..605d01e
--- /dev/null
+++ b/bin/loader/modules.h
@@ -0,0 +1,47 @@
+/*
+ * modules.h
+ *
+ * Copyright (C) 2007, 2009  Red Hat, Inc.  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 as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ *
+ * Author(s): David Cantrell <dcantrell@xxxxxxxxxx>
+ */
+
+#ifndef H_MODULES
+#define H_MODULES
+
+#include <glib.h>
+#include "loader.h"
+#include "moduleinfo.h"
+
+#define MODULES_CONF "/etc/modprobe.d/anaconda.conf"
+
+typedef struct _module_t {
+    gchar *name;
+    GSList *options;
+} module_t;
+
+gboolean mlInitModuleConfig(void);
+gboolean mlLoadModule(const gchar *, gchar **);
+gboolean mlLoadModuleSet(const gchar *);
+gboolean mlAddBlacklist(gchar *);
+gboolean mlRemoveBlacklist(gchar *);
+void loadKickstartModule(struct loaderData_s *, int, char **);
+
+GTree* mlSaveModuleState();
+void mlRestoreModuleState(GTree *state);
+void mlFreeModuleState(GTree *state);
+
+#endif
diff --git a/bin/loader/net.c b/bin/loader/net.c
new file mode 100644
index 0000000..0a3afa1
--- /dev/null
+++ b/bin/loader/net.c
@@ -0,0 +1,2122 @@
+/*
+ * net.c
+ *
+ * Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005  Red Hat, Inc.
+ *               2006, 2007, 2008, 2009
+ *
+ * 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; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ *
+ * Author(s): David Cantrell <dcantrell@xxxxxxxxxx>
+ */
+
+#include <netdb.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/ioctl.h>
+#include <sys/socket.h>
+#include <sys/utsname.h>
+#include <arpa/inet.h>
+#include <errno.h>
+#include <resolv.h>
+#include <net/if.h>
+#include <newt.h>
+#include <stdlib.h>
+#include <string.h>
+#include <strings.h>
+#include <unistd.h>
+
+#include <glib.h>
+#include <NetworkManager.h>
+#include <nm-client.h>
+
+#include "../isys/isys.h"
+#include "../isys/ethtool.h"
+#include "../isys/iface.h"
+#include "../isys/log.h"
+
+#include "lang.h"
+#include "loader.h"
+#include "loadermisc.h"
+#include "method.h"
+#include "net.h"
+#include "windows.h"
+#include "ibft.h"
+
+/* boot flags */
+extern uint64_t flags;
+
+/**
+ * Callback function for the CIDR entry boxes on the manual TCP/IP
+ * configuration window.
+ *
+ * @param co The entry field that triggered the callback.
+ * @param dptr Pointer to intfconfig_s data structure for this field.
+ * @see intfconfig_s
+ */
+static void cidrCallback(newtComponent co, void * dptr) {
+    struct intfconfig_s * data = dptr;
+    int cidr, upper = 0;
+    struct in_addr addr;
+
+    if (co == data->cidr4Entry) {
+        if (data->cidr4 == NULL && data->ipv4 == NULL)
+            return;
+
+        if (inet_pton(AF_INET, data->cidr4, &addr) >= 1)
+            return;
+
+        errno = 0;
+        cidr = strtol(data->cidr4, NULL, 10);
+        if ((errno == ERANGE && (cidr == LONG_MIN || cidr == LONG_MAX)) ||
+            (errno != 0 && cidr == 0)) {
+            logMessage(ERROR, "%s: %d: %m", __func__, __LINE__);
+            abort();
+        }
+
+        if (strcmp(data->ipv4, ""))
+            upper = 32;
+#ifdef ENABLE_IPV6
+    } else if (co == data->cidr6Entry) {
+        if (data->cidr6 == NULL && data->ipv6 == NULL)
+            return;
+
+        errno = 0;
+        cidr = strtol(data->cidr6, NULL, 10);
+        if ((errno == ERANGE && (cidr == LONG_MIN || cidr == LONG_MAX)) ||
+            (errno != 0 && cidr == 0)) {
+            logMessage(ERROR, "%s: %d: %m", __func__, __LINE__);
+            abort();
+        }
+
+        if (strcmp(data->ipv6, ""))
+            upper = 128;
+#endif
+    }
+
+    if (upper != 0) {
+        if (cidr < 1 || cidr > upper) {
+            newtWinMessage(_("Invalid Prefix"), _("Retry"),
+                           _("Prefix must be between 1 and 32 "
+                             "for IPv4 networks or between 1 and 128 "
+                             "for IPv6 networks"));
+        }
+    }
+}
+
+static void ipCallback(newtComponent co, void * dptr) {
+    int i;
+    char *buf, *octet;
+    struct intfconfig_s * data = dptr;
+
+    if (co == data->ipv4Entry) {
+        /* do we need to guess a netmask for the user? */
+        if (data->cidr4 == NULL && data->ipv4 != NULL) {
+            buf = strdup(data->ipv4);
+            octet = strtok(buf, ".");
+            errno = 0;
+            i = strtol(octet, NULL, 10);
+
+            if ((errno == ERANGE && (i == LONG_MIN || i == LONG_MAX)) ||
+                (errno != 0 && i == 0)) {
+                logMessage(ERROR, "%s: %d: %m", __func__, __LINE__);
+                abort();
+            }
+
+            free(buf);
+            free(octet);
+
+            if (i >= 0 && i <= 127)
+                newtEntrySet(data->cidr4Entry, "8", 1);
+            else if (i >= 128 && i <= 191)
+                newtEntrySet(data->cidr4Entry, "16", 1);
+            else if (i >= 192 && i <= 222)
+                newtEntrySet(data->cidr4Entry, "24", 1);
+        }
+
+        return;
+#ifdef ENABLE_IPV6
+    } else if (co == data->ipv6Entry) {
+        /* users must provide a mask, we can't guess for ipv6 */
+        return;
+#endif
+    }
+}
+
+static void setMethodSensitivity(void *dptr, int radio_button_count) {
+    int i = 0;
+
+    for (i = 0; i < radio_button_count; i++) {
+        newtCheckboxSetFlags(*((newtComponent *) dptr), NEWT_FLAG_DISABLED,
+                             NEWT_FLAGS_TOGGLE);
+        dptr += sizeof (newtComponent);
+    }
+
+    return;
+}
+
+static void v4MethodCallback(newtComponent co, void *dptr) {
+    setMethodSensitivity(dptr, 2);
+    return;
+}
+
+#ifdef ENABLE_IPV6
+static void v6MethodCallback(newtComponent co, void *dptr) {
+    setMethodSensitivity(dptr, 3);
+    return;
+}
+#endif
+
+static void parseEthtoolSettings(struct loaderData_s * loaderData) {
+    char * option, * buf;
+    ethtool_duplex duplex = ETHTOOL_DUPLEX_UNSPEC;
+    ethtool_speed speed = ETHTOOL_SPEED_UNSPEC;
+    
+    buf = strdup(loaderData->ethtool);
+    option = strtok(buf, " ");
+    while (option) {
+        if (option[strlen(option) - 1] == '\"')
+            option[strlen(option) - 1] = '\0';
+        if (option[0] == '\"')
+            option++;
+        if (!strncmp(option, "duplex", 6)) {
+            if (!strncmp(option + 7, "full", 4)) 
+                duplex = ETHTOOL_DUPLEX_FULL;
+            else if (!strncmp(option + 7, "half", 4))
+                duplex = ETHTOOL_DUPLEX_HALF;
+            else
+                logMessage(WARNING, "Unknown duplex setting: %s", option + 7);
+            option = strtok(NULL, " ");
+        } else if (!strncmp("speed", option, 5)) {
+            if (!strncmp(option + 6, "1000", 4))
+                speed = ETHTOOL_SPEED_1000;
+            else if (!strncmp(option + 6, "100", 3))
+                speed = ETHTOOL_SPEED_100;
+            else if (!strncmp(option + 6, "10", 2))
+                speed = ETHTOOL_SPEED_10;
+            else
+                logMessage(WARNING, "Unknown speed setting: %s", option + 6);
+            option = strtok(NULL, " ");
+        } else {
+            logMessage(WARNING, "Unknown ethtool setting: %s", option);
+        }
+        option = strtok(NULL, " ");
+    }
+    setEthtoolSettings(loaderData->netDev, speed, duplex);
+    free(buf);
+}
+
+/* given loader data from kickstart, populate network configuration struct */
+void setupIfaceStruct(iface_t * iface, struct loaderData_s * loaderData) {
+    struct in_addr addr;
+    struct in6_addr addr6;
+    char * c;
+
+    memset(&addr, 0, sizeof(addr));
+    memset(&addr6, 0, sizeof(addr6));
+
+    if (loaderData->ethtool) {
+        parseEthtoolSettings(loaderData);
+    }
+
+    if (loaderData->netCls_set) {
+        iface->vendorclass = loaderData->netCls;
+    } else {
+        iface->vendorclass = NULL;
+    }
+
+    if (loaderData->ipinfo_set && loaderData->ipv4 != NULL) {
+	/* this is iBFT configured device */
+	if (!strncmp(loaderData->ipv4, "ibft", 4)) {
+	    char *devmacaddr = iface_mac2str(loaderData->netDev);
+	    iface->ipv4method = IPV4_IBFT_METHOD;
+	    iface->isiBFT = 1;
+
+	    /* Problems with getting the info from iBFT or iBFT uses dhcp*/
+	    if(!devmacaddr || !ibft_present()){
+		iface->ipv4method = IPV4_DHCP_METHOD;
+		logMessage(INFO, "iBFT is not present");
+	    }
+
+	    /* MAC address doesn't match */
+	    else if(strcasecmp(ibft_iface_mac(), devmacaddr)){
+		iface->ipv4method = IPV4_DHCP_METHOD;
+		logMessage(INFO, "iBFT doesn't know what NIC to use - falling back to DHCP");
+	    }
+	    else if(ibft_iface_dhcp()){
+		iface->ipv4method = IPV4_IBFT_DHCP_METHOD;
+		logMessage(INFO, "iBFT is configured to use DHCP");
+	    }
+	    if(devmacaddr) free(devmacaddr);
+	}
+        /* this is how we specify dhcp */
+        else if (!strncmp(loaderData->ipv4, "dhcp", 4)) {
+            iface->dhcptimeout = loaderData->dhcpTimeout;
+            iface->ipv4method = IPV4_DHCP_METHOD;
+        } else if (inet_pton(AF_INET, loaderData->ipv4, &addr) >= 1) {
+            iface->ipaddr.s_addr = addr.s_addr;
+            iface->ipv4method = IPV4_MANUAL_METHOD;
+        } else { /* invalid ip information, disable the setting of ip info */
+            loaderData->ipinfo_set = 0;
+            iface->ipv4method = 0;
+            loaderData->ipv4 = NULL;
+        }
+     }
+
+    if (loaderData->netmask != NULL) {
+        if (inet_pton(AF_INET, loaderData->netmask, &iface->netmask) <= 0) {
+            logMessage(ERROR, "%s (%d): %s", __func__, __LINE__,
+                       strerror(errno));
+        }
+    }
+
+    if (loaderData->gateway != NULL) {
+        if (inet_pton(AF_INET, loaderData->gateway, &iface->gateway) <= 0) {
+            logMessage(ERROR, "%s (%d): %s", __func__, __LINE__,
+                       strerror(errno));
+        }
+    }
+
+#ifdef ENABLE_IPV6
+    if (loaderData->ipv6info_set && loaderData->ipv6 != NULL) {
+        if (!strncmp(loaderData->ipv6, "dhcp", 4)) {
+            iface->ipv6method = IPV6_DHCP_METHOD;
+        } else if (!strncmp(loaderData->ipv6, "auto", 4)) {
+            iface->ipv6method = IPV6_AUTO_METHOD;
+        } else if (inet_pton(AF_INET6, loaderData->ipv6, &addr6) >= 1) {
+            memcpy(&iface->ip6addr, &addr6, sizeof(struct in6_addr));
+            iface->ipv6method = IPV6_MANUAL_METHOD;
+        } else {
+            iface->ipv6method = 0;
+            loaderData->ipv6info_set = 0;
+            loaderData->ipv6 = NULL;
+        }
+    }
+
+    if (loaderData->gateway6 != NULL) {
+        if (inet_pton(AF_INET6, loaderData->gateway6, &iface->gateway6) <= 0) {
+            logMessage(ERROR, "%s (%d): %s", __func__, __LINE__,
+                       strerror(errno));
+        }
+    }
+#endif
+
+    /* iBFT configured DNS */
+    if(iface->ipv4method == IPV4_IBFT_METHOD){
+	if(iface->numdns<MAXNS){
+	    if(ibft_iface_dns1() && inet_pton(AF_INET, ibft_iface_dns1(), &addr)>=1){
+		iface->dns[iface->numdns] = strdup(ibft_iface_dns1());
+		iface->numdns++;
+		logMessage(INFO, "adding iBFT dns server %s", ibft_iface_dns1());
+	    }
+	}
+	if(iface->numdns<MAXNS){
+	    if(ibft_iface_dns2() && inet_pton(AF_INET, ibft_iface_dns2(), &addr)>=1){
+		iface->dns[iface->numdns] = strdup(ibft_iface_dns2());
+		iface->numdns++;
+		logMessage(INFO, "adding iBFT dns server %s", ibft_iface_dns2());
+	    }
+	}
+    }
+
+    if (loaderData->dns) {
+        char * buf;
+        char ret[INET6_ADDRSTRLEN+1];
+        buf = strdup(loaderData->dns);
+
+        /* Scan the dns parameter for multiple comma-separated IP addresses */
+        c = strtok(buf, ",");
+        while ((iface->numdns < MAXNS) && (c != NULL)) {
+            if (inet_pton(AF_INET, c, &addr) >= 1) {
+                iface->dns[iface->numdns] = strdup(c);
+                iface->numdns++;
+
+                if (inet_ntop(AF_INET, &addr, ret, INET_ADDRSTRLEN) == NULL) {
+                    logMessage(ERROR, "%s (%d): %s", __func__, __LINE__, strerror(errno));
+                } else {
+                    logMessage(DEBUGLVL, "adding dns4 %s", ret);
+                    c = strtok(NULL, ",");
+                }
+            } else if (inet_pton(AF_INET6, c, &addr6) >= 1) {
+                iface->dns[iface->numdns] = strdup(c);
+                iface->numdns++;
+
+                if (inet_ntop(AF_INET6, &addr6, ret, INET6_ADDRSTRLEN) == NULL) {
+                    logMessage(ERROR, "%s (%d): %s", __func__, __LINE__, strerror(errno));
+                } else {
+                    logMessage(DEBUGLVL, "adding dns6 %s", ret);
+                    c = strtok(NULL, ",");
+                }
+            }
+        }
+
+
+
+        logMessage(INFO, "dnsservers is %s", loaderData->dns);
+    }
+
+    if (loaderData->hostname) {
+        logMessage(INFO, "setting specified hostname of %s",
+                   loaderData->hostname);
+        iface->hostname = strdup(loaderData->hostname);
+    }
+
+    if (loaderData->mtu) {
+        iface->mtu = loaderData->mtu;
+    }
+
+    if (loaderData->peerid) {
+        iface->peerid = strdup(loaderData->peerid);
+    }
+
+    if (loaderData->subchannels) {
+        iface->subchannels = strdup(loaderData->subchannels);
+    }
+
+    if (loaderData->ctcprot) {
+        iface->ctcprot = strdup(loaderData->ctcprot);
+    }
+
+    if (loaderData->portname) {
+        iface->portname = strdup(loaderData->portname);
+    }
+
+    if (loaderData->nettype) {
+        iface->nettype = strdup(loaderData->nettype);
+    }
+
+    if (loaderData->ethtool) {
+        parseEthtoolSettings(loaderData);
+    }
+
+    if (loaderData->layer2) {
+        iface->layer2 = strdup(loaderData->layer2);
+    }
+
+    if (loaderData->portno) {
+        iface->portno = strdup(loaderData->portno);
+    }
+
+    if (loaderData->noDns) {
+        iface->flags |= IFACE_FLAGS_NO_WRITE_RESOLV_CONF;
+    }
+
+    iface->dhcptimeout = loaderData->dhcpTimeout;
+
+    return;
+}
+
+int readNetConfig(char * device, iface_t * iface,
+                  char * dhcpclass, int methodNum) {
+    int err;
+    int ret;
+    int i = 0;
+    struct netconfopts opts;
+    struct in_addr addr;
+    struct intfconfig_s ipcomps;
+
+    /* ipcomps contains the user interface components */
+    ipcomps.ipv4 = NULL;
+    ipcomps.cidr4 = NULL;
+    ipcomps.gw = NULL;
+#ifdef ENABLE_IPV6
+    ipcomps.ipv6 = NULL;
+    ipcomps.cidr6 = NULL;
+    ipcomps.gw6 = NULL;
+#endif
+    ipcomps.ns = NULL;
+
+    /* init opts */
+    opts.ipv4Choice = 0;
+#ifdef ENABLE_IPV6
+    opts.ipv6Choice = 0;
+#endif
+
+    /* JKFIXME: we really need a way to override this and be able to change
+     * our network config */
+    if (!FL_ASKNETWORK(flags) &&
+        ((iface->ipv4method > IPV4_UNUSED_METHOD) ||
+         (iface->ipv6method > IPV4_UNUSED_METHOD))) {
+        logMessage(INFO, "doing kickstart... setting it up");
+
+        err = writeEnabledNetInfo(iface);
+        if (err) {
+            logMessage(ERROR, "failed to write %s data for %s (%d)",
+                       SYSCONFIG_PATH, iface->device, err);
+            return LOADER_BACK;
+        }
+
+        i = get_connection(iface);
+        newtPopWindow();
+
+        if (i > 0) {
+            if (FL_CMDLINE(flags)) {
+                fprintf(stderr, _("There was an error configuring your network "
+                                  "interface."));
+                fprintf(stderr, _("\nThis cannot be corrected in cmdline mode.\n"
+                                  "Halting.\n"));
+                exit(1);
+            }
+
+            newtWinMessage(_("Network Error"), _("Retry"),
+                           _("There was an error configuring your network "
+                             "interface."));
+            return LOADER_BACK;
+        }
+
+        return LOADER_NOOP;
+    }
+
+    /* dhcp/manual network configuration loop */
+    i = 1;
+    while (i == 1) {
+        ret = configureTCPIP(device, iface, &opts, methodNum);
+
+        if (ret == LOADER_NOOP) {
+            /* dhcp selected, proceed */
+            i = 0;
+        } else if (ret == LOADER_OK) {
+            /* do manual configuration */
+            ret = manualNetConfig(device, iface, &ipcomps, &opts);
+
+            if (ret == LOADER_BACK) {
+                continue;
+            } else if (ret == LOADER_OK) {
+                i = 0;
+            }
+        } else if (ret == LOADER_BACK) {
+            return LOADER_BACK;
+        }
+    }
+
+    /* calculate any missing IPv4 pieces */
+    if (opts.ipv4Choice == '*') {
+        memset(&addr, 0, sizeof(addr));
+        addr.s_addr = (iface->ipaddr.s_addr) & (iface->netmask.s_addr);
+
+        if (iface->broadcast.s_addr == 0) {
+            iface->broadcast.s_addr = addr.s_addr | ~(iface->netmask.s_addr);
+        }
+    }
+
+    /* bring up the interface */
+    err = writeEnabledNetInfo(iface);
+    if (err) {
+        logMessage(ERROR, "failed to write %s data for %s (%d)",
+                   SYSCONFIG_PATH, iface->device, err);
+        iface->ipv4method = IPV4_UNUSED_METHOD;
+        iface->ipv6method = IPV6_UNUSED_METHOD;
+        return LOADER_BACK;
+    }
+
+    i = get_connection(iface);
+    newtPopWindow();
+
+    if (i > 0) {
+        newtWinMessage(_("Network Error"), _("Retry"),
+                       _("There was an error configuring your network "
+                         "interface."));
+        iface->ipv4method = IPV4_UNUSED_METHOD;
+        iface->ipv6method = IPV6_UNUSED_METHOD;
+        return LOADER_ERROR;
+    }
+
+    return LOADER_OK;
+}
+
+int configureTCPIP(char * device, iface_t * iface,
+                   struct netconfopts * opts, int methodNum) {
+    int i = 0, z = 0, skipForm = 0, ret;
+    newtComponent f, okay, back, answer;
+    newtComponent ipv4Checkbox, v4Method[2];
+#ifdef ENABLE_IPV6
+    newtComponent ipv6Checkbox, v6Method[3];
+#endif
+    newtGrid grid, checkgrid, buttons;
+
+    /* UI WINDOW 1: ask for ipv4 choice, ipv6 choice, and conf methods */
+
+    /* IPv4 checkbox */
+    if (!opts->ipv4Choice) {
+        if (FL_NOIPV4(flags) && !FL_IP_PARAM(flags))
+            opts->ipv4Choice = ' ';
+        else
+            opts->ipv4Choice = '*';
+    }
+
+    ipv4Checkbox = newtCheckbox(-1, -1, _("Enable IPv4 support"),
+                                opts->ipv4Choice, NULL, &(opts->ipv4Choice));
+    v4Method[0] = newtRadiobutton(-1, -1, DHCP_METHOD_STR, 1, NULL);
+    v4Method[1] = newtRadiobutton(-1, -1, MANUAL_METHOD_STR, 0, v4Method[0]);
+
+#ifdef ENABLE_IPV6
+    /* IPv6 checkbox */
+    if (!opts->ipv6Choice) {
+        if (FL_NOIPV6(flags) && !FL_IPV6_PARAM(flags))
+            opts->ipv6Choice = ' ';
+        else
+            opts->ipv6Choice = '*';
+    }
+
+    ipv6Checkbox = newtCheckbox(-1, -1, _("Enable IPv6 support"),
+                                opts->ipv6Choice, NULL, &(opts->ipv6Choice));
+    v6Method[0] = newtRadiobutton(-1, -1, AUTO_METHOD_STR, 1, NULL);
+    v6Method[1] = newtRadiobutton(-1, -1, DHCPV6_METHOD_STR, 0, v6Method[0]);
+    v6Method[2] = newtRadiobutton(-1, -1, MANUAL_METHOD_STR, 0, v6Method[1]);
+#endif
+
+    /* button bar at the bottom of the window */
+    buttons = newtButtonBar(_("OK"), &okay, _("Back"), &back, NULL);
+
+    /* checkgrid contains the toggle options for net configuration */
+#ifdef ENABLE_IPV6
+    checkgrid = newtCreateGrid(1, 8);
+#else
+    checkgrid = newtCreateGrid(1, 3);
+#endif
+
+    newtGridSetField(checkgrid, 0, 0, NEWT_GRID_COMPONENT, ipv4Checkbox,
+                     0, 0, 0, 0, NEWT_ANCHOR_LEFT, 0);
+    for (i = 1; i < 3; i++)
+        newtGridSetField(checkgrid, 0, i, NEWT_GRID_COMPONENT, v4Method[i-1],
+                         7, 0, 0, 0, NEWT_ANCHOR_LEFT, 0);
+
+#ifdef ENABLE_IPV6
+    newtGridSetField(checkgrid, 0, 4, NEWT_GRID_COMPONENT, ipv6Checkbox,
+                     0, 1, 0, 0, NEWT_ANCHOR_LEFT, 0);
+    for (i = 5; i < 8; i++)
+        newtGridSetField(checkgrid, 0, i, NEWT_GRID_COMPONENT, v6Method[i-5],
+                         7, 0, 0, 0, NEWT_ANCHOR_LEFT, 0);
+#endif
+
+    /* main window layout */
+    grid = newtCreateGrid(1, 2);
+    newtGridSetField(grid, 0, 0, NEWT_GRID_SUBGRID, checkgrid,
+                     0, 0, 0, 1, 0, 0);
+    newtGridSetField(grid, 0, 1, NEWT_GRID_SUBGRID, buttons,
+                     0, 0, 0, 0, 0, NEWT_GRID_FLAG_GROWX);
+
+    f = newtForm(NULL, NULL, 0);
+    newtGridAddComponentsToForm(grid, f, 1);
+    newtGridWrappedWindow(grid, _("Configure TCP/IP"));
+    newtGridFree(grid, 1);
+
+    /* callbacks */
+    newtComponentAddCallback(ipv4Checkbox, v4MethodCallback, &v4Method);
+#ifdef ENABLE_IPV6
+    newtComponentAddCallback(ipv6Checkbox, v6MethodCallback, &v6Method);
+#endif
+
+    /* match radio button sensitivity to initial checkbox choices */
+    if (opts->ipv4Choice == ' ')
+        setMethodSensitivity(&v4Method, 2);
+
+#ifdef ENABLE_IPV6
+    if (opts->ipv6Choice == ' ')
+        setMethodSensitivity(&v6Method, 3);
+#endif
+
+#ifdef ENABLE_IPV6
+    /* If the user provided any of the following boot paramters, skip
+     * prompting for network configuration information:
+     *     ip=<val> ipv6=<val>
+     *     noipv4 noipv6
+     *     ip=<val> noipv6
+     *     ipv6=<val> noipv4
+     */
+    if ((FL_IP_PARAM(flags) && FL_IPV6_PARAM(flags)) ||
+        (FL_IP_PARAM(flags) && FL_NOIPV6(flags)) ||
+        (FL_IPV6_PARAM(flags) && FL_NOIPV4(flags)) ||
+        (FL_NOIPV4(flags) && FL_NOIPV6(flags))) {
+        skipForm = 1;
+        newtPopWindow();
+    }
+#else
+    if (FL_IP_PARAM(flags) || FL_NOIPV4(flags)) {
+        skipForm = 1;
+        newtPopWindow();
+    }
+#endif
+
+    /* run the form */
+    do {
+        if (!skipForm) {
+            answer = newtRunForm(f);
+
+            if (answer == back) {
+                newtFormDestroy(f);
+                newtPopWindow();
+                return LOADER_BACK;
+            }
+
+            /* need at least one stack */
+#ifdef ENABLE_IPV6
+            if (opts->ipv4Choice == ' ' && opts->ipv6Choice == ' ') {
+#else
+            if (opts->ipv4Choice == ' ') {
+#endif
+                newtWinMessage(_("Missing Protocol"), _("Retry"),
+                               _("You must select at least one protocol (IPv4 "
+                                 "or IPv6)."));
+                continue;
+            }
+
+            /* NFS only works over IPv4 */
+            if (opts->ipv4Choice == ' ' && methodNum == METHOD_NFS) {
+                newtWinMessage(_("IPv4 Needed for NFS"), _("Retry"),
+                           _("NFS installation method requires IPv4 support."));
+                continue;
+            }
+        }
+
+        /* what TCP/IP stacks do we use? what conf methods? */
+        if (opts->ipv4Choice == '*') {
+            flags &= ~LOADER_FLAGS_NOIPV4;
+            for (z = IPV4_FIRST_METHOD; z <= IPV4_LAST_METHOD; z++)
+                if (newtRadioGetCurrent(v4Method[0]) == v4Method[z-1])
+                    iface->ipv4method = z;
+        } else {
+            flags |= LOADER_FLAGS_NOIPV4;
+        }
+
+#ifdef ENABLE_IPV6
+        if (opts->ipv6Choice == '*') {
+            flags &= ~LOADER_FLAGS_NOIPV6;
+            for (z = IPV6_FIRST_METHOD; z <= IPV6_LAST_METHOD; z++)
+                if (newtRadioGetCurrent(v6Method[0]) == v6Method[z-1])
+                    iface->ipv6method = z;
+        } else {
+            flags |= LOADER_FLAGS_NOIPV6;
+        }
+#endif
+
+        /* do interface configuration (call DHCP here, or return for manual) */
+#ifdef ENABLE_IPV6
+        if ((!FL_NOIPV4(flags) && iface->ipv4method == IPV4_DHCP_METHOD) ||
+            (!FL_NOIPV6(flags) && (iface->ipv6method == IPV6_AUTO_METHOD ||
+                                   iface->ipv6method == IPV6_DHCP_METHOD))) {
+#else
+        if (!FL_NOIPV4(flags) && iface->ipv4method == IPV4_DHCP_METHOD) {
+#endif
+            /* DHCP selected, exit the loop */
+            ret = LOADER_NOOP;
+            i = 1;
+#ifdef ENABLE_IPV6
+        } else if ((!FL_NOIPV4(flags) && iface->ipv4method == IPV4_MANUAL_METHOD) ||
+                   (!FL_NOIPV6(flags) && iface->ipv6method == IPV6_MANUAL_METHOD)) {
+#else
+        } else if (!FL_NOIPV4(flags) && iface->ipv4method == IPV4_MANUAL_METHOD) {
+#endif
+
+            /* manual IP configuration selected */
+            ret = LOADER_OK;
+            i = 1;
+        }
+    } while (i != 1);
+
+    newtFormDestroy(f);
+    newtPopWindow();
+    return ret;
+}
+
+int manualNetConfig(char * device, iface_t * iface,
+                    struct intfconfig_s * ipcomps, struct netconfopts * opts) {
+    int i, rows, pos, cidr, have[2], stack[2];
+    char *buf = NULL;
+    char ret[48];
+    struct in_addr addr;
+#ifdef ENABLE_IPV6
+    struct in6_addr addr6;
+    int prefix;
+#endif
+    struct in_addr *tmpaddr = NULL;
+    newtComponent f, okay, back, answer;
+    newtGrid egrid = NULL;
+    newtGrid qgrid = NULL;
+#ifdef ENABLE_IPV6
+    newtGrid rgrid = NULL;
+#endif
+    newtGrid buttons, grid;
+    newtComponent text = NULL;
+
+    memset(ret, '\0', INET6_ADDRSTRLEN+1);
+
+    /* so we don't perform this test over and over */
+    stack[IPV4] = opts->ipv4Choice == '*' &&
+                  iface->ipv4method == IPV4_MANUAL_METHOD;
+#ifdef ENABLE_IPV6
+    stack[IPV6] = opts->ipv6Choice == '*' &&
+                  iface->ipv6method == IPV6_MANUAL_METHOD;
+#endif
+
+    /* UI WINDOW 2 (optional): manual IP config for non-DHCP installs */
+    rows = 2;
+    for (i = 0; i < 2; i++) {
+        if (stack[i]) {
+            rows++;
+        }
+    }
+    egrid = newtCreateGrid(4, rows);
+
+    pos = 0;
+
+    /* IPv4 entry items */
+    if (stack[IPV4]) {
+        newtGridSetField(egrid, 0, pos, NEWT_GRID_COMPONENT,
+                         newtLabel(-1, -1, _("IPv4 address:")),
+                         0, 0, 0, 0, NEWT_ANCHOR_LEFT, 0);
+
+        ipcomps->ipv4Entry = newtEntry(-1, -1, NULL, 16, &ipcomps->ipv4, 0);
+        ipcomps->cidr4Entry = newtEntry(-1, -1, NULL, 16, &ipcomps->cidr4, 0);
+
+        /* use a nested grid for ipv4 addr & netmask */
+        qgrid = newtCreateGrid(3, 1);
+
+        newtGridSetField(qgrid, 0, 0, NEWT_GRID_COMPONENT,
+                         ipcomps->ipv4Entry, 1, 0, 0, 0, NEWT_ANCHOR_LEFT, 0);
+        newtGridSetField(qgrid, 1, 0, NEWT_GRID_COMPONENT,
+                         newtLabel(-1, -1, _("/")),
+                         1, 0, 0, 0, NEWT_ANCHOR_LEFT, 0);
+        newtGridSetField(qgrid, 2, 0, NEWT_GRID_COMPONENT,
+                         ipcomps->cidr4Entry, 1, 0, 0, 0, NEWT_ANCHOR_LEFT, 0);
+
+        newtGridSetField(egrid, 1, pos, NEWT_GRID_SUBGRID, qgrid,
+                         0, 0, 0, 0, NEWT_ANCHOR_LEFT, 0);
+
+        newtComponentAddCallback(ipcomps->ipv4Entry, ipCallback, ipcomps);
+        newtComponentAddCallback(ipcomps->cidr4Entry, cidrCallback, ipcomps);
+
+        /* populate fields if we have data already */
+        if (iface_have_in_addr(&iface->ipaddr)) {
+            if (inet_ntop(AF_INET, &iface->ipaddr, ret,
+                          INET_ADDRSTRLEN) == NULL) {
+                logMessage(ERROR, "%s (%d): %s", __func__, __LINE__,
+                           strerror(errno));
+            }
+        } else if (iface_have_in_addr(&iface->ipaddr)) {
+            if (inet_ntop(AF_INET, &iface->ipaddr, ret,
+                          INET_ADDRSTRLEN) == NULL) {
+                logMessage(ERROR, "%s (%d): %s", __func__, __LINE__,
+                           strerror(errno));
+            }
+        }
+
+        if (*ret) {
+            newtEntrySet(ipcomps->ipv4Entry, ret, 1);
+        }
+
+        if (iface_have_in_addr(&iface->netmask)) {
+            if (inet_ntop(AF_INET, &iface->netmask, ret,
+                          INET_ADDRSTRLEN) == NULL) {
+                logMessage(ERROR, "%s (%d): %s", __func__, __LINE__,
+                           strerror(errno));
+            }
+        } else if (iface_have_in_addr(&iface->netmask)) {
+            if (inet_ntop(AF_INET, &iface->netmask, ret,
+                          INET_ADDRSTRLEN) == NULL) {
+                logMessage(ERROR, "%s (%d): %s", __func__, __LINE__,
+                           strerror(errno));
+            }
+        }
+
+        if (*ret) {
+            newtEntrySet(ipcomps->cidr4Entry, ret, 1);
+        }
+
+        pos++;
+    }
+
+#ifdef ENABLE_IPV6
+    /* IPv6 entry items */
+    if (stack[IPV6]) {
+        newtGridSetField(egrid, 0, pos, NEWT_GRID_COMPONENT,
+                         newtLabel(-1, -1, _("IPv6 address:")),
+                         0, 0, 0, 0, NEWT_ANCHOR_LEFT, 0);
+
+        ipcomps->ipv6Entry = newtEntry(-1, -1, NULL, 41, &ipcomps->ipv6, 0);
+        ipcomps->cidr6Entry = newtEntry(-1, -1, NULL, 4, &ipcomps->cidr6, 0);
+
+        /* use a nested grid for ipv6 addr & netmask */
+        rgrid = newtCreateGrid(3, 1);
+
+        newtGridSetField(rgrid, 0, 0, NEWT_GRID_COMPONENT,
+                         ipcomps->ipv6Entry, 1, 0, 0, 0, NEWT_ANCHOR_LEFT, 0);
+        newtGridSetField(rgrid, 1, 0, NEWT_GRID_COMPONENT,
+                         newtLabel(-1, -1, _("/")),
+                         1, 0, 0, 0, NEWT_ANCHOR_LEFT, 0);
+        newtGridSetField(rgrid, 2, 0, NEWT_GRID_COMPONENT,
+                         ipcomps->cidr6Entry, 1, 0, 0, 0, NEWT_ANCHOR_LEFT, 0);
+
+        newtGridSetField(egrid, 1, pos, NEWT_GRID_SUBGRID, rgrid,
+                         0, 0, 0, 0, NEWT_ANCHOR_LEFT, 0);
+
+        newtComponentAddCallback(ipcomps->ipv6Entry, ipCallback, ipcomps);
+        newtComponentAddCallback(ipcomps->cidr6Entry, cidrCallback, ipcomps);
+
+        /* populate fields if we have data already */
+        if (iface_have_in6_addr(&iface->ip6addr)) {
+            if (inet_ntop(AF_INET6, &iface->ip6addr, ret,
+                          INET6_ADDRSTRLEN) == NULL) {
+                logMessage(ERROR, "%s (%d): %s", __func__, __LINE__,
+                           strerror(errno));
+            }
+        } else if (iface_have_in6_addr(&iface->ip6addr)) {
+            if (inet_ntop(AF_INET6, &iface->ip6addr, ret,
+                          INET6_ADDRSTRLEN) == NULL) {
+                logMessage(ERROR, "%s (%d): %s", __func__, __LINE__,
+                           strerror(errno));
+            }
+        }
+
+        if (*ret) {
+            newtEntrySet(ipcomps->ipv6Entry, ret, 1);
+        }
+
+        if (iface->ip6prefix) {
+            if (asprintf(&buf, "%d", iface->ip6prefix) == -1) {
+                buf = NULL;
+            }
+        } else if (iface->ip6prefix) {
+            if (asprintf(&buf, "%d", iface->ip6prefix) == -1) {
+                buf = NULL;
+            }
+        }
+
+        if (buf != NULL) {
+            newtEntrySet(ipcomps->cidr6Entry, buf, 1);
+            free(buf);
+        }
+
+        pos++;
+    }
+#endif
+
+    /* common entry items */
+    ipcomps->gwEntry = newtEntry(-1, -1, NULL, 41, &ipcomps->gw, 0);
+    ipcomps->nsEntry = newtEntry(-1, -1, NULL, 41, &ipcomps->ns, 0);
+
+    newtGridSetField(egrid, 0, pos, NEWT_GRID_COMPONENT,
+                     newtLabel(-1, -1, _("Gateway:")),
+                     0, 0, 0, 0, NEWT_ANCHOR_LEFT, 0);
+    newtGridSetField(egrid, 1, pos, NEWT_GRID_COMPONENT,
+                     ipcomps->gwEntry, 1, 0, 0, 0, NEWT_ANCHOR_LEFT, 0);
+
+    pos++;
+
+    newtGridSetField(egrid, 0, pos, NEWT_GRID_COMPONENT,
+                     newtLabel(-1, -1, _("Name Server:")),
+                     0, 0, 0, 0, NEWT_ANCHOR_LEFT, 0);
+    newtGridSetField(egrid, 1, pos, NEWT_GRID_COMPONENT,
+                     ipcomps->nsEntry, 1, 0, 0, 0, NEWT_ANCHOR_LEFT, 0);
+
+    if (iface_have_in_addr(&iface->gateway)) {
+        if (inet_ntop(AF_INET, &iface->gateway, ret,
+                      INET_ADDRSTRLEN) == NULL) {
+            logMessage(ERROR, "%s (%d): %s", __func__, __LINE__,
+                       strerror(errno));
+        } else {
+            newtEntrySet(ipcomps->gwEntry, ret, 1);
+        }
+    } else if (iface_have_in6_addr(&iface->gateway6)) {
+        if (inet_ntop(AF_INET6, &iface->gateway6, ret,
+                      INET6_ADDRSTRLEN) == NULL) {
+            logMessage(ERROR, "%s (%d): %s", __func__, __LINE__,
+                       strerror(errno));
+        } else {
+            newtEntrySet(ipcomps->gwEntry, ret, 1);
+        }
+    }
+
+    if (iface->numdns) {
+        newtEntrySet(ipcomps->nsEntry, iface->dns[0], 1);
+    } else if (iface->numdns) {
+        newtEntrySet(ipcomps->nsEntry, iface->dns[0], 1);
+    }
+
+    newtComponentAddCallback(ipcomps->gwEntry, ipCallback, ipcomps);
+    newtComponentAddCallback(ipcomps->nsEntry, ipCallback, ipcomps);
+
+    /* button bar at the bottom of the window */
+    buttons = newtButtonBar(_("OK"), &okay, _("Back"), &back, NULL);
+
+    /* main window layout */
+    grid = newtCreateGrid(1, 3);
+
+    checked_asprintf(&buf,
+                     _("Enter the IPv4 and/or the IPv6 address and prefix "
+                       "(address / prefix).  For IPv4, the dotted-quad "
+                       "netmask or the CIDR-style prefix are acceptable. "
+                       "The gateway and name server fields must be valid IPv4 "
+                       "or IPv6 addresses."));
+
+    text = newtTextboxReflowed(-1, -1, buf, 52, 0, 10, 0);
+
+    newtGridSetField(grid, 0, 0, NEWT_GRID_COMPONENT, text,
+                     0, 0, 0, 1, NEWT_ANCHOR_LEFT, 0);
+    newtGridSetField(grid, 0, 1, NEWT_GRID_SUBGRID, egrid,
+                     0, 0, 0, 1, NEWT_ANCHOR_LEFT, 0);
+    newtGridSetField(grid, 0, 2, NEWT_GRID_SUBGRID, buttons,
+                     0, 0, 0, 0, 0, NEWT_GRID_FLAG_GROWX);
+
+    f = newtForm(NULL, NULL, 0);
+    newtGridAddComponentsToForm(grid, f, 1);
+    newtGridWrappedWindow(grid, _("Manual TCP/IP Configuration"));
+    newtGridFree(grid, 1);
+
+    have[IPV4] = 0;
+    have[IPV6] = 0;
+
+    for (i = IPV4; i <= IPV6; i++) {
+        if (!stack[i]) {
+            have[i] = 2;
+        }
+    }
+
+    /* run the form */
+    while ((have[IPV4] != 2) || (have[IPV6] != 2)) {
+        answer = newtRunForm(f);
+
+        /* collect IPv4 data */
+        if (stack[IPV4]) {
+            if (ipcomps->ipv4) {
+                if (inet_pton(AF_INET, ipcomps->ipv4, &iface->ipaddr) <= 0) {
+                    logMessage(ERROR, "%s (%d): %s", __func__, __LINE__,
+                               strerror(errno));
+                } else {
+                    have[IPV4]++;
+                }
+            }
+
+            if (ipcomps->cidr4) {
+                if (inet_pton(AF_INET, ipcomps->cidr4, &iface->netmask) >= 1) {
+                    have[IPV4]++;
+                } else {
+                    errno = 0;
+                    cidr = strtol(ipcomps->cidr4, NULL, 10);
+
+                    if ((errno == ERANGE && (cidr == LONG_MIN ||
+                                             cidr == LONG_MAX)) ||
+                        (errno != 0 && cidr == 0)) {
+                        logMessage(ERROR, "%s: %d: %m", __func__, __LINE__);
+                        abort();
+                    }
+
+                    if (cidr >= 1 && cidr <= 32) {
+                        tmpaddr = iface_prefix2netmask(cidr);
+                        if (tmpaddr != NULL) {
+                            memcpy(&iface->netmask, tmpaddr,
+                                   sizeof(struct in_addr));
+                            have[IPV4]++;
+                        } else {
+                            iface->netmask.s_addr = 0;
+                        }
+                    }
+                }
+            }
+        }
+
+#ifdef ENABLE_IPV6
+        /* collect IPv6 data */
+        if (stack[IPV6]) {
+            if (ipcomps->ipv6) {
+                if (inet_pton(AF_INET6, ipcomps->ipv6, &iface->ip6addr) <= 0) {
+                    logMessage(ERROR, "%s (%d): %s", __func__, __LINE__,
+                               strerror(errno));
+                } else {
+                    have[IPV6]++;
+                }
+            }
+
+            if (ipcomps->cidr6) {
+                errno = 0;
+                prefix = strtol(ipcomps->cidr6, NULL, 10);
+
+                if ((errno == ERANGE && (prefix == LONG_MIN ||
+                                         prefix == LONG_MAX)) ||
+                    (errno != 0 && prefix == 0)) {
+                    logMessage(ERROR, "%s: %d: %m", __func__, __LINE__);
+                    abort();
+                }
+
+                if (prefix > 0 || prefix <= 128) {
+                    iface->ip6prefix = prefix;
+                    have[IPV6]++;
+                }
+            }
+        }
+#endif
+
+        /* collect common network settings */
+        if (ipcomps->gw) {
+            if (inet_pton(AF_INET, ipcomps->gw, &iface->gateway) <= 0) {
+               memset(&iface->gateway, 0, sizeof(iface->gateway));
+
+               if (inet_pton(AF_INET6, ipcomps->gw, &iface->gateway6) <= 0) {
+                   logMessage(ERROR, "%s (%d): %s", __func__, __LINE__,
+                              strerror(errno));
+                   memset(&iface->gateway6, 0, sizeof(iface->gateway6));
+               }
+            }
+        }
+
+        /* gather nameservers */
+        if (ipcomps->ns) {
+#ifdef ENABLE_IPV6
+            if ((inet_pton(AF_INET, ipcomps->ns, &addr) >= 1) ||
+                (inet_pton(AF_INET6, ipcomps->ns, &addr6) >= 1)) {
+#else
+            if (inet_pton(AF_INET, ipcomps->ns, &addr) >= 1) {
+#endif
+                iface->dns[0] = strdup(ipcomps->ns);
+                if (iface->numdns < 1)
+                    iface->numdns = 1;
+            }
+        }
+
+        /* user selected back, but we've saved what they entered already */
+        if (answer == back) {
+            newtFormDestroy(f);
+            newtPopWindow();
+            free(buf);
+            return LOADER_BACK;
+        }
+
+        /* we might be done now */
+        if (stack[IPV4] && have[IPV4] != 2) {
+            have[IPV4] = 0;
+            newtWinMessage(_("Missing Information"), _("Retry"),
+                           _("You must enter both a valid IPv4 address and a "
+                             "network mask or CIDR prefix."));
+        }
+
+#ifdef ENABLE_IPV6
+        if (stack[IPV6] && have[IPV6] != 2) {
+            have[IPV6] = 0;
+            newtWinMessage(_("Missing Information"), _("Retry"),
+                           _("You must enter both a valid IPv6 address and a "
+                             "CIDR prefix."));
+        }
+#endif
+
+        strcpy(iface->device, device);
+    }
+
+    free(buf);
+    newtFormDestroy(f);
+    newtPopWindow();
+
+    return LOADER_OK;
+}
+
+/*
+ * By default, we disable all network interfaces and then only
+ * bring up the ones the user wants.
+ */
+int writeDisabledNetInfo(void) {
+    int i = 0;
+    char *ofile = NULL;
+    char *nfile = NULL;
+    FILE *fp = NULL;
+    struct device **devs = NULL;
+
+    devs = getDevices(DEVICE_NETWORK);
+
+    if (devs == NULL) {
+        return 1;
+    }
+
+    for (i = 0; devs[i]; i++) {
+        /* remove dhclient-DEVICE.conf if we have it */
+        if (asprintf(&ofile, "/etc/dhcp/dhclient-%s.conf", devs[i]->device) == -1) {
+            return 5;
+        }
+
+        if (!access(ofile, R_OK|W_OK)) {
+            if (unlink(ofile)) {
+                logMessage(ERROR, "error removing %s", ofile);
+            }
+        }
+
+        if (ofile) {
+            free(ofile);
+            ofile = NULL;
+        }
+
+        /* write disabled ifcfg-DEVICE file */
+        
+        checked_asprintf(&ofile, "%s/.ifcfg-%s",
+                         NETWORK_SCRIPTS_PATH,
+                         devs[i]->device);
+        checked_asprintf(&nfile, "%s/ifcfg-%s",
+                         NETWORK_SCRIPTS_PATH,
+                         devs[i]->device);
+
+        if ((fp = fopen(ofile, "w")) == NULL) {
+            free(ofile);
+            return 2;
+        }
+
+        fprintf(fp, "DEVICE=%s\n", devs[i]->device);
+        fprintf(fp, "HWADDR=%s\n", iface_mac2str(devs[i]->device));
+        fprintf(fp, "ONBOOT=no\n");
+        fprintf(fp, "NM_CONTROLLED=no\n");
+
+        if (fclose(fp) == EOF) {
+            return 3;
+        }
+
+        if (rename(ofile, nfile) == -1) {
+            free(ofile);
+            free(nfile);
+            return 4;
+        }
+
+        if (ofile) {
+            free(ofile);
+            ofile = NULL;
+        }
+
+        if (nfile) {
+            free(nfile);
+            nfile = NULL;
+        }
+    }
+
+    return 0;
+}
+
+/*
+ * Write out network interface control files:
+ *     /etc/sysconfig/network-scripts/ifcfg-DEVICE
+ *     /etc/sysconfig/network
+ */
+int writeEnabledNetInfo(iface_t *iface) {
+    int i = 0, osa_layer2 = 0, osa_portno = 0;
+    mode_t mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH;
+    FILE *fp = NULL;
+    char buf[INET6_ADDRSTRLEN+1];
+    char *ofile = NULL;
+    char *nfile = NULL;
+    struct utsname kv;
+
+    memset(&buf, '\0', sizeof(buf));
+
+    if ((mkdir(NETWORK_SCRIPTS_PATH, mode) == -1) && (errno != EEXIST)) {
+        return 16;
+    }
+
+    /* write vendor class */
+    if (iface->vendorclass == NULL) {
+        if (uname(&kv) == -1) {
+            iface->vendorclass = "anaconda";
+        } else {
+            if (asprintf(&iface->vendorclass, "anaconda-%s %s %s",
+                         kv.sysname, kv.release, kv.machine) == -1 ) {
+                return 20;
+            }
+        }
+    }
+
+    if (asprintf(&ofile, "/etc/dhcp/dhclient-%s.conf", iface->device) == -1) {
+        return 17;
+    }
+
+    if ((fp = fopen(ofile, "w")) == NULL) {
+        free(ofile);
+        return 18;
+    }
+
+    fprintf(fp, "send vendor-class-identifier \"%s\";\n",
+            iface->vendorclass);
+
+    if (fclose(fp) == EOF) {
+        free(ofile);
+        return 19;
+    }
+
+    if (ofile) {
+        free(ofile);
+        ofile = NULL;
+    }
+
+    /* write out new ifcfg-DEVICE file */
+    if (asprintf(&ofile, "%s/.ifcfg-%s",
+                 NETWORK_SCRIPTS_PATH, iface->device) == -1) {
+        return 1;
+    }
+
+    if (asprintf(&nfile, "%s/ifcfg-%s",
+                 NETWORK_SCRIPTS_PATH, iface->device) == -1) {
+        return 13;
+    }
+
+    if ((fp = fopen(ofile, "w")) == NULL) {
+        free(ofile);
+        return 2;
+    }
+
+    fprintf(fp, "DEVICE=%s\n", iface->device);
+    fprintf(fp, "HWADDR=%s\n", iface_mac2str(iface->device));
+    fprintf(fp, "ONBOOT=yes\n");
+
+    if (!FL_NOIPV4(flags)) {
+        if (iface->ipv4method == IPV4_IBFT_METHOD) {
+	    /* When initrd and NM support iBFT, we should just write
+	     * BOOTPROTO=ibft and let NM deal with it. Until than,
+	     * just use static and do it ourselves. */
+            fprintf(fp, "BOOTPROTO=static\n");
+	    if(ibft_iface_ip()) fprintf(fp, "IPADDR=%s\n", ibft_iface_ip());
+	    if(ibft_iface_mask()) fprintf(fp, "NETMASK=%s\n", ibft_iface_mask());
+	    if(ibft_iface_gw()) fprintf(fp, "GATEWAY=%s\n", ibft_iface_gw());
+        } else if (iface->ipv4method == IPV4_IBFT_DHCP_METHOD) {
+            fprintf(fp, "BOOTPROTO=dhcp\n");
+        } else if (iface->ipv4method == IPV4_DHCP_METHOD) {
+            fprintf(fp, "BOOTPROTO=dhcp\n");
+        } else if (iface->ipv4method == IPV4_MANUAL_METHOD) {
+            fprintf(fp, "BOOTPROTO=static\n");
+
+            if (iface_have_in_addr(&iface->ipaddr)) {
+                if (inet_ntop(AF_INET, &iface->ipaddr, buf,
+                              INET_ADDRSTRLEN) == NULL) {
+                    free(ofile);
+                    fclose(fp);
+                    return 3;
+                }
+
+                fprintf(fp, "IPADDR=%s\n", buf);
+            }
+
+            if (iface_have_in_addr(&iface->netmask)) {
+                if (inet_ntop(AF_INET, &iface->netmask, buf,
+                              INET_ADDRSTRLEN) == NULL) {
+                    free(ofile);
+                    fclose(fp);
+                    return 4;
+                }
+
+                fprintf(fp, "NETMASK=%s\n", buf);
+            }
+
+            if (iface_have_in_addr(&iface->broadcast)) {
+                if (inet_ntop(AF_INET, &iface->broadcast, buf,
+                              INET_ADDRSTRLEN) == NULL) {
+                    free(ofile);
+                    fclose(fp);
+                    return 5;
+                }
+
+                fprintf(fp, "BROADCAST=%s\n", buf);
+            }
+
+            if (iface_have_in_addr(&iface->gateway)) {
+                if (inet_ntop(AF_INET, &iface->gateway, buf,
+                              INET_ADDRSTRLEN) == NULL) {
+                    free(ofile);
+                    fclose(fp);
+                    return 6;
+                }
+
+                fprintf(fp, "GATEWAY=%s\n", buf);
+            }
+        }
+    }
+
+#ifdef ENABLE_IPV6
+    if (!FL_NOIPV6(flags)) {
+        if (iface->ipv6method == IPV6_AUTO_METHOD ||
+            iface->ipv6method == IPV6_DHCP_METHOD ||
+            iface->ipv6method == IPV6_MANUAL_METHOD) {
+            fprintf(fp, "IPV6INIT=yes\n");
+
+            if (iface->ipv6method == IPV6_AUTO_METHOD) {
+                fprintf(fp, "IPV6_AUTOCONF=yes\n");
+            } else if (iface->ipv6method == IPV6_DHCP_METHOD) {
+                fprintf(fp, "DHCPV6C=yes\n");
+            } else if (iface->ipv6method == IPV6_MANUAL_METHOD) {
+                if (iface_have_in6_addr(&iface->ip6addr)) {
+                    if (inet_ntop(AF_INET6, &iface->ip6addr, buf,
+                                  INET6_ADDRSTRLEN) == NULL) {
+                        free(ofile);
+                        fclose(fp);
+                        return 7;
+                    }
+
+                    if (iface->ip6prefix) {
+                        fprintf(fp, "IPV6ADDR=%s/%d\n", buf, iface->ip6prefix);
+                    } else {
+                        fprintf(fp, "IPV6ADDR=%s\n", buf);
+                    }
+                }
+            }
+
+            if (iface_have_in6_addr(&iface->gateway6)) {
+                if (inet_ntop(AF_INET6, &iface->gateway6, buf,
+                              INET6_ADDRSTRLEN) == NULL) {
+                    free(ofile);
+                    fclose(fp);
+                    return 8;
+                }
+
+                fprintf(fp, "IPV6_DEFAULTGW=%s\n", buf);
+            }
+        }
+    }
+#endif
+
+    if (iface->numdns > 0) {
+        for (i = 0; i < iface->numdns; i++) {
+            fprintf(fp, "DNS%d=%s\n", i+1, iface->dns[i]);
+        }
+    }
+
+    if (iface->hostname) {
+        fprintf(fp, "HOSTNAME=%s\n", iface->hostname);
+    }
+
+    if (iface->domain) {
+        fprintf(fp, "DOMAIN=%s\n", iface->domain);
+    }
+
+    if (iface->mtu) {
+        fprintf(fp, "MTU=%d\n", iface->mtu);
+    }
+
+    if (iface->peerid) {
+        fprintf(fp, "PEERID=%s\n", iface->peerid);
+    }
+
+    if (iface->subchannels) {
+        fprintf(fp, "SUBCHANNELS=%s\n", iface->subchannels);
+    }
+
+    if (iface->portname) {
+        fprintf(fp, "PORTNAME=%s\n", iface->portname);
+    }
+
+    if (iface->nettype) {
+        fprintf(fp, "NETTYPE=%s\n", iface->nettype);
+    }
+
+    if (iface->ctcprot) {
+        fprintf(fp, "CTCPROT=%s\n", iface->ctcprot);
+    }
+
+    if (iface->layer2 && !strcmp(iface->layer2, "1")) {
+        osa_layer2 = 1;
+    }
+
+    if (iface->portno && !strcmp(iface->portno, "1")) {
+        osa_portno = 1;
+    }
+
+    if (osa_layer2 || osa_portno) {
+        fprintf(fp, "OPTIONS=\"");
+
+        if (osa_layer2) {
+            fprintf(fp, "layer2=1");
+        }
+
+        if (osa_layer2 && osa_portno) {
+            fprintf(fp, " ");
+        }
+
+        if (osa_portno) {
+            fprintf(fp, "portno=1");
+        }
+
+        fprintf(fp, "\"\n");
+    }
+
+    if (iface->macaddr) {
+        fprintf(fp, "MACADDR=%s\n", iface->macaddr);
+    }
+
+    if (fclose(fp) == EOF) {
+        free(ofile);
+        free(nfile);
+        return 8;
+    }
+
+    if (rename(ofile, nfile) == -1) {
+        free(ofile);
+        free(nfile);
+        return 14;
+    }
+
+    if (ofile) {
+        free(ofile);
+    }
+
+    if (nfile) {
+        free(nfile);
+    }
+
+    /* Global settings */
+    if ((fp = fopen(SYSCONFIG_PATH"/.network", "w")) == NULL) {
+        return 9;
+    }
+
+    if (!FL_NOIPV4(flags)) {
+        fprintf(fp, "NETWORKING=yes\n");
+    }
+
+#ifdef ENABLE_IPV6
+    if (!FL_NOIPV6(flags)) {
+        fprintf(fp, "NETWORKING_IPV6=yes\n");
+    }
+#endif
+
+    if (iface->hostname != NULL) {
+        fprintf(fp, "HOSTNAME=%s\n", iface->hostname);
+    }
+
+    if (iface_have_in_addr(&iface->gateway)) {
+        if (inet_ntop(AF_INET, &iface->gateway, buf,
+                      INET_ADDRSTRLEN) == NULL) {
+            fclose(fp);
+            return 10;
+        }
+
+        fprintf(fp, "GATEWAY=%s\n", buf);
+    }
+
+#ifdef ENABLE_IPV6
+    if (iface_have_in6_addr(&iface->gateway6)) {
+        if (inet_ntop(AF_INET6, &iface->gateway6, buf,
+                      INET6_ADDRSTRLEN) == NULL) {
+            fclose(fp);
+            return 11;
+        }
+
+        fprintf(fp, "IPV6_DEFAULTGW=%s\n", buf);
+    }
+#endif
+
+    if (fclose(fp) == EOF) {
+        return 12;
+    }
+
+    if (rename(SYSCONFIG_PATH"/.network",
+               SYSCONFIG_PATH"/network") == -1) {
+        return 15;
+    }
+
+    return 0;
+}
+
+void setKickstartNetwork(struct loaderData_s * loaderData, int argc, 
+                         char ** argv) {
+    iface_t iface;
+    gchar *bootProto = NULL, *device = NULL, *class = NULL, *ethtool = NULL;
+    gchar *essid = NULL, *wepkey = NULL, *onboot = NULL;
+    gint mtu = 1500, dhcpTimeout = -1;
+    gboolean noipv4 = FALSE, noipv6 = FALSE, noDns = FALSE, noksdev = FALSE;
+    GOptionContext *optCon = g_option_context_new(NULL);
+    GError *optErr = NULL;
+    GOptionEntry ksOptions[] = {
+        { "bootproto", 0, 0, G_OPTION_ARG_STRING, &bootProto, NULL, NULL },
+        { "device", 0, 0, G_OPTION_ARG_STRING, &device, NULL, NULL },
+        { "dhcpclass", 0, 0, G_OPTION_ARG_STRING, &class, NULL, NULL },
+        { "gateway", 'g', 0, G_OPTION_ARG_STRING, &loaderData->gateway,
+          NULL, NULL },
+        { "ip", 'i', 0, G_OPTION_ARG_STRING, &loaderData->ipv4, NULL, NULL },
+        { "mtu", 0, 0, G_OPTION_ARG_INT, &mtu, NULL, NULL },
+        { "nameserver", 'n', 0, G_OPTION_ARG_STRING, &loaderData->dns,
+          NULL, NULL },
+        { "netmask", 'm', 0, G_OPTION_ARG_STRING, &loaderData->netmask,
+          NULL, NULL },
+        { "noipv4", 0, 0, G_OPTION_ARG_NONE, &noipv4, NULL, NULL },
+        { "noipv6", 0, 0, G_OPTION_ARG_NONE, &noipv6, NULL, NULL },
+        { "nodns", 0, 0, G_OPTION_ARG_NONE, &noDns, NULL, NULL },
+        { "hostname", 'h', 0, G_OPTION_ARG_STRING, &loaderData->hostname,
+          NULL, NULL },
+        { "ethtool", 0, 0, G_OPTION_ARG_STRING, &ethtool, NULL, NULL },
+        { "essid", 0, 0, G_OPTION_ARG_STRING, &essid, NULL, NULL },
+        { "wepkey", 0, 0, G_OPTION_ARG_STRING, &wepkey, NULL, NULL },
+        { "onboot", 0, 0, G_OPTION_ARG_STRING, &onboot, NULL, NULL },
+        { "notksdevice", 0, 0, G_OPTION_ARG_NONE, &noksdev, NULL, NULL },
+        { "dhcptimeout", 0, 0, G_OPTION_ARG_INT, &dhcpTimeout, NULL, NULL },
+        { NULL },
+    };
+
+    iface_init_iface_t(&iface);
+
+    g_option_context_set_help_enabled(optCon, FALSE);
+    g_option_context_add_main_entries(optCon, ksOptions, NULL);
+
+    if (!g_option_context_parse(optCon, &argc, &argv, &optErr)) {
+        newtWinMessage(_("Kickstart Error"), _("OK"),
+                       _("Bad argument to kickstart network command: %s"),
+                       optErr->message);
+        g_error_free(optErr);
+    }
+
+    g_option_context_free(optCon);
+
+    /* if they've specified dhcp/bootp use dhcp for the interface */
+    if (bootProto && (!strncmp(bootProto, "dhcp", 4) || 
+                       !strncmp(bootProto, "bootp", 4))) {
+        loaderData->ipv4 = strdup("dhcp");
+        loaderData->ipinfo_set = 1;
+    } else if (loaderData->ipv4) {
+        /* JKFIXME: this assumes a bit... */
+        loaderData->ipinfo_set = 1;
+    }
+
+    /* now make sure the specified bootproto is valid */
+    if (bootProto && strcmp(bootProto, "dhcp") && strcmp(bootProto, "bootp") &&
+        strcmp(bootProto, "static") && strcmp(bootProto, "query")) {
+        newtWinMessage(_("Kickstart Error"), _("OK"),
+                       _("Bad bootproto %s specified in network command"),
+                       bootProto);
+    }
+
+    if (!noksdev) {
+        if (device) {
+            /* If --device=MAC was given, translate into a device name now. */
+            if (index(device, ':') != NULL)
+                loaderData->netDev = iface_mac2device(device);
+            else
+                loaderData->netDev = strdup(device);
+
+            loaderData->netDev_set = 1;
+        }
+
+        if (class) {
+            loaderData->netCls = strdup(class);
+            loaderData->netCls_set = 1;
+        }
+
+        if (ethtool) {
+            if (loaderData->ethtool)
+                free(loaderData->ethtool);
+            loaderData->ethtool = strdup(ethtool);
+            free(ethtool);
+        }
+
+        if (essid) {
+            if (loaderData->essid)
+                free(loaderData->essid);
+            loaderData->essid = strdup(essid);
+            free(essid);
+        }
+
+        if (wepkey) {
+            if (loaderData->wepkey)
+                free(loaderData->wepkey);
+            loaderData->wepkey = strdup(wepkey);
+            free(wepkey);
+        }
+
+        if (mtu) {
+           loaderData->mtu = mtu;
+        }
+
+        if (noipv4)
+            flags |= LOADER_FLAGS_NOIPV4;
+
+#ifdef ENABLE_IPV6
+        if (noipv6)
+            flags |= LOADER_FLAGS_NOIPV6;
+#endif
+    }
+
+    if (noDns) {
+        loaderData->noDns = 1;
+    }
+
+    /* Make sure the network is always up if there's a network line in the
+     * kickstart file, as %post/%pre scripts might require that.
+     */
+    if (loaderData->method != METHOD_NFS && loaderData->method != METHOD_URL) {
+        if (kickstartNetworkUp(loaderData, &iface))
+            logMessage(ERROR, "unable to bring up network");
+    }
+}
+
+/* if multiple interfaces get one to use from user.   */
+/* NOTE - uses kickstart data available in loaderData */
+int chooseNetworkInterface(struct loaderData_s * loaderData) {
+    int i, rc, ask, idrc, secs, deviceNums = 0, deviceNum, foundDev = 0;
+    unsigned int max = 40;
+    char **devices;
+    char **deviceNames;
+    char *ksMacAddr = NULL, *seconds = strdup("10"), *idstr = NULL;
+    struct device **devs;
+    int lookForLink = 0;
+    struct newtWinEntry entry[] = {{N_("Seconds:"), (char **) &seconds, 0},
+                                   {NULL, NULL, 0 }};
+
+    devs = getDevices(DEVICE_NETWORK);
+    if (!devs) {
+        logMessage(ERROR, "no network devices in choose network device!");
+        return LOADER_ERROR;
+    }
+
+    for (i = 0; devs[i]; i++);
+
+    devices = alloca((i + 1) * sizeof(*devices));
+    deviceNames = alloca((i + 1) * sizeof(*devices));
+    if (loaderData->netDev && (loaderData->netDev_set) == 1) {
+        if ((loaderData->bootIf && (loaderData->bootIf_set) == 1) &&
+            !strcasecmp(loaderData->netDev, "bootif")) {
+            ksMacAddr = g_ascii_strup(loaderData->bootIf, -1);
+        } else {
+            ksMacAddr = g_ascii_strup(loaderData->netDev, -1);
+        }
+    }
+
+    for (i = 0; devs[i]; i++) {
+        if (!devs[i]->device)
+            continue;
+
+        if (devs[i]->description) {
+            deviceNames[deviceNums] = alloca(strlen(devs[i]->device) +
+                                      strlen(devs[i]->description) + 4);
+            sprintf(deviceNames[deviceNums],"%s - %.50s",
+                    devs[i]->device, devs[i]->description);
+
+            if (strlen(deviceNames[deviceNums]) > max)
+                max = strlen(deviceNames[deviceNums]);
+
+            devices[deviceNums] = devs[i]->device;
+        } else {
+            devices[deviceNums] = devs[i]->device;
+            deviceNames[deviceNums] = devs[i]->device;
+        }
+
+        deviceNums++;
+
+        /* this device has been set and we don't really need to ask 
+         * about it again... */
+        if (loaderData->netDev && (loaderData->netDev_set == 1)) {
+            if (!strcmp(loaderData->netDev, devs[i]->device)) {
+                foundDev = 1;
+            } else if (ksMacAddr != NULL) {
+                /* maybe it's a mac address */
+                char *devmacaddr = iface_mac2str(devs[i]->device);
+
+                if ((devmacaddr != NULL) && !strcmp(ksMacAddr, devmacaddr)) {
+                    foundDev = 1;
+                    free(loaderData->netDev);
+                    loaderData->netDev = devs[i]->device;
+                    if (devmacaddr != NULL)
+                        free(devmacaddr);
+                    break;
+                }
+
+                if (devmacaddr != NULL)
+                    free(devmacaddr);
+            }
+        }
+    }
+
+    if (ksMacAddr)
+        free(ksMacAddr);
+    if (foundDev == 1)
+        return LOADER_NOOP;
+
+    devices[deviceNums] = NULL;
+    deviceNames[deviceNums] = NULL;
+    qsort(devices, deviceNums, sizeof(*devices), simpleStringCmp);
+    qsort(deviceNames, deviceNums, sizeof(*devices), simpleStringCmp);
+
+    /* ASSERT: we should *ALWAYS* have a network device when we get here */
+    if (!deviceNums) {
+        logMessage(CRITICAL, "no network device in chooseNetworkInterface");
+        return LOADER_ERROR;
+    }
+
+    /* If there is iBFT table and ksdevice doesn't say otherwise, use it */
+    while (!loaderData->netDev_set || !strcmp(loaderData->netDev, "ibft")) {
+        char *devmacaddr = NULL;
+        char *ibftmacaddr = "";
+
+        /* get MAC from the iBFT table */
+        if (!(ibftmacaddr = ibft_iface_mac())) { /* iBFT not present or error */
+            logMessage(ERROR, "iBFT doesn't couldn't provide valid NIC MAC address");
+            break;
+        }
+
+        logMessage(INFO, "looking for iBFT configured device %s with link",
+                   ibftmacaddr);
+
+        for (i = 0; devs[i]; i++) {
+            if (!devs[i]->device)
+                continue;
+
+            devmacaddr = iface_mac2str(devs[i]->device);
+
+            if(!strcasecmp(devmacaddr, ibftmacaddr)){
+                logMessage(INFO,
+                           "%s has the right MAC (%s), checking for link",
+                           devs[i]->device, devmacaddr);
+                free(devmacaddr);
+
+                /* wait for the link (max 5s) */
+                for (rc = 0; rc < 5; rc++) {
+                    if (get_link_status(devs[i]->device) == 0) {
+                        logMessage(INFO, "%s still has no link, waiting", devs[i]->device);
+                        sleep(1);                 
+                    } else {
+                        lookForLink = 0;
+                        loaderData->netDev = devs[i]->device;
+                        loaderData->netDev_set = 1;
+                        logMessage(INFO, "%s has link, using it", devs[i]->device);
+
+                        /* set the IP method to ibft if not requested differently */
+                        if (loaderData->ipv4 == NULL) {
+                            loaderData->ipv4 = strdup("ibft");
+                            loaderData->ipinfo_set = 1;
+                            logMessage(INFO,
+                                       "%s will be configured using iBFT values",
+                                       devices[i]);
+                        }
+
+                        return LOADER_NOOP;
+                    }
+                }
+
+                logMessage(INFO, "%s has no link, skipping it", devices[i]);
+
+                break;
+            } else {
+                free(devmacaddr);
+            }
+        }
+
+        break;
+    }
+
+    if ((loaderData->netDev && (loaderData->netDev_set == 1)) &&
+        !strcmp(loaderData->netDev, "link")) {
+        lookForLink = 1;
+    }
+
+    if (lookForLink) {
+        logMessage(INFO, "looking for first netDev with link");
+
+        for (rc = 0; rc < 5; rc++) {
+            for (i = 0; i < deviceNums; i++) {
+                if (get_link_status(devices[i]) == 1) {
+                    loaderData->netDev = devices[i];
+                    logMessage(INFO, "%s has link, using it", devices[i]);
+                    return LOADER_NOOP;
+                }
+            }
+
+            sleep(1);
+        }
+
+        logMessage(WARNING,
+                   "wanted netdev with link, but none present.  prompting");
+    }
+
+    /* JKFIXME: if we only have one interface and it doesn't have link,
+     * do we go ahead? */
+    if (deviceNums == 1) {
+        logMessage(INFO, "only have one network device: %s", devices[0]);
+        loaderData->netDev = devices[0];
+        loaderData->netDev_set = 1;
+        return LOADER_NOOP;
+    }
+
+    if (FL_CMDLINE(flags)) {
+        fprintf(stderr, "No way to determine which NIC to use, and cannot "
+                        "prompt in cmdline\nmode.  Halting.\n");
+        fprintf(stderr, "Please use the ksdevice= parameter to specify the "
+                        "device name (e.g., eth0)\n or the MAC address of "
+                        "the NIC to use for installation.\n");
+        exit(1);
+    }
+
+    startNewt();
+
+    if (max > 70)
+        max = 70;
+
+    /* JKFIXME: should display link status */
+    deviceNum = 0;
+    ask = 1;
+    while (ask) {
+        rc = newtWinMenu(_("Networking Device"),
+                         _("You have multiple network devices on this system. "
+                           "Which would you like to install through?"),
+                         max, 10, 10,
+                         deviceNums < 6 ? deviceNums : 6, deviceNames,
+                         &deviceNum, _("OK"), _("Identify"), _("Back"), NULL);
+
+        if (rc == 2) {
+            if (!devices[deviceNum]) {
+                logMessage(ERROR, "NIC %d contains no device name", deviceNum);
+                continue;
+            }
+
+            checked_asprintf(&idstr, "%s %s %s",
+                             _("You can identify the physical port for"),
+                             devices[deviceNum],
+                             _("by flashing the LED lights for a number of "
+                               "seconds.  Enter a number between 1 and 30 to "
+                               "set the duration to flash the LED port "
+                               "lights."));
+
+            i = 1;
+            while (i) {
+                idrc = newtWinEntries(_("Identify NIC"), idstr, 50, 5, 15, 24,
+                                      entry, _("OK"), _("Back"), NULL);
+
+                if (idrc == 0 || idrc == 1) {
+                    errno = 0;
+                    secs = strtol((const char *) seconds, NULL, 10);
+                    if (errno == EINVAL || errno == ERANGE) {
+                        logMessage(ERROR, "strtol() failure in %s: %m",
+                                   __func__);
+                        continue;
+                    }
+
+                    if (secs <=0 || secs > 300) {
+                        newtWinMessage(_("Invalid Duration"), _("OK"),
+                                       _("You must enter the number of "
+                                         "seconds as an integer between 1 "
+                                         "and 30."));
+                        continue;
+                    }
+
+                    idrc = 41 + strlen(devices[deviceNum]);
+                    if (secs > 9) {
+                        idrc += 1;
+                    }
+
+                    winStatus(idrc, 3, NULL,
+                              _("Flashing %s port lights for %d seconds."),
+                              devices[deviceNum], secs);
+
+                    if (identifyNIC(devices[deviceNum], secs)) {
+                        logMessage(ERROR,
+                                   "error during physical NIC identification");
+                    }
+
+                    newtPopWindow();
+                    i = 0;
+                } else if (idrc == 2) {
+                    i = 0;
+                }
+            }
+        } else if (rc == 3) {
+            ask = 0;
+            return LOADER_BACK;
+        } else {
+            ask = 0;
+        }
+    }
+
+    loaderData->netDev = devices[deviceNum];
+    return LOADER_OK;
+}
+
+/* JKFIXME: bad name.  this function brings up networking early on a 
+ * kickstart install so that we can do things like grab the ks.cfg from
+ * the network */
+int kickstartNetworkUp(struct loaderData_s * loaderData, iface_t * iface) {
+    int rc, err;
+
+    if ((is_nm_connected() == TRUE) &&
+        (loaderData->netDev != NULL) && (loaderData->netDev_set == 1))
+        return 0;
+
+    memset(iface, 0, sizeof(*iface));
+
+    do {
+        do {
+            /* this is smart and does the right thing based on whether or not
+             * we have ksdevice= specified */
+            rc = chooseNetworkInterface(loaderData);
+
+            if (rc == LOADER_ERROR) {
+                /* JKFIXME: ask for a driver disk? */
+                logMessage(ERROR, "no network drivers for doing kickstart");
+                return -1;
+            } else if (rc == LOADER_BACK) {
+                return -1;
+            }
+
+            /* insert device into iface structure */
+            strcpy(iface->device, loaderData->netDev);
+
+            break;
+        } while (1);
+
+        /* we don't want to end up asking about interface more than once
+         * if we're in a kickstart-ish case (#100724) */
+        loaderData->netDev_set = 1;
+
+        /* default to DHCP for IPv4 if nothing is provided */
+        if (loaderData->ipv4 == NULL) {
+            loaderData->ipv4 = strdup("dhcp");
+            loaderData->ipinfo_set = 1;
+        }
+
+        setupIfaceStruct(iface, loaderData);
+        rc = readNetConfig(loaderData->netDev, iface, loaderData->netCls,
+                           loaderData->method);
+
+        if (rc == LOADER_ERROR) {
+            logMessage(ERROR, "unable to setup networking");
+            return -1;
+        } else if (rc == LOADER_BACK) {
+            /* Going back to the interface selection screen, so unset anything
+             * we set before attempting to bring the incorrect interface up.
+             */
+            if ((rc = writeDisabledNetInfo()) != 0) {
+                logMessage(ERROR, "writeDisabledNetInfo failure (%s): %d",
+                           __func__, rc);
+            }
+
+            loaderData->netDev_set = 0;
+            loaderData->ipinfo_set = 0;
+            free(loaderData->ipv4);
+            loaderData->ipv4 = NULL;
+            break;
+        } else {
+            break;
+        }
+
+        err = writeEnabledNetInfo(iface);
+        if (err) {
+            logMessage(ERROR,
+                       "failed to write %s data for %s (%d)",
+                       SYSCONFIG_PATH, iface->device, err);
+            return -1;
+        }
+
+        err = get_connection(iface);
+        newtPopWindow();
+
+        if (err) {
+            logMessage(ERROR, "failed to start NetworkManager (%d)", err);
+            return -1;
+        }
+    } while (1);
+
+    return 0;
+}
+
+void splitHostname (char *str, char **host, char **port)
+{
+    char *rightbrack = strchr(str, ']');
+    char *firstcolon = strchr(str, ':');
+    char *secondcolon = strrchr(str, ':');
+
+    *host = NULL;
+    *port = NULL;
+
+    if (*str == '[' && rightbrack) {
+        /* An IPv6 address surrounded by brackets, optionally with a colon and
+         * port number.
+         */
+        char *colon = strrchr(rightbrack, ':');
+
+        if (colon) {
+            *host = strndup(str+1, rightbrack-1-str);
+            *port = strdup(colon+1);
+        }
+        else
+            *host = strndup(str+1, rightbrack-1-str);
+    } else if (firstcolon && secondcolon && firstcolon != secondcolon) {
+        /* An IPv6 address without brackets.  Don't make the user surround the
+         * address with brackets if there's no port number.
+         */
+        *host = strdup(str);
+    } else {
+        /* An IPv4 address, optionally with a colon and port number. */
+        char *colon = strrchr(str, ':');
+
+        if (colon) {
+            *host = strndup(str, colon-str);
+            *port = strdup(colon+1);
+        }
+        else
+            *host = strdup(str);
+    }
+}
+
+/*
+ * Start NetworkManager and wait for a valid link, return non-zero on error.
+ */
+int get_connection(iface_t *iface) {
+    int count = 0;
+    NMClient *client = NULL;
+    NMState state;
+    GMainLoop *loop;
+    GMainContext *ctx;
+
+    if (iface == NULL) {
+        return 1;
+    }
+
+    logMessage(DEBUGLVL, "configuring device %s", iface->device);
+
+    /* display status */
+    if (FL_CMDLINE(flags)) {
+        printf(_("Waiting for NetworkManager to configure %s.\n"),
+               iface->device);
+    } else {
+        winStatus(55, 3, NULL,
+                  _("Waiting for NetworkManager to configure %s.\n"),
+                  iface->device, 0);
+    }
+
+    g_type_init();
+
+    client = nm_client_new();
+    if (!client) {
+        logMessage(ERROR, "%s (%d): could not connect to system bus",
+                   __func__, __LINE__);
+        return 2;
+    }
+
+    /* Create a loop for processing dbus signals */
+    loop = g_main_loop_new(NULL, FALSE);
+    ctx = g_main_loop_get_context(loop);
+
+    /* pump the loop until all the messages are clear */
+    while (g_main_context_pending (ctx)) {
+        g_main_context_iteration (ctx, FALSE);
+    }
+
+    /* send message and block until a reply or error comes back */
+    while (count < 45) {
+        /* pump the loop again to clear the messages */
+        while (g_main_context_pending (ctx)) {
+            g_main_context_iteration (ctx, FALSE);
+        }
+        state = nm_client_get_state(client);
+
+        if (state == NM_STATE_CONNECTED) {
+            logMessage(INFO, "%s (%d): NetworkManager connected",
+                       __func__, __LINE__);
+            res_init();
+            g_object_unref(client);
+            return 0;
+        }
+
+        sleep(1);
+        count++;
+    }
+
+    g_main_loop_unref(loop);
+    g_object_unref(client);
+    return 3;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4: */
diff --git a/bin/loader/net.h b/bin/loader/net.h
new file mode 100644
index 0000000..8245084
--- /dev/null
+++ b/bin/loader/net.h
@@ -0,0 +1,77 @@
+/*
+ * net.h
+ *
+ * Copyright (C) 2007  Red Hat, Inc.  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 as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef H_LOADER_NET
+#define H_LOADER_NET
+
+#include <newt.h>
+#include "../isys/iface.h"
+#include "loader.h"
+
+#define DHCP_METHOD_STR   _("Dynamic IP configuration (DHCP)")
+#define MANUAL_METHOD_STR _("Manual configuration")
+#ifdef ENABLE_IPV6
+#define DHCPV6_METHOD_STR _("Dynamic IP configuration (DHCPv6)")
+#define AUTO_METHOD_STR   _("Automatic neighbor discovery")
+#endif
+
+#define SYSCONFIG_PATH       "/etc/sysconfig"
+#define NETWORK_SCRIPTS_PATH "/etc/sysconfig/network-scripts"
+
+struct intfconfig_s {
+    newtComponent ipv4Entry, cidr4Entry;
+    newtComponent gwEntry, nsEntry;
+    const char *ipv4, *cidr4;
+#ifdef ENABLE_IPV6
+    newtComponent ipv6Entry, cidr6Entry;
+    const char *ipv6, *cidr6;
+    const char *gw6;
+#endif
+    const char *gw, *ns;
+};
+
+struct netconfopts {
+    char ipv4Choice;
+#ifdef ENABLE_IPV6
+    char ipv6Choice;
+#endif
+};
+
+typedef int int32;
+
+int readNetConfig(char * device, iface_t * iface,
+                  char * dhcpclass, int methodNum);
+int configureTCPIP(char * device, iface_t * iface, struct netconfopts * opts,
+                   int methodNum);
+int manualNetConfig(char * device, iface_t * iface,
+                    struct intfconfig_s * ipcomps, struct netconfopts * opts);
+void debugNetworkInfo(iface_t * iface);
+int writeDisabledNetInfo(void);
+int writeEnabledNetInfo(iface_t * iface);
+int chooseNetworkInterface(struct loaderData_s * loaderData);
+void setupIfaceStruct(iface_t * iface, struct loaderData_s * loaderData);
+int setupWireless(iface_t * iface);
+void setKickstartNetwork(struct loaderData_s * loaderData, int argc, 
+                         char ** argv);
+int kickstartNetworkUp(struct loaderData_s * loaderData,
+                       iface_t * iface);
+void splitHostname (char *str, char **host, char **port);
+int get_connection(iface_t * iface);
+
+#endif
diff --git a/bin/loader/nfsinstall.c b/bin/loader/nfsinstall.c
new file mode 100644
index 0000000..b6c3c82
--- /dev/null
+++ b/bin/loader/nfsinstall.c
@@ -0,0 +1,586 @@
+/*
+ * nfsinstall.c - code to set up nfs installs
+ *
+ * Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
+ * 2006, 2007  Red Hat, Inc.  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 as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ *
+ * Author(s): Erik Troan <ewt@xxxxxxxxxx>
+ *            Matt Wilson <msw@xxxxxxxxxx>
+ *            Michael Fulbright <msf@xxxxxxxxxx>
+ *            Jeremy Katz <katzj@xxxxxxxxxx>
+ */
+
+#include <fcntl.h>
+#include <newt.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <errno.h>
+#include <string.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <arpa/inet.h>
+#include <netdb.h>
+#include <glib.h>
+#include <nm-client.h>
+#include <nm-device.h>
+#include <nm-dhcp4-config.h>
+
+#include "copy.h"
+#include "loader.h"
+#include "lang.h"
+#include "loadermisc.h"
+#include "kickstart.h"
+#include "method.h"
+#include "nfsinstall.h"
+#include "net.h"
+#include "cdinstall.h"
+#include "windows.h"
+
+#include "../isys/imount.h"
+#include "../isys/iface.h"
+#include "../isys/log.h"
+
+/* boot flags */
+extern uint64_t flags;
+
+/**
+ * Test whether the mounted stage2 path is an uncompreseed image, not a squashfs.
+ * 
+ * Asusme path is readable.
+ */
+static int isNfsMountDirect(const char * path) {
+    struct stat stat_info;
+    if (stat(path, &stat_info))
+        return 0;
+
+    if (!S_ISDIR(stat_info.st_mode))
+        /* if it's not a directory, then it's not an uncompressed image */
+        return 0;
+
+    char * buildstamp;
+    checked_asprintf(&buildstamp, "%s/%s", path, ".buildstamp");
+    if (access(buildstamp, F_OK))
+        /* if it doesn't contain buildstamp, then it's not an uncompressed image */
+        return 0;
+    free(buildstamp);
+
+    return 1;
+}
+
+static int nfsGetSetup(char ** hostptr, char ** dirptr, char ** optsptr) {
+    struct newtWinEntry entries[4];
+    char * buf;
+    char * newServer = *hostptr ? strdup(*hostptr) : NULL;
+    char * newDir = *dirptr ? strdup(*dirptr) : NULL;
+    char * newMountOpts = *optsptr ? strdup(*optsptr) : NULL;
+    int rc;
+
+    entries[0].text = _("NFS server name:");
+    entries[0].value = &newServer;
+    entries[0].flags = NEWT_FLAG_SCROLL;
+    
+    checked_asprintf(&entries[1].text, _("%s directory:"), getProductName());
+
+    entries[1].value = &newDir;
+    entries[1].flags = NEWT_FLAG_SCROLL;
+    entries[2].text = _("NFS mount options (optional):");
+    entries[2].value = &newMountOpts;
+    entries[2].flags = NEWT_FLAG_SCROLL;
+    entries[3].text = NULL; 
+    entries[3].value = NULL;
+
+    if (asprintf(&buf, _("Please enter the server and path to your %s "
+                         "installation image and optionally additional "
+                         "NFS mount options."), getProductName()) == -1) {
+        logMessage(CRITICAL, "%s: %d: %m", __func__, __LINE__);
+        abort();
+    }
+
+    do {
+        rc = newtWinEntries(_("NFS Setup"), buf, 60, 5, 15,
+                            24, entries, _("OK"), _("Back"), NULL);
+    } while ((!strcmp(newServer, "") || !strcmp(newDir, "")) && rc != 2);
+
+    free(buf);
+    free(entries[1].text);
+
+    if (rc == 2) {
+        if (newServer) free(newServer);
+        if (newDir) free(newDir);
+        if (newMountOpts) free(newMountOpts);
+        return LOADER_BACK;
+    }
+
+    if (*hostptr) free(*hostptr);
+    if (*dirptr) free(*dirptr);
+    if (*optsptr) free(*optsptr);
+    *hostptr = newServer;
+    *dirptr = newDir;
+    *optsptr = newMountOpts;
+
+    return 0;
+}
+
+void parseNfsHostPathOpts(char *url, char **host, char **path, char **opts) {
+    char *tmp;
+    char *hostsrc;
+
+    logMessage(DEBUGLVL, "parseNfsHostPathOpts url: |%s|", url);
+
+    hostsrc = strdup(url);
+    *host = hostsrc;
+    tmp = strchr(*host, ':');
+
+    if (tmp) {
+       *path = strdup(tmp + 1);
+       *tmp = '\0';
+    }
+    else {
+        *path = malloc(sizeof(char *));
+        **path = '\0';
+    }
+
+    tmp = strchr(*path, ':');
+    if (tmp && (strlen(tmp) > 1)) {
+	char * c = tmp;
+        *opts = *host;
+        *host = *path;
+	*path = strdup(c + 1);
+	*c = '\0';
+    } else {
+	*opts = NULL;
+    }
+
+    logMessage(DEBUGLVL, "parseNfsHostPathOpts host: |%s|", *host);
+    logMessage(DEBUGLVL, "parseNfsHostPathOpts path: |%s|", *path);
+    logMessage(DEBUGLVL, "parseNfsHostPathOpts opts: |%s|", *opts);
+}
+
+static void addDefaultKickstartFile(char **file, char *ip) {
+    /* if the filename ends with / or is null, use default kickstart
+     * name of IP_ADDRESS-kickstart appended to *file
+     */
+    if ((*file) && (((*file)[strlen(*file) - 1] == '/') ||
+                    ((*file)[strlen(*file) - 1] == '\0'))) {
+        checked_asprintf(file, "%s%s-kickstart", *file, ip);
+        logMessage(DEBUGLVL, "addDefaultKickstartFile file: |%s|", *file);
+    }
+}
+
+char * mountNfsImage(struct installMethod * method,
+                     char * location, struct loaderData_s * loaderData) {
+    char * host = NULL;
+    char * directory = NULL;
+    char * mountOpts = NULL;
+    char * fullPath = NULL;
+    char * url = NULL;
+
+    enum { NFS_STAGE_NFS, NFS_STAGE_MOUNT, NFS_STAGE_DONE,
+           NFS_STAGE_UPDATES } stage = NFS_STAGE_NFS;
+
+    int rc;
+
+    /* JKFIXME: ASSERT -- we have a network device setup when we get here */
+    while (stage != NFS_STAGE_DONE) {
+        switch (stage) {
+        case NFS_STAGE_NFS:
+            if (loaderData->method == METHOD_NFS && loaderData->stage2Data) {
+                host = ((struct nfsInstallData *)loaderData->stage2Data)->host;
+                directory = ((struct nfsInstallData *)loaderData->stage2Data)->directory;
+
+                if (((struct nfsInstallData *)
+                    loaderData->stage2Data)->mountOpts == NULL) {
+                    mountOpts = strdup("ro");
+                } else {
+                    checked_asprintf(&mountOpts, "ro,%s",
+                                     ((struct nfsInstallData *)
+                                      loaderData->stage2Data)->mountOpts);
+                }
+
+                logMessage(INFO, "host is %s, dir is %s, opts are '%s'", host, directory, mountOpts);
+
+                if (!host || !directory) {
+                    logMessage(ERROR, "missing host or directory specification");
+
+                    if (loaderData->inferredStage2)
+                        loaderData->invalidRepoParam = 1;
+
+                    loaderData->method = -1;
+                    break;
+                } else {
+                    host = strdup(host);
+                    directory = strdup(directory);
+                }
+            } else {
+                char *colonopts, *substr, *tmp;
+
+                logMessage(INFO, "going to do nfsGetSetup");
+                if (nfsGetSetup(&host, &directory, &mountOpts) == LOADER_BACK) {
+                    loaderData->stage2Data = NULL;
+                    return NULL;
+                }
+
+                /* If the user-provided URL points at a repo instead of a
+                 * stage2 image, fix that up now.
+                 */
+                substr = strstr(directory, ".img");
+                if (!substr || (substr && *(substr+4) != '\0')) {
+                    if (mountOpts && strlen(mountOpts)) {
+                        checked_asprintf(&colonopts, ":%s", mountOpts);
+                    } else {
+                        colonopts = strdup("");
+                    }
+
+                    checked_asprintf(&(loaderData->instRepo), "nfs%s:%s:%s",
+                                     colonopts, host, directory);
+                    checked_asprintf(&tmp, "nfs%s:%s:%s/images/install.img",
+                                     colonopts, host, directory);
+
+                    setStage2LocFromCmdline(tmp, loaderData);
+                    free(host);
+                    free(directory);
+                    free(mountOpts);
+                    free(colonopts);
+                    free(tmp);
+                    continue;
+                }
+
+                loaderData->invalidRepoParam = 1;
+            }
+
+            stage = NFS_STAGE_MOUNT;
+            break;
+
+        case NFS_STAGE_MOUNT: {
+            char *buf;
+
+            checked_asprintf(&fullPath, "%s:%.*s", host,
+                             (int) (strrchr(directory, '/')-directory),
+                             directory);
+            logMessage(INFO, "mounting nfs path %s", fullPath);
+
+            stage = NFS_STAGE_NFS;
+
+            if (!doPwMount(fullPath, "/mnt/stage2", "nfs", mountOpts, NULL)) {
+                checked_asprintf(&buf, "/mnt/stage2/%s",
+                                 strrchr(directory, '/') + 1);
+
+                if (!access(buf, R_OK)) {
+                    logMessage(INFO, "can access %s", buf);
+                    if (isNfsMountDirect(buf)) {
+                        logMessage(INFO, "using uncompressed stage2 image");
+                        rc = mountStage2Direct(buf);
+                    } else {
+                        rc = mountStage2(buf);
+                    }
+
+                    if (rc == 0) {
+                        stage = NFS_STAGE_UPDATES;
+                        checked_asprintf(&url, "nfs:%s:%s", host,
+                                         directory);
+                        free(buf);
+                        break;
+                    } else {
+                        logMessage(WARNING, "unable to mount %s", buf);
+                        free(buf);
+                        break;
+                    }
+                } else {
+                    logMessage(WARNING, "unable to access %s", buf);
+                    free(buf);
+                    umount("/mnt/stage2");
+                }
+            } else {
+                newtWinMessage(_("Error"), _("OK"),
+                               _("That directory could not be mounted from "
+                                 "the server."));
+                if (loaderData->method >= 0)
+                    loaderData->method = -1;
+
+                if (loaderData->inferredStage2)
+                    loaderData->invalidRepoParam = 1;
+
+                break;
+            }
+
+            checked_asprintf(&buf,
+                             _("That directory does not seem to "
+                               "contain a %s installation image."),
+                             getProductName());
+
+            newtWinMessage(_("Error"), _("OK"), buf);
+            free(buf);
+
+            if (loaderData->method >= 0)
+                loaderData->method = -1;
+
+            if (loaderData->inferredStage2)
+                loaderData->invalidRepoParam = 1;
+
+            break;
+        }
+
+        case NFS_STAGE_UPDATES: {
+            char *buf;
+
+            checked_asprintf(&buf, "%.*s/RHupdates",
+                             (int) (strrchr(fullPath, '/')-fullPath),
+                             fullPath);
+
+            logMessage(INFO, "mounting nfs path %s for updates", buf);
+
+            if (!doPwMount(buf, "/tmp/update-disk", "nfs", mountOpts, NULL)) {
+                logMessage(INFO, "Using RHupdates/ for NFS install");
+                copyDirectory("/tmp/update-disk", "/tmp/updates", NULL, NULL);
+                umount("/tmp/update-disk");
+                unlink("/tmp/update-disk");
+            } else {
+                logMessage(INFO, "No RHupdates/ directory found, skipping");
+            }
+
+            stage = NFS_STAGE_DONE;
+            break;
+        }
+
+        case NFS_STAGE_DONE:
+            break;
+        }
+    }
+
+    free(host);
+    free(directory);
+    if (mountOpts)
+        free(mountOpts);
+    if (fullPath)
+        free(fullPath);
+
+    return url;
+}
+
+
+void setKickstartNfs(struct loaderData_s * loaderData, int argc,
+                     char ** argv) {
+    char *substr = NULL;
+    gchar *host = NULL, *dir = NULL, *mountOpts = NULL;
+    GOptionContext *optCon = g_option_context_new(NULL);
+    GError *optErr = NULL;
+    GOptionEntry ksNfsOptions[] = {
+        { "server", 0, 0, G_OPTION_ARG_STRING, &host, NULL, NULL },
+        { "dir", 0, 0, G_OPTION_ARG_STRING, &dir, NULL, NULL },
+        { "opts", 0, 0, G_OPTION_ARG_STRING, &mountOpts, NULL, NULL },
+        { NULL },
+    };
+
+    logMessage(INFO, "kickstartFromNfs");
+
+    g_option_context_set_help_enabled(optCon, FALSE);
+    g_option_context_add_main_entries(optCon, ksNfsOptions, NULL);
+
+    if (!g_option_context_parse(optCon, &argc, &argv, &optErr)) {
+        startNewt();
+        newtWinMessage(_("Kickstart Error"), _("OK"),
+                       _("Bad argument to NFS kickstart method "
+                         "command: %s"), optErr->message);
+        g_error_free(optErr);
+        g_option_context_free(optCon);
+        return;
+    }
+
+    g_option_context_free(optCon);
+
+    if (!host || !dir) {
+        logMessage(ERROR, "host and directory for nfs kickstart not specified");
+        return;
+    }
+
+    loaderData->method = METHOD_NFS;
+    loaderData->stage2Data = NULL;
+
+    substr = strstr(dir, ".img");
+    if (!substr || (substr && *(substr+4) != '\0')) {
+        checked_asprintf(&(loaderData->instRepo), "nfs:%s:%s", host, dir);
+
+        logMessage(INFO, "results of nfs, host is %s, dir is %s, opts are '%s'",
+                   host, dir, mountOpts);
+    } else {
+        loaderData->stage2Data = calloc(sizeof(struct nfsInstallData *), 1);
+        ((struct nfsInstallData *)loaderData->stage2Data)->host = host;
+        ((struct nfsInstallData *)loaderData->stage2Data)->directory = dir;
+        ((struct nfsInstallData *)loaderData->stage2Data)->mountOpts = mountOpts;
+
+        logMessage(INFO, "results of nfs, host is %s, dir is %s, opts are '%s'",
+                   ((struct nfsInstallData *) loaderData->stage2Data)->host,
+                   ((struct nfsInstallData *) loaderData->stage2Data)->directory,
+                   ((struct nfsInstallData *) loaderData->stage2Data)->mountOpts);
+    }
+}
+
+
+int getFileFromNfs(char * url, char * dest, struct loaderData_s * loaderData) {
+    char * host = NULL, *path = NULL, * file = NULL, * opts = NULL;
+    char * chk = NULL, *ip = NULL;
+    int failed = 0, i = 0;
+    iface_t iface;
+    NMClient *client = NULL;
+    NMState state;
+    const GPtrArray *devices;
+
+    if (kickstartNetworkUp(loaderData, &iface)) {
+        logMessage(ERROR, "unable to bring up network");
+        return 1;
+    }
+
+    /* if they just did 'linux ks', they want us to figure it out from
+     * the dhcp/bootp information
+     */
+    if (!url) {
+        g_type_init();
+
+        client = nm_client_new();
+        if (!client) {
+            logMessage(CRITICAL, "%s (%d): failure creating NM proxy",
+                       __func__, __LINE__);
+            return 1;
+        }
+
+        state = nm_client_get_state(client);
+        if (state != NM_STATE_CONNECTED) {
+            logMessage(ERROR, "%s (%d): no active network devices",
+                       __func__, __LINE__);
+            g_object_unref(client);
+            return 1;
+        }
+
+        devices = nm_client_get_devices(client);
+        for (i = 0; i < devices->len; i++) {
+            NMDevice *candidate = g_ptr_array_index(devices, i);
+            const char *devname = nm_device_get_iface(candidate);
+            NMDHCP4Config *dhcp = NULL;
+            const char *server_name = NULL;
+            const char *filename = NULL;
+            struct in_addr addr;
+            char nextserver[INET_ADDRSTRLEN+1];
+
+            if (nm_device_get_state(candidate) != NM_DEVICE_STATE_ACTIVATED)
+                continue;
+
+            if (strcmp(iface.device, devname))
+                continue;
+
+            dhcp = nm_device_get_dhcp4_config(candidate);
+            if (!dhcp) {
+                logMessage(ERROR, "no boot options received by DHCP");
+                continue;
+            }
+
+            server_name = nm_dhcp4_config_get_one_option(dhcp, "server_name");
+            if (!server_name) {
+                logMessage(ERROR, "no bootserver was found");
+                g_object_unref(client);
+                return 1;
+            }
+
+            /* 'server_name' may be a hostname or an IPv4 address */
+            memset(&nextserver, '\0', sizeof(nextserver));
+            if (inet_pton(AF_INET, server_name, &addr) >= 1) {
+                strcpy(nextserver, server_name);
+            } else {
+                struct hostent *he = gethostbyname(server_name);
+                if (he != NULL) {
+                    if (inet_ntop(AF_INET, he->h_addr_list[0],
+                                  nextserver, INET_ADDRSTRLEN) == NULL) {
+                        memset(&nextserver, '\0', sizeof(nextserver));
+                    }
+                }
+            }
+
+            filename = nm_dhcp4_config_get_one_option(dhcp, "filename");
+            if (filename == NULL) {
+                checked_asprintf(&url, "%s:/kickstart/", nextserver);
+                logMessage(ERROR, "bootp: no bootfile received");
+            } else {
+                checked_asprintf(&url, "%s:%s", nextserver, filename);
+                logMessage(INFO, "bootp: bootfile is %s", filename);
+            }
+
+            break;
+        }
+
+        g_object_unref(client);
+    }
+
+    /* get the IP of the target system */
+    if ((ip = iface_ip2str(loaderData->netDev, AF_INET)) == NULL) {
+        logMessage(ERROR, "iface_ip2str returned NULL");
+        return 1;
+    }
+
+    logMessage(INFO, "url is %s", url);
+
+    parseNfsHostPathOpts(url, &host, &path, &opts);
+    addDefaultKickstartFile(&path, ip);
+
+    /* nfs has to be a little bit different... split off the last part as
+     * the file and then concatenate host + dir path */
+    file = strrchr(path, '/');
+    if (!file) {
+        file = path;
+    } else {
+        *file++ ='\0';
+        chk = host + strlen(host)-1;
+
+        if (*chk == '/' || *path == '/') {
+            checked_asprintf(&host, "%s:%s", host, path);
+        } else {
+            checked_asprintf(&host, "%s:/%s", host, path);
+        }
+    }
+
+    logMessage(INFO, "file location: nfs:%s/%s", host, file);
+
+    if (!doPwMount(host, "/tmp/mnt", "nfs", opts, NULL)) {
+        char * buf;
+
+        checked_asprintf(&buf, "/tmp/mnt/%s", file);
+
+        if (copyFile(buf, dest)) {
+            logMessage(ERROR, "failed to copy file to %s", dest);
+            failed = 1;
+        }
+
+        free(buf);
+    } else {
+        logMessage(ERROR, "failed to mount nfs source");
+        failed = 1;
+    }
+
+    free(host);
+    free(path);
+    if (ip) free(ip);
+
+    umount("/tmp/mnt");
+    unlink("/tmp/mnt");
+
+    return failed;
+}
+
+int kickstartFromNfs(char * url, struct loaderData_s * loaderData) {
+    return getFileFromNfs(url, "/tmp/ks.cfg", loaderData);
+}
+
+/* vim:set shiftwidth=4 softtabstop=4: */
diff --git a/bin/loader/nfsinstall.h b/bin/loader/nfsinstall.h
new file mode 100644
index 0000000..99a8b06
--- /dev/null
+++ b/bin/loader/nfsinstall.h
@@ -0,0 +1,40 @@
+/*
+ * nfsinstall.h
+ *
+ * Copyright (C) 2007  Red Hat, Inc.  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 as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef NFSINSTALL_H
+#define NFSINSTALL_H
+
+#include "method.h"
+
+struct nfsInstallData {
+    char * host;
+    char * directory;
+    char * mountOpts;
+};
+
+
+void setKickstartNfs(struct loaderData_s * loaderData, int argc,
+                     char ** argv);
+int kickstartFromNfs(char * url, struct loaderData_s * loaderData);
+char * mountNfsImage(struct installMethod * method,
+                     char * location, struct loaderData_s * loaderData);
+int getFileFromNfs(char * url, char * dest, struct loaderData_s * loaderData);
+void parseNfsHostPathOpts(char * url, char ** host, char ** path, char ** opts);
+
+#endif
diff --git a/bin/loader/rpmextract.c b/bin/loader/rpmextract.c
new file mode 100644
index 0000000..d1549b8
--- /dev/null
+++ b/bin/loader/rpmextract.c
@@ -0,0 +1,325 @@
+/* unpack the payload of RPM package to the current directory
+ * 
+ * File name: rpmextract.c
+ * Date:      2009/12/18
+ * Author:    Martin Sivak <msivak at redhat dot com>
+ * 
+ * Copyright (C) 2009 Red Hat, Inc. 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 as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ * 
+ * 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, see <http://www.gnu.org/licenses/>.
+ *
+ * */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#include <rpm/rpmlib.h>		/* rpmReadPackageFile .. */
+#include <rpm/rpmtag.h>
+#include <rpm/rpmio.h>
+#include <rpm/rpmpgp.h>
+
+#include <rpm/rpmts.h>
+
+#include <stdio.h>
+#include <archive.h>
+#include <archive_entry.h>
+
+#include "loader.h"
+#include "rpmextract.h"
+
+#include "../isys/log.h"
+
+/*
+ * internal structure to pass to libarchive callbacks
+ */
+
+struct cpio_mydata {
+    FD_t gzdi;
+    char *buffer;
+};
+
+/*
+ * libarchive callbacks
+ */
+
+ssize_t rpm_myread(struct archive *a, void *client_data, const void **buff)
+{
+    struct cpio_mydata *mydata = client_data;
+    *buff = mydata->buffer;
+    return Fread(mydata->buffer, BUFFERSIZE, 1, mydata->gzdi);
+}
+
+int rpm_myclose(struct archive *a, void *client_data)
+{
+    struct cpio_mydata *mydata = client_data;
+    if (mydata->gzdi > 0)
+        Fclose(mydata->gzdi);
+    return ARCHIVE_OK;
+}
+
+/* read data from RPM header */
+
+const char * headerGetString(Header h, rpmTag tag)
+{
+    const char *res = NULL;
+    struct rpmtd_s td;
+
+    if (headerGet(h, tag, &td, HEADERGET_MINMEM)) {
+        if (rpmtdCount(&td) == 1) {
+            res = rpmtdGetString(&td);
+        }
+        rpmtdFreeData(&td);
+    }
+    return res;
+}
+
+/*
+ * explode source RPM into the current directory
+ * use filters to skip packages and files we do not need
+ */
+int explodeRPM(const char *source,
+        filterfunc filter,
+        dependencyfunc provides,
+        dependencyfunc deps,
+        void* userptr)
+{
+    char buffer[BUFFERSIZE+1]; /* make space for trailing \0 */
+    FD_t fdi;
+    Header h;
+    char * rpmio_flags = NULL;
+    rpmRC rc;
+    FD_t gzdi;
+    struct archive *cpio;
+    struct archive_entry *cpio_entry;
+    struct cpio_mydata cpio_mydata;
+
+    rpmts ts;
+    rpmVSFlags vsflags;
+    const char *compr;
+
+    if (strcmp(source, "-") == 0)
+        fdi = fdDup(STDIN_FILENO);
+    else
+        fdi = Fopen(source, "r.ufdio");
+
+    if (Ferror(fdi)) {
+        const char *srcname = (strcmp(source, "-") == 0) ? "<stdin>" : source;
+        logMessage(ERROR, "%s: %s\n", srcname, Fstrerror(fdi));
+        return EXIT_FAILURE;
+    }
+    rpmReadConfigFiles(NULL, NULL);
+
+    /* Initialize RPM transaction */
+    ts = rpmtsCreate();
+    vsflags = 0;
+
+    /* Do not check digests, signatures or headers */
+    vsflags |= _RPMVSF_NODIGESTS;
+    vsflags |= _RPMVSF_NOSIGNATURES;
+    vsflags |= RPMVSF_NOHDRCHK;
+    (void) rpmtsSetVSFlags(ts, vsflags);
+
+    rc = rpmReadPackageFile(ts, fdi, "rpm2dir", &h);
+
+    ts = rpmtsFree(ts);
+
+    switch (rc) {
+        case RPMRC_OK:
+        case RPMRC_NOKEY:
+        case RPMRC_NOTTRUSTED:
+            break;
+        case RPMRC_NOTFOUND:
+            logMessage(ERROR, "%s is not an RPM package", source);
+            return EXIT_FAILURE;
+            break;
+        case RPMRC_FAIL:
+        default:
+            logMessage(ERROR, "error reading header from %s package\n", source);
+            return EXIT_FAILURE;
+            break;
+    }
+
+    /* Retrieve all dependencies and run them through deps function */
+    while (deps) {
+        struct rpmtd_s td;
+        const char *depname;
+
+        if (!headerGet(h, RPMTAG_REQUIRENAME, &td, HEADERGET_MINMEM))
+            break;
+
+        /* iterator */
+        while ((depname = rpmtdNextString(&td))) {
+            if (deps(depname, userptr)) {
+                Fclose(fdi);
+                return EXIT_BADDEPS;
+            }
+        }
+        rpmtdFreeData(&td);
+        break;
+    }
+
+    /* Retrieve all provides and run them through provides function */
+    while (provides) {
+        struct rpmtd_s td;
+        const char *depname;
+        int found = 0;
+
+        if (!headerGet(h, RPMTAG_PROVIDES, &td, HEADERGET_MINMEM))
+            break;
+
+        /* iterator */
+        while ((depname = rpmtdNextString(&td))) {
+            if (!provides(depname, userptr)) {
+                found++;
+            }
+        }
+        rpmtdFreeData(&td);
+        if (found<=0)
+            return EXIT_BADDEPS;
+        break;
+    }
+
+    /* Retrieve type of payload compression. */
+    compr = headerGetString(h, RPMTAG_PAYLOADCOMPRESSOR);
+    if (compr && strcmp(compr, "gzip")) {
+        checked_asprintf(&rpmio_flags, "r.%sdio", compr);
+    }
+    else {
+        checked_asprintf(&rpmio_flags, "r.gzdio");
+    }
+
+    /* Open uncompressed cpio stream */
+    gzdi = Fdopen(fdi, rpmio_flags);
+    free(rpmio_flags);
+
+    if (gzdi == NULL) {
+        logMessage(ERROR, "cannot re-open payload: %s\n", Fstrerror(gzdi));
+        return EXIT_FAILURE;
+    }
+
+    /* initialize cpio decompressor */
+    cpio = archive_read_new();
+    if (cpio==NULL) {
+        Fclose(gzdi);
+        return -1;
+    }
+
+    cpio_mydata.gzdi = gzdi;
+    cpio_mydata.buffer = buffer;
+    archive_read_support_compression_all(cpio);
+    archive_read_support_format_all(cpio);
+    rc = archive_read_open(cpio, &cpio_mydata, NULL, rpm_myread, rpm_myclose);
+
+    /* check the status of archive_open */
+    if (rc != ARCHIVE_OK){
+        Fclose(gzdi);
+        return -1;
+    }
+
+    /* read all files in cpio archive */
+    while ((rc = archive_read_next_header(cpio, &cpio_entry)) == ARCHIVE_OK){
+        const struct stat *fstat;
+        int64_t fsize;
+        const char* filename;
+        int needskip = 1; /* do we need to read the data to get to the next header? */
+        int offset = 0;
+        int towrite = 0;
+
+        filename = archive_entry_pathname(cpio_entry);
+        fstat = archive_entry_stat(cpio_entry);
+        fsize = archive_entry_size(cpio_entry);
+
+        /* Strip leading slashes */
+        while (filename[offset] == '/')
+            offset+=1;
+
+        /* Strip leading ./ */
+        while (filename[offset] == '.' && filename[offset+1] == '/')
+            offset+=2;
+
+        /* Other file type - we do not care except special cases */
+        if (!S_ISREG(fstat->st_mode))
+            towrite = 1;
+        else
+            towrite = 2;
+
+        if (filter && filter(filename+offset, fstat, userptr)) {
+            /* filter this file */
+            towrite = 0;
+        }
+
+        /* Create directories */
+        char* dirname = strdup(filename+offset);
+
+        /* If the dup fails, let's hope the dirs already exist */
+        if (dirname){
+            char* dirptr = dirname;
+            while (dirptr && *dirptr) {
+                dirptr = strchr(dirptr, '/');
+                if (dirptr) {
+                    *dirptr = 0;
+                    mkdir(dirname, 0700);
+                    *dirptr = '/';
+                    dirptr++;
+                }
+            }
+            free(dirname);
+        }
+
+        /* Regular file */
+        if (towrite>=2) {
+            FILE *fdout = fopen(filename+offset, "w");
+
+            if (fdout==NULL){
+                rc = 33;
+                break;
+            }
+            
+            rc = archive_read_data_into_fd(cpio, fileno(fdout));
+            if (rc!=ARCHIVE_OK) {
+                /* XXX We didn't get the file.. well.. */
+                needskip = 0;
+            } else {
+                needskip = 0;
+                fclose(fdout);
+            }
+        }
+
+        /* symlink, we assume that the path contained in symlink
+         * is shorter than BUFFERSIZE */
+        while (towrite && S_ISLNK(fstat->st_mode)) {
+            char symlinkbuffer[BUFFERSIZE-1];
+
+            needskip = 0;
+            if ((rc = archive_read_data(cpio, symlinkbuffer, fsize))!=ARCHIVE_OK) {
+                /* XXX We didn't get the file.. well.. */
+                break;
+            }
+
+            if (symlink(buffer, filename+offset)) {
+                logMessage(ERROR, "Failed to create symlink %s -> %s", filename+offset, buffer);
+            }
+
+            break;
+        }
+
+        if(needskip)
+            archive_read_data_skip(cpio);
+    }
+
+    archive_read_finish(cpio);
+
+    return rc != ARCHIVE_OK;
+}
diff --git a/bin/loader/rpmextract.h b/bin/loader/rpmextract.h
new file mode 100644
index 0000000..53a90cf
--- /dev/null
+++ b/bin/loader/rpmextract.h
@@ -0,0 +1,45 @@
+/*
+   File name: rpmextract.h
+   Date:      2009/09/16
+   Author:    msivak
+
+   Copyright (C) 2009 Red Hat, 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; either version 2 of the
+   License, or (at your option) any later version.
+
+   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, see <http://www.gnu.org/licenses/>.
+*/
+
+
+#ifndef __RPMEXTRACT_H__
+#define __RPMEXTRACT_H__
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+
+#define EXIT_BADDEPS 4
+#define BUFFERSIZE 1024
+
+/* both filter functions return 0 - match, 1 - match not found */
+typedef int (*filterfunc)(const char* name, const struct stat *fstat, void *userptr);
+typedef int (*dependencyfunc)(const char* depends, void *userptr);
+
+int explodeRPM(const char* file,
+               filterfunc filter,
+               dependencyfunc provides,
+               dependencyfunc deps,
+               void* userptr);
+
+#endif
+
+/* end of rpmextract.h */
diff --git a/bin/loader/selinux.c b/bin/loader/selinux.c
new file mode 100644
index 0000000..66bfe4d
--- /dev/null
+++ b/bin/loader/selinux.c
@@ -0,0 +1,56 @@
+/*
+ * selinux.c - Various SELinux related functionality needed for the loader.
+ * Portions extracted from libselinux which was released as public domain
+ * software by the NSA.
+ *
+ * Copyright (C) 2004  Red Hat, Inc.  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 as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ *
+ * Author(s): Jeremy Katz <katzj@xxxxxxxxxx>
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <string.h>
+
+#include "loader.h"
+#include "loadermisc.h"
+#include "../isys/log.h"
+
+int loadpolicy() {
+    int pid, status;
+
+    logMessage(INFO, "Loading SELinux policy");
+
+    if (!(pid = fork())) {
+        setenv("LD_LIBRARY_PATH", LIBPATH, 1);
+        execl("/sbin/load_policy",
+              "/sbin/load_policy", "-q", NULL);
+        logMessage(ERROR, "exec of load_policy failed: %m");
+        exit(1);
+    }
+
+    waitpid(pid, &status, 0);
+    if (WIFEXITED(status) && (WEXITSTATUS(status) != 0))
+        return 1;
+
+    return 0;
+}
+
diff --git a/bin/loader/selinux.h b/bin/loader/selinux.h
new file mode 100644
index 0000000..5877ddd
--- /dev/null
+++ b/bin/loader/selinux.h
@@ -0,0 +1,27 @@
+/*
+ * selinux.h
+ *
+ * Copyright (C) 2007  Red Hat, Inc.  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 as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef SELINUX_H
+#define SELINUX_H
+
+int loadpolicy();
+
+#define ANACONDA_CONTEXT "system_u:system_r:anaconda_t:s0"
+
+#endif
diff --git a/bin/loader/shutdown.c b/bin/loader/shutdown.c
new file mode 100644
index 0000000..3b481f2
--- /dev/null
+++ b/bin/loader/shutdown.c
@@ -0,0 +1,153 @@
+/*
+ * shutdown.c
+ *
+ * Shutdown a running system.  If built with -DAS_SHUTDOWN=1, then
+ * it builds a standalone shutdown binary.
+ *
+ * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003  Red Hat, Inc.
+ * 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 as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <fcntl.h>
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/reboot.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+#include "init.h"
+
+void disableSwap(void);
+void unmountFilesystems(void);
+
+static void performTerminations(void) {
+	sync();
+	printf("sending termination signals...");
+	kill(-1, 15);
+	sleep(2);
+	printf("done\n");
+
+	printf("sending kill signals...");
+	kill(-1, 9);
+	sleep(2);
+	printf("done\n");
+}
+
+static void performUnmounts(void) {
+	int ignore;
+
+	printf("disabling swap...\n");
+	disableSwap();
+
+	printf("unmounting filesystems...\n"); 
+	unmountFilesystems();
+
+	printf("waiting for mdraid sets to become clean...\n"); 
+	ignore = system("/sbin/mdadm --wait-clean --scan");
+}
+
+static void performReboot(reboot_action rebootAction) {
+    switch (rebootAction) {
+    case POWEROFF:
+        printf("powering off system\n");
+        sleep(2);
+        reboot(RB_POWER_OFF);
+        break;
+    case REBOOT:
+        printf("rebooting system\n");
+        sleep(2);
+#if USE_MINILIBC
+        reboot(0xfee1dead, 672274793, 0x1234567);
+#else
+        reboot(RB_AUTOBOOT);
+#endif
+        break;
+    case HALT:
+        printf("halting system\n");
+        reboot(RB_HALT_SYSTEM);
+        break;
+    default:
+        break;
+    }
+}
+
+static void performDelayedReboot()
+{
+    printf("The system will be rebooted when you press Ctrl-C or Ctrl-Alt-Delete.\n");
+    while (1) {
+        sleep(1);
+    }
+}
+
+void shutDown(int doKill, reboot_action rebootAction)
+{
+    static int reentered = 0;
+    
+    if (reentered) {
+        performUnmounts();
+        performTerminations();
+        performReboot(rebootAction);
+    }
+    reentered = 1;
+    if (rebootAction != DELAYED_REBOOT && doKill) {
+        performUnmounts();
+        performTerminations();
+        performReboot(rebootAction);
+    } else {
+        performDelayedReboot();
+    }
+    exit(0);
+}
+
+#ifdef AS_SHUTDOWN
+int main(int argc, char ** argv) {
+    int fd;
+    reboot_action rebootAction = HALT;
+    int doKill = 1;
+    int i = 1;
+
+    while (i < argc) {
+      if (!strncmp("-r", argv[i], 2))
+        rebootAction = REBOOT;
+      else if (!strncmp("--nokill", argv[i], 8))
+        doKill = 0;
+      else if (!strncmp("-P", argv[i], 2))
+        rebootAction = POWEROFF;
+      i++;
+    }
+
+    /* ignore some signals so we don't kill ourself */
+    signal(SIGINT, SIG_IGN);
+    signal(SIGTSTP, SIG_IGN);
+
+    /* now change to / */
+    i = chdir("/");
+
+    /* redirect output to the real console */
+    fd = open("/dev/console", O_RDWR);
+    dup2(fd, 0);
+    dup2(fd, 1);
+    dup2(fd, 2);
+    close(fd);
+
+    shutDown(doKill, rebootAction);
+    return 0;
+}
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 ts=4: */
diff --git a/bin/loader/simplemot b/bin/loader/simplemot
new file mode 100755
index 0000000..bebc1cf
--- /dev/null
+++ b/bin/loader/simplemot
@@ -0,0 +1,81 @@
+#!/usr/bin/perl
+#
+# simplemot
+#
+# Copyright (C) 2007  Red Hat, Inc.  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 as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# 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, see <http://www.gnu.org/licenses/>.
+#
+
+$inone = 0;
+$intran = 0;
+$total = 0;
+
+binmode(STDIN, ":raw");
+binmode(STDOUT, ":raw");
+
+while (<>) {
+    if (!$inone && /^msgid/) {
+	chop;
+	$str = substr($_, 7, length($_) - 8);
+	$inone = 1;
+    } elsif ($inone && /^"/) {
+	chop;
+	$str .= substr($_, 1, length($_) - 2);
+    } elsif ($inone) {
+	$inone = 0;
+
+	$str =~ s/\\n/\n/g;
+	$str =~ s/\\t/\t/g;
+	$str =~ s/\\"/"/g;
+
+	# the string is complete -- calculate a hash
+	$sum = 0;
+	$xor = 0;
+	for ($i = 0; $i < length($str); $i++) {
+	    $char = ord(substr($str, $i, 1));
+	    $sum += $char;
+	    $xor ^= $char;
+	}
+
+	$total = ($sum << 16) | (($xor & 0xFF) << 8) | (length($str) & 0xFF);
+    }
+
+    if (!$intran && /^msgstr/) {
+	chop;
+	$tran = substr($_, 8, length($_) - 9);
+	$intran = 1;
+    } elsif ($intran && /^"/) {
+	chop;
+	$tran .= substr($_, 1, length($_) - 2);
+    } elsif ($intran) {
+	$intran = 0;
+
+	$tran =~ s/\\n/\n/g;
+	$tran =~ s/\\t/\t/g;
+	$tran =~ s/\\"/"/g;
+
+	if (!$total && $str) {
+	    print STDERR "Missing string for $tran";
+	    exit 1
+	} elsif ($str && $tran) {
+	    print pack("Nn", $total, length($tran));
+	    print $tran;
+
+	    #if ($tran < 60) {
+		#printf STDERR ("0x%x %s\n", $total, $tran);
+	    #}
+	}
+    }
+}
diff --git a/bin/loader/telnet.c b/bin/loader/telnet.c
new file mode 100644
index 0000000..3c123ae
--- /dev/null
+++ b/bin/loader/telnet.c
@@ -0,0 +1,273 @@
+/*
+ * telnet.c -- basic telnet protocol handling for ttywatch
+ *
+ * Copyright (C) 2001  Red Hat, Inc.  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 as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ *
+ * Author(s): Michael K. Johnson <johnsonm@xxxxxxxxxx>
+ */
+
+/* Shamelessly stolen from ttywatch -- oot */
+
+#include <ctype.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#include "telnet.h"
+#include "../isys/log.h"
+
+#define IAC "\xff"
+#define DONT "\xfe"
+#define WONT "\xfc"
+#define WILL "\xfb"
+#define DO "\xfd"
+#define SB "\xfa"
+#define SE "\xf0"
+#define ECHO "\x01"
+#define SUPPRESS_GO_AHEAD "\x03"
+#define TERMINAL_TYPE "\x18"
+#define NAWS "\x1f"
+#define LINEMODE "\x22"
+#define NEWENVIRON "\x27"
+#define MODE "\x01"
+
+/* Make a request.  Not intended to be RFC-compatible, just enough
+ * to convince telnet clients to do what we want...  To do this
+ * right, we would have to honestly negotiate, not speak blind.
+ *
+ * For now, assume all responses will be favorable and stripped
+ * out in telnet_process_input()...  Sending it all in a single
+ * write makes it more efficient because it will all go out in a
+ * single packet, and the responses are more likely to all come
+ * back in a single packet (and thus, practically, a single read)
+ * too.
+ */
+void
+telnet_negotiate(int socket, char ** term_type_ptr, int * heightPtr,
+		 int * widthPtr) {
+    char ch;
+    int done = 0;
+    char * termType = NULL;
+    int termLength = 0, termAlloced = 0;
+    enum { ST_NONE, ST_TERMTYPE, ST_WINDOWSIZE } state;
+    char sizeBuf[4];
+    int height = -1, width = -1;
+    char * sizePtr = sizeBuf;
+    char request[]=
+      IAC DONT ECHO
+      IAC WILL ECHO
+      IAC WILL NAWS
+      IAC WILL SUPPRESS_GO_AHEAD
+      IAC DO SUPPRESS_GO_AHEAD
+      IAC DONT NEWENVIRON
+      IAC WONT NEWENVIRON
+      IAC WONT LINEMODE
+      IAC DO NAWS
+      IAC SB TERMINAL_TYPE "\x01" IAC SE
+      ;
+    int ret;
+
+    ret = write(socket, request, sizeof(request)-1);
+
+    /* Read from the terminal until we get the terminal type. This will
+       do bad things if the client doesn't send the terminal type, but
+       those clients have existed for aeons (right?) */
+
+    do {
+	ret = read(socket, &ch, 1);
+	if (ch != '\xff') {
+	    abort();
+	}
+
+	ret = read(socket, &ch, 1);	    /* command */
+
+	if (ch != '\xfa') {
+	    ret = read(socket, &ch, 1);   /* verb */
+	    continue;
+	}
+
+	ret = read(socket, &ch, 1);   /* suboption */
+	if (ch == '\x18') {
+	    state = ST_TERMTYPE;
+	    ret = read(socket, &ch, 1);	    /* should be 0x0! */
+	    done = 1;
+	} else if (ch == '\x1f') {
+	    state = ST_WINDOWSIZE;
+	} else {
+	    state = ST_NONE;;
+	}
+
+	ret = read(socket, &ch, 1);   /* data */
+	while (ch != '\xff') {
+	    if (state == ST_TERMTYPE) {
+		if (termAlloced == termLength) {
+		    termAlloced += 10;
+		    termType = realloc(termType, termAlloced + 1);
+		}
+
+		termType[termLength++] = tolower(ch);
+	    } else if (state == ST_WINDOWSIZE) {
+		if ((sizePtr - sizeBuf) < (int)sizeof(sizeBuf))
+		    *sizePtr++ = ch;
+	    }
+
+	    ret = read(socket, &ch, 1);   /* data */
+	}
+
+	ret = read(socket, &ch, 1);   /* should be a SE */
+
+    } while (!done);
+
+    termType[termLength] = '\0';
+
+    if (sizePtr - sizeBuf == sizeof(sizeBuf)) {
+	width = (sizeBuf[0] << 8) + sizeBuf[1];
+	height = (sizeBuf[2] << 8) + sizeBuf[3];
+    }
+
+    if (heightPtr) *heightPtr = height;
+    if (widthPtr) *widthPtr = width;
+
+    if (term_type_ptr) *term_type_ptr = termType;
+}
+
+int
+telnet_process_input(telnet_state * ts, char *data, int len) {
+    char *s, *d; /* source, destination */
+
+#   if DEBUG_TELNET
+    printf("\nprinting packet:");
+    for (s=data; s<data+len; s++) {
+	if (!((s-data)%10))
+	    printf("\n %03d: ", s-data);
+	printf("%02x ", *s & 0x000000FF);
+    }
+    printf("\n");
+#   endif /* DEBUG_TELNET */
+
+    for (s=data, d=data; s<data+len; s++) {
+	switch (*ts) {
+	case TS_DATA:
+	    if (*s == '\xff') { /* IAC */
+		*ts = TS_IAC;
+		continue;
+	    }
+#if	    DEBUG_TELNET
+	    printf("copying data element '%c'\n", *s);
+#endif	    /* DEBUG_TELNET */
+	    if (s>d) {
+		*(d++) = *s;
+	    } else {
+		d++;
+	    }
+	    break;
+
+	case TS_IAC:
+	    if (*s == '\xfa') { /* SB */
+		*ts = TS_SB;
+		continue;
+	    }
+	    /* if not SB, skip IAC verb object */
+#	    if DEBUG_TELNET
+	    printf("skipping verb/object (offset %d)...\n", s-data-1);
+#	    endif /* DEBUG_TELNET */
+	    s += 1;
+	    *ts = TS_DATA;
+	    break;
+
+	case TS_SB:
+#	    if DEBUG_TELNET
+	    printf("skipping SB (offset %d)...\n", s-data-1);
+#	    endif /* DEBUG_TELNET */
+	    while (s < (data+(len-1))) {
+		if (*s == '\xff') {
+		    break; /* fall through to TS_SB_IAC setting below */
+		} else {
+		    s++;
+		}
+	    }
+	    if (*s == '\xff') {
+		*ts = TS_SB_IAC;
+	    }
+	    break;
+
+	case TS_SB_IAC:
+	    if (*s == '\xf0') { /* SE */
+#		if DEBUG_TELNET
+		printf("SE ends SB (offset %d)...\n", s-data-1);
+#		endif /* DEBUG_TELNET */
+		*ts = TS_DATA;
+	    } else {
+#		if DEBUG_TELNET
+		printf("IAC without SE in SB (offset %d)\n", s-data-1);
+#		endif /* DEBUG_TELNET */
+		*ts = TS_SB;
+	    }
+	    break;
+
+	default:
+	    logMessage(WARNING, "unknown telnet state %d for data element %c",
+                       *ts, *s);
+	    *ts = TS_DATA;
+	    break;
+	}
+    }
+
+    /* calculate new length after copying data around */
+    len = d - data;
+#if DEBUG_TELNET
+    printf("returning len: %d of packet:", len);
+    for (s=data; s<data+len; s++) {
+	if (!((s-data)%10))
+	    printf("\n %03d: ", s-data);
+	printf("%02x ", *s & 0x000000FF);
+    }
+    printf("\n");
+#endif /* DEBUG_TELNET */
+
+    return len;
+}
+
+/* The telnet protocol requires CR/NL instead of just NL
+ * We normally deal with Unix, which just uses NL, so we need to translate.
+ *
+ * It would be easy to go through line-by-line and write each line, but
+ * that would create more packet overhead by sending out one packet
+ * per line, and over things like slow PPP connections, that is painful.
+ * Therefore, instead, we create a modified copy of the data and write
+ * the whole modified copy at once.
+ */
+void
+telnet_send_output(int sock, char *data, int len) {
+    char *s, *d; /* source, destination */
+    char *buf;
+    int ret;
+
+    buf = alloca((len*2)+1);  /* max necessary size */
+
+    /* just may need to add CR before NL (but do not double existing CRs) */
+    for (s=data, d=buf; d-buf<len; s++, d++) {
+	if ((*s == '\n') && (s == data || (*(s-1) != '\r'))) {
+	    /* NL without preceding CR */
+	    *(d++) = '\r';
+	    len++;
+	}
+	*d = *s;
+    }
+
+    /* now send it... */
+    ret = write(sock, buf, len);
+}
diff --git a/bin/loader/telnet.h b/bin/loader/telnet.h
new file mode 100644
index 0000000..5c34154
--- /dev/null
+++ b/bin/loader/telnet.h
@@ -0,0 +1,40 @@
+/*
+ * telnet.h -- basic telnet protocol handling for ttywatch
+ *
+ * Copyright (C) 2001  Red Hat, Inc.  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 as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ *
+ * Author(s): Michael K. Johnson <johnsonm@xxxxxxxxxx>
+ */
+
+#ifndef __TELNET_H__
+#define __TELNET_H__
+
+typedef enum {
+	TS_DATA = 0,
+	TS_IAC,
+	TS_SB,
+	TS_SB_IAC,
+} telnet_state;
+
+void
+telnet_negotiate(int socket, char ** term_type_ptr, int * heightPtr,
+		 int * widthPtr);
+int
+telnet_process_input(telnet_state * ts, char *data, int len);
+void
+telnet_send_output(int sock, char *data, int len);
+
+#endif /* __TELNET_H__ */
diff --git a/bin/loader/telnetd.c b/bin/loader/telnetd.c
new file mode 100644
index 0000000..219df78
--- /dev/null
+++ b/bin/loader/telnetd.c
@@ -0,0 +1,256 @@
+/*
+ * telnetd.c - glue to tie telnet.c from ttywatch to the loader
+ *
+ * Copyright (C) 2002  Red Hat, Inc.  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 as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ *
+ * Author(s): Erik Troan <ewt@xxxxxxxxxx>
+ *            Jeremy Katz <katzj@xxxxxxxxxx>
+ */
+
+#include <arpa/inet.h>
+#include <ctype.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <netinet/in.h>
+#include <newt.h>
+#include <pty.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/ioctl.h>
+#include <sys/poll.h>
+#include <sys/signal.h>
+#include <sys/socket.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+#include "../isys/log.h"
+
+#include "lang.h"
+#include "loader.h"
+#include "modules.h"
+#include "net.h"
+#include "telnet.h"
+#include "windows.h"
+
+#ifndef IPPORT_TELNET
+#define IPPORT_TELNET 23
+#endif
+
+/* boot flags */
+extern uint64_t flags;
+
+/* Forks, keeping the loader as our child (so we know when it dies). */
+int beTelnet(void) {
+    int sock;
+    int conn;
+    socklen_t addrLength;
+    pid_t child;
+    int i;
+    int masterFd, ttyFd;
+    struct sockaddr_in address;
+    char buf[4096];
+    struct pollfd fds[3];
+    telnet_state ts = TS_DATA;
+    char * termType;
+    int height, width;
+    struct winsize ws;
+
+    if ((sock = socket(PF_INET, SOCK_STREAM, 0)) < 0) {
+        logMessage(ERROR, "socket: %s", strerror(errno));
+        return -1;
+    }
+
+    address.sin_family = AF_INET;
+    address.sin_port = htons(IPPORT_TELNET);
+    memset(&address.sin_addr, 0, sizeof(address.sin_addr));
+    addrLength = sizeof(address);
+
+    /* Let the kernel reuse the socket address. This lets us run
+       twice in a row, without waiting for the (ip, port) tuple
+       to time out. Makes testing much easier*/
+    conn = 1;
+    setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &conn, sizeof(conn));
+
+    bind(sock, (struct sockaddr *) &address, sizeof(address));
+    listen(sock, 5);
+
+    winStatus(45, 3, _("Telnet"), _("Waiting for telnet connection."));
+
+    if ((conn = accept(sock, (struct sockaddr *) &address, &addrLength)) < 0) {
+        newtWinMessage(_("Error"), _("OK"), "accept failed: %s",
+                       strerror(errno));
+        close(sock);
+        return -1;
+    }
+
+    stopNewt();
+    close(sock);
+    telnet_negotiate(conn, &termType, &height, &width);
+
+#ifdef DEBUG_TELNET
+    printf("got term type %s\n", termType);
+#endif
+
+    masterFd = open("/dev/ptmx", O_RDWR);
+    if (masterFd < 0) {
+        logMessage(CRITICAL, "cannot open /dev/ptmx");
+        close(conn);
+        return -1;
+    }
+
+    if (height != -1 && width != -1) {
+#ifdef DEBUG_TELNET
+        printf("setting window size to %d x %d\n", width, height);
+#endif
+        ws.ws_row = height;
+        ws.ws_col = width;
+        ioctl(masterFd, TIOCSWINSZ, &ws);
+    }
+
+
+    child = fork();
+
+    if (child) {
+#ifndef DEBUG_TELNET
+        startNewt();
+        winStatus(45, 3, _("Telnet"), _("Running anaconda via telnet."));
+#endif
+
+        fds[0].events = POLLIN;
+        fds[0].fd = masterFd;
+
+        fds[1].events = POLLIN;
+        fds[1].fd = conn;
+
+        while ((i = poll(fds, 2, -1)) > 0) {
+            if (fds[0].revents) {
+                i = read(masterFd, buf, sizeof(buf));
+#ifdef DEBUG_TELNET
+                {
+                    int j;
+                    int row;
+
+                    for (row = 0; row < (i / 12) + 1; row++) {
+                        printf("wrote:");
+
+                        for (j = (row * 12); j < i && j < ((row + 1) * 12); j++)
+                            printf(" 0x%2x", (unsigned char) buf[j]);
+
+                        printf("\nwrote:");
+
+                        for (j = (row*12); j < i && j < ((row+1)*12); j++) {
+                            if (isprint(buf[j]))
+                                printf("   %c ", buf[j]);
+                            else
+                                printf("     ");
+                        }
+
+                        printf("\n");
+                    }
+                }
+#endif
+                /* child died */
+                if (i < 0)
+                    break;
+
+                telnet_send_output(conn, buf, i);
+            }
+
+            if (fds[1].revents) {
+                int ret;
+                i = read(conn, buf, sizeof(buf));
+
+                /* connection went away */
+                if (!i)
+                    break;
+
+                i = telnet_process_input(&ts, buf, i);
+                ret = write(masterFd, buf, i);
+#ifdef DEBUG_TELNET
+                {
+                    int j;
+
+                    printf("got:");
+                    for (j = 0; j < i; j++)
+                        printf(" 0x%x", (unsigned char) buf[j]);
+                    printf("\n");
+                }
+#endif
+            }
+        }
+
+        if (i < 0) {
+            logMessage(ERROR, "poll: %s", strerror(errno));
+        }
+
+#ifndef DEBUG_TELNET
+        stopNewt();
+#endif
+
+        kill(child, SIGTERM);
+        close(conn);
+        doExit(0);
+    }
+
+    unlockpt(masterFd);
+    grantpt(masterFd);
+    ttyFd = open(ptsname(masterFd), O_RDWR);
+    close(masterFd);
+    setsid();
+    close(0);
+    close(1);
+    close(2);
+
+    if (ttyFd != 0) {
+        dup2(ttyFd, 0);
+        close(ttyFd);
+    }
+
+    dup2(0, 1);
+    dup2(0, 2);
+
+    /* brand new tty! */
+    setenv("TERM", termType, 1);
+
+    startNewt();
+
+    return 0;
+}
+
+void startTelnetd(struct loaderData_s * loaderData) {
+    char *ipaddr = NULL;
+    iface_t iface;
+
+    iface_init_iface_t(&iface);
+
+    if (kickstartNetworkUp(loaderData, &iface)) {
+        logMessage(ERROR, "unable to bring up network");
+        return;
+    }
+
+    ipaddr = iface_ip2str(iface.device, AF_INET);
+    if (ipaddr == NULL) {
+        logMessage(ERROR, "%s (%d): no IP address found for %s",
+                   __func__, __LINE__, iface.device);
+        return;
+    }
+
+    logMessage(INFO, "going to beTelnet for %s", ipaddr);
+    if (!beTelnet())
+        flags |= LOADER_FLAGS_TEXT | LOADER_FLAGS_NOSHELL;
+
+    return;
+}
diff --git a/bin/loader/telnetd.h b/bin/loader/telnetd.h
new file mode 100644
index 0000000..fedb0fa
--- /dev/null
+++ b/bin/loader/telnetd.h
@@ -0,0 +1,25 @@
+/*
+ * telnetd.h
+ *
+ * Copyright (C) 2007  Red Hat, Inc.  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 as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef TELNETD_H
+#define TELNETD_H
+
+void startTelnetd(struct loaderData_s * loaderData);
+
+#endif
diff --git a/bin/loader/udelay.h b/bin/loader/udelay.h
new file mode 100644
index 0000000..5315074
--- /dev/null
+++ b/bin/loader/udelay.h
@@ -0,0 +1,199 @@
+/*
+ * udelay.h -- udelay and other time related functions.
+ *
+ * Copyright (C) 2006, 2007  Red Hat, Inc.  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 as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ *
+ * Author(s): Peter Jones <pjones@xxxxxxxxxx>
+ */
+
+#ifndef UDELAY_H
+#define UDELAY_H 1
+
+#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/time.h>
+#include <time.h>
+
+#define USECS_PER_SEC 1000000LL
+#define NSECS_PER_USEC 1000LL
+#define NSECS_PER_SEC (NSECS_PER_USEC * USECS_PER_SEC)
+
+static inline void
+nsectospec(long long nsecs, struct timespec *ts)
+{
+    if (nsecs < 0) {
+        ts->tv_sec = -1;
+        ts->tv_nsec = -1;
+        return;
+    }
+    ts->tv_sec = nsecs / NSECS_PER_SEC;
+    ts->tv_nsec = (nsecs % NSECS_PER_SEC);
+}
+
+static inline void
+usectospec(long long usecs, struct timespec *ts)
+{
+    if (usecs > 0 && LLONG_MAX / NSECS_PER_USEC > usecs)
+        usecs *= NSECS_PER_USEC;
+    
+    nsectospec(usecs, ts);
+}
+
+static inline int
+speczero(struct timespec *ts)
+{
+    return (ts->tv_sec == 0 && ts->tv_nsec == 0);
+}
+
+static inline int
+specinf(struct timespec *ts)
+{
+    return (ts->tv_sec < 0 || ts->tv_nsec < 0);
+}
+
+static inline long long
+spectonsec(struct timespec *ts)
+{
+    long long nsecs = 0;
+    if (specinf(ts))
+        return -1;
+    
+    nsecs = ts->tv_sec * NSECS_PER_SEC;
+    nsecs += ts->tv_nsec;
+    return nsecs;
+}
+
+static inline long long
+spectousec(struct timespec *ts)
+{
+    long long usecs = spectonsec(ts);
+
+    return usecs < 0 ? usecs : usecs / NSECS_PER_USEC;
+}
+
+static inline int
+gettimespecofday(struct timespec *ts)
+{
+    struct timeval tv = {0, 0};
+    int rc;
+
+    rc = gettimeofday(&tv, NULL);
+    if (rc >= 0) {
+        ts->tv_sec = tv.tv_sec;
+        ts->tv_nsec = tv.tv_usec * NSECS_PER_USEC;
+    }
+    return rc;
+}
+
+/* minuend minus subtrahend equals difference */
+static inline void
+tssub(struct timespec *minuend, struct timespec *subtrahend,
+      struct timespec *difference)
+{
+    long long m, s, d;
+
+    m = spectonsec(minuend);
+    s = spectonsec(subtrahend);
+
+    if (s < 0) {
+        d = 0;
+    } else if (m < 0) {
+        d = -1;
+    } else {
+        m -= s;
+        d = m < 0 ? 0 : m;
+    }
+
+    nsectospec(d, difference);
+    return;
+}
+
+static inline void
+tsadd(struct timespec *augend, struct timespec *addend, struct timespec *sum)
+{
+    long long aug, add;
+
+    aug = spectonsec(augend);
+    add = spectonsec(addend);
+
+//    printf("aug: %Ld add: %Ld\n", aug, add);
+
+    if (aug < 0 || add < 0)
+        nsectospec(-1, sum);
+    else if (LLONG_MAX - MAX(add,aug) < MAX(add,aug))
+        nsectospec(LLONG_MAX, sum);
+    else
+        nsectospec(aug+add, sum);
+    return;
+}
+
+#define tsGT(x,y) (tscmp((x), (y)) < 0)
+#define tsGE(x,y) (tscmp((x), (y)) <= 0)
+#define tsET(x,y) (tscmp((x), (y)) == 0)
+#define tsNE(x,y) (tscmp((x), (y)) != 0)
+#define tsLE(x,y) (tscmp((x), (y)) >= 0)
+#define tsLT(x,y) (tscmp((x), (y)) > 0)
+
+static inline int
+tscmp(struct timespec *a, struct timespec *b)
+{
+    long long m, s;
+    long long rc;
+
+    m = spectonsec(a);
+    s = spectonsec(b);
+
+    if (s < 0) {
+        rc = 1;
+        if (m < 0)
+            rc = 0;
+    } else if (m < 0) {
+        rc = -1;
+    } else {
+        rc = MIN(MAX(s-m, -1), 1);
+    }
+
+    return rc;
+}
+
+static inline void
+udelayspec(struct timespec total)
+{
+    struct timespec rem;
+    if (specinf(&total)) {
+        do {
+            usectospec(LLONG_MAX, &rem);
+        } while (nanosleep(&rem, &rem) == -1 && errno == EINTR);
+    } else {
+        rem = total;
+        while (nanosleep(&rem, &rem) == -1 && errno == EINTR)
+            ;
+    }
+}
+
+static inline void
+udelay(long long usecs)
+{
+    struct timespec rem = {0,0};
+
+    usectospec(usecs, &rem);
+    udelayspec(rem);
+}
+
+#endif /* UDELAY_H */
+/*
+ * vim:ts=8:sw=4:sts=4:et
+ */
diff --git a/bin/loader/undomounts.c b/bin/loader/undomounts.c
new file mode 100644
index 0000000..af5caaa
--- /dev/null
+++ b/bin/loader/undomounts.c
@@ -0,0 +1,239 @@
+/*
+ * undomounts.c: Handles some basic unmounting stuff for init
+ * Broken out so that it can be used on s390 in a shutdown binary
+ *
+ * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003  Red Hat, Inc.
+ * 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 as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ *
+ * Author(s): Erik Troan <ewt@xxxxxxxxxx>
+ *            Jeremy Katz <katzj@xxxxxxxxxx>
+ */
+
+#include <errno.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/ioctl.h>
+#include <sys/mount.h>
+#include <sys/stat.h>
+#include <sys/swap.h>
+#include <unistd.h>
+
+#include "devt.h"
+
+/* Defined in linux/fs.h, but inside __KERNEL__. */
+#ifdef MNT_DETACH
+#undef MNT_DETACH
+#endif
+
+#define MNT_DETACH 0x00000002
+
+struct unmountInfo {
+    char * name;
+    int mounted;
+    int loopDevice;
+    enum { FS, LOOP } what;
+} ;
+
+void undoLoop(struct unmountInfo * fs, int numFs, int this);
+
+static void printstr(char * string) {
+    int ret;
+    
+    ret = write(1, string, strlen(string));
+}
+
+void undoMount(struct unmountInfo * fs, int numFs, int this) {
+    size_t len = strlen(fs[this].name);
+    int i;
+
+    if (!fs[this].mounted) return;
+    fs[this].mounted = 0;
+
+    /* unmount everything underneath this */
+    for (i = 0; i < numFs; i++) {
+	if (fs[i].name && (strlen(fs[i].name) >= len) &&
+	    (fs[i].name[len] == '/') && 
+	    !strncmp(fs[this].name, fs[i].name, len)) {
+	    if (fs[i].what == LOOP)
+		undoLoop(fs, numFs, i);
+	    else
+		undoMount(fs, numFs, i);
+	} 
+    }
+
+    printf("\t%s", fs[this].name);
+    /* don't need to unmount /tmp.  it is busy anyway. */
+    if (umount2(fs[this].name, MNT_DETACH) < 0) {
+        printf(" umount failed (%d)", errno);
+    } else {
+        printf(" done");
+    }
+    printf("\n");
+}
+
+void undoLoop(struct unmountInfo * fs, int numFs, int this) {
+    int i;
+    int fd;
+
+    if (!fs[this].mounted) return;
+    fs[this].mounted = 0;
+
+    /* find the device mount */
+    for (i = 0; i < numFs; i++) {
+	if (fs[i].what == FS && (fs[i].loopDevice == fs[this].loopDevice))
+	    break;
+    }
+
+    if (i < numFs) {
+	/* the device is mounted, unmount it (and recursively, anything
+	 * underneath) */
+	undoMount(fs, numFs, i);
+    }
+
+    unlink("/tmp/loop");
+    mknod("/tmp/loop", 0600 | S_IFBLK, (7 << 8) | fs[this].loopDevice);
+    printf("\tdisabling /dev/loop%d", fs[this].loopDevice);
+    if ((fd = open("/tmp/loop", O_RDONLY, 0)) < 0) {
+	printf(" failed to open device: %d", errno);
+    } else {
+	if (ioctl(fd, LOOP_CLR_FD, 0))
+	    printf(" LOOP_CLR_FD failed: %d", errno);
+	close(fd);
+    }
+
+    printf("\n");
+}
+
+void unmountFilesystems(void) {
+    int fd, size;
+    char buf[65535];			/* this should be big enough */
+    char * chptr, * start;
+    struct unmountInfo filesystems[500];
+    int numFilesystems = 0;
+    int i;
+    struct loop_info li;
+    char * device;
+    struct stat sb;
+
+    fd = open("/proc/mounts", O_RDONLY, 0);
+    if (fd < 1) {
+	/* FIXME: was perror */
+	printstr("failed to open /proc/mounts");
+	sleep(2);
+	return;
+    }
+
+    size = read(fd, buf, sizeof(buf) - 1);
+    buf[size] = '\0';
+
+    close(fd);
+
+    chptr = buf;
+    while (*chptr) {
+	device = chptr;
+	while (*chptr != ' ') chptr++;
+	*chptr++ = '\0';
+	start = chptr;
+	while (*chptr != ' ') chptr++;
+	*chptr++ = '\0';
+
+	if (strcmp(start, "/") && strcmp(start, "/tmp") &&
+            strcmp(start, "/dev")) {
+	    filesystems[numFilesystems].name = strdup(start);
+	    filesystems[numFilesystems].what = FS;
+	    filesystems[numFilesystems].mounted = 1;
+
+	    stat(start, &sb);
+	    if ((sb.st_dev >> 8) == 7) {
+		filesystems[numFilesystems].loopDevice = sb.st_dev & 0xf;
+	    } else {
+		filesystems[numFilesystems].loopDevice = -1;
+	    }
+
+	    numFilesystems++;
+	}
+
+	while (*chptr != '\n') chptr++;
+	chptr++;
+    }
+
+    for (i = 0; i < 7; i++) {
+	unlink("/tmp/loop");
+	mknod("/tmp/loop", 0600 | S_IFBLK, (7 << 8) | i);
+	if ((fd = open("/tmp/loop", O_RDONLY, 0)) >= 0) {
+	    if (!ioctl(fd, LOOP_GET_STATUS, &li) && li.lo_name[0]) {
+		filesystems[numFilesystems].name = strdup(li.lo_name);
+		filesystems[numFilesystems].what = LOOP;
+		filesystems[numFilesystems].mounted = 1;
+		filesystems[numFilesystems].loopDevice = i;
+		numFilesystems++;
+	    }
+
+	    close(fd);
+	}
+    }
+
+    for (i = 0; i < numFilesystems; i++) {
+	if (filesystems[i].what == LOOP) {
+	    undoLoop(filesystems, numFilesystems, i);
+	}
+    }
+
+    for (i = 0; i < numFilesystems; i++) {
+	if ((filesystems[i].mounted) && (filesystems[i].name)) {
+	    undoMount(filesystems, numFilesystems, i);
+	}
+    }
+
+    for (i = 0; i < numFilesystems; i++) 
+        free(filesystems[i].name);
+}
+
+void disableSwap(void) {
+    int fd;
+    char buf[4096];
+    int i;
+    char * start;
+    char * chptr;
+
+    if ((fd = open("/proc/swaps", O_RDONLY, 0)) < 0) return;
+
+    i = read(fd, buf, sizeof(buf) - 1);
+    close(fd);
+    if (i < 0) return;
+    buf[i] = '\0';
+
+    start = buf;
+    while (*start) {
+	while (*start != '\n' && *start) start++;
+	if (!*start) return;
+
+	start++;
+	if (*start != '/') return;
+	chptr = start;
+	while (*chptr && *chptr != ' ') chptr++;
+	if (!(*chptr)) return;
+	*chptr = '\0';
+	printf("\t%s", start);
+	if (swapoff(start)) 
+	    printf(" failed (%d)", errno);
+	printf("\n");
+
+	start = chptr + 1;
+    }
+}
diff --git a/bin/loader/unicode-linedraw-chars.txt b/bin/loader/unicode-linedraw-chars.txt
new file mode 100644
index 0000000..c1a4814
--- /dev/null
+++ b/bin/loader/unicode-linedraw-chars.txt
@@ -0,0 +1,22 @@
+â??
+â??
+â??
+â??
+â??
+â??
+â?¤
+â??
+â?´
+â?¬
+â?¼
+â??
+â??
+°
+±
+·
+â??
+â??
+â??
+â??
+â??
+â?®
diff --git a/bin/loader/urlinstall.c b/bin/loader/urlinstall.c
new file mode 100644
index 0000000..54d1398
--- /dev/null
+++ b/bin/loader/urlinstall.c
@@ -0,0 +1,414 @@
+/*
+ * urlinstall.c - code to set up url (ftp/http) installs
+ *
+ * Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003  Red Hat, Inc.
+ * 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 as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ *
+ * Author(s): Erik Troan <ewt@xxxxxxxxxx>
+ *            Matt Wilson <msw@xxxxxxxxxx>
+ *            Michael Fulbright <msf@xxxxxxxxxx>
+ *            Jeremy Katz <katzj@xxxxxxxxxx>
+ */
+
+#include <newt.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/mount.h>
+#include <unistd.h>
+#include <errno.h>
+#include <glib.h>
+
+#include "../isys/iface.h"
+#include "../isys/log.h"
+
+#include "copy.h"
+#include "kickstart.h"
+#include "loader.h"
+#include "loadermisc.h"
+#include "lang.h"
+#include "method.h"
+#include "net.h"
+#include "method.h"
+#include "urlinstall.h"
+#include "cdinstall.h"
+#include "urls.h"
+#include "windows.h"
+
+/* boot flags */
+extern uint64_t flags;
+
+char **extraHeaders = NULL;
+
+static char **headers() {
+    int len = 2;
+
+    /* The list of HTTP headers is unlikely to change, unless a new ethernet
+     * device suddenly shows up since last time we downloaded a file.  So,
+     * cache the result here to save some time.
+     */
+    if (extraHeaders != NULL)
+        return extraHeaders;
+
+    if ((extraHeaders = realloc(extraHeaders, 2*sizeof(char *))) == NULL) {
+        logMessage(CRITICAL, "%s: %d: %m", __func__, __LINE__);
+        abort();
+    }
+    
+    checked_asprintf(&extraHeaders[0], "X-Anaconda-Architecture: %s", getProductArch());
+    checked_asprintf(&extraHeaders[1], "X-Anaconda-System-Release: %s", getProductName());
+
+    if (FL_KICKSTART_SEND_MAC(flags)) {
+        /* find all ethernet devices and make a header entry for each one */
+        int i;
+        char *dev, *mac;
+        struct device **devices;
+
+        devices = getDevices(DEVICE_NETWORK);
+        for (i = 0; devices && devices[i]; i++) {
+            dev = devices[i]->device;
+            mac = iface_mac2str(dev);
+
+            if (mac) {
+                extraHeaders = realloc(extraHeaders, (len+1)*sizeof(char *));
+                checked_asprintf(&extraHeaders[len], "X-RHN-Provisioning-MAC-%d: %s %s",
+                                 i, dev, mac);
+
+                len++;
+                free(mac);
+            }
+        }
+    }
+
+    if (FL_KICKSTART_SEND_SERIAL(flags) && !access("/sbin/dmidecode", X_OK)) {
+        FILE *f;
+        char sn[1024];
+        size_t sn_len;
+
+        if ((f = popen("/sbin/dmidecode -s system-serial-number", "r")) == NULL) {
+            logMessage(CRITICAL, "%s: %d: %m", __func__, __LINE__);
+            abort();
+        }
+
+        sn_len = fread(sn, sizeof(char), 1023, f);
+        if (ferror(f)) {
+            logMessage(CRITICAL, "%s: %d: %m", __func__, __LINE__);
+            abort();
+        }
+
+        sn[sn_len] = '\0';
+        pclose(f);
+
+        extraHeaders = realloc(extraHeaders, (len+1)*sizeof(char *));
+
+        checked_asprintf(&extraHeaders[len], "X-System-Serial-Number: %s", sn);
+
+        len++;
+    }
+
+    extraHeaders = realloc(extraHeaders, (len+1)*sizeof(char *));
+    extraHeaders[len] = NULL;
+    return extraHeaders;
+}
+
+static int loadSingleUrlImage(struct loaderData_s *loaderData, struct iurlinfo *ui,
+                              char *dest, char *mntpoint, char *device, int silentErrors) {
+    char **ehdrs = NULL;
+    int status;
+
+    if (!strncmp(ui->url, "http", 4))
+        ehdrs = headers();
+
+    status = urlinstTransfer(loaderData, ui, ehdrs, dest);
+    if (status) {
+        if (!silentErrors) {
+            newtWinMessage(_("Error"), _("OK"),
+                           _("Unable to retrieve %s."), ui->url);
+        }
+
+        return 2;
+    }
+
+    if (dest != NULL) {
+        if (mountLoopback(dest, mntpoint, device)) {
+            logMessage(ERROR, "Error mounting %s on %s: %m", device, mntpoint);
+            return 1;
+        }
+    }
+
+    return 0;
+}
+
+static void copyWarnFn (char *msg) {
+   logMessage(WARNING, msg);
+}
+
+static void copyErrorFn (char *msg) {
+   newtWinMessage(_("Error"), _("OK"), _(msg));
+}
+
+static int loadUrlImages(struct loaderData_s *loaderData, struct iurlinfo *ui) {
+    char *oldUrl, *path, *dest, *slash;
+    int rc;
+
+    oldUrl = strdup(ui->url);
+    free(ui->url);
+
+    /* Figure out the path where updates.img and product.img files are
+     * kept.  Since ui->url points to a stage2 image file, we just need
+     * to trim off the file name and look in the same directory.
+     */
+    if ((slash = strrchr(oldUrl, '/')) == NULL)
+        return 0;
+
+    if ((path = strndup(oldUrl, slash-oldUrl)) == NULL)
+        path = oldUrl;
+
+    /* grab the updates.img before install.img so that we minimize our
+     * ramdisk usage */
+    checked_asprintf(&ui->url, "%s/%s", path, "updates.img");
+
+    if (!loadSingleUrlImage(loaderData, ui, "/tmp/updates-disk.img", "/tmp/update-disk",
+                            "/dev/loop7", 1)) {
+        copyDirectory("/tmp/update-disk", "/tmp/updates", copyWarnFn,
+                      copyErrorFn);
+        umountLoopback("/tmp/update-disk", "/dev/loop7");
+        unlink("/tmp/updates-disk.img");
+        unlink("/tmp/update-disk");
+    } else if (!access("/tmp/updates-disk.img", R_OK)) {
+        unpackCpioBall("/tmp/updates-disk.img", "/tmp/updates");
+        unlink("/tmp/updates-disk.img");
+    }
+
+    free(ui->url);
+
+    /* grab the product.img before install.img so that we minimize our
+     * ramdisk usage */
+    checked_asprintf(&ui->url, "%s/%s", path, "product.img");
+
+    if (!loadSingleUrlImage(loaderData, ui, "/tmp/product-disk.img", "/tmp/product-disk",
+                            "/dev/loop7", 1)) {
+        copyDirectory("/tmp/product-disk", "/tmp/product", copyWarnFn,
+                      copyErrorFn);
+        umountLoopback("/tmp/product-disk", "/dev/loop7");
+        unlink("/tmp/product-disk.img");
+        unlink("/tmp/product-disk");
+    }
+
+    free(ui->url);
+    ui->url = strdup(oldUrl);
+
+    checked_asprintf(&dest, "/tmp/install.img");
+
+    rc = loadSingleUrlImage(loaderData, ui, dest, "/mnt/runtime", "/dev/loop0", 0);
+    free(dest);
+    free(oldUrl);
+
+    if (rc) {
+        if (rc != 2) 
+            newtWinMessage(_("Error"), _("OK"),
+                           _("Unable to retrieve the install image."));
+        return 1;
+    }
+
+    return 0;
+}
+
+char *mountUrlImage(struct installMethod *method, char *location,
+                    struct loaderData_s *loaderData) {
+    urlInstallData *stage2Data = (urlInstallData *) loaderData->stage2Data;
+    struct iurlinfo ui;
+
+    enum { URL_STAGE_MAIN, URL_STAGE_FETCH,
+           URL_STAGE_DONE } stage = URL_STAGE_MAIN;
+
+    memset(&ui, 0, sizeof(ui));
+
+    while (stage != URL_STAGE_DONE) {
+        switch(stage) {
+            case URL_STAGE_MAIN: {
+                /* If the stage2= parameter was given (or inferred from repo=)
+                 * then use that configuration info to fetch the image.  This
+                 * could also have come from kickstart.  Else, we need to show
+                 * the UI.
+                 */
+                if (loaderData->method == METHOD_URL && stage2Data) {
+                    ui.url = strdup(stage2Data->url);
+                    logMessage(INFO, "URL_STAGE_MAIN: url is %s", ui.url);
+
+                    if (!ui.url) {
+                        logMessage(ERROR, "missing URL specification");
+                        loaderData->method = -1;
+                        free(loaderData->stage2Data);
+                        loaderData->stage2Data = NULL;
+
+                        if (loaderData->inferredStage2)
+                            loaderData->invalidRepoParam = 1;
+
+                        break;
+                    }
+
+                    /* ks info was adequate, lets skip to fetching image */
+                    stage = URL_STAGE_FETCH;
+                    break;
+                } else {
+                    char *substr;
+
+                    if (urlMainSetupPanel(loaderData, &ui)) {
+                        loaderData->stage2Data = NULL;
+                        return NULL;
+                    }
+
+                    /* If the user-provided URL points at a repo instead of
+                     * a stage2 image, fix it up now.
+                     */
+                    substr = strstr(ui.url, ".img");
+                    if (!substr || (substr && *(substr+4) != '\0')) {
+                        loaderData->instRepo = strdup(ui.url);
+
+                        checked_asprintf(&ui.url, "%s/images/install.img",
+                                         ui.url);
+                    }
+
+                    loaderData->invalidRepoParam = 1;
+                }
+
+                stage = URL_STAGE_FETCH;
+                break;
+            }
+
+            case URL_STAGE_FETCH: {
+                if (loadUrlImages(loaderData, &ui)) {
+                    stage = URL_STAGE_MAIN;
+
+                    if (loaderData->method >= 0)
+                        loaderData->method = -1;
+
+                    if (loaderData->inferredStage2)
+                        loaderData->invalidRepoParam = 1;
+                } else {
+                    stage = URL_STAGE_DONE;
+                }
+
+                break;
+            }
+
+            case URL_STAGE_DONE:
+                break;
+        }
+    }
+
+    return ui.url;
+}
+
+int getFileFromUrl(char * url, char * dest, 
+                   struct loaderData_s * loaderData) {
+    struct iurlinfo ui;
+    char **ehdrs = NULL;
+    int rc;
+    iface_t iface;
+
+    iface_init_iface_t(&iface);
+
+    if (kickstartNetworkUp(loaderData, &iface)) {
+        logMessage(ERROR, "unable to bring up network");
+        return 1;
+    }
+
+    memset(&ui, 0, sizeof(ui));
+    ui.url = url;
+
+    logMessage(INFO, "file location: %s", url);
+
+    if (!strncmp(url, "http", 4)) {
+        ehdrs = headers();
+    }
+
+    rc = urlinstTransfer(loaderData, &ui, ehdrs, dest);
+    if (rc) {
+        logMessage(ERROR, "failed to retrieve %s", ui.url);
+        return 1;
+    }
+
+    return 0;
+}
+
+/* pull kickstart configuration file via http */
+int kickstartFromUrl(char * url, struct loaderData_s * loaderData) {
+    return getFileFromUrl(url, "/tmp/ks.cfg", loaderData);
+}
+
+void setKickstartUrl(struct loaderData_s * loaderData, int argc,
+		    char ** argv) {
+    char *substr = NULL;
+    gchar *url = NULL, *proxy = NULL;
+    GOptionContext *optCon = g_option_context_new(NULL);
+    GError *optErr = NULL;
+    GOptionEntry ksUrlOptions[] = {
+        { "url", 0, 0, G_OPTION_ARG_STRING, &url, NULL, NULL },
+        { "proxy", 0, 0, G_OPTION_ARG_STRING, &proxy, NULL, NULL },
+        { NULL },
+    };
+
+    logMessage(INFO, "kickstartFromUrl");
+
+    g_option_context_set_help_enabled(optCon, FALSE);
+    g_option_context_add_main_entries(optCon, ksUrlOptions, NULL);
+
+    if (!g_option_context_parse(optCon, &argc, &argv, &optErr)) {
+        startNewt();
+        newtWinMessage(_("Kickstart Error"), _("OK"),
+                       _("Bad argument to URL kickstart method "
+                         "command: %s"), optErr->message);
+        g_error_free(optErr);
+        g_option_context_free(optCon);
+        return;
+    }
+
+    g_option_context_free(optCon);
+
+    if (!url) {
+        newtWinMessage(_("Kickstart Error"), _("OK"),
+                       _("Must supply a --url argument to Url kickstart method."));
+        return;
+    }
+
+    /* determine install type */
+    if (strncmp(url, "http", 4) && strncmp(url, "ftp://";, 6)) {
+        newtWinMessage(_("Kickstart Error"), _("OK"),
+                       _("Unknown Url method %s"), url);
+        return;
+    }
+
+    substr = strstr(url, ".img");
+    if (!substr || (substr && *(substr+4) != '\0')) {
+        loaderData->instRepo = strdup(url);
+    } else {
+        if ((loaderData->stage2Data = calloc(sizeof(urlInstallData *), 1)) == NULL)
+            return;
+
+        ((urlInstallData *)loaderData->stage2Data)->url = url;
+        loaderData->method = METHOD_URL;
+    }
+
+    if (proxy) {
+        splitProxyParam(proxy, &loaderData->proxyUser,
+			       &loaderData->proxyPassword,
+			       &loaderData->proxy);
+    }
+    logMessage(INFO, "results of url ks, url %s", url);
+}
+
+/* vim:set shiftwidth=4 softtabstop=4: */
diff --git a/bin/loader/urlinstall.h b/bin/loader/urlinstall.h
new file mode 100644
index 0000000..710b0ae
--- /dev/null
+++ b/bin/loader/urlinstall.h
@@ -0,0 +1,36 @@
+/*
+ * urlinstall.h
+ *
+ * Copyright (C) 2007  Red Hat, Inc.  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 as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef URLINSTALL_H
+#define URLINSTALL_H
+
+#include "method.h"
+#include "urls.h"
+
+typedef struct iurlinfo urlInstallData;
+
+void setKickstartUrl(struct loaderData_s * loaderData, int argc,
+		     char ** argv);
+int kickstartFromUrl(char * url, struct loaderData_s * loaderData);
+char * mountUrlImage(struct installMethod * method,
+                     char * location, struct loaderData_s * loaderData);
+int getFileFromUrl(char * url, char * dest, struct loaderData_s * loaderData);
+
+
+#endif
diff --git a/bin/loader/urls.c b/bin/loader/urls.c
new file mode 100644
index 0000000..c0a9f53
--- /dev/null
+++ b/bin/loader/urls.c
@@ -0,0 +1,371 @@
+/*
+ * urls.c - url handling code
+ *
+ * Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2009  Red Hat, Inc.
+ * 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 as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ *
+ * Author(s): Erik Troan <ewt@xxxxxxxxxx>
+ *            Matt Wilson <msw@xxxxxxxxxx>
+ *            Michael Fulbright <msf@xxxxxxxxxx>
+ *            Jeremy Katz <katzj@xxxxxxxxxx>
+ *            Chris Lumens <clumens@xxxxxxxxxx>
+ */
+
+#include <arpa/inet.h>
+#include <ctype.h>
+#include <fcntl.h>
+#include <netinet/in.h>
+#include <newt.h>
+#include <regex.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+#include <unistd.h>
+#include <netdb.h>
+#include <errno.h>
+#include <curl/curl.h>
+
+#include "../isys/log.h"
+
+#include "lang.h"
+#include "loader.h"
+#include "loadermisc.h"
+#include "urls.h"
+#include "windows.h"
+#include "net.h"
+
+#define NMATCH 10
+
+/* boot flags */
+extern uint64_t flags;
+
+/* This is just a wrapper around the windows.c progress callback that accepts
+ * the arguments libcurl provides.
+ */
+int progress_cb(void *data, double dltotal, double dlnow, double ultotal, double ulnow) {
+    struct progressCBdata *cb_data = (struct progressCBdata *) data;
+
+    progressCallback(cb_data, dlnow, dltotal);
+    return 0;
+}
+
+int splitProxyParam(char *param, char **user, char **password, char **proxy) {
+    /* proxy=[protocol://][username[:password]@]host[:port] */
+    char *pattern = "([[:alpha:]]+://)?(([[:alnum:]]+)(:[^:@]+)?@)?([^:]+)(:[[:digit:]]+)?(/.*)?";
+    regex_t re;
+    regmatch_t pmatch[NMATCH];
+
+    if (regcomp(&re, pattern, REG_EXTENDED)) {
+        return 0;
+    }
+
+    if (regexec(&re, param, NMATCH, pmatch, 0) == REG_NOMATCH) {
+        regfree(&re);
+        return 0;
+    }
+
+    /* Match 0 is always the whole string (assuming regexec matched anything)
+     * so skip it.  Then, these indices are just the number of the starting
+     * paren in pattern above.  Make sure to change these whenever changing
+     * the pattern.
+     */
+    if (pmatch[3].rm_so != -1)
+        *user = strndup(param+pmatch[3].rm_so, pmatch[3].rm_eo-pmatch[3].rm_so);
+
+    /* Skip the leading colon. */
+    if (pmatch[4].rm_so != -1)
+        *password = strndup(param+pmatch[4].rm_so+1, pmatch[4].rm_eo-pmatch[4].rm_so-1);
+
+    if (pmatch[5].rm_so != -1) {
+        char *portStr = "";
+
+        if (pmatch[6].rm_so != -1)
+            portStr = strndup(param+pmatch[6].rm_so, pmatch[6].rm_eo-pmatch[6].rm_so);
+
+        /* If no parameter was given, default to HTTP.  yum will want to know
+         * the protocol, and curl will just ignore it if given.
+         */
+        if (pmatch[1].rm_so != -1) {
+            checked_asprintf(proxy, "%.*s%.*s%s", pmatch[1].rm_eo-pmatch[1].rm_so,
+                                                  param+pmatch[1].rm_so,
+                                                  pmatch[5].rm_eo-pmatch[5].rm_so,
+                                                  param+pmatch[5].rm_so,
+                                                  portStr);
+        } else {
+            checked_asprintf(proxy, "http://%.*s%s";, pmatch[5].rm_eo-pmatch[5].rm_so,
+                                                     param+pmatch[5].rm_so,
+                                                     portStr);
+        }
+    }
+
+    regfree(&re);
+    return 1;
+}
+
+int urlinstTransfer(struct loaderData_s *loaderData, struct iurlinfo *ui,
+                    char **extraHeaders, char *dest) {
+    struct progressCBdata *cb_data;
+    CURL *curl = NULL;
+    CURLcode status;
+    struct curl_slist *headers = NULL;
+    char *version;
+    FILE *f = NULL;
+
+    logMessage(INFO, "transferring %s", ui->url);
+
+    f = fopen(dest, "w");
+
+    /* Initialize libcurl */
+    curl_global_init(CURL_GLOBAL_SSL);
+    curl = curl_easy_init();
+
+    checked_asprintf(&version, "anaconda/%s", VERSION);
+
+    curl_easy_setopt(curl, CURLOPT_USERAGENT, version);
+    curl_easy_setopt(curl, CURLOPT_URL, ui->url);
+    curl_easy_setopt(curl, CURLOPT_WRITEDATA, f);
+    curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1);
+    curl_easy_setopt(curl, CURLOPT_MAXREDIRS, 10);
+    curl_easy_setopt(curl, CURLOPT_FAILONERROR, 1);
+
+    /* If a proxy was provided, add the options for that now. */
+    if (loaderData->proxy && strcmp(loaderData->proxy, "")) {
+        curl_easy_setopt(curl, CURLOPT_PROXY, loaderData->proxy);
+
+        if (loaderData->proxyUser && strcmp(loaderData->proxyUser, ""))
+            curl_easy_setopt(curl, CURLOPT_PROXYUSERNAME,
+                             loaderData->proxyUser);
+
+        if (loaderData->proxyPassword && strcmp(loaderData->proxyPassword, ""))
+            curl_easy_setopt(curl, CURLOPT_PROXYPASSWORD,
+                             loaderData->proxyPassword);
+    }
+
+    if (extraHeaders) {
+        int i;
+        for (i = 0; extraHeaders[i] != NULL; i++) {
+            headers = curl_slist_append(headers, extraHeaders[i]);
+        }
+
+        curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
+    }
+
+    /* Only set up the progress bar if we've got a UI to display it. */
+    if (FL_CMDLINE(flags)) {
+        printf("%s %s...\n", _("Retrieving"), ui->url);
+    } else {
+        char *filename;
+
+        filename = strrchr(ui->url, '/');
+        if (!filename)
+           filename = ui->url;
+
+        cb_data = winProgressBar(70, 5, _("Retrieving"), "%s %s...", _("Retrieving"), filename);
+
+        curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 0);
+        curl_easy_setopt(curl, CURLOPT_PROGRESSFUNCTION, progress_cb);
+        curl_easy_setopt(curl, CURLOPT_PROGRESSDATA, cb_data);
+    }
+
+    /* Finally, do the transfer. */
+    status = curl_easy_perform(curl);
+    if (status)
+        logMessage(ERROR, "Error downloading %s: %s", ui->url, curl_easy_strerror(status));
+
+    if (!FL_CMDLINE(flags))
+       newtPopWindow();
+
+    if (headers)
+        curl_slist_free_all(headers);
+
+    fclose(f);
+    free(version);
+
+    curl_easy_cleanup(curl);
+    curl_global_cleanup();
+
+    return status;
+}
+
+char * addrToIp(char * hostname) {
+    struct in_addr ad;
+    struct in6_addr ad6;
+    char *ret;
+    struct hostent *host;
+
+    if ((ret = malloc(INET6_ADDRSTRLEN+1)) == NULL)
+        return hostname;
+
+    if (inet_ntop(AF_INET, &ad, ret, INET_ADDRSTRLEN) != NULL)
+        return ret;
+    else if (inet_ntop(AF_INET6, &ad6, ret, INET6_ADDRSTRLEN) != NULL)
+        return ret;
+    else if ((host = gethostbyname(hostname)) != NULL)
+        return host->h_name;
+    else
+        return NULL;
+}
+
+static void setProxySensitivity(newtComponent co, void *dptr) {
+    int i;
+
+    /* It's 3 because there are three entry boxes in the proxy grid.  Lame. */
+    for (i = 0; i < 3; i++) {
+        newtEntrySetFlags(*((newtComponent *) dptr), NEWT_FLAG_DISABLED,
+                          NEWT_FLAGS_TOGGLE);
+        dptr += sizeof(newtComponent);
+    }
+
+    return;
+}
+
+int urlMainSetupPanel(struct loaderData_s *loaderData, struct iurlinfo * ui) {
+    newtComponent form, okay, cancel, urlEntry, proxyCheckbox;
+    newtComponent proxyEntries[3];
+    newtComponent answer, text;
+    char enableProxy;
+    char *url = "", *proxy = "", *proxyUser = "", *proxyPassword = "";
+    char * reflowedText = NULL;
+    int width, height;
+    newtGrid buttons, grid, proxyGrid;
+    char * buf = NULL;
+
+    /* Populate the UI with whatever initial value we've got. */
+    if (ui && ui->url)
+        url = ui->url;
+
+    if (loaderData->proxy)
+        proxy = loaderData->proxy;
+
+    if (loaderData->proxyUser)
+        proxyUser = loaderData->proxyUser;
+
+    if (loaderData->proxyPassword)
+        proxyPassword = loaderData->proxyPassword;
+
+    buttons = newtButtonBar(_("OK"), &okay, _("Back"), &cancel, NULL);
+
+    checked_asprintf(&buf,
+                     _("Please enter the URL containing the %s installation image on your server."),
+                     getProductName());
+
+    reflowedText = newtReflowText(buf, 47, 5, 5, &width, &height);
+    free(buf);
+
+    text = newtTextbox(-1, -1, width, height, NEWT_TEXTBOX_WRAP);
+    newtTextboxSetText(text, reflowedText);
+    free(reflowedText);
+
+    urlEntry = newtEntry(22, 8, url, 60, (const char **) &url,
+                         NEWT_ENTRY_SCROLL);
+
+    /* If we've been provided with proxy settings already, enable the proxy
+     * grid.  This will make sure all the fields get filled in, too.
+     */
+    enableProxy = loaderData->proxy != NULL && strcmp("", loaderData->proxy) ? '*' : ' ';
+
+    proxyCheckbox = newtCheckbox(-1, -1, _("Enable HTTP proxy"), enableProxy,
+                                 NULL, &enableProxy);
+    newtComponentAddCallback(proxyCheckbox, setProxySensitivity, &proxyEntries);
+
+    proxyEntries[0] = newtEntry(-1, -1, proxy, 35, (const char **) &proxy, NEWT_FLAG_SCROLL);
+    proxyEntries[1] = newtEntry(-1, -1, proxyUser, 15, (const char **) &proxyUser, NEWT_FLAG_SCROLL);
+    proxyEntries[2] = newtEntry(-1, -1, proxyPassword, 15, (const char **) &proxyPassword, NEWT_FLAG_SCROLL|NEWT_FLAG_PASSWORD);
+
+    /* Set the initial proxy grid sensitivity to match. */
+    if (enableProxy == ' ')
+        setProxySensitivity(proxyCheckbox, proxyEntries);
+
+    proxyGrid = newtCreateGrid(2, 3);
+    newtGridSetField(proxyGrid, 0, 0, NEWT_GRID_COMPONENT,
+                     newtLabel(-1, -1, _("Proxy URL")),
+                     0, 0, 0, 0, 0, NEWT_ANCHOR_LEFT);
+    newtGridSetField(proxyGrid, 1, 0, NEWT_GRID_COMPONENT, proxyEntries[0],
+                     0, 0, 0, 0, 0, NEWT_ANCHOR_LEFT);
+    newtGridSetField(proxyGrid, 0, 1, NEWT_GRID_COMPONENT,
+                     newtLabel(-1, -1, _("Username")),
+                     0, 0, 0, 1, 0, NEWT_ANCHOR_LEFT);
+    newtGridSetField(proxyGrid, 1, 1, NEWT_GRID_COMPONENT, proxyEntries[1],
+                     0, 0, 0, 1, 0, NEWT_ANCHOR_LEFT);
+    newtGridSetField(proxyGrid, 0, 2, NEWT_GRID_COMPONENT,
+                     newtLabel(-1, -1, _("Password")),
+                     0, 0, 0, 1, 0, NEWT_ANCHOR_LEFT);
+    newtGridSetField(proxyGrid, 1, 2, NEWT_GRID_COMPONENT, proxyEntries[2],
+                     0, 0, 0, 1, 0, NEWT_ANCHOR_LEFT);
+
+    grid = newtCreateGrid(1, 5);
+    newtGridSetField(grid, 0, 0, NEWT_GRID_COMPONENT, text,
+                     0, 0, 0, 1, 0, 0);
+    newtGridSetField(grid, 0, 1, NEWT_GRID_COMPONENT, urlEntry,
+                     0, 0, 0, 1, 0, 0);
+    newtGridSetField(grid, 0, 2, NEWT_GRID_COMPONENT, proxyCheckbox,
+                     0, 0, 0, 1, 0, NEWT_ANCHOR_LEFT);
+    newtGridSetField(grid, 0, 3, NEWT_GRID_SUBGRID, proxyGrid,
+                     0, 0, 0, 0, 0, NEWT_GRID_FLAG_GROWX);
+    newtGridSetField(grid, 0, 4, NEWT_GRID_SUBGRID, buttons,
+                     0, 0, 0, 0, 0, NEWT_GRID_FLAG_GROWX);
+
+    form = newtForm(NULL, NULL, 0);
+    newtGridAddComponentsToForm(grid, form, 1); 
+    newtGridWrappedWindow(grid, _("URL Setup"));
+    newtGridFree(grid, 1);
+
+    do {
+        answer = newtRunForm(form);
+        if (answer != cancel) {
+            if (!strlen(url)) {
+                newtWinMessage(_("Error"), _("OK"),
+                               _("You must enter a URL."));
+                continue;
+            }
+
+            if (strncmp(url, "http", 4) && strncmp(url, "ftp://";, 6)) {
+                newtWinMessage(_("Error"), _("OK"),
+                               _("URL must be either an ftp or http URL"));
+                continue;
+            }
+
+            ui->url = strdup(url);
+
+            if (enableProxy == '*') {
+               loaderData->proxy = strdup(proxy);
+               loaderData->proxyUser = strdup(proxyUser);
+               loaderData->proxyPassword = strdup(proxyPassword);
+            } else {
+               loaderData->proxy = "";
+               loaderData->proxyUser = "";
+               loaderData->proxyPassword = "";
+            }
+
+            /* FIXME:  add back in hostname checking */
+        }
+
+        break;
+    } while (1);
+
+    if (answer == cancel) {
+        newtFormDestroy(form);
+        newtPopWindow();
+
+        return LOADER_BACK;
+    }
+
+    newtFormDestroy(form);
+    newtPopWindow();
+
+    return 0;
+}
diff --git a/bin/loader/urls.h b/bin/loader/urls.h
new file mode 100644
index 0000000..4ca538f
--- /dev/null
+++ b/bin/loader/urls.h
@@ -0,0 +1,35 @@
+/*
+ * urls.h
+ *
+ * Copyright (C) 2007  Red Hat, Inc.  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 as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef H_LOADER_URLS
+#define H_LOADER_URLS
+
+#include "loader.h"
+#include "windows.h"
+
+struct iurlinfo {
+    char * url;
+};
+
+int splitProxyParam(char *param, char **user, char **password, char **proxy);
+int urlMainSetupPanel(struct loaderData_s *loaderData, struct iurlinfo * ui);
+int urlinstTransfer(struct loaderData_s *loaderData, struct iurlinfo *ui,
+                    char **extraHeaders, char *dest);
+
+#endif
diff --git a/bin/loader/windows.c b/bin/loader/windows.c
new file mode 100644
index 0000000..51b00db
--- /dev/null
+++ b/bin/loader/windows.c
@@ -0,0 +1,121 @@
+/*
+ * windows.c - simple popup windows used by the loader
+ *
+ * Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002  Red Hat, Inc.
+ * 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 as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ *
+ * Author(s): Erik Troan <ewt@xxxxxxxxxx>
+ *            Matt Wilson <msw@xxxxxxxxxx>
+ *            Michael Fulbright <msf@xxxxxxxxxx>
+ *            Jeremy Katz <katzj@xxxxxxxxxx>
+ */
+
+#include <errno.h>
+#include <newt.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+#include <stdarg.h>
+#include <math.h>
+
+#include "../isys/log.h"
+
+#include "windows.h"
+
+void winStatus(int width, int height, char * title, char * text, ...) {
+    newtComponent t, f;
+    char * buf = NULL;
+    va_list args;
+
+    va_start(args, text);
+
+    if (vasprintf(&buf, text, args) != -1) {
+        newtCenteredWindow(width, height, title);
+
+        t = newtTextbox(1, 1, width - 2, height - 2, NEWT_TEXTBOX_WRAP);
+        newtTextboxSetText(t, buf);
+        f = newtForm(NULL, NULL, 0);
+
+        free(buf);
+
+        newtFormAddComponent(f, t);
+
+        newtDrawForm(f);
+        newtRefresh();
+        newtFormDestroy(f);
+    }
+
+    va_end(args);
+}
+
+
+void scsiWindow(const char * driver) {
+    winStatus(40, 3, _("Loading SCSI driver"),
+        _("Loading %s driver"), driver);
+}
+
+int progressCallback(void *pbdata, long long pos, long long total) {
+    struct progressCBdata *data = pbdata;
+    char tickmark[2] = "-";
+    char *ticks = "-\\|/";
+    int x = ceil(pos * 100.0 / total);
+
+    newtScaleSet(data->scale, x);
+    *tickmark = ticks[x % 4];
+
+    newtLabelSetText(data->label, tickmark);
+    newtRefresh();
+    return 0;
+}
+
+struct progressCBdata *winProgressBar(int width, int height, char *title, char *text, ...) {
+    struct progressCBdata *data;
+    char *buf = NULL;
+    va_list args;
+    int llen;
+    newtComponent t, f, scale, label;
+
+    va_start(args, text);
+
+    if (vasprintf(&buf, text, args) != -1) {
+        va_end(args);
+        newtCenteredWindow(width, height, title);
+        t = newtTextbox(1, 1, width - 2, height - 2, NEWT_TEXTBOX_WRAP);
+        newtTextboxSetText(t, buf);
+        llen = strlen(buf);
+        free(buf);
+        label = newtLabel(llen + 1, 1, "-");
+        f = newtForm(NULL, NULL, 0);
+        newtFormAddComponent(f, t);
+        scale = newtScale(3, 3, width - 6, 100);
+        newtFormAddComponent(f, scale);
+        newtDrawForm(f);
+        newtRefresh();
+
+        if ((data = malloc(sizeof(struct progressCBdata))) == NULL) {
+            logMessage(ERROR, "%s: %d: %m", __func__, __LINE__);
+            abort();
+        }
+
+        data->scale = scale;
+        data->label = label;
+        return data;
+    }
+
+    return NULL;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4: */
diff --git a/bin/loader/windows.h b/bin/loader/windows.h
new file mode 100644
index 0000000..a1646d4
--- /dev/null
+++ b/bin/loader/windows.h
@@ -0,0 +1,43 @@
+/*
+ * windows.h
+ *
+ * Copyright (C) 2007  Red Hat, Inc.  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 as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _WINDOWS_H_
+#define _WINDOWS_H_
+
+#include <newt.h>
+
+#include "lang.h"
+
+void winStatus(int width, int height, char * title, char * text, ...);
+void scsiWindow(const char * driver);
+
+#define errorWindow(String) \
+	newtWinMessage(_("Error"), _("OK"), String, strerror (errno));
+
+typedef void (*progressCB) (void *pbdata, long long offset, long long total);
+
+struct progressCBdata {
+    newtComponent scale;
+    newtComponent label;
+};
+
+int progressCallback(void *pbdata, long long pos, long long total);
+struct progressCBdata *winProgressBar(int width, int height, char *title, char *text, ...);
+
+#endif /* _WINDOWS_H_ */
diff --git a/bootdisk/Makefile.am b/bootdisk/Makefile.am
deleted file mode 100644
index e6ba4bd..0000000
--- a/bootdisk/Makefile.am
+++ /dev/null
@@ -1,22 +0,0 @@
-# bootdisk/Makefile.am for anaconda
-#
-# Copyright (C) 2009  Red Hat, Inc.
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU Lesser General Public License as published
-# by the Free Software Foundation; either version 2.1 of the License, or
-# (at your option) any later version.
-#
-# 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 Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public License
-# along with this program.  If not, see <http://www.gnu.org/licenses/>.
-#
-# Author: David Cantrell <dcantrell@xxxxxxxxxx>
-
-SUBDIRS = i386 ppc sparc s390x x86_64
-
-MAINTAINERCLEANFILES = Makefile.in
diff --git a/bootdisk/i386/Makefile.am b/bootdisk/i386/Makefile.am
deleted file mode 100644
index 030b8d5..0000000
--- a/bootdisk/i386/Makefile.am
+++ /dev/null
@@ -1,25 +0,0 @@
-# bootdisk/i386/Makefile.am for anaconda
-#
-# Copyright (C) 2009  Red Hat, Inc.
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU Lesser General Public License as published
-# by the Free Software Foundation; either version 2.1 of the License, or
-# (at your option) any later version.
-#
-# 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 Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public License
-# along with this program.  If not, see <http://www.gnu.org/licenses/>.
-#
-# Author: David Cantrell <dcantrell@xxxxxxxxxx>
-
-if IS_I386
-bootdir        = $(datadir)/$(PACKAGE_NAME)/boot
-dist_boot_DATA = boot.msg grub.conf syslinux.cfg
-endif
-
-MAINTAINERCLEANFILES = Makefile.in
diff --git a/bootdisk/i386/boot.msg b/bootdisk/i386/boot.msg
deleted file mode 100644
index ff54899..0000000
--- a/bootdisk/i386/boot.msg
+++ /dev/null
@@ -1,5 +0,0 @@
- 
-splash.lss
-
- -  Press the 01<ENTER>07 key to begin the installation process.
-
diff --git a/bootdisk/i386/grub.conf b/bootdisk/i386/grub.conf
deleted file mode 100644
index 6e94d05..0000000
--- a/bootdisk/i386/grub.conf
+++ /dev/null
@@ -1,8 +0,0 @@
-#debug --graphics
-default=0
-splashimage=@SPLASHPATH@
-timeout 5
-hiddenmenu
-title @PRODUCT@ @VERSION@
-	kernel @KERNELPATH@
-	initrd @INITRDPATH@
diff --git a/bootdisk/i386/syslinux.cfg b/bootdisk/i386/syslinux.cfg
deleted file mode 100644
index 06a0842..0000000
--- a/bootdisk/i386/syslinux.cfg
+++ /dev/null
@@ -1,33 +0,0 @@
-default linux
-prompt 1
-timeout 600
-
-display boot.msg
-
-menu background splash.jpg
-menu title Welcome to @PRODUCT@ @VERSION@!
-menu color border 0 #ffffffff #00000000
-menu color sel 7 #ffffffff #ff000000
-menu color title 0 #ffffffff #00000000
-menu color tabmsg 0 #ffffffff #00000000
-menu color unsel 0 #ffffffff #00000000
-menu color hotsel 0 #ff000000 #ffffffff
-menu color hotkey 7 #ffffffff #ff000000
-menu color scrollbar 0 #ffffffff #00000000
-
-label linux
-  menu label ^Install a new system or upgrade an existing system
-  menu default
-  kernel vmlinuz
-  append initrd=initrd.img
-label vesa
-  menu label Install system with ^basic video driver
-  kernel vmlinuz
-  append initrd=initrd.img xdriver=vesa nomodeset
-label rescue
-  menu label ^Rescue installed system
-  kernel vmlinuz
-  append initrd=initrd.img rescue
-label local
-  menu label Boot from ^local drive
-  localboot 0xffff
diff --git a/bootdisk/ppc/Makefile.am b/bootdisk/ppc/Makefile.am
deleted file mode 100644
index 4f6e298..0000000
--- a/bootdisk/ppc/Makefile.am
+++ /dev/null
@@ -1,26 +0,0 @@
-# bootdisk/ppc/Makefile.am for anaconda
-#
-# Copyright (C) 2009  Red Hat, Inc.
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU Lesser General Public License as published
-# by the Free Software Foundation; either version 2.1 of the License, or
-# (at your option) any later version.
-#
-# 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 Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public License
-# along with this program.  If not, see <http://www.gnu.org/licenses/>.
-#
-# Author: David Cantrell <dcantrell@xxxxxxxxxx>
-
-if IS_PPC
-bootdir        = $(datadir)/$(PACKAGE_NAME)/boot
-dist_boot_DATA = magic ofboot.b yaboot.conf.in bootinfo.txt mapping \
-                 yaboot.conf.3264
-endif
-
-MAINTAINERCLEANFILES = Makefile.in
diff --git a/bootdisk/ppc/bootinfo.txt b/bootdisk/ppc/bootinfo.txt
deleted file mode 100644
index ac766d4..0000000
--- a/bootdisk/ppc/bootinfo.txt
+++ /dev/null
@@ -1,169 +0,0 @@
-<chrp-boot> <description>Linux</description> 
-<os-name>Linux</os-name> 
-<boot-script>boot &device;:\ppc\chrp\yaboot</boot-script> 
-<icon size=64,64 color-space=3,3,2> 
-<bitmap> FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
-FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
-FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
-FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
-FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
-FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
-FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
-FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
-FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
-FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
-FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
-FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
-FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
-FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
-FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
-FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
-FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
-FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
-FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
-FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
-FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
-FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
-FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
-FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
-FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
-FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
-FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
-FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
-FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
-FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
-FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
-FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
-FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
-FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
-FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
-FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
-FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
-FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
-FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
-FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
-FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
-FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
-FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
-FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
-FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
-FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
-FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
-FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
-FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
-FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
-FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
-FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
-FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
-FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
-FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
-FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
-FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
-FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
-FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
-FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
-FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
-FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
-FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
-FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
-FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
-FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
-FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
-FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
-FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
-FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
-FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
-FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
-FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
-FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
-FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
-FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
-FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
-FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
-FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
-FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
-FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
-FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
-FF FF FF FF FF FF FF FF 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
-00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
-00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
-00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
-00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
-00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
-00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
-00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
-00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
-00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
-00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
-00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
-00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
-00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
-00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
-00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
-00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
-00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
-00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
-00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
-00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
-00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
-00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
-00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
-00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
-00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
-00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
-00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
-00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
-00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
-00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
-00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
-00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
-00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
-00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
-00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
-00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
-00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
-00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
-00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
-00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
-00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
-00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
-00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
-00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
-00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
-00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
-00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
-00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
-00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
-00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
-00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
-00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
-00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
-00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
-00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
-00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
-00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
-00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
-00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
-00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
-00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
-00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
-00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
-00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
-00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
-00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
-00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
-00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
-00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
-00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
-00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
-00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
-00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
-00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
-00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
-00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
-00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
-00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
-00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
-00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
-00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
-00 00 00 00 00 00 </bitmap> </icon> </chrp-boot>
diff --git a/bootdisk/ppc/magic b/bootdisk/ppc/magic
deleted file mode 100644
index 387727c..0000000
--- a/bootdisk/ppc/magic
+++ /dev/null
@@ -1,81 +0,0 @@
-#
-# Example magic file for mkhybrid
-#
-# The "message" for the offset MUST be 4 characters for the CREATOR
-# and 4 characters for the TYPE - white space is optional between them.
-# Any other characters on this line are ignored. Continuation lines (starting
-# with '>') are also ignored i.e. only the initial offset lines are used.
-#
-# The continuation lines are given here, but they do not need to exist.
-
-#
-# James Pearson 20/5/98
-
-# off	type		test		message
-
-# GIF
-0	string		GIF8		8BIM GIFf
->4	string		7a		\b, version 8%s,
->4	string		9a		\b, version 8%s,
->6	leshort		>0		%hd x
->8	leshort		>0		%hd,
-#>10	byte		&0x80		color mapped,
-#>10	byte&0x07	=0x00		2 colors
-#>10	byte&0x07	=0x01		4 colors
-#>10	byte&0x07	=0x02		8 colors
-#>10	byte&0x07	=0x03		16 colors
-#>10	byte&0x07	=0x04		32 colors
-#>10	byte&0x07	=0x05		64 colors
-#>10	byte&0x07	=0x06		128 colors
-#>10	byte&0x07	=0x07		256 colors
-
-# JPEG images
-#
-0	ubeshort		0xffd8		8BIM JPEG  image data
-
-# StuffIt
-#
-0	string		SIT!		SIT!SIT!
-
-# standard unix compress
-0	string		\037\235	LZIV ZIVU
->2	byte&0x80	>0		block compressed
->2	byte&0x1f	x		%d bits
-
-# gzip (GNU zip, not to be confused with Info-ZIP or PKWARE zip archiver)
-0       string          \037\213        GNUz ZIVU gzip compressed data
->2      byte            <8              \b, reserved method,
->2      byte            8               \b, deflated,
->3	byte		&0x01		ASCII,
->3	byte		&0x02		continuation,
->3	byte		&0x04		extra field,
->3	byte		&0x08		original filename,
->3	byte		&0x10		comment,
->3	byte		&0x20		encrypted,
->4	ledate		x		last modified: %s,
->8	byte		2		max compression,
->8	byte		4		max speed,
->9	byte		=0x00		os: MS-DOS
->9	byte		=0x01		os: Amiga
->9	byte		=0x02		os: VMS
->9	byte		=0x03		os: Unix
->9	byte		=0x05		os: Atari
->9	byte		=0x06		os: OS/2
->9	byte		=0x07		os: MacOS
->9	byte		=0x0A		os: Tops/20
->9	byte		=0x0B		os: Win/32
-
-# Postscript
-0	string		%!		ASPSTEXT
->2	string		PS-Adobe-	conforming
->>11	string		>\0		at level %.3s
->>>15	string		EPS		- type %s
->>>15	string		Query		- type %s
->>>15	string		ExitServer	- type %s
-# Some PCs have the annoying habit of adding a ^D as a document separator
-0	string		\004%!		ASPS TEXT PostScript document text
->3	string		PS-Adobe-	conforming
->>12	string		>\0		at level %.3s
->>>16	string		EPS		- type %s
->>>16	string		Query		- type %s
->>>16	string		ExitServer	- type %s
diff --git a/bootdisk/ppc/mapping b/bootdisk/ppc/mapping
deleted file mode 100644
index cf83076..0000000
--- a/bootdisk/ppc/mapping
+++ /dev/null
@@ -1,27 +0,0 @@
-# Example filename mapping file
-#
-# yaboot		Raw	'UNIX'	'boot'	"Bootstrap"
-# vmlinux		Raw	'UNIX'	'boot'	"Bootstrap"
-#
-# EXTN          XLate   CREATOR   TYPE     Comment
-COPYING         Ascii   'ttxt'  'ttro'  "Text File"
-CREDITS         Ascii   'ttxt'  'ttro'  "Text File"
-README          Ascii   'ttxt'  'ttro'  "Text File"
-RPM-GPG-KEY     Ascii   'ttxt'  'ttro'  "Text File"
-RELEASE_NOTES   Ascii   'ttxt'  'ttro'  "Text File"
-.b              Raw     'chrp'  'tbxi'  "Macintosh Toolbox ROM file"
-.gif            Raw     '8BIM'  'GIFf'  "Gif File"
-.jpg            Raw     '8BIM'  'JPEG'  "Jpeg File"
-.tif            Raw     '8BIM'  'TIFF'  "Photoshop TIFF image"
-.hqx            Ascii   'BnHq'  'TEXT'  "BinHex file"
-.doc            Raw     'MSWD'  'WDBN'  "Word file"
-.mov            Raw     'TVOD'  'MooV'  "QuickTime Movie"
-.html           Ascii   'MOSS'  'TEXT'  "HTML File"
-.htm            Ascii   'MOSS'  'TEXT'  "HTML File"
-.conf           Ascii   'ttxt'  'TEXT'  "config file"
-.txt            Ascii   'ttxt'  'TEXT'  "Text File"
-.tbxi           Raw     'chrp'  'tbxi'  "Macintosh Toolbox ROM file"
-.sea            Raw     'aust'  'APPL'  "Self Expanding Archive"
-.sit            Raw     'SIT!'  'SITD'  "Stuffit Expander file"
-*               Raw     '????'  '????'  "Unknown"
-
diff --git a/bootdisk/ppc/ofboot.b b/bootdisk/ppc/ofboot.b
deleted file mode 100644
index c811894..0000000
--- a/bootdisk/ppc/ofboot.b
+++ /dev/null
@@ -1,74 +0,0 @@
-<CHRP-BOOT>
-<COMPATIBLE>
-MacRISC MacRISC3 MacRISC4
-</COMPATIBLE>
-
-<DESCRIPTION>
-Boot Chooser
-</DESCRIPTION>
-
-<BOOT-SCRIPT>
-" screen" output
-load-base release-load-area
-" /cpus/@0" find-package if
- " 64-bit" rot get-package-property 0= if
-  2drop
-  " boot cd:,\ppc\mac\yaboot conf=cd:,\ppc\ppc64\yaboot.conf" eval
- else
-  " boot cd:,\ppc\mac\yaboot conf=cd:,\ppc\ppc32\yaboot.conf" eval
- then
-then
-</BOOT-SCRIPT>
-
-<OS-BADGE-ICONS>
-1010
-000000000000F8FEACF6000000000000
-0000000000F5FFFFFEFEF50000000000
-00000000002BFAFEFAFCF70000000000
-0000000000F65D5857812B0000000000
-0000000000F5350B2F88560000000000
-0000000000F6335708F8FE0000000000
-00000000005600F600F5FD8100000000
-00000000F9F8000000F5FAFFF8000000
-000000008100F5F50000F6FEFE000000
-000000F8F700F500F50000FCFFF70000
-00000088F70000F50000F5FCFF2B0000
-0000002F582A00F5000008ADE02C0000
-00090B0A35A62B0000002D3B350A0000
-000A0A0B0B3BF60000505E0B0A0B0A00
-002E350B0B2F87FAFCF45F0B2E090000
-00000007335FF82BF72B575907000000
-000000000000ACFFFF81000000000000
-000000000081FFFFFFFF810000000000
-0000000000FBFFFFFFFFAC0000000000
-000000000081DFDFDFFFFB0000000000
-000000000081DD5F83FFFD0000000000
-000000000081DDDF5EACFF0000000000
-0000000000FDF981F981FFFF00000000
-00000000FFACF9F9F981FFFFAC000000
-00000000FFF98181F9F981FFFF000000
-000000ACACF981F981F9F9FFFFAC0000
-000000FFACF9F981F9F981FFFFFB0000
-00000083DFFBF981F9F95EFFFFFC0000
-005F5F5FDDFFFBF9F9F983DDDD5F0000
-005F5F5F5FDD81F9F9E7DF5F5F5F5F00
-0083DD5F5F83FFFFFFFFDF5F835F0000
-000000FBDDDFACFBACFBDFDFFB000000
-000000000000FFFFFFFF000000000000
-0000000000FFFFFFFFFFFF0000000000
-0000000000FFFFFFFFFFFF0000000000
-0000000000FFFFFFFFFFFF0000000000
-0000000000FFFFFFFFFFFF0000000000
-0000000000FFFFFFFFFFFF0000000000
-0000000000FFFFFFFFFFFFFF00000000
-00000000FFFFFFFFFFFFFFFFFF000000
-00000000FFFFFFFFFFFFFFFFFF000000
-000000FFFFFFFFFFFFFFFFFFFFFF0000
-000000FFFFFFFFFFFFFFFFFFFFFF0000
-000000FFFFFFFFFFFFFFFFFFFFFF0000
-00FFFFFFFFFFFFFFFFFFFFFFFFFF0000
-00FFFFFFFFFFFFFFFFFFFFFFFFFFFF00
-00FFFFFFFFFFFFFFFFFFFFFFFFFF0000
-000000FFFFFFFFFFFFFFFFFFFF000000
-</OS-BADGE-ICONS>
-</CHRP-BOOT>
diff --git a/bootdisk/ppc/yaboot.conf.3264 b/bootdisk/ppc/yaboot.conf.3264
deleted file mode 100644
index 8b5af08..0000000
--- a/bootdisk/ppc/yaboot.conf.3264
+++ /dev/null
@@ -1,14 +0,0 @@
-init-message = "\nWelcome to the %PRODUCT% %VERSION% installer!\nUse 'linux32' for 32-bit kernel.\n\n"
-timeout=6000
-default=linux
-
-image=/ppc/ppc64/vmlinuz
-	label=linux64
-	alias=linux
-	initrd=/ppc/ppc64/ramdisk.image.gz
-	read-only
-
-image=/ppc/ppc32/vmlinuz
-	label=linux32
-	initrd=/ppc/ppc32/ramdisk.image.gz
-	read-only
diff --git a/bootdisk/ppc/yaboot.conf.in b/bootdisk/ppc/yaboot.conf.in
deleted file mode 100644
index d06768a..0000000
--- a/bootdisk/ppc/yaboot.conf.in
+++ /dev/null
@@ -1,8 +0,0 @@
-init-message = "\nWelcome to the %BITS%-bit %PRODUCT% %VERSION% installer!\nHit <TAB> for boot options.\n\n"
-timeout=6000
-default=linux
-
-image=/ppc/ppc%BITS%/vmlinuz
-	label=linux
-	initrd=/ppc/ppc%BITS%/ramdisk.image.gz
-	read-only
diff --git a/bootdisk/s390x/Makefile.am b/bootdisk/s390x/Makefile.am
deleted file mode 100644
index c75ccbe..0000000
--- a/bootdisk/s390x/Makefile.am
+++ /dev/null
@@ -1,25 +0,0 @@
-# bootdisk/s390x/Makefile.am for anaconda
-#
-# Copyright (C) 2009  Red Hat, Inc.
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU Lesser General Public License as published
-# by the Free Software Foundation; either version 2.1 of the License, or
-# (at your option) any later version.
-#
-# 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 Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public License
-# along with this program.  If not, see <http://www.gnu.org/licenses/>.
-#
-# Author: David Cantrell <dcantrell@xxxxxxxxxx>
-
-if IS_S390
-bootdir        = $(datadir)/$(PACKAGE_NAME)/boot
-dist_boot_DATA = generic.ins generic.prm redhat.exec
-endif
-
-MAINTAINERCLEANFILES = Makefile.in
diff --git a/bootdisk/s390x/generic.ins b/bootdisk/s390x/generic.ins
deleted file mode 100644
index a690f2e..0000000
--- a/bootdisk/s390x/generic.ins
+++ /dev/null
@@ -1,5 +0,0 @@
-* minimal lpar ins file
-images/kernel.img 0x00000000
-images/initrd.img @INITRD_LOAD_ADDRESS@
-images/generic.prm 0x00010480
-images/initrd.addrsize 0x00010408
diff --git a/bootdisk/s390x/generic.prm b/bootdisk/s390x/generic.prm
deleted file mode 100644
index e953ce2..0000000
--- a/bootdisk/s390x/generic.prm
+++ /dev/null
@@ -1 +0,0 @@
-root=/dev/ram0 ro ip=off ramdisk_size=40000 cio_ignore=all,!0.0.0009
diff --git a/bootdisk/s390x/redhat.exec b/bootdisk/s390x/redhat.exec
deleted file mode 100644
index f1e5931..0000000
--- a/bootdisk/s390x/redhat.exec
+++ /dev/null
@@ -1,9 +0,0 @@
-/* */
-'CL RDR'
-'PURGE RDR ALL'
-'SPOOL PUNCH * RDR'
-'PUNCH KERNEL IMG A (NOH'
-'PUNCH GENERIC PRM A (NOH'
-'PUNCH INITRD IMG A (NOH'
-'CH RDR ALL KEEP NOHOLD'
-'I 00C'
diff --git a/bootdisk/sparc/Makefile.am b/bootdisk/sparc/Makefile.am
deleted file mode 100644
index 4d2c3f2..0000000
--- a/bootdisk/sparc/Makefile.am
+++ /dev/null
@@ -1,25 +0,0 @@
-# bootdisk/sparc/Makefile.am for anaconda
-#
-# Copyright (C) 2009  Red Hat, Inc.
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU Lesser General Public License as published
-# by the Free Software Foundation; either version 2.1 of the License, or
-# (at your option) any later version.
-#
-# 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 Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public License
-# along with this program.  If not, see <http://www.gnu.org/licenses/>.
-#
-# Author: Dennis Gilmore <dgilmore@xxxxxxxxxx>
-
-if IS_SPARC
-bootdir        = $(datadir)/$(PACKAGE_NAME)/boot
-dist_boot_DATA = boot.msg silo.conf
-endif
-
-MAINTAINERCLEANFILES = Makefile.in
diff --git a/bootdisk/sparc/boot.msg b/bootdisk/sparc/boot.msg
deleted file mode 100644
index b28310e..0000000
--- a/bootdisk/sparc/boot.msg
+++ /dev/null
@@ -1,9 +0,0 @@
-
-                   Welcome to Fedora SPARC Linux!
-
- -  To install or upgrade in graphical mode, press the <ENTER> key.
-
- -  To install or upgrade in text mode, type: linux text <ENTER>.
-
- -  To enter rescue mode] type: linux resuce <ENTER>.
-
diff --git a/bootdisk/sparc/silo.conf b/bootdisk/sparc/silo.conf
deleted file mode 100644
index 285546f..0000000
--- a/bootdisk/sparc/silo.conf
+++ /dev/null
@@ -1,17 +0,0 @@
-partition=1
-default=linux
-read-write
-timeout=100
-message=/boot/boot.msg
-image[sun4u]=/boot/vmlinuz
-        label=linux
-        alias=install
-        initrd=/boot/initrd.img
-image[sun4u]=/boot/vmlinuz
-        label=text
-        append=text
-        initrd=/boot/initrd.img
-image[sun4u]=/boot/vmlinuz
-        label=ks
-        append=ks
-        initrd=/boot/initrd.img
diff --git a/bootdisk/x86_64/Makefile.am b/bootdisk/x86_64/Makefile.am
deleted file mode 100644
index a4012c5..0000000
--- a/bootdisk/x86_64/Makefile.am
+++ /dev/null
@@ -1,25 +0,0 @@
-# bootdisk/x86_64/Makefile.am for anaconda
-#
-# Copyright (C) 2009  Red Hat, Inc.
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU Lesser General Public License as published
-# by the Free Software Foundation; either version 2.1 of the License, or
-# (at your option) any later version.
-#
-# 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 Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public License
-# along with this program.  If not, see <http://www.gnu.org/licenses/>.
-#
-# Author: David Cantrell <dcantrell@xxxxxxxxxx>
-
-if IS_X86_64
-bootdir        = $(datadir)/$(PACKAGE_NAME)/boot
-dist_boot_DATA = boot.msg grub.conf syslinux.cfg
-endif
-
-MAINTAINERCLEANFILES = Makefile.in
diff --git a/bootdisk/x86_64/boot.msg b/bootdisk/x86_64/boot.msg
deleted file mode 100644
index ff54899..0000000
--- a/bootdisk/x86_64/boot.msg
+++ /dev/null
@@ -1,5 +0,0 @@
- 
-splash.lss
-
- -  Press the 01<ENTER>07 key to begin the installation process.
-
diff --git a/bootdisk/x86_64/grub.conf b/bootdisk/x86_64/grub.conf
deleted file mode 100644
index 6e94d05..0000000
--- a/bootdisk/x86_64/grub.conf
+++ /dev/null
@@ -1,8 +0,0 @@
-#debug --graphics
-default=0
-splashimage=@SPLASHPATH@
-timeout 5
-hiddenmenu
-title @PRODUCT@ @VERSION@
-	kernel @KERNELPATH@
-	initrd @INITRDPATH@
diff --git a/bootdisk/x86_64/syslinux.cfg b/bootdisk/x86_64/syslinux.cfg
deleted file mode 100644
index 06a0842..0000000
--- a/bootdisk/x86_64/syslinux.cfg
+++ /dev/null
@@ -1,33 +0,0 @@
-default linux
-prompt 1
-timeout 600
-
-display boot.msg
-
-menu background splash.jpg
-menu title Welcome to @PRODUCT@ @VERSION@!
-menu color border 0 #ffffffff #00000000
-menu color sel 7 #ffffffff #ff000000
-menu color title 0 #ffffffff #00000000
-menu color tabmsg 0 #ffffffff #00000000
-menu color unsel 0 #ffffffff #00000000
-menu color hotsel 0 #ff000000 #ffffffff
-menu color hotkey 7 #ffffffff #ff000000
-menu color scrollbar 0 #ffffffff #00000000
-
-label linux
-  menu label ^Install a new system or upgrade an existing system
-  menu default
-  kernel vmlinuz
-  append initrd=initrd.img
-label vesa
-  menu label Install system with ^basic video driver
-  kernel vmlinuz
-  append initrd=initrd.img xdriver=vesa nomodeset
-label rescue
-  menu label ^Rescue installed system
-  kernel vmlinuz
-  append initrd=initrd.img rescue
-label local
-  menu label Boot from ^local drive
-  localboot 0xffff
diff --git a/bootloader.py b/bootloader.py
deleted file mode 100644
index 30912e7..0000000
--- a/bootloader.py
+++ /dev/null
@@ -1,244 +0,0 @@
-#
-# bootloader.py: anaconda bootloader shims
-#
-# Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006  Red Hat, Inc.
-# 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 as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# 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, see <http://www.gnu.org/licenses/>.
-#
-# Author(s): Erik Troan <ewt@xxxxxxxxxx>
-#            Jeremy Katz <katzj@xxxxxxxxxx>
-#
-
-import isys
-import parted
-import os, sys
-import iutil
-import string
-from flags import flags
-from constants import *
-from storage.devices import devicePathToName
-from storage import getReleaseString
-from booty.util import getDiskPart
-
-import gettext
-_ = lambda x: gettext.ldgettext("anaconda", x)
-
-import logging
-log = logging.getLogger("anaconda")
-
-import booty
-from booty import bootloaderInfo, checkbootloader
-
-def isEfiSystemPartition(part):
-    if not part.active:
-        return False
-    return (part.disk.type == "gpt" and
-            part.name == "EFI System Partition" and
-            part.getFlag(parted.PARTITION_BOOT) and
-            part.fileSystem.type in ("fat16", "fat32") and
-            isys.readFSLabel(part.getDeviceNodeName()) != "ANACONDA")
-
-def bootloaderSetupChoices(anaconda):
-    if anaconda.dir == DISPATCH_BACK:
-        rc = anaconda.intf.messageWindow(_("Warning"),
-                _("Filesystems have already been activated.  You "
-                  "cannot go back past this point.\n\nWould you like to "
-                  "continue with the installation?"),
-                type="custom", custom_icon=["error","error"],
-                custom_buttons=[_("_Exit installer"), _("_Continue")])
-
-        if rc == 0:
-            sys.exit(0)
-        return DISPATCH_FORWARD
-
-    if anaconda.ksdata and anaconda.ksdata.bootloader.driveorder:
-        anaconda.bootloader.updateDriveList(anaconda.ksdata.bootloader.driveorder)
-    else:
-        #We want the selected bootloader drive to be preferred
-        pref = anaconda.bootloader.drivelist[:1]
-        anaconda.bootloader.updateDriveList(pref)
-
-    if iutil.isEfi() and not anaconda.bootloader.device:
-        bootPart = None
-        partitions = anaconda.storage.partitions
-        for part in partitions:
-            if part.partedPartition.active and isEfiSystemPartition(part.partedPartition):
-                bootPart = part.name
-                break
-        if bootPart:
-            anaconda.bootloader.setDevice(bootPart)
-
-# iSeries bootloader on upgrades
-    if iutil.getPPCMachine() == "iSeries" and not anaconda.bootloader.device:
-        bootPart = None
-        partitions = anaconda.storage.partitions
-        for part in partitions:
-            if part.partedPartition.active and \
-               part.partedPartition.getFlag(parted.PARTITION_PREP):
-                bootPart = part.name
-                break
-        if bootPart:
-            anaconda.bootloader.setDevice(bootPart)
-
-    choices = anaconda.platform.bootloaderChoices(anaconda.bootloader)
-    if not choices and iutil.getPPCMachine() != "iSeries":
-	anaconda.dispatch.skipStep("instbootloader")
-    else:
-	anaconda.dispatch.skipStep("instbootloader", skip = 0)
-
-    # FIXME: ...
-    anaconda.bootloader.images.setup(anaconda.storage)
-
-    if anaconda.bootloader.defaultDevice != None and choices:
-        keys = choices.keys()
-        # there are only two possible things that can be in the keys
-        # mbr and boot.  boot is ALWAYS present.  so if the dev isn't
-        # listed, it was mbr and we should nicely fall back to boot
-        if anaconda.bootloader.defaultDevice not in keys:
-            log.warning("MBR not suitable as boot device; installing to partition")
-            anaconda.bootloader.defaultDevice = "boot"
-        anaconda.bootloader.setDevice(choices[anaconda.bootloader.defaultDevice][0])
-    elif choices and iutil.isMactel() and choices.has_key("boot"): # haccckkkk
-        anaconda.bootloader.setDevice(choices["boot"][0])        
-    elif choices and choices.has_key("mbr"):
-        anaconda.bootloader.setDevice(choices["mbr"][0])
-    elif choices and choices.has_key("boot"):
-        anaconda.bootloader.setDevice(choices["boot"][0])
-
-def fixedMdraidGrubTarget(anaconda, grubTarget):
-    # handle change made in F12 - before F12 mdX used to mean installation
-    # into mbrs of mdX members' disks
-    fixedGrubTarget = grubTarget
-    (product, version) = getReleaseString(anaconda.rootPath)
-    try:
-        if float(version) < 12:
-            stage1Devs = anaconda.bootloader.getPhysicalDevices(grubTarget)
-            fixedGrubTarget = getDiskPart(stage1Devs[0], anaconda.storage)[0]
-            log.info("Mdraid grub upgrade: %s -> %s" % (grubTarget,
-                                                       fixedGrubTarget))
-    except ValueError:
-        log.warning("Can't decide mdraid grub upgrade fix, product: %s, version: %s" % (product, version))
-
-    return fixedGrubTarget
-
-def writeBootloader(anaconda):
-    def dosync():
-        isys.sync()
-        isys.sync()
-        isys.sync()
-
-    if anaconda.bootloader.defaultDevice == -1:
-        return
-
-    if anaconda.bootloader.doUpgradeOnly:
-        (bootType, theDev) = checkbootloader.getBootloaderTypeAndBoot(anaconda.rootPath, storage=anaconda.storage)
-        
-        anaconda.bootloader.doUpgradeonly = 1
-        if bootType == "GRUB":
-            if theDev.startswith('/dev/md'):
-                theDev = fixedMdraidGrubTarget(anaconda,
-                                               devicePathToName(theDev))
-            anaconda.bootloader.useGrubVal = 1
-            anaconda.bootloader.setDevice(devicePathToName(theDev))
-        else:
-            anaconda.bootloader.doUpgradeOnly = 0    
-
-    w = anaconda.intf.waitWindow(_("Bootloader"), _("Installing bootloader."))
-
-    kernelList = []
-    otherList = []
-    # getDefault needs to return a device, but that's too invasive for now.
-    rootDev = anaconda.storage.rootDevice
-
-    if not anaconda.bootloader.images.getDefault():
-        defaultDev = None
-    else:
-        defaultDev = anaconda.storage.devicetree.getDeviceByName(anaconda.bootloader.images.getDefault())
-
-    kernelLabel = None
-    kernelLongLabel = None
-
-    for (dev, (label, longlabel, type)) in anaconda.bootloader.images.getImages().items():
-        if (rootDev is None and kernelLabel is None) or (dev == rootDev.name):
-	    kernelLabel = label
-            kernelLongLabel = longlabel
-	elif (not defaultDev and not dev) or (defaultDev and dev == defaultDev.name):
-	    otherList = [(label, longlabel, dev)] + otherList
-	else:
-	    otherList.append((label, longlabel, dev))
-
-    if kernelLabel is None:
-        log.error("unable to find default image, bailing")
-        w.pop()
-        return
-
-    plainLabelUsed = 0
-    defkern = "kernel"
-    for (version, arch, nick) in \
-            anaconda.backend.kernelVersionList(anaconda.rootPath):
-	if plainLabelUsed:
-            kernelList.append(("%s-%s" %(kernelLabel, nick),
-                               "%s-%s" %(kernelLongLabel, nick),
-                               version))
-	else:
-	    kernelList.append((kernelLabel, kernelLongLabel, version))
-            if nick != "base":
-                defkern = "kernel-%s" %(nick,)
-	    plainLabelUsed = 1
-
-    f = open(anaconda.rootPath + "/etc/sysconfig/kernel", "w+")
-    f.write("# UPDATEDEFAULT specifies if new-kernel-pkg should make\n"
-            "# new kernels the default\n")
-    # only update the default if we're setting the default to linux (#156678)
-    if (not defaultDev and not rootDev) or (defaultDev and rootDev.name == defaultDev.name):
-        f.write("UPDATEDEFAULT=yes\n")
-    else:
-        f.write("UPDATEDEFAULT=no\n")        
-    f.write("\n")
-    f.write("# DEFAULTKERNEL specifies the default kernel package type\n")
-    f.write("DEFAULTKERNEL=%s\n" %(defkern,))
-    f.close()
-
-    dosync()
-    try:
-        rc = anaconda.bootloader.write(anaconda.rootPath, anaconda.bootloader,
-                                       kernelList, otherList, defaultDev)
-        w.pop()
-
-        if rc and anaconda.intf:
-            anaconda.intf.messageWindow(_("Warning"),
-                               _("There was an error installing the bootloader.  "
-                                 "The system may not be bootable."))
-    except booty.BootyNoKernelWarning:
-        w.pop()
-        if anaconda.intf:
-            anaconda.intf.messageWindow(_("Warning"),
-                               _("No kernel packages were installed on the "
-                                 "system.  Bootloader configuration "
-                                 "will not be changed."))
-
-    dosync()
-
-def hasWindows(bl):
-    if not booty.doesDualBoot():
-        return False
-
-    foundWindows = False
-    for (dev, type) in bl.images.availableBootDevices(bl.storage):
-        if type in booty.dosFilesystems:
-            foundWindows = True
-            break
-
-    return foundWindows
diff --git a/cmdline.py b/cmdline.py
deleted file mode 100644
index a531940..0000000
--- a/cmdline.py
+++ /dev/null
@@ -1,221 +0,0 @@
-#
-# cmdline.py - non-interactive, very very simple frontend to anaconda
-#
-# Copyright (C) 2003, 2004, 2005, 2006, 2007  Red Hat, Inc.
-# 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 as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# 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, see <http://www.gnu.org/licenses/>.
-#
-# Author(s): Jeremy Katz <katzj@xxxxxxxxxx
-#
-
-import time
-import signal
-import parted
-from constants import *
-from flags import flags
-from iutil import strip_markup
-from installinterfacebase import InstallInterfaceBase
-
-import gettext
-_ = lambda x: gettext.ldgettext("anaconda", x)
-
-import logging
-log = logging.getLogger("anaconda")
-
-stepToClasses = { "install" : "setupProgressDisplay" }
-
-class WaitWindow:
-    def pop(self):
-        pass
-    def refresh(self):
-        pass
-    def __init__(self, title, text):
-        print(text)
-
-class ProgressWindow:
-    def pop(self):
-        print("")
-
-    def pulse(self):
-        pass
-
-    def set(self, amount):
-        if amount == self.total:
-            print(_("Completed"))
-
-    def refresh(self):
-        pass
-
-    def __init__(self, title, text, total, updpct = 0.05, pulse = False):
-        self.total = total
-        print(text)
-        print(_("In progress"))
-
-class InstallInterface(InstallInterfaceBase):
-    def __init__(self):
-        InstallInterfaceBase.__init__(self)
-#        signal.signal(signal.SIGINT, signal.SIG_IGN)
-        signal.signal(signal.SIGTSTP, signal.SIG_DFL)
-        self.instProgress = None
-
-    def __del__(self):
-        pass
-
-    def shutdown(self):
-        pass
-
-    def suspend(self):
-        pass
-
-    def resume(self):
-        pass
-
-    def progressWindow(self, title, text, total, updpct = 0.05, pulse = False):
-        return ProgressWindow(title, text, total, updpct, pulse)
-
-    def kickstartErrorWindow(self, text):
-        s = _("The following error was found while parsing the "
-              "kickstart configuration file:\n\n%s") %(text,)
-        print(s)
-
-        while 1:
-            time.sleep(5)
-
-    def messageWindow(self, title, text, type="ok", default = None,
-                      custom_icon = None, custom_buttons = []):
-        if type == "ok":
-            print(text)
-        else:
-            print(_("Command line mode requires all choices to be specified in a kickstart configuration file."))
-            print(title)
-            print(text)
-            print(type, custom_buttons)
-
-            # don't exit
-            while 1:
-                time.sleep(5)
-
-    def detailedMessageWindow(self, title, text, longText=None, type="ok",
-                              default=None, custom_buttons=None,
-                              custom_icon=None, expanded=False):
-        if longText:
-            text += "\n\n%s" % longText
-
-        self.messageWindow(title, text, type=type, default=default,
-                           custom_buttons=custom_buttons, custom_icon=custom_icon)
-
-    def passphraseEntryWindow(self, device):
-        print(_("Can't have a question in command line mode!"))
-        print("(passphraseEntryWindow: '%s')" % device)
-        # don't exit
-        while 1:
-            time.sleep(5)
-
-    def getLUKSPassphrase(self, passphrase = "", isglobal = False):
-        print(_("Can't have a question in command line mode!"))
-        print("(getLUKSPassphrase)")
-        # don't exit
-        while 1:
-            time.sleep(5)
-
-    def enableNetwork(self):
-        print(_("Can't have a question in command line mode!"))
-        print("(enableNetwork)")
-        # don't exit
-        while 1:
-            time.sleep(5)
-
-    def resetInitializeDiskQuestion(self):
-        pass
-
-    def questionInitializeDisk(self, path, description, size, details=""):
-        print(_("Can't have a question in command line mode!"))
-        print("(questionInitializeDisk)")
-        # don't exit
-        while 1:
-            time.sleep(5)
-
-    def resetReinitInconsistentLVMQuestion(self):
-        pass
-
-    def questionReinitInconsistentLVM(self, pv_names=None, lv_name=None, vg_name=None):
-        print(_("Can't have a question in command line mode!"))
-        print("(questionReinitInconsistentLVM)")
-        # don't exit
-        while 1:
-            time.sleep(5)
-
-    def mainExceptionWindow(self, shortText, longTextFile):
-        print(shortText)
-
-    def waitWindow(self, title, text):
-        return WaitWindow(title, text)
-
-    def beep(self):
-        pass
-
-    def run(self, anaconda):
-        (step, instance) = anaconda.dispatch.currentStep()
-        while step:
-            if stepToClasses.has_key(step):
-                s = "nextWin = %s" %(stepToClasses[step],)
-                exec s
-                nextWin(instance)
-            else:
-                print("In interactive step %s, can't continue" %(step,))
-                while 1:
-                    time.sleep(1)
-
-            anaconda.dispatch.gotoNext()
-	    (step, instance) = anaconda.dispatch.currentStep()
-
-    def setInstallProgressClass(self, c):
-        self.instProgress = c
-
-    def setSteps(self, anaconda):
-        pass
-
-class progressDisplay:
-    def __init__(self):
-        self.pct = 0
-        self.display = ""
-
-    def __del__(self):
-        pass
-
-    def processEvents(self):
-        pass
-    def setShowPercentage(self, val):
-        pass
-    def get_fraction(self):
-        return self.pct
-    def set_fraction(self, pct):
-        self.pct = pct
-    def set_text(self, txt):
-        pass
-    def set_label(self, txt):
-        stripped = strip_markup(txt)
-        if stripped != self.display:
-            self.display = stripped
-            print(self.display)
-
-def setupProgressDisplay(anaconda):
-    if anaconda.dir == DISPATCH_BACK:
-        anaconda.intf.setInstallProgressClass(None)
-        return DISPATCH_BACK
-    else:
-        anaconda.intf.setInstallProgressClass(progressDisplay())
-        
-    return DISPATCH_FORWARD
diff --git a/command-stubs/Makefile.am b/command-stubs/Makefile.am
deleted file mode 100644
index cab5f89..0000000
--- a/command-stubs/Makefile.am
+++ /dev/null
@@ -1,23 +0,0 @@
-# command-stubs/Makefile.am for anaconda
-#
-# Copyright (C) 2009  Red Hat, Inc.
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU Lesser General Public License as published
-# by the Free Software Foundation; either version 2.1 of the License, or
-# (at your option) any later version.
-#
-# 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 Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public License
-# along with this program.  If not, see <http://www.gnu.org/licenses/>.
-#
-# Author: David Cantrell <dcantrell@xxxxxxxxxx>
-
-commandstubsdir           = $(datadir)/$(PACKAGE_NAME)
-dist_commandstubs_SCRIPTS = *-stub
-
-MAINTAINERCLEANFILES = Makefile.in
diff --git a/command-stubs/list-harddrives-stub b/command-stubs/list-harddrives-stub
deleted file mode 100755
index 2d9e225..0000000
--- a/command-stubs/list-harddrives-stub
+++ /dev/null
@@ -1,45 +0,0 @@
-#!/usr/bin/python
-#
-# scan system for harddrives and output device name/size
-#
-# Copyright (C) 2007, 2009  Red Hat, Inc.  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 as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# 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, see <http://www.gnu.org/licenses/>.
-#
-
-import sys
-import parted
-import _ped
-
-def main(argv):
-    lst = set()
-
-    for dev in filter(lambda d: d.type != parted.DEVICE_DM, parted.getAllDevices()):
-        try:
-            disk = parted.Disk(dev)
-        except _ped.DiskLabelException:
-            continue
-
-        for part in disk.partitions:
-            lst.add("%s %s" % (part.path, int(part.getSize())))
-
-        print("%s %s" % (dev.path, int(dev.getSize())))
-
-    lst = list(lst)
-    lst.sort()
-    for entry in lst:
-        print entry
-
-if __name__ == "__main__":
-    main(sys.argv)
diff --git a/command-stubs/loadkeys-stub b/command-stubs/loadkeys-stub
deleted file mode 100755
index 1fdc2c9..0000000
--- a/command-stubs/loadkeys-stub
+++ /dev/null
@@ -1,41 +0,0 @@
-#!/usr/bin/python
-#
-# loadkeys-stub
-#
-# Copyright (C) 2007  Red Hat, Inc.  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 as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# 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, see <http://www.gnu.org/licenses/>.
-#
-
-import os
-import sys
-
-from pyanaconda import isys
-
-def usage():
-    print "usage: %s keymap" %(sys.argv[0],)
-    sys.exit(1)
-
-def main():
-    if len(sys.argv) != 2:
-        usage()
-
-    try:
-        isys.loadKeymap(sys.argv[1])
-    except SystemError:
-        pass
-    sys.exit(0)
-
-if __name__ == "__main__":
-    main()
diff --git a/command-stubs/losetup-stub b/command-stubs/losetup-stub
deleted file mode 100755
index 27c6bbc..0000000
--- a/command-stubs/losetup-stub
+++ /dev/null
@@ -1,50 +0,0 @@
-#!/usr/bin/python
-#
-# losetup-stub
-#
-# Copyright (C) 2007  Red Hat, Inc.  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 as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# 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, see <http://www.gnu.org/licenses/>.
-#
-
-import os
-import sys
-
-from pyanaconda import isys
-from sys import argv
-
-def usage():
-    print "usage: losetup [-d] /dev/loopN [image]"
-    sys.exit(1)
-
-if len(argv) < 3:
-    usage()
-
-if argv[1] == "-d" and len(argv[2]) > 4 and argv[2][-5:-1] == "loop":
-    try:
-        isys.unlosetup(argv[2])
-    except SystemError, (errno, msg):
-        print msg
-        sys.exit (1)
-    sys.exit(0)
-
-if len(argv[1]) > 4 and argv[1][-5:-1] == "loop":
-    try:
-        isys.losetup(argv[1], argv[2])
-    except SystemError, (errno, msg):
-        print msg
-        sys.exit (1)
-    sys.exit(0)
-
-usage()
diff --git a/command-stubs/mknod-stub b/command-stubs/mknod-stub
deleted file mode 100755
index cafc221..0000000
--- a/command-stubs/mknod-stub
+++ /dev/null
@@ -1,54 +0,0 @@
-#!/usr/bin/python
-#
-# mknod-stub
-#
-# Copyright (C) 2007  Red Hat, Inc.  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 as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# 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, see <http://www.gnu.org/licenses/>.
-#
-
-import stat, string, sys, os
-from pyanaconda import isys
-
-def usage():
-    sys.stderr.write("Usage: %s <path> [b|c] <major> <minor>\n" %(sys.argv[0],))
-    sys.exit(1)
-
-def main():
-    if len(sys.argv) < 2:
-        usage()
-
-    if (sys.argv[1] == '-h') or (sys.argv[1] == '--help'):
-        usage()
-
-    path = sys.argv[1]
-
-    if len(sys.argv) < 5:
-        usage()
-
-    if (sys.argv[2] == 'b'):
-        type = stat.S_IFBLK
-    elif (sys.argv[2] == 'c'):
-        type = stat.S_IFCHR
-    else:
-        usage()
-
-    major = int(sys.argv[3])
-    minor = int(sys.argv[4])
-    path = sys.argv[1]
-
-    os.mknod(path, 0644 | type, os.makedev(major, minor))
-
-if __name__ == "__main__":
-    main()
diff --git a/command-stubs/raidstart-stub b/command-stubs/raidstart-stub
deleted file mode 100755
index 6913006..0000000
--- a/command-stubs/raidstart-stub
+++ /dev/null
@@ -1,44 +0,0 @@
-#!/usr/bin/python
-#
-# raidstart-stub
-#
-# Copyright (C) 2007  Red Hat, Inc.  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 as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# 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, see <http://www.gnu.org/licenses/>.
-#
-
-import os
-import sys
-
-from pyanaconda import anaconda_log, fsset, raid, isys
-from sys import argv
-
-if len(argv) != 2 or argv[1][:7] != "/dev/md":
-    print "usage: raidstart /dev/md[minornum]"
-    sys.exit(1)
-
-targMinor = int(argv[1][7:])
-
-drives = isys.hardDriveDict().keys()
-drives.sort (isys.compareDrives)
-
-raidDevices = raid.scanForRaid(drives)
-for (minor, devices, level, totalDisks) in raidDevices:
-    if targMinor == minor:
-    	devName = "md%d" % (minor,)
-	isys.raidstart(devName, devices[0])
-	sys.exit(0)
-
-print "could not find devices associated with raid device md%d" % targMinor
-sys.exit(1)
diff --git a/command-stubs/raidstop-stub b/command-stubs/raidstop-stub
deleted file mode 100755
index 21f809d..0000000
--- a/command-stubs/raidstop-stub
+++ /dev/null
@@ -1,31 +0,0 @@
-#!/usr/bin/python
-#
-# raidstop-stub
-#
-# Copyright (C) 2007  Red Hat, Inc.  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 as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# 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, see <http://www.gnu.org/licenses/>.
-#
-
-import os
-import sys
-
-from pyanaconda import anaconda_log, fsset, raid, isys
-from sys import argv
-
-if len(argv) != 2 or argv[1][:7] != "/dev/md":
-    print "usage: raidstop /dev/md[minornum]"
-    sys.exit(1)
-
-isys.raidstop(argv[1][5:])
diff --git a/compssort.py b/compssort.py
deleted file mode 100644
index 3ad9795..0000000
--- a/compssort.py
+++ /dev/null
@@ -1,69 +0,0 @@
-#
-# compssort.py
-#
-# Copyright (C) 2005, 2006, 2007  Red Hat, Inc.  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 as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# 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, see <http://www.gnu.org/licenses/>.
-#
-
-import os
-
-import gettext
-_ = lambda x: gettext.ldgettext("anaconda", x)
-
-def _getDefaultLangs():
-    languages = []
-    for envar in ('LANGUAGE', 'LC_ALL', 'LC_MESSAGES', 'LANG'):
-        val = os.environ.get(envar)
-        if val:
-            languages = val.split(':')
-            break
-    if 'C' not in languages:
-        languages.append('C')
-
-    # now normalize and expand the languages
-    nelangs = []
-    for lang in languages:
-        for nelang in gettext._expand_lang(lang):
-            if nelang not in nelangs:
-                nelangs.append(nelang)
-    return nelangs
-
-# kind of lame caching of translations so we don't always have
-# to do all the looping
-strs = {}
-def xmltrans(base, thedict):
-    if strs.has_key(base):
-        return strs[base]
-
-    langs = _getDefaultLangs()
-    for l in langs:
-        if thedict.has_key(l):
-            strs[base] = thedict[l]
-            return strs[base]
-    strs[base] = base
-    return base
-
-def ui_comps_sort(one, two):
-    if one.display_order > two.display_order:
-        return 1
-    elif one.display_order < two.display_order:
-        return -1
-    elif xmltrans(one.name, one.translated_name) > \
-         xmltrans(two.name, two.translated_name):
-        return 1
-    elif xmltrans(one.name, one.translated_name) < \
-         xmltrans(two.name, two.translated_name):
-        return -1
-    return 0
diff --git a/configure.ac b/configure.ac
index e5611d1..54c4084 100644
--- a/configure.ac
+++ b/configure.ac
@@ -247,35 +247,38 @@ AM_CONDITIONAL(IS_SPARC,
   [test x$s_arch == xsparc || test x$s_arch == xsparc64])
 
 AC_CONFIG_FILES([Makefile
-                 bootdisk/Makefile
-                 bootdisk/i386/Makefile
-                 bootdisk/ppc/Makefile
-                 bootdisk/sparc/Makefile
-                 bootdisk/s390x/Makefile
-                 bootdisk/x86_64/Makefile
+                 data/Makefile
+                 data/bootdisk/Makefile
+                 data/bootdisk/i386/Makefile
+                 data/bootdisk/ppc/Makefile
+                 data/bootdisk/sparc/Makefile
+                 data/bootdisk/s390x/Makefile
+                 data/bootdisk/x86_64/Makefile
                  booty/Makefile
-                 command-stubs/Makefile
+                 data/command-stubs/Makefile
                  docs/Makefile
-                 fonts/Makefile
-                 gptsync/Makefile
-                 installclasses/Makefile
-                 isys/Makefile
-                 iw/Makefile
-                 liveinst/Makefile
-                 liveinst/console.apps/Makefile
-                 liveinst/pam.d/Makefile
-                 loader/Makefile
-                 pixmaps/Makefile
+                 data/fonts/Makefile
+                 bin/Makefile
+                 bin/gptsync/Makefile
+                 pyanaconda/installclasses/Makefile
+                 pyanaconda/isys/Makefile
+                 pyanaconda/iw/Makefile
+                 data/liveinst/Makefile
+                 data/liveinst/console.apps/Makefile
+                 data/liveinst/pam.d/Makefile
+                 bin/loader/Makefile
+                 data/pixmaps/Makefile
                  po/Makefile.in
                  scripts/Makefile
-                 storage/Makefile
-                 storage/devicelibs/Makefile
-                 storage/formats/Makefile
+                 pyanaconda/Makefile
+                 pyanaconda/storage/Makefile
+                 pyanaconda/storage/devicelibs/Makefile
+                 pyanaconda/storage/formats/Makefile
                  tests/Makefile
-                 tests/kickstart/Makefile
-                 tests/storage/Makefile
-                 tests/storage/devicelibs/Makefile
-                 textw/Makefile
-                 ui/Makefile
+                 tests/kickstart_test/Makefile
+                 tests/storage_test/Makefile
+                 tests/storage_test/devicelibs_test/Makefile
+                 pyanaconda/textw/Makefile
+                 data/ui/Makefile
                  utils/Makefile])
 AC_OUTPUT
diff --git a/constants.py b/constants.py
deleted file mode 100644
index fb81c90..0000000
--- a/constants.py
+++ /dev/null
@@ -1,89 +0,0 @@
-#
-# constants.py: anaconda constants
-#
-# Copyright (C) 2001  Red Hat, Inc.  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 as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# 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, see <http://www.gnu.org/licenses/>.
-#
-# Author(s): Erik Troan <ewt@xxxxxxxxxx>
-#
-
-import gettext
-_ = lambda x: gettext.ldgettext("anaconda", x)
-N_ = lambda x: x
-
-BETANAG = 1
-
-SELINUX_DEFAULT = 1
-
-DISPATCH_BACK = -1
-DISPATCH_FORWARD = 1
-DISPATCH_NOOP = None
-
-EXN_OK = 0
-EXN_DEBUG = 1
-EXN_SAVE = 2
-EXN_CANCEL = 3
-
-# different types of partition requests
-# REQUEST_PREEXIST is a placeholder for a pre-existing partition on the system
-# REQUEST_NEW is a request for a partition which will be automatically
-#              created based on various constraints on size, drive, etc
-# REQUEST_RAID is a request for a raid device
-# REQUEST_PROTECTED is a preexisting partition which can't change
-#              (harddrive install, harddrive with the isos on it)
-#
-REQUEST_PREEXIST = 1
-REQUEST_NEW = 2
-REQUEST_RAID = 4
-REQUEST_PROTECTED = 8
-REQUEST_VG = 16 # volume group
-REQUEST_LV = 32 # logical volume
-
-# XXX this is made up and used by the size spinner; should just be set with
-# a callback
-MAX_PART_SIZE = 1024*1024*1024
-
-# install key related constants
-SKIP_KEY = -50
-
-# pull in kickstart constants as well
-from pykickstart.constants import *
-
-# common string needs to be easy to change
-import product
-productName = product.productName
-productVersion = product.productVersion
-productArch = product.productArch
-productPath = product.productPath
-bugzillaUrl = product.bugUrl
-
-lvmErrorOutput = "/tmp/lvmout"
-
-exceptionText = _("An unhandled exception has occurred.  This "
-                  "is most likely a bug.  Please save a copy of "
-                  "the detailed exception and file a bug report")
-if not bugzillaUrl:
-    # this string will be combined with "An unhandled exception"...
-    # the leading space is not a typo.
-    exceptionText += _(" with the provider of this software.")
-else:
-    # this string will be combined with "An unhandled exception"...
-    # the leading space is not a typo.
-    exceptionText += _(" against anaconda at %s") %(bugzillaUrl,)
-
-# DriverDisc Paths
-DD_EXTRACTED = "/tmp/DD"
-DD_RPMS = "/tmp/DD-*"
-
diff --git a/data/70-anaconda.rules b/data/70-anaconda.rules
new file mode 100644
index 0000000..bba0bfb
--- /dev/null
+++ b/data/70-anaconda.rules
@@ -0,0 +1,56 @@
+# If $ANACONDA isn't set in the environment, skip all these rules.
+ENV{ANACONDA}!="?*", GOTO="anaconda_end"
+
+ACTION!="add|change", GOTO="anaconda_end"
+SUBSYSTEM!="block", GOTO="anaconda_end"
+
+# for device-mapper device we are supposed to only operate on "change" events
+KERNEL=="dm-*", ACTION=="add", GOTO="anaconda_end"
+
+ENV{ANACBIN}="/sbin"
+TEST!="$env{ANACBIN}/dmsetup", ENV{ANACBIN}="/usr/sbin"
+
+KERNEL=="dm-*", ENV{DM_UDEV_DISABLE_DISK_RULES_FLAG}=="1", GOTO="anaconda_end"
+KERNEL=="dm-*", ENV{DM_NAME}!="?*", GOTO="anaconda_end"
+KERNEL=="dm-*", ENV{DM_SUSPENDED}=="1", GOTO="anaconda_end"
+KERNEL=="dm-*", ENV{DM_SUSPENDED}=="Suspended", GOTO="anaconda_end"
+
+IMPORT{program}="$env{ANACBIN}/blkid -o udev -p $tempnode"
+
+LABEL="anaconda_mdraid"
+KERNEL!="md*", GOTO="anaconda_mdraid_member"
+
+# container devices have a metadata version of e.g. 'external:ddf' and
+# never leave state 'inactive'
+ATTR{md/metadata_version}=="external:[A-Za-z]*", ATTR{md/array_state}=="inactive", GOTO="md_ignore_state"
+TEST!="md/array_state", GOTO="anaconda_mdraid_member"
+ATTR{md/array_state}=="|clear|inactive", GOTO="anaconda_mdraid_member"
+LABEL="md_ignore_state"
+
+IMPORT{program}="$env{ANACBIN}/mdadm --detail --export $tempnode"
+ENV{DEVTYPE}=="disk", ENV{MD_NAME}=="?*", SYMLINK+="disk/by-id/md-name-$env{MD_NAME}", OPTIONS+="string_escape=replace"
+ENV{DEVTYPE}=="disk", ENV{MD_UUID}=="?*", SYMLINK+="disk/by-id/md-uuid-$env{MD_UUID}"
+ENV{DEVTYPE}=="disk", ENV{MD_DEVNAME}=="?*", SYMLINK+="md/$env{MD_DEVNAME}"
+ENV{DEVTYPE}=="partition", ENV{MD_NAME}=="?*", SYMLINK+="disk/by-id/md-name-$env{MD_NAME}-part%n", OPTIONS+="string_escape=replace"
+ENV{DEVTYPE}=="partition", ENV{MD_UUID}=="?*", SYMLINK+="disk/by-id/md-uuid-$env{MD_UUID}-part%n"
+ENV{DEVTYPE}=="partition", ENV{MD_DEVNAME}=="*[^0-9]", SYMLINK+="md/$env{MD_DEVNAME}%n"
+ENV{DEVTYPE}=="partition", ENV{MD_DEVNAME}=="*[0-9]", SYMLINK+="md/$env{MD_DEVNAME}p%n"
+
+OPTIONS+="link_priority=100"
+OPTIONS+="watch"
+ENV{ID_FS_USAGE}=="filesystem|other|crypto", ENV{ID_FS_UUID_ENC}=="?*", SYMLINK+="disk/by-uuid/$env{ID_FS_UUID_ENC}"
+ENV{ID_FS_USAGE}=="filesystem|other", ENV{ID_FS_LABEL_ENC}=="?*", SYMLINK+="disk/by-label/$env{ID_FS_LABEL_ENC}"
+
+LABEL="anaconda_mdraid_member"
+# probe raid metadata of mdraid member devices
+ENV{ID_FS_TYPE}=="linux_raid_member", IMPORT{program}="$env{ANACBIN}/mdadm --examine --export $tempnode"
+ENV{ID_FS_TYPE}=="isw_raid_member", IMPORT{program}="$env{ANACBIN}/mdadm --examine --export $tempnode"
+
+# probe metadata of LVM2 physical volumes
+ENV{ID_FS_TYPE}=="LVM2_member", IMPORT{program}="$env{ANACBIN}/lvm pvs --ignorelockingfailure --units k --nosuffix --nameprefixes --rows --unquoted --noheadings -opv_name,pv_uuid,pv_size,vg_name,vg_uuid,pv_pe_count,pv_pe_alloc_count,pe_start $tempnode"
+ENV{LVM2_VG_NAME}!="?*", GOTO="anaconda_end"
+ENV{ID_FS_TYPE}=="LVM2_member", IMPORT{program}="$env{ANACBIN}/lvm vgs --ignorelockingfailure --units k --nosuffix --nameprefixes --rows --unquoted --noheadings -ouuid,size,free,extent_size,extent_count,free_count,pv_count $env{LVM2_VG_NAME}"
+ENV{ID_FS_TYPE}=="LVM2_member", IMPORT{program}="$env{ANACBIN}/lvm lvs -a --ignorelockingfailure --units k --nosuffix --nameprefixes --rows --unquoted --noheadings -olv_name,lv_uuid,lv_size,lv_attr $env{LVM2_VG_NAME}"
+
+LABEL="anaconda_end"
+
diff --git a/data/Makefile.am b/data/Makefile.am
new file mode 100644
index 0000000..841d340
--- /dev/null
+++ b/data/Makefile.am
@@ -0,0 +1,36 @@
+# liveinst/Makefile.am for anaconda
+#
+# Copyright (C) 2009  Red Hat, Inc.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License as published
+# by the Free Software Foundation; either version 2.1 of the License, or
+# (at your option) any later version.
+#
+# 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 Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+#
+# Author: Martin Sivak <msivak@xxxxxxxxxx>
+
+SUBDIRS = bootdisk command-stubs fonts icons liveinst pixmaps ui 
+
+EXTRA_DIST = lang-table
+CLEANFILES = *~ lang-names 
+
+udevdir               = /lib/udev/rules.d
+dist_udev_DATA        = 70-anaconda.rules
+
+langdir               = $(datadir)/$(PACKAGE_NAME)
+lang_DATA             = lang-names
+dist_lang_DATA        = lang-table
+
+MAINTAINERCLEANFILES = Makefile.in
+
+lang-names: lang-table
+	PYTHONPATH="../" $(PYTHON) scripts/getlangnames.py > lang-names
+
diff --git a/data/bootdisk/Makefile.am b/data/bootdisk/Makefile.am
new file mode 100644
index 0000000..e6ba4bd
--- /dev/null
+++ b/data/bootdisk/Makefile.am
@@ -0,0 +1,22 @@
+# bootdisk/Makefile.am for anaconda
+#
+# Copyright (C) 2009  Red Hat, Inc.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License as published
+# by the Free Software Foundation; either version 2.1 of the License, or
+# (at your option) any later version.
+#
+# 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 Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+#
+# Author: David Cantrell <dcantrell@xxxxxxxxxx>
+
+SUBDIRS = i386 ppc sparc s390x x86_64
+
+MAINTAINERCLEANFILES = Makefile.in
diff --git a/data/bootdisk/i386/Makefile.am b/data/bootdisk/i386/Makefile.am
new file mode 100644
index 0000000..030b8d5
--- /dev/null
+++ b/data/bootdisk/i386/Makefile.am
@@ -0,0 +1,25 @@
+# bootdisk/i386/Makefile.am for anaconda
+#
+# Copyright (C) 2009  Red Hat, Inc.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License as published
+# by the Free Software Foundation; either version 2.1 of the License, or
+# (at your option) any later version.
+#
+# 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 Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+#
+# Author: David Cantrell <dcantrell@xxxxxxxxxx>
+
+if IS_I386
+bootdir        = $(datadir)/$(PACKAGE_NAME)/boot
+dist_boot_DATA = boot.msg grub.conf syslinux.cfg
+endif
+
+MAINTAINERCLEANFILES = Makefile.in
diff --git a/data/bootdisk/i386/boot.msg b/data/bootdisk/i386/boot.msg
new file mode 100644
index 0000000..ff54899
--- /dev/null
+++ b/data/bootdisk/i386/boot.msg
@@ -0,0 +1,5 @@
+ 
+splash.lss
+
+ -  Press the 01<ENTER>07 key to begin the installation process.
+
diff --git a/data/bootdisk/i386/grub.conf b/data/bootdisk/i386/grub.conf
new file mode 100644
index 0000000..6e94d05
--- /dev/null
+++ b/data/bootdisk/i386/grub.conf
@@ -0,0 +1,8 @@
+#debug --graphics
+default=0
+splashimage=@SPLASHPATH@
+timeout 5
+hiddenmenu
+title @PRODUCT@ @VERSION@
+	kernel @KERNELPATH@
+	initrd @INITRDPATH@
diff --git a/data/bootdisk/i386/syslinux.cfg b/data/bootdisk/i386/syslinux.cfg
new file mode 100644
index 0000000..06a0842
--- /dev/null
+++ b/data/bootdisk/i386/syslinux.cfg
@@ -0,0 +1,33 @@
+default linux
+prompt 1
+timeout 600
+
+display boot.msg
+
+menu background splash.jpg
+menu title Welcome to @PRODUCT@ @VERSION@!
+menu color border 0 #ffffffff #00000000
+menu color sel 7 #ffffffff #ff000000
+menu color title 0 #ffffffff #00000000
+menu color tabmsg 0 #ffffffff #00000000
+menu color unsel 0 #ffffffff #00000000
+menu color hotsel 0 #ff000000 #ffffffff
+menu color hotkey 7 #ffffffff #ff000000
+menu color scrollbar 0 #ffffffff #00000000
+
+label linux
+  menu label ^Install a new system or upgrade an existing system
+  menu default
+  kernel vmlinuz
+  append initrd=initrd.img
+label vesa
+  menu label Install system with ^basic video driver
+  kernel vmlinuz
+  append initrd=initrd.img xdriver=vesa nomodeset
+label rescue
+  menu label ^Rescue installed system
+  kernel vmlinuz
+  append initrd=initrd.img rescue
+label local
+  menu label Boot from ^local drive
+  localboot 0xffff
diff --git a/data/bootdisk/ppc/Makefile.am b/data/bootdisk/ppc/Makefile.am
new file mode 100644
index 0000000..4f6e298
--- /dev/null
+++ b/data/bootdisk/ppc/Makefile.am
@@ -0,0 +1,26 @@
+# bootdisk/ppc/Makefile.am for anaconda
+#
+# Copyright (C) 2009  Red Hat, Inc.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License as published
+# by the Free Software Foundation; either version 2.1 of the License, or
+# (at your option) any later version.
+#
+# 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 Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+#
+# Author: David Cantrell <dcantrell@xxxxxxxxxx>
+
+if IS_PPC
+bootdir        = $(datadir)/$(PACKAGE_NAME)/boot
+dist_boot_DATA = magic ofboot.b yaboot.conf.in bootinfo.txt mapping \
+                 yaboot.conf.3264
+endif
+
+MAINTAINERCLEANFILES = Makefile.in
diff --git a/data/bootdisk/ppc/bootinfo.txt b/data/bootdisk/ppc/bootinfo.txt
new file mode 100644
index 0000000..ac766d4
--- /dev/null
+++ b/data/bootdisk/ppc/bootinfo.txt
@@ -0,0 +1,169 @@
+<chrp-boot> <description>Linux</description> 
+<os-name>Linux</os-name> 
+<boot-script>boot &device;:\ppc\chrp\yaboot</boot-script> 
+<icon size=64,64 color-space=3,3,2> 
+<bitmap> FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
+FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
+FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
+FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
+FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
+FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
+FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
+FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
+FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
+FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
+FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
+FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
+FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
+FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
+FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
+FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
+FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
+FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
+FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
+FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
+FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
+FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
+FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
+FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
+FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
+FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
+FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
+FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
+FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
+FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
+FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
+FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
+FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
+FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
+FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
+FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
+FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
+FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
+FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
+FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
+FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
+FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
+FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
+FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
+FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
+FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
+FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
+FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
+FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
+FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
+FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
+FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
+FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
+FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
+FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
+FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
+FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
+FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
+FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
+FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
+FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
+FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
+FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
+FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
+FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
+FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
+FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
+FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
+FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
+FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
+FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
+FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
+FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
+FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
+FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
+FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
+FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
+FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
+FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
+FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
+FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
+FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
+FF FF FF FF FF FF FF FF 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+00 00 00 00 00 00 </bitmap> </icon> </chrp-boot>
diff --git a/data/bootdisk/ppc/magic b/data/bootdisk/ppc/magic
new file mode 100644
index 0000000..387727c
--- /dev/null
+++ b/data/bootdisk/ppc/magic
@@ -0,0 +1,81 @@
+#
+# Example magic file for mkhybrid
+#
+# The "message" for the offset MUST be 4 characters for the CREATOR
+# and 4 characters for the TYPE - white space is optional between them.
+# Any other characters on this line are ignored. Continuation lines (starting
+# with '>') are also ignored i.e. only the initial offset lines are used.
+#
+# The continuation lines are given here, but they do not need to exist.
+
+#
+# James Pearson 20/5/98
+
+# off	type		test		message
+
+# GIF
+0	string		GIF8		8BIM GIFf
+>4	string		7a		\b, version 8%s,
+>4	string		9a		\b, version 8%s,
+>6	leshort		>0		%hd x
+>8	leshort		>0		%hd,
+#>10	byte		&0x80		color mapped,
+#>10	byte&0x07	=0x00		2 colors
+#>10	byte&0x07	=0x01		4 colors
+#>10	byte&0x07	=0x02		8 colors
+#>10	byte&0x07	=0x03		16 colors
+#>10	byte&0x07	=0x04		32 colors
+#>10	byte&0x07	=0x05		64 colors
+#>10	byte&0x07	=0x06		128 colors
+#>10	byte&0x07	=0x07		256 colors
+
+# JPEG images
+#
+0	ubeshort		0xffd8		8BIM JPEG  image data
+
+# StuffIt
+#
+0	string		SIT!		SIT!SIT!
+
+# standard unix compress
+0	string		\037\235	LZIV ZIVU
+>2	byte&0x80	>0		block compressed
+>2	byte&0x1f	x		%d bits
+
+# gzip (GNU zip, not to be confused with Info-ZIP or PKWARE zip archiver)
+0       string          \037\213        GNUz ZIVU gzip compressed data
+>2      byte            <8              \b, reserved method,
+>2      byte            8               \b, deflated,
+>3	byte		&0x01		ASCII,
+>3	byte		&0x02		continuation,
+>3	byte		&0x04		extra field,
+>3	byte		&0x08		original filename,
+>3	byte		&0x10		comment,
+>3	byte		&0x20		encrypted,
+>4	ledate		x		last modified: %s,
+>8	byte		2		max compression,
+>8	byte		4		max speed,
+>9	byte		=0x00		os: MS-DOS
+>9	byte		=0x01		os: Amiga
+>9	byte		=0x02		os: VMS
+>9	byte		=0x03		os: Unix
+>9	byte		=0x05		os: Atari
+>9	byte		=0x06		os: OS/2
+>9	byte		=0x07		os: MacOS
+>9	byte		=0x0A		os: Tops/20
+>9	byte		=0x0B		os: Win/32
+
+# Postscript
+0	string		%!		ASPSTEXT
+>2	string		PS-Adobe-	conforming
+>>11	string		>\0		at level %.3s
+>>>15	string		EPS		- type %s
+>>>15	string		Query		- type %s
+>>>15	string		ExitServer	- type %s
+# Some PCs have the annoying habit of adding a ^D as a document separator
+0	string		\004%!		ASPS TEXT PostScript document text
+>3	string		PS-Adobe-	conforming
+>>12	string		>\0		at level %.3s
+>>>16	string		EPS		- type %s
+>>>16	string		Query		- type %s
+>>>16	string		ExitServer	- type %s
diff --git a/data/bootdisk/ppc/mapping b/data/bootdisk/ppc/mapping
new file mode 100644
index 0000000..cf83076
--- /dev/null
+++ b/data/bootdisk/ppc/mapping
@@ -0,0 +1,27 @@
+# Example filename mapping file
+#
+# yaboot		Raw	'UNIX'	'boot'	"Bootstrap"
+# vmlinux		Raw	'UNIX'	'boot'	"Bootstrap"
+#
+# EXTN          XLate   CREATOR   TYPE     Comment
+COPYING         Ascii   'ttxt'  'ttro'  "Text File"
+CREDITS         Ascii   'ttxt'  'ttro'  "Text File"
+README          Ascii   'ttxt'  'ttro'  "Text File"
+RPM-GPG-KEY     Ascii   'ttxt'  'ttro'  "Text File"
+RELEASE_NOTES   Ascii   'ttxt'  'ttro'  "Text File"
+.b              Raw     'chrp'  'tbxi'  "Macintosh Toolbox ROM file"
+.gif            Raw     '8BIM'  'GIFf'  "Gif File"
+.jpg            Raw     '8BIM'  'JPEG'  "Jpeg File"
+.tif            Raw     '8BIM'  'TIFF'  "Photoshop TIFF image"
+.hqx            Ascii   'BnHq'  'TEXT'  "BinHex file"
+.doc            Raw     'MSWD'  'WDBN'  "Word file"
+.mov            Raw     'TVOD'  'MooV'  "QuickTime Movie"
+.html           Ascii   'MOSS'  'TEXT'  "HTML File"
+.htm            Ascii   'MOSS'  'TEXT'  "HTML File"
+.conf           Ascii   'ttxt'  'TEXT'  "config file"
+.txt            Ascii   'ttxt'  'TEXT'  "Text File"
+.tbxi           Raw     'chrp'  'tbxi'  "Macintosh Toolbox ROM file"
+.sea            Raw     'aust'  'APPL'  "Self Expanding Archive"
+.sit            Raw     'SIT!'  'SITD'  "Stuffit Expander file"
+*               Raw     '????'  '????'  "Unknown"
+
diff --git a/data/bootdisk/ppc/ofboot.b b/data/bootdisk/ppc/ofboot.b
new file mode 100644
index 0000000..c811894
--- /dev/null
+++ b/data/bootdisk/ppc/ofboot.b
@@ -0,0 +1,74 @@
+<CHRP-BOOT>
+<COMPATIBLE>
+MacRISC MacRISC3 MacRISC4
+</COMPATIBLE>
+
+<DESCRIPTION>
+Boot Chooser
+</DESCRIPTION>
+
+<BOOT-SCRIPT>
+" screen" output
+load-base release-load-area
+" /cpus/@0" find-package if
+ " 64-bit" rot get-package-property 0= if
+  2drop
+  " boot cd:,\ppc\mac\yaboot conf=cd:,\ppc\ppc64\yaboot.conf" eval
+ else
+  " boot cd:,\ppc\mac\yaboot conf=cd:,\ppc\ppc32\yaboot.conf" eval
+ then
+then
+</BOOT-SCRIPT>
+
+<OS-BADGE-ICONS>
+1010
+000000000000F8FEACF6000000000000
+0000000000F5FFFFFEFEF50000000000
+00000000002BFAFEFAFCF70000000000
+0000000000F65D5857812B0000000000
+0000000000F5350B2F88560000000000
+0000000000F6335708F8FE0000000000
+00000000005600F600F5FD8100000000
+00000000F9F8000000F5FAFFF8000000
+000000008100F5F50000F6FEFE000000
+000000F8F700F500F50000FCFFF70000
+00000088F70000F50000F5FCFF2B0000
+0000002F582A00F5000008ADE02C0000
+00090B0A35A62B0000002D3B350A0000
+000A0A0B0B3BF60000505E0B0A0B0A00
+002E350B0B2F87FAFCF45F0B2E090000
+00000007335FF82BF72B575907000000
+000000000000ACFFFF81000000000000
+000000000081FFFFFFFF810000000000
+0000000000FBFFFFFFFFAC0000000000
+000000000081DFDFDFFFFB0000000000
+000000000081DD5F83FFFD0000000000
+000000000081DDDF5EACFF0000000000
+0000000000FDF981F981FFFF00000000
+00000000FFACF9F9F981FFFFAC000000
+00000000FFF98181F9F981FFFF000000
+000000ACACF981F981F9F9FFFFAC0000
+000000FFACF9F981F9F981FFFFFB0000
+00000083DFFBF981F9F95EFFFFFC0000
+005F5F5FDDFFFBF9F9F983DDDD5F0000
+005F5F5F5FDD81F9F9E7DF5F5F5F5F00
+0083DD5F5F83FFFFFFFFDF5F835F0000
+000000FBDDDFACFBACFBDFDFFB000000
+000000000000FFFFFFFF000000000000
+0000000000FFFFFFFFFFFF0000000000
+0000000000FFFFFFFFFFFF0000000000
+0000000000FFFFFFFFFFFF0000000000
+0000000000FFFFFFFFFFFF0000000000
+0000000000FFFFFFFFFFFF0000000000
+0000000000FFFFFFFFFFFFFF00000000
+00000000FFFFFFFFFFFFFFFFFF000000
+00000000FFFFFFFFFFFFFFFFFF000000
+000000FFFFFFFFFFFFFFFFFFFFFF0000
+000000FFFFFFFFFFFFFFFFFFFFFF0000
+000000FFFFFFFFFFFFFFFFFFFFFF0000
+00FFFFFFFFFFFFFFFFFFFFFFFFFF0000
+00FFFFFFFFFFFFFFFFFFFFFFFFFFFF00
+00FFFFFFFFFFFFFFFFFFFFFFFFFF0000
+000000FFFFFFFFFFFFFFFFFFFF000000
+</OS-BADGE-ICONS>
+</CHRP-BOOT>
diff --git a/data/bootdisk/ppc/yaboot.conf.3264 b/data/bootdisk/ppc/yaboot.conf.3264
new file mode 100644
index 0000000..8b5af08
--- /dev/null
+++ b/data/bootdisk/ppc/yaboot.conf.3264
@@ -0,0 +1,14 @@
+init-message = "\nWelcome to the %PRODUCT% %VERSION% installer!\nUse 'linux32' for 32-bit kernel.\n\n"
+timeout=6000
+default=linux
+
+image=/ppc/ppc64/vmlinuz
+	label=linux64
+	alias=linux
+	initrd=/ppc/ppc64/ramdisk.image.gz
+	read-only
+
+image=/ppc/ppc32/vmlinuz
+	label=linux32
+	initrd=/ppc/ppc32/ramdisk.image.gz
+	read-only
diff --git a/data/bootdisk/ppc/yaboot.conf.in b/data/bootdisk/ppc/yaboot.conf.in
new file mode 100644
index 0000000..d06768a
--- /dev/null
+++ b/data/bootdisk/ppc/yaboot.conf.in
@@ -0,0 +1,8 @@
+init-message = "\nWelcome to the %BITS%-bit %PRODUCT% %VERSION% installer!\nHit <TAB> for boot options.\n\n"
+timeout=6000
+default=linux
+
+image=/ppc/ppc%BITS%/vmlinuz
+	label=linux
+	initrd=/ppc/ppc%BITS%/ramdisk.image.gz
+	read-only
diff --git a/data/bootdisk/s390x/Makefile.am b/data/bootdisk/s390x/Makefile.am
new file mode 100644
index 0000000..c75ccbe
--- /dev/null
+++ b/data/bootdisk/s390x/Makefile.am
@@ -0,0 +1,25 @@
+# bootdisk/s390x/Makefile.am for anaconda
+#
+# Copyright (C) 2009  Red Hat, Inc.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License as published
+# by the Free Software Foundation; either version 2.1 of the License, or
+# (at your option) any later version.
+#
+# 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 Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+#
+# Author: David Cantrell <dcantrell@xxxxxxxxxx>
+
+if IS_S390
+bootdir        = $(datadir)/$(PACKAGE_NAME)/boot
+dist_boot_DATA = generic.ins generic.prm redhat.exec
+endif
+
+MAINTAINERCLEANFILES = Makefile.in
diff --git a/data/bootdisk/s390x/generic.ins b/data/bootdisk/s390x/generic.ins
new file mode 100644
index 0000000..a690f2e
--- /dev/null
+++ b/data/bootdisk/s390x/generic.ins
@@ -0,0 +1,5 @@
+* minimal lpar ins file
+images/kernel.img 0x00000000
+images/initrd.img @INITRD_LOAD_ADDRESS@
+images/generic.prm 0x00010480
+images/initrd.addrsize 0x00010408
diff --git a/data/bootdisk/s390x/generic.prm b/data/bootdisk/s390x/generic.prm
new file mode 100644
index 0000000..e953ce2
--- /dev/null
+++ b/data/bootdisk/s390x/generic.prm
@@ -0,0 +1 @@
+root=/dev/ram0 ro ip=off ramdisk_size=40000 cio_ignore=all,!0.0.0009
diff --git a/data/bootdisk/s390x/redhat.exec b/data/bootdisk/s390x/redhat.exec
new file mode 100644
index 0000000..f1e5931
--- /dev/null
+++ b/data/bootdisk/s390x/redhat.exec
@@ -0,0 +1,9 @@
+/* */
+'CL RDR'
+'PURGE RDR ALL'
+'SPOOL PUNCH * RDR'
+'PUNCH KERNEL IMG A (NOH'
+'PUNCH GENERIC PRM A (NOH'
+'PUNCH INITRD IMG A (NOH'
+'CH RDR ALL KEEP NOHOLD'
+'I 00C'
diff --git a/data/bootdisk/sparc/Makefile.am b/data/bootdisk/sparc/Makefile.am
new file mode 100644
index 0000000..4d2c3f2
--- /dev/null
+++ b/data/bootdisk/sparc/Makefile.am
@@ -0,0 +1,25 @@
+# bootdisk/sparc/Makefile.am for anaconda
+#
+# Copyright (C) 2009  Red Hat, Inc.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License as published
+# by the Free Software Foundation; either version 2.1 of the License, or
+# (at your option) any later version.
+#
+# 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 Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+#
+# Author: Dennis Gilmore <dgilmore@xxxxxxxxxx>
+
+if IS_SPARC
+bootdir        = $(datadir)/$(PACKAGE_NAME)/boot
+dist_boot_DATA = boot.msg silo.conf
+endif
+
+MAINTAINERCLEANFILES = Makefile.in
diff --git a/data/bootdisk/sparc/boot.msg b/data/bootdisk/sparc/boot.msg
new file mode 100644
index 0000000..b28310e
--- /dev/null
+++ b/data/bootdisk/sparc/boot.msg
@@ -0,0 +1,9 @@
+
+                   Welcome to Fedora SPARC Linux!
+
+ -  To install or upgrade in graphical mode, press the <ENTER> key.
+
+ -  To install or upgrade in text mode, type: linux text <ENTER>.
+
+ -  To enter rescue mode] type: linux resuce <ENTER>.
+
diff --git a/data/bootdisk/sparc/silo.conf b/data/bootdisk/sparc/silo.conf
new file mode 100644
index 0000000..285546f
--- /dev/null
+++ b/data/bootdisk/sparc/silo.conf
@@ -0,0 +1,17 @@
+partition=1
+default=linux
+read-write
+timeout=100
+message=/boot/boot.msg
+image[sun4u]=/boot/vmlinuz
+        label=linux
+        alias=install
+        initrd=/boot/initrd.img
+image[sun4u]=/boot/vmlinuz
+        label=text
+        append=text
+        initrd=/boot/initrd.img
+image[sun4u]=/boot/vmlinuz
+        label=ks
+        append=ks
+        initrd=/boot/initrd.img
diff --git a/data/bootdisk/x86_64/Makefile.am b/data/bootdisk/x86_64/Makefile.am
new file mode 100644
index 0000000..a4012c5
--- /dev/null
+++ b/data/bootdisk/x86_64/Makefile.am
@@ -0,0 +1,25 @@
+# bootdisk/x86_64/Makefile.am for anaconda
+#
+# Copyright (C) 2009  Red Hat, Inc.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License as published
+# by the Free Software Foundation; either version 2.1 of the License, or
+# (at your option) any later version.
+#
+# 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 Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+#
+# Author: David Cantrell <dcantrell@xxxxxxxxxx>
+
+if IS_X86_64
+bootdir        = $(datadir)/$(PACKAGE_NAME)/boot
+dist_boot_DATA = boot.msg grub.conf syslinux.cfg
+endif
+
+MAINTAINERCLEANFILES = Makefile.in
diff --git a/data/bootdisk/x86_64/boot.msg b/data/bootdisk/x86_64/boot.msg
new file mode 100644
index 0000000..ff54899
--- /dev/null
+++ b/data/bootdisk/x86_64/boot.msg
@@ -0,0 +1,5 @@
+ 
+splash.lss
+
+ -  Press the 01<ENTER>07 key to begin the installation process.
+
diff --git a/data/bootdisk/x86_64/grub.conf b/data/bootdisk/x86_64/grub.conf
new file mode 100644
index 0000000..6e94d05
--- /dev/null
+++ b/data/bootdisk/x86_64/grub.conf
@@ -0,0 +1,8 @@
+#debug --graphics
+default=0
+splashimage=@SPLASHPATH@
+timeout 5
+hiddenmenu
+title @PRODUCT@ @VERSION@
+	kernel @KERNELPATH@
+	initrd @INITRDPATH@
diff --git a/data/bootdisk/x86_64/syslinux.cfg b/data/bootdisk/x86_64/syslinux.cfg
new file mode 100644
index 0000000..06a0842
--- /dev/null
+++ b/data/bootdisk/x86_64/syslinux.cfg
@@ -0,0 +1,33 @@
+default linux
+prompt 1
+timeout 600
+
+display boot.msg
+
+menu background splash.jpg
+menu title Welcome to @PRODUCT@ @VERSION@!
+menu color border 0 #ffffffff #00000000
+menu color sel 7 #ffffffff #ff000000
+menu color title 0 #ffffffff #00000000
+menu color tabmsg 0 #ffffffff #00000000
+menu color unsel 0 #ffffffff #00000000
+menu color hotsel 0 #ff000000 #ffffffff
+menu color hotkey 7 #ffffffff #ff000000
+menu color scrollbar 0 #ffffffff #00000000
+
+label linux
+  menu label ^Install a new system or upgrade an existing system
+  menu default
+  kernel vmlinuz
+  append initrd=initrd.img
+label vesa
+  menu label Install system with ^basic video driver
+  kernel vmlinuz
+  append initrd=initrd.img xdriver=vesa nomodeset
+label rescue
+  menu label ^Rescue installed system
+  kernel vmlinuz
+  append initrd=initrd.img rescue
+label local
+  menu label Boot from ^local drive
+  localboot 0xffff
diff --git a/data/command-stubs/Makefile.am b/data/command-stubs/Makefile.am
new file mode 100644
index 0000000..cab5f89
--- /dev/null
+++ b/data/command-stubs/Makefile.am
@@ -0,0 +1,23 @@
+# command-stubs/Makefile.am for anaconda
+#
+# Copyright (C) 2009  Red Hat, Inc.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License as published
+# by the Free Software Foundation; either version 2.1 of the License, or
+# (at your option) any later version.
+#
+# 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 Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+#
+# Author: David Cantrell <dcantrell@xxxxxxxxxx>
+
+commandstubsdir           = $(datadir)/$(PACKAGE_NAME)
+dist_commandstubs_SCRIPTS = *-stub
+
+MAINTAINERCLEANFILES = Makefile.in
diff --git a/data/command-stubs/list-harddrives-stub b/data/command-stubs/list-harddrives-stub
new file mode 100755
index 0000000..2d9e225
--- /dev/null
+++ b/data/command-stubs/list-harddrives-stub
@@ -0,0 +1,45 @@
+#!/usr/bin/python
+#
+# scan system for harddrives and output device name/size
+#
+# Copyright (C) 2007, 2009  Red Hat, Inc.  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 as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# 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, see <http://www.gnu.org/licenses/>.
+#
+
+import sys
+import parted
+import _ped
+
+def main(argv):
+    lst = set()
+
+    for dev in filter(lambda d: d.type != parted.DEVICE_DM, parted.getAllDevices()):
+        try:
+            disk = parted.Disk(dev)
+        except _ped.DiskLabelException:
+            continue
+
+        for part in disk.partitions:
+            lst.add("%s %s" % (part.path, int(part.getSize())))
+
+        print("%s %s" % (dev.path, int(dev.getSize())))
+
+    lst = list(lst)
+    lst.sort()
+    for entry in lst:
+        print entry
+
+if __name__ == "__main__":
+    main(sys.argv)
diff --git a/data/command-stubs/loadkeys-stub b/data/command-stubs/loadkeys-stub
new file mode 100755
index 0000000..1fdc2c9
--- /dev/null
+++ b/data/command-stubs/loadkeys-stub
@@ -0,0 +1,41 @@
+#!/usr/bin/python
+#
+# loadkeys-stub
+#
+# Copyright (C) 2007  Red Hat, Inc.  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 as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# 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, see <http://www.gnu.org/licenses/>.
+#
+
+import os
+import sys
+
+from pyanaconda import isys
+
+def usage():
+    print "usage: %s keymap" %(sys.argv[0],)
+    sys.exit(1)
+
+def main():
+    if len(sys.argv) != 2:
+        usage()
+
+    try:
+        isys.loadKeymap(sys.argv[1])
+    except SystemError:
+        pass
+    sys.exit(0)
+
+if __name__ == "__main__":
+    main()
diff --git a/data/command-stubs/losetup-stub b/data/command-stubs/losetup-stub
new file mode 100755
index 0000000..27c6bbc
--- /dev/null
+++ b/data/command-stubs/losetup-stub
@@ -0,0 +1,50 @@
+#!/usr/bin/python
+#
+# losetup-stub
+#
+# Copyright (C) 2007  Red Hat, Inc.  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 as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# 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, see <http://www.gnu.org/licenses/>.
+#
+
+import os
+import sys
+
+from pyanaconda import isys
+from sys import argv
+
+def usage():
+    print "usage: losetup [-d] /dev/loopN [image]"
+    sys.exit(1)
+
+if len(argv) < 3:
+    usage()
+
+if argv[1] == "-d" and len(argv[2]) > 4 and argv[2][-5:-1] == "loop":
+    try:
+        isys.unlosetup(argv[2])
+    except SystemError, (errno, msg):
+        print msg
+        sys.exit (1)
+    sys.exit(0)
+
+if len(argv[1]) > 4 and argv[1][-5:-1] == "loop":
+    try:
+        isys.losetup(argv[1], argv[2])
+    except SystemError, (errno, msg):
+        print msg
+        sys.exit (1)
+    sys.exit(0)
+
+usage()
diff --git a/data/command-stubs/mknod-stub b/data/command-stubs/mknod-stub
new file mode 100755
index 0000000..cafc221
--- /dev/null
+++ b/data/command-stubs/mknod-stub
@@ -0,0 +1,54 @@
+#!/usr/bin/python
+#
+# mknod-stub
+#
+# Copyright (C) 2007  Red Hat, Inc.  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 as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# 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, see <http://www.gnu.org/licenses/>.
+#
+
+import stat, string, sys, os
+from pyanaconda import isys
+
+def usage():
+    sys.stderr.write("Usage: %s <path> [b|c] <major> <minor>\n" %(sys.argv[0],))
+    sys.exit(1)
+
+def main():
+    if len(sys.argv) < 2:
+        usage()
+
+    if (sys.argv[1] == '-h') or (sys.argv[1] == '--help'):
+        usage()
+
+    path = sys.argv[1]
+
+    if len(sys.argv) < 5:
+        usage()
+
+    if (sys.argv[2] == 'b'):
+        type = stat.S_IFBLK
+    elif (sys.argv[2] == 'c'):
+        type = stat.S_IFCHR
+    else:
+        usage()
+
+    major = int(sys.argv[3])
+    minor = int(sys.argv[4])
+    path = sys.argv[1]
+
+    os.mknod(path, 0644 | type, os.makedev(major, minor))
+
+if __name__ == "__main__":
+    main()
diff --git a/data/command-stubs/raidstart-stub b/data/command-stubs/raidstart-stub
new file mode 100755
index 0000000..6913006
--- /dev/null
+++ b/data/command-stubs/raidstart-stub
@@ -0,0 +1,44 @@
+#!/usr/bin/python
+#
+# raidstart-stub
+#
+# Copyright (C) 2007  Red Hat, Inc.  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 as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# 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, see <http://www.gnu.org/licenses/>.
+#
+
+import os
+import sys
+
+from pyanaconda import anaconda_log, fsset, raid, isys
+from sys import argv
+
+if len(argv) != 2 or argv[1][:7] != "/dev/md":
+    print "usage: raidstart /dev/md[minornum]"
+    sys.exit(1)
+
+targMinor = int(argv[1][7:])
+
+drives = isys.hardDriveDict().keys()
+drives.sort (isys.compareDrives)
+
+raidDevices = raid.scanForRaid(drives)
+for (minor, devices, level, totalDisks) in raidDevices:
+    if targMinor == minor:
+    	devName = "md%d" % (minor,)
+	isys.raidstart(devName, devices[0])
+	sys.exit(0)
+
+print "could not find devices associated with raid device md%d" % targMinor
+sys.exit(1)
diff --git a/data/command-stubs/raidstop-stub b/data/command-stubs/raidstop-stub
new file mode 100755
index 0000000..21f809d
--- /dev/null
+++ b/data/command-stubs/raidstop-stub
@@ -0,0 +1,31 @@
+#!/usr/bin/python
+#
+# raidstop-stub
+#
+# Copyright (C) 2007  Red Hat, Inc.  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 as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# 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, see <http://www.gnu.org/licenses/>.
+#
+
+import os
+import sys
+
+from pyanaconda import anaconda_log, fsset, raid, isys
+from sys import argv
+
+if len(argv) != 2 or argv[1][:7] != "/dev/md":
+    print "usage: raidstop /dev/md[minornum]"
+    sys.exit(1)
+
+isys.raidstop(argv[1][5:])
diff --git a/data/fonts/Makefile.am b/data/fonts/Makefile.am
new file mode 100644
index 0000000..5ad0197
--- /dev/null
+++ b/data/fonts/Makefile.am
@@ -0,0 +1,39 @@
+# fonts/Makefile.am for anaconda
+#
+# Copyright (C) 2009  Red Hat, Inc.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License as published
+# by the Free Software Foundation; either version 2.1 of the License, or
+# (at your option) any later version.
+#
+# 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 Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+#
+# Author: David Cantrell <dcantrell@xxxxxxxxxx>
+
+if IS_FONT_ARCH
+fontsdir        = $(datadir)/$(PACKAGE_NAME)
+dist_fonts_DATA = screenfont-$(ARCH).gz
+endif
+
+EXTRA_DIST = screenfont-*.gz updfonts
+
+MAINTAINERCLEANFILES = Makefile.in
+
+i386:
+	./updfonts i386
+
+alpha:
+	./updfonts alpha
+
+sparc:
+	./updfonts sparc
+
+ia64:
+	./updfonts ia64
diff --git a/data/fonts/screenfont-alpha.gz b/data/fonts/screenfont-alpha.gz
new file mode 100644
index 0000000000000000000000000000000000000000..b12001b59c1f93fdd4d3f292ae65fa240939f3cc
GIT binary patch
literal 4893
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
DhG(MS

literal 0
HcmV?d00001

diff --git a/data/fonts/screenfont-i386.gz b/data/fonts/screenfont-i386.gz
new file mode 100644
index 0000000000000000000000000000000000000000..fa88be123eab64806ef59a2ec1b77ce104daba3f
GIT binary patch
literal 5507
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
A3;+NC

literal 0
HcmV?d00001

diff --git a/data/fonts/screenfont-ia64.gz b/data/fonts/screenfont-ia64.gz
new file mode 100644
index 0000000000000000000000000000000000000000..ef0569c666a3794b79c061cee376723d65151167
GIT binary patch
literal 3821
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

literal 0
HcmV?d00001

diff --git a/data/fonts/screenfont-ppc.gz b/data/fonts/screenfont-ppc.gz
new file mode 100644
index 0000000000000000000000000000000000000000..036064c76d7ad03d81171cccb854c601822ca5e1
GIT binary patch
literal 5305
zcmd6q`9Bkm<HsH443$ucb<#0M<lK<EcaqAT7;?)^TgB#z3aQlOTqU`0a&JNuG0cWJ
z=6EyPFbf-Yeczw|;`?~K9<S$bub-a3yZ~upVxbq07z+tUJ&g4A4fP8PjaCZ}e<-k)
z2ZcE};=261r-Dax4mfm}9r|2)&Fk)=BTk3JZZs85D)h?vKA-d+j}ez&d*!|+^^89I
zVU<XjyqbHs?x1A%#a9d+`i34W6nT+kME<)s!RqITzzQ{?!v?JP22m?B0s@3Yn=^bh
zk&E$<R)$^<BYLCaRlgUM+Nfm3h)*-&o*u#G=Jw|1<}~og)tWlSV2V{(oaLj($!Blb
z<TXdY*4`CEf$mzmm1@cZ52flN3$(z@y<)6}dr-YU%_XV1oYsOE=-a2raO`ynHTqms
zeVy^qMdcgCT9>SFyj86YzVB%G$lv2<zhf=Vy@j1WIs|i7aPG|)ZQQ4-+-R!AUYiJ}
zlK(E1ohp<)ACR~62&F}-Iz5iZTlRbpc_wq`ypOr9X5sCUil%dal;)%DT>JrczVH5_
z@6SqWQ3{lUUbV%eW7pXUO0SOZypALOWOEZAqeW$%YVk{g%HO5-Ptu)#^*)$~c%}9X
zug3dvqcGdr3Ww7ScKkbN&FiorSFKRjw0jW+sjkSy+b_P#C-f!sUM|mT<SIxo1U}B!
zyRUs}E|gOTOB;S!c%&ahHFKjG@tNtLg>F3R)(;H6SewtYAv_I!5=qdj2^$@<tGyER
zC_8!B*g5uc5#G&fus(WO)TX;GItA3?p#5Zu-E?B@%Gt_^8jWA!+}5iEG~#k-ZDza8
z;Fx+fvrz9)c)N#QM<|N{Y`9ev_EDg^%0A^g*R*FphE&tq+Ip$%3EvyVEz2;vJ`<4{
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
Hf&%{s?sVel

literal 0
HcmV?d00001

diff --git a/data/fonts/screenfont-sparc.gz b/data/fonts/screenfont-sparc.gz
new file mode 100644
index 0000000000000000000000000000000000000000..0c38d3bd735cd8eb2999039a4717de870972dc12
GIT binary patch
literal 6455
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
D+cO$&

literal 0
HcmV?d00001

diff --git a/data/fonts/screenfont-x86_64.gz b/data/fonts/screenfont-x86_64.gz
new file mode 100644
index 0000000000000000000000000000000000000000..fcaee505742edca8d8a8bb1c59797e27226b12c6
GIT binary patch
literal 5473
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
Xy~X4eT!mU+;ov5Qb)m~ov9tXTd=@bZ

literal 0
HcmV?d00001

diff --git a/data/fonts/updfonts b/data/fonts/updfonts
new file mode 100755
index 0000000..10b74c1
--- /dev/null
+++ b/data/fonts/updfonts
@@ -0,0 +1,11 @@
+#!/bin/sh
+
+ARCH=$1
+if [ -z "$ARCH" ]; then
+    echo "usage: $0 <arch>"
+    exit 1
+fi
+
+setfont latarcyrheb-sun16
+../utils/snarffont > screenfont-$ARCH
+gzip -9 -f screenfont-$ARCH
diff --git a/data/icons/Makefile.am b/data/icons/Makefile.am
new file mode 100644
index 0000000..0fdcec3
--- /dev/null
+++ b/data/icons/Makefile.am
@@ -0,0 +1,22 @@
+# icons/Makefile.am for anaconda
+#
+# Copyright (C) 2010  Red Hat, Inc.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License as published
+# by the Free Software Foundation; either version 2.1 of the License, or
+# (at your option) any later version.
+#
+# 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 Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+#
+# Author: David Cantrell <dcantrell@xxxxxxxxxx>
+
+SUBDIRS = hicolor
+
+MAINTAINERCLEANFILES = Makefile.in
diff --git a/data/icons/hicolor/16x16/Makefile.am b/data/icons/hicolor/16x16/Makefile.am
new file mode 100644
index 0000000..ab8a795
--- /dev/null
+++ b/data/icons/hicolor/16x16/Makefile.am
@@ -0,0 +1,22 @@
+# icons/hicolor/16x16/Makefile.am for anaconda
+#
+# Copyright (C) 2010  Red Hat, Inc.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License as published
+# by the Free Software Foundation; either version 2.1 of the License, or
+# (at your option) any later version.
+#
+# 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 Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+#
+# Author: David Cantrell <dcantrell@xxxxxxxxxx>
+
+SUBDIRS = apps
+
+MAINTAINERCLEANFILES = Makefile.in
diff --git a/data/icons/hicolor/16x16/apps/Makefile.am b/data/icons/hicolor/16x16/apps/Makefile.am
new file mode 100644
index 0000000..6b600a4
--- /dev/null
+++ b/data/icons/hicolor/16x16/apps/Makefile.am
@@ -0,0 +1,23 @@
+# icons/hicolor/16x16/apps/Makefile.am for anaconda
+#
+# Copyright (C) 2010  Red Hat, Inc.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License as published
+# by the Free Software Foundation; either version 2.1 of the License, or
+# (at your option) any later version.
+#
+# 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 Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+#
+# Author: David Cantrell <dcantrell@xxxxxxxxxx>
+
+iconsdir        = $(datadir)/icons/hicolor/16x16/apps
+dist_icons_DATA = anaconda.png
+
+MAINTAINERCLEANFILES = Makefile.in
diff --git a/data/icons/hicolor/16x16/apps/anaconda.png b/data/icons/hicolor/16x16/apps/anaconda.png
new file mode 100644
index 0000000000000000000000000000000000000000..c58fae5b8fb5958853d2d53a33d5af95edfc2bf3
GIT binary patch
literal 925
zcmV;O17iG%P)<h;3K|Lk000e1NJLTq000mG000mO1^@s6AM^iV00004b3#c}2nYxW
zd<bNS00009a7bBm000fw000fw0YWI7cmMzZ8FWQhbW?9;ba!ELWdL_~cP?peYja~^
zaAhuUa%Y?FJQ@H101$LVSaeirbZlh+NMUkhAVhL$c4etgw=w_#02FjZSad;kbZBpK
z07_wNbz&e>bY*F7Wpd{G_b&hd03&ooSaefwb#h~60BCe{a5^t9bYX61Z!TtXWo2Y#
zb8B>Oa4v6hXMM7arvLx~uSrBfR5*=|ld*4GRTPK6`|dT*#O5`5PC^pbNNJO_baDj}
zGZNCX7#NV~LR2Bqfwe>V3z)i81tGN*rCnIssjVsus@PDZ{sAOusDd5zlteOlaqfGu
z{c`VRpt2jL{-iUVb3T1%I3kK70GiF_=jQn@pY-oFE{WnP5FRJuEUtHe|3&k@T#6nw
z8jYU-L=;6_yLR=Xf?xQ4>FmN%;n7$46BSAyUIjY<=fIPszulmh?4zS^`Tg0mr2EhQ
zXAd7fdFlaJVQ<#!@3-HcsjZhTKOouNCtmpy+CM|<3GvDmIy(tRAKxO)a%LuH#=Dum
z37}pIUI@y8h~sz#xb9!NL+9>g{`&PX0NRGw=o^mW9gdHW3BwARPA>qwdT1%n^NYq9
zlCEawgReO-<7D0x>eKIVLNYe?CIFu2k!2aL8UTzLW8Pa^|ATNM<m|$E?3ugddCp)k
zz}lS6%}r)!t4Jx)I%Q~(rWt_x^Tp=k<m41nQ`1N(nVz1eTCL*yJ^<qrA&2@9rPR>i
zB_PE)S4g!M<x-hE&)MDGWqW&@t*tFutrpf=%B2!<{5Mic27|%qgj8z)b-H%?L^F<K
zgb)NlfH8(3IK}Mj98yYz5F>#8&p^FVC^9!UN0KCTyWQcS@B4&dh?J7Oy*-ptCjqHW
zan8wpzt7s*8r5o*TCGO0Sj1XOnx=F*9op?SN-305c%C-`^m;v<b8KvEu(-HLyWK_z
zfpZQiCBE;Yl%i6pu)4ZRy<W#!I|B531GLsGFE3+^K?s2m0&6YKxnUV&n4h0VDMg;=
zBfz0P+`04P?U{4u-lf%Qk);_rOUaIU2qAc@TxNVCBuNt1H=eU_W*+P8i{Uc`!B_)N
z`~afHYs6aHlES-kaG;+mfNnQy0`I)e^8fQMOcy_BH0|Ys00000NkvXXu0mjfn&+U)

literal 0
HcmV?d00001

diff --git a/data/icons/hicolor/22x22/Makefile.am b/data/icons/hicolor/22x22/Makefile.am
new file mode 100644
index 0000000..3b94dde
--- /dev/null
+++ b/data/icons/hicolor/22x22/Makefile.am
@@ -0,0 +1,22 @@
+# icons/hicolor/22x22/Makefile.am for anaconda
+#
+# Copyright (C) 2010  Red Hat, Inc.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License as published
+# by the Free Software Foundation; either version 2.1 of the License, or
+# (at your option) any later version.
+#
+# 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 Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+#
+# Author: David Cantrell <dcantrell@xxxxxxxxxx>
+
+SUBDIRS = apps
+
+MAINTAINERCLEANFILES = Makefile.in
diff --git a/data/icons/hicolor/22x22/apps/Makefile.am b/data/icons/hicolor/22x22/apps/Makefile.am
new file mode 100644
index 0000000..d189b10
--- /dev/null
+++ b/data/icons/hicolor/22x22/apps/Makefile.am
@@ -0,0 +1,23 @@
+# icons/hicolor/22x22/apps/Makefile.am for anaconda
+#
+# Copyright (C) 2010  Red Hat, Inc.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License as published
+# by the Free Software Foundation; either version 2.1 of the License, or
+# (at your option) any later version.
+#
+# 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 Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+#
+# Author: David Cantrell <dcantrell@xxxxxxxxxx>
+
+iconsdir        = $(datadir)/icons/hicolor/22x22/apps
+dist_icons_DATA = anaconda.png
+
+MAINTAINERCLEANFILES = Makefile.in
diff --git a/data/icons/hicolor/22x22/apps/anaconda.png b/data/icons/hicolor/22x22/apps/anaconda.png
new file mode 100644
index 0000000000000000000000000000000000000000..062eb7687b7d4f58f4a6348413e021910fd41b30
GIT binary patch
literal 1326
zcmV+}1=0G6P)<h;3K|Lk000e1NJLTq000&M000&U1^@s6#I$TX00004b3#c}2nYxW
zd<bNS00009a7bBm000fw000fw0YWI7cmMzZ8FWQhbW?9;ba!ELWdL_~cP?peYja~^
zaAhuUa%Y?FJQ@H101$LVSaeirbZlh+NMUkhAVhL$c4etgw=w_#02FjZSad;kbZBpK
z07_wNbz&e>bY*F7Wpd{G_b&hd03&ooSaefwb#h~60BCe{a5^t9bYX61Z!TtXWo2Y#
zb8B>Oa4v6hXMM7arvLy1KuJVFR5*>bl}%_|RTRg6_r8yL^Jd<>WRiJNORY^4i`7I+
zied>AO6|}utczd~KdRV8-3Wq^jZj1|%erwR2t{3pA_}^A65Lcl?83TG+O&)GD{V4P
zCX-Cwo5_9eT^DJFf)zyUfwQ<D=YRj_f6l#ERI63)g~@w@3Yh=2@YSyAZ_)Y?R{riA
zRD_W7%jeGRoA_72larGsU@lMp_O4Wm<Gs(mS2DNm5oBwC24S)`6YAzSr<U4gWomNr
zm;(<bQ&UsPoj77c<1h@x_tW3KvDj#y?(gdph9MEnYXsA88^OpJ<;R}}ol^hxM;8A0
zol8%?lXi0bXq~a#TuGfm?!aefKL6owj3*{0tW@jw_wLzeMp1<8y0qKdi5~cx8=t;R
zv=X7Urhat}b@U7a`CdaxNxfbtpDP;mM(u+z3`eWgs)pOe3&T)6b71d&ujt#IP6x+v
zNYfOpHNp!>CqAZjqfYHslScJ4iyc9;*`(2EAf?3fN<?w|@TpUiTQ`VqbcM7G>-C|*
zVLOgvY}+QwGL%v%r4WT)a<6`Y@xmwg!6y3p`tW@p&-3W*?ZvVzHgDQu2*WuZhN0*J
zkByDxq%^AK-m;KVa&cycBuU8Sa(JGHUn*hSHu-!W+qN+b11Tk1Yvyj=BuP_tJhH>k
zS@zlnrVPVS965Sq|D!ub%rs5;`ImD9l?rK^qLd;@5`5pMQmGIG0i{xjPNzebWoWJG
z@qOmzZqn1!L(X=B6DN+3gkdO5K;|s_<j}Su^U~$ZY<X}qNs=Ih03gdU&YwSz@B3)2
zSz216SS*rdS=aBsZ-5IIXLw@gPV4&h8z+I2a&&amQHk2)c^<2+RhrG^uC^PDgCM{(
zO-$3o_x<jHS(X8CYoW&C;vz%ahKS?%c|e-Gcke#5eR#VW$1#>=G7wZ47#Lu6b(L1D
zMUo`lw9_>0x)6eLxxCI^YbyQyxUNgFSS%bqe0bc<=ksrljqNh#=jTyMA*Ez?c9vqX
zNDu@FA&^ocgg|RemSv=AN|t5RYBlEP=jrX~!7vPzQjCv}n^6?KWj30Pr><PNg4UWs
zq0kLpSy^FaWd)!+cPDEh1eRrC+jiGyXJ;vw%d}dp{btmPvf<%jqf)7mWf?+<ZsCLw
zU4~lgb>Q3MPP@%gvq=<1EH)a%aZKE9bM@MFlu|j<^NPAuD)G`QFXB1{Ov~){ss@rI
zK_v+Vw}9g~6pBR(1(*6_g9{ffuu%JxBuPlK^{h<OWO&PFOd+H^`_ow}{Q)D7jo`X2
zN+}j<3n-<C+ig^m;5rU&(Zh9J+<YDo3=R%r+c}anL1*ioA`O9*G7$$49{k9*?PGvp
z7>3-CL9dGopwl$fhGF11j<77NTc|aqbR5TMtv3Pyk|>Hk6hI#E0OxKG_J6Q7U|9g-
k_Wc(B6R-xfxL2R)UmimdRwD1#!~g&Q07*qoM6N<$f{ycQ(f|Me

literal 0
HcmV?d00001

diff --git a/data/icons/hicolor/24x24/Makefile.am b/data/icons/hicolor/24x24/Makefile.am
new file mode 100644
index 0000000..c4a4745
--- /dev/null
+++ b/data/icons/hicolor/24x24/Makefile.am
@@ -0,0 +1,22 @@
+# icons/hicolor/24x24/Makefile.am for anaconda
+#
+# Copyright (C) 2010  Red Hat, Inc.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License as published
+# by the Free Software Foundation; either version 2.1 of the License, or
+# (at your option) any later version.
+#
+# 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 Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+#
+# Author: David Cantrell <dcantrell@xxxxxxxxxx>
+
+SUBDIRS = apps
+
+MAINTAINERCLEANFILES = Makefile.in
diff --git a/data/icons/hicolor/24x24/apps/Makefile.am b/data/icons/hicolor/24x24/apps/Makefile.am
new file mode 100644
index 0000000..2e1f206
--- /dev/null
+++ b/data/icons/hicolor/24x24/apps/Makefile.am
@@ -0,0 +1,23 @@
+# icons/hicolor/24x24/apps/Makefile.am for anaconda
+#
+# Copyright (C) 2010  Red Hat, Inc.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License as published
+# by the Free Software Foundation; either version 2.1 of the License, or
+# (at your option) any later version.
+#
+# 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 Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+#
+# Author: David Cantrell <dcantrell@xxxxxxxxxx>
+
+iconsdir        = $(datadir)/icons/hicolor/24x24/apps
+dist_icons_DATA = anaconda.png
+
+MAINTAINERCLEANFILES = Makefile.in
diff --git a/data/icons/hicolor/24x24/apps/anaconda.png b/data/icons/hicolor/24x24/apps/anaconda.png
new file mode 100644
index 0000000000000000000000000000000000000000..e69f822ffa25a4d13a53b01874e235a6ae83b6d9
GIT binary patch
literal 1368
zcmV-e1*iInP)<h;3K|Lk000e1NJLTq000;O000;W1^@s6;CDUv00004b3#c}2nYxW
zd<bNS00009a7bBm000fw000fw0YWI7cmMzZ8FWQhbW?9;ba!ELWdL_~cP?peYja~^
zaAhuUa%Y?FJQ@H101$LVSaeirbZlh+NMUkhAVhL$c4etgw=w_#02FjZSad;kbZBpK
z07_wNbz&e>bY*F7Wpd{G_b&hd03&ooSaefwb#h~60BCe{a5^t9bYX61Z!TtXWo2Y#
zb8B>Oa4v6hXMM7arvLy1YDq*vR7i=vl}n6NMHGg=s$2Kj-P7H44?WN@A|qyah%Xd1
zvvM;eKnxp#iBTsIBqqj$s2dXFj*T0m3l^@x#ApnzjCA6LC?v{)urZ7igD||Lr@Lo{
z?&+R;>sGm#2gC;p0-ofg7FG5C=bZmk9WgpO%EL7IP|^Pn0(Gy=lh6Hd3~OJ#*BK$4
z@AsU0dEb2z%*~}=S;u?5xcB40scsWsu>jVRUO&&wH}B7r^uD-f0Dl+x@CWbiPLkxf
z=X!wv;kPEl%F`cum6t}zZ`cY})A{2f*H3@P?@t|0=2mPp#uyvNaTjBEpE&X5ng7h7
zR;xLO-+SlSmf@`hDIFZgLF-M-uieDu<F8SfnMV0OSARZ3Z|7$eN{_iE$6;z}3dvk>
zyFLARtybGKIy!2XFy&p~;@GiIpLSh;MG%B2wZLtyCGD$X_Z{cvuNRp-_Y2cIK4Dt*
zGd(>`v)ROP914XZ-EMdN(W4&?-5vDZT_j!K-#@healg~)5JeHL=Ml#-I!)0*5jl1e
z^TxMCt2R(97AX`8WV2cN`}=WSmuhv;Nv#~K)oS8j351Y)D=RC)bzLrwkJD<l2*Z%R
zT#izyM3~7D<?@7Ki0isIj)M?_%U7;ot!3lzMn@-l>~37SRGuS8j%;7|$fJEyN`5+f
zmX-bec%F;a8m%?CT#j<N%<9#vDV0hjNrJT&Yc0h>ft!EcBA+i11Y!B$!LcWovRD#X
zX0qXd&6~HVYuBzbP^pk42||cv9WGqBK)GB7pw()jl)`ZwthE?p7^tjd{I?07eP)|`
zb@JLF;1FOJQrV27b-HIoaRsebi`(rsNs=tP)|yJCf|L>=1lepBr4+^(j4=Q-nk}wO
zPBJt!M7P)7yHp)ntJTDT7Y~dK3=BkRnqo}Ks!D}{fdPUbAWhR{k|arp<CukWhBQqH
z!;rzjK{A<$%^QdDeV=?^KH9Zw*GR2a6AF--O!W5l=U-6udL6AbQc5mex<s*9q*|?F
zj6n#2)*53Bj^kjAK}t!h)uPd8P%f2FN|7W9BO@d3?Ck7e;70|>cBiwe*=#a7IY~aB
zM@os5l6t*Py<T6|Vd-u3dOft(0C=8<=XoflP)ac|F+mhXbUK|KfTM<ohx=w{X4RUt
zYZzQRh?I9acS&Sp%yRU`7*b<MwPt>Po_4#<T(?WN*P}T-LuxEjQw`!ccB<8CP6;8h
zK@gb!a@iT%|0aPKpj;Qv^^nd2S-MCNgdx5kkj+G7vN;-!1{cT2xmBMcNfL~)q-lzf
zlHv91@O?j{;y5-+DS7_<c?yLBPi)yr6h^e$Z5qu6iPofA6Kjp{`9x7fl+6$YAtp^1
zvUVJjIKfzpH5P<GDaDN&H;e$HojZ4)h@$8fYpqzQ%<@ae+U0)>*L7_slOYHKlv2cT
zOt06Y-EJ?p>*5{T>2$t6b?Vex0&oByC@!vd(C^<8pb7L?oCk7|NIgK8fcVG2dC>OI
ahyGuJ!1PR%sa<pc0000<MNUMnLSTYvNN;=q

literal 0
HcmV?d00001

diff --git a/data/icons/hicolor/32x32/Makefile.am b/data/icons/hicolor/32x32/Makefile.am
new file mode 100644
index 0000000..0dee034
--- /dev/null
+++ b/data/icons/hicolor/32x32/Makefile.am
@@ -0,0 +1,22 @@
+# icons/hicolor/32x32/Makefile.am for anaconda
+#
+# Copyright (C) 2010  Red Hat, Inc.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License as published
+# by the Free Software Foundation; either version 2.1 of the License, or
+# (at your option) any later version.
+#
+# 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 Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+#
+# Author: David Cantrell <dcantrell@xxxxxxxxxx>
+
+SUBDIRS = apps
+
+MAINTAINERCLEANFILES = Makefile.in
diff --git a/data/icons/hicolor/32x32/apps/Makefile.am b/data/icons/hicolor/32x32/apps/Makefile.am
new file mode 100644
index 0000000..378201b
--- /dev/null
+++ b/data/icons/hicolor/32x32/apps/Makefile.am
@@ -0,0 +1,23 @@
+# icons/hicolor/32x32/apps/Makefile.am for anaconda
+#
+# Copyright (C) 2010  Red Hat, Inc.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License as published
+# by the Free Software Foundation; either version 2.1 of the License, or
+# (at your option) any later version.
+#
+# 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 Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+#
+# Author: David Cantrell <dcantrell@xxxxxxxxxx>
+
+iconsdir        = $(datadir)/icons/hicolor/32x32/apps
+dist_icons_DATA = anaconda.png
+
+MAINTAINERCLEANFILES = Makefile.in
diff --git a/data/icons/hicolor/32x32/apps/anaconda.png b/data/icons/hicolor/32x32/apps/anaconda.png
new file mode 100644
index 0000000000000000000000000000000000000000..51bbdc74f968ac0d26c0c9a2bc7dd4302fa0cd0c
GIT binary patch
literal 1860
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

literal 0
HcmV?d00001

diff --git a/data/icons/hicolor/48x48/Makefile.am b/data/icons/hicolor/48x48/Makefile.am
new file mode 100644
index 0000000..9d23a6e
--- /dev/null
+++ b/data/icons/hicolor/48x48/Makefile.am
@@ -0,0 +1,22 @@
+# icons/hicolor/48x48/Makefile.am for anaconda
+#
+# Copyright (C) 2010  Red Hat, Inc.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License as published
+# by the Free Software Foundation; either version 2.1 of the License, or
+# (at your option) any later version.
+#
+# 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 Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+#
+# Author: David Cantrell <dcantrell@xxxxxxxxxx>
+
+SUBDIRS = apps
+
+MAINTAINERCLEANFILES = Makefile.in
diff --git a/data/icons/hicolor/48x48/apps/Makefile.am b/data/icons/hicolor/48x48/apps/Makefile.am
new file mode 100644
index 0000000..3cf250f
--- /dev/null
+++ b/data/icons/hicolor/48x48/apps/Makefile.am
@@ -0,0 +1,23 @@
+# icons/hicolor/48x48/apps/Makefile.am for anaconda
+#
+# Copyright (C) 2010  Red Hat, Inc.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License as published
+# by the Free Software Foundation; either version 2.1 of the License, or
+# (at your option) any later version.
+#
+# 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 Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+#
+# Author: David Cantrell <dcantrell@xxxxxxxxxx>
+
+iconsdir        = $(datadir)/icons/hicolor/48x48/apps
+dist_icons_DATA = anaconda.png
+
+MAINTAINERCLEANFILES = Makefile.in
diff --git a/data/icons/hicolor/48x48/apps/anaconda.png b/data/icons/hicolor/48x48/apps/anaconda.png
new file mode 100644
index 0000000000000000000000000000000000000000..c633dd38c8be549c6529b0275fb6c4301bc24e78
GIT binary patch
literal 3020
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
O0000<MNUMnLSTYxaNte=

literal 0
HcmV?d00001

diff --git a/data/icons/hicolor/Makefile.am b/data/icons/hicolor/Makefile.am
new file mode 100644
index 0000000..97e9d5f
--- /dev/null
+++ b/data/icons/hicolor/Makefile.am
@@ -0,0 +1,22 @@
+# icons/hicolor/Makefile.am for anaconda
+#
+# Copyright (C) 2010  Red Hat, Inc.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License as published
+# by the Free Software Foundation; either version 2.1 of the License, or
+# (at your option) any later version.
+#
+# 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 Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+#
+# Author: David Cantrell <dcantrell@xxxxxxxxxx>
+
+SUBDIRS = 16x16 22x22 24x24 32x32 48x48
+
+MAINTAINERCLEANFILES = Makefile.in
diff --git a/data/lang-table b/data/lang-table
new file mode 100644
index 0000000..2378b8d
--- /dev/null
+++ b/data/lang-table
@@ -0,0 +1,61 @@
+Afrikaans	af	latarcyrheb-sun16	af_ZA.UTF-8	us	Africa/Johannesburg
+Arabic	ar	none	ar_SA.UTF-8	us	Asia/Riyadh
+Assamese	as	none	as_IN.UTF-8	us	Asia/Kolkata
+Bengali	bn	none	bn_BD.UTF-8	us	Asia/Dhaka
+Bengali(India)	bn	none	bn_IN.UTF-8	us	Asia/Kolkata
+Bulgarian	bg	latarcyrheb-sun16	bg_BG.UTF-8	bg_bds-utf8	Europe/Sofia
+Catalan	ca	latarcyrheb-sun16	ca_ES.UTF-8	es	Europe/Madrid
+Chinese(Simplified)	zh_CN	none	zh_CN.UTF-8	us	Asia/Shanghai
+Chinese(Traditional)	zh_TW	none	zh_TW.UTF-8	us	Asia/Taipei
+Croatian	hr	latarcyrheb-sun16	hr_HR.UTF-8	croat	Europe/Zagreb
+Czech	cs	latarcyrheb-sun16	cs_CZ.UTF-8	cz-lat2	Europe/Prague
+Danish	da	latarcyrheb-sun16	da_DK.UTF-8	dk	Europe/Copenhagen
+Dutch	nl	latarcyrheb-sun16	nl_NL.UTF-8	nl	Europe/Amsterdam
+English	en	latarcyrheb-sun16	en_US.UTF-8	us	America/New_York
+Estonian	et	latarcyrheb-sun16	et_EE.UTF-8	et	Europe/Tallinn
+Finnish	fi	latarcyrheb-sun16	fi_FI.UTF-8	fi	Europe/Helsinki
+French	fr	latarcyrheb-sun16	fr_FR.UTF-8	fr-latin9	Europe/Paris
+German	de	latarcyrheb-sun16	de_DE.UTF-8	de-latin1-nodeadkeys	Europe/Berlin
+Greek	el	iso07u-16	el_GR.UTF-8	gr	Europe/Athens
+Gujarati	gu	none	gu_IN.UTF-8	us	Asia/Kolkata
+Hebrew	he	none	he_IL.UTF-8	us	Asia/Jerusalem
+Hindi	hi	none	hi_IN.UTF-8	us	Asia/Kolkata
+Hungarian	hu	latarcyrheb-sun16	hu_HU.UTF-8	hu	Europe/Budapest
+Icelandic	is	latarcyrheb-sun16	is_IS.UTF-8	is-latin1	Atlantic/Reykjavik
+Iloko	ilo	latarcyrheb-sun16	ilo_PH.UTF-8	us	Asia/Manila
+Indonesian	id	latarcyrheb-sun16	id_ID.UTF-8	us	Asia/Jakarta
+Italian	it	latarcyrheb-sun16	it_IT.UTF-8	it	Europe/Rome
+Japanese	ja	none	ja_JP.UTF-8	jp106	Asia/Tokyo	
+Kannada	kn	none	kn_IN.UTF-8	us	Asia/Kolkata
+Korean	ko	none	ko_KR.UTF-8	us	Asia/Seoul	
+Macedonian	mk	latarcyrheb-sun16	mk_MK.UTF-8	mk	Europe/Skopje
+Maithili	mai	none	mai_IN.UTF-8	us	Asia/Kolkata
+Malay	ms	latarcyrheb-sun16	ms_MY.UTF-8	us	Asia/Kuala_Lumpur
+Malayalam	ml	none	ml_IN.UTF-8	us	Asia/Kolkata
+Marathi	mr	none	mr_IN.UTF-8	us	Asia/Kolkata
+Nepali	ne	none	ne_NP.UTF-8	us	Asia/Kathmandu
+Norwegian(Bokmål)	nb	latarcyrheb-sun16	nb_NO.UTF-8	no	Europe/Oslo
+Northern Sotho	nso	latarcyrheb-sun16	nso_ZA.UTF-8	us	Africa/Johannesburg
+Oriya	or	none	or_IN.UTF-8	us	Asia/Kolkata
+Persian	fa	none	fa_IR.UTF-8	us	Asia/Tehran
+Polish	pl	latarcyrheb-sun16	pl_PL.UTF-8	pl2	Europe/Warsaw
+Portuguese	pt	latarcyrheb-sun16	pt_PT.UTF-8	pt-latin1	Europe/Lisbon
+Portuguese(Brazilian)	pt_BR	latarcyrheb-sun16	pt_BR.UTF-8	br-abnt2	America/Sao_Paulo
+Punjabi	pa	none	pa_IN.UTF-8	us	Asia/Kolkata
+Romanian	ro	Lat2-Terminus16	ro_RO.UTF-8	ro	Europe/Bucharest
+Russian	ru	none	ru_RU.UTF-8	ru	Europe/Moscow
+Serbian	sr	latarcyrheb-sun16	sr_RS.UTF-8	sr-cy	Europe/Belgrade
+Serbian(Latin)	sr@latin	latarcyrheb-sun16	sr_RS.UTF-8@latin	sr-latin	Europe/Belgrade
+Sinhala	si	none	si_LK.UTF-8	us	Asia/Colombo
+Slovak	sk	latarcyrheb-sun16	sk_SK.UTF-8	sk-qwerty	Europe/Bratislava
+Slovenian	sl	latarcyrheb-sun16	sl_SI.UTF-8	slovene	Europe/Ljubljana
+Spanish	es	latarcyrheb-sun16	es_ES.UTF-8	es	Europe/Madrid
+Swedish	sv	latarcyrheb-sun16	sv_SE.UTF-8	sv-latin1	Europe/Stockholm
+Tajik	tg	none	tg_TG.UTF-8	tj	Asia/Dushanbe
+Tamil	ta	none	ta_IN.UTF-8	us	Asia/Kolkata
+Telugu	te	none	te_IN.UTF-8	us	Asia/Kolkata
+Turkish	tr	latarcyrheb-sun16	tr_TR.UTF-8	trq	Europe/Istanbul
+Ukrainian	uk	latarcyrheb-sun16	uk_UA.UTF-8	ua-utf	Europe/Kiev
+Vietnamese	vi	latarcyrheb-sun16	vi_VN.UTF-8	us	Asia/Saigon
+Welsh	cy	latarcyrheb-sun16	cy_GB.UTF-8	uk	Europe/London
+Zulu	zu	latarcyrheb-sun16	zu_ZA.UTF-8	us	Africa/Johannesburg
diff --git a/data/liveinst/.gitignore b/data/liveinst/.gitignore
new file mode 100644
index 0000000..48d183f
--- /dev/null
+++ b/data/liveinst/.gitignore
@@ -0,0 +1 @@
+liveinst.desktop
diff --git a/data/liveinst/Makefile.am b/data/liveinst/Makefile.am
new file mode 100644
index 0000000..2f51dfa
--- /dev/null
+++ b/data/liveinst/Makefile.am
@@ -0,0 +1,56 @@
+# liveinst/Makefile.am for anaconda
+#
+# Copyright (C) 2009  Red Hat, Inc.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License as published
+# by the Free Software Foundation; either version 2.1 of the License, or
+# (at your option) any later version.
+#
+# 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 Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+#
+# Author: David Cantrell <dcantrell@xxxxxxxxxx>
+
+SUBDIRS = console.apps pam.d
+
+if IS_LIVEINST_ARCH
+dist_sbin_SCRIPTS  = liveinst
+
+desktopdir         = $(datadir)/applications
+desktop_DATA       = liveinst.desktop
+
+xinitdir           = /etc/X11/xinit/xinitrc.d
+dist_xinit_SCRIPTS = zz-liveinst.sh
+endif
+
+EXTRA_DIST = README liveinst.desktop.in
+
+CLEANFILES = liveinst.desktop *.h
+
+MAINTAINERCLEANFILES = Makefile.in
+
+intltool_merge_verbose = $(intltool_merge_verbose_$(V))
+intltool_merge_verbose_ = $(intltool_merge_verbose_$(AM_DEFAULT_VERBOSITY))
+intltool_merge_verbose_0 = @echo "  MERGE  "$@;
+
+liveinst.desktop: liveinst.desktop.in
+	$(intltool_merge_verbose)LC_ALL=C intltool-merge -q -d -u $(top_srcdir)/po liveinst.desktop.in liveinst.desktop
+
+install-exec-local:
+	mkdir -p $(DESTDIR)$(bindir)
+	ln -s consolehelper $(DESTDIR)$(bindir)/liveinst
+
+uninstall-local:
+	rm -f $(DESTDIR)$(bindir)/liveinst
+	for d in $(DESTDIR)$(bindir) ; do
+		while [ ! -z "$$d" ]; do \
+			rmdir $$d 2>/dev/null ; \
+			d="`dirname $$d`" ; \
+		done ; \
+	done
diff --git a/data/liveinst/README b/data/liveinst/README
new file mode 100644
index 0000000..afa64e0
--- /dev/null
+++ b/data/liveinst/README
@@ -0,0 +1 @@
+Simple wrapper around anaconda to kick off an install from a live CD
diff --git a/data/liveinst/console.apps/Makefile.am b/data/liveinst/console.apps/Makefile.am
new file mode 100644
index 0000000..f153902
--- /dev/null
+++ b/data/liveinst/console.apps/Makefile.am
@@ -0,0 +1,26 @@
+# liveinst/console.apps/Makefile.am for anaconda
+#
+# Copyright (C) 2009  Red Hat, Inc.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License as published
+# by the Free Software Foundation; either version 2.1 of the License, or
+# (at your option) any later version.
+#
+# 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 Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+#
+# Author: David Cantrell <dcantrell@xxxxxxxxxx>
+
+if IS_LIVEINST_ARCH
+consoledir        = /etc/security/console.apps
+dist_console_DATA = liveinst
+endif
+
+CLEANFILES = *.h
+MAINTAINERCLEANFILES = Makefile.in
diff --git a/data/liveinst/console.apps/liveinst b/data/liveinst/console.apps/liveinst
new file mode 100644
index 0000000..7c31081
--- /dev/null
+++ b/data/liveinst/console.apps/liveinst
@@ -0,0 +1,6 @@
+USER=root
+PROGRAM=/usr/sbin/liveinst
+SESSION=true
+# has to be here otherwise consolehelper switches off the waiting cursor too early
+STARTUP_NOTIFICATION_NAME="Starting Install to Hard Drive"
+DOMAIN=anaconda
\ No newline at end of file
diff --git a/data/liveinst/liveinst b/data/liveinst/liveinst
new file mode 100755
index 0000000..95bd35f
--- /dev/null
+++ b/data/liveinst/liveinst
@@ -0,0 +1,95 @@
+#!/bin/sh
+#
+# Simple script to kick off an install from a live CD
+#
+# Copyright (C) 2007  Red Hat, Inc.  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 as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# 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, see <http://www.gnu.org/licenses/>.
+#
+
+if [ -z "$LIVE_BLOCK" ]; then
+    if [ -b "/dev/mapper/live-osimg-min" ]; then
+       LIVE_BLOCK="/dev/mapper/live-osimg-min"
+    else
+       LIVE_BLOCK="/dev/live-osimg"
+    fi
+fi
+
+if [ ! -b $LIVE_BLOCK ]; then
+  zenity --error --title="Not a Live image" --text "Can't do live image installation unless running from a live image"
+  exit 1
+fi
+
+# load modules that would get loaded by the loader... (#230945)
+for i in raid0 raid1 raid5 raid6 raid456 raid10 dm-mod dm-zero dm-mirror dm-snapshot dm-multipath dm-round-robin vfat dm-crypt cbc sha256 lrw xts ; do /sbin/modprobe $i 2>/dev/null ; done
+
+export ANACONDA_PRODUCTNAME=$( cat /etc/system-release | sed -r -e 's/ *release.*//' )
+export ANACONDA_PRODUCTVERSION=$( cat /etc/system-release | sed -r -e 's/^.* ([0-9\.]+).*$/\1/' )
+export ANACONDA_BUGURL=${ANACONDA_BUGURL:="https://bugzilla.redhat.com/bugzilla/"}
+
+export PATH=/sbin:/usr/sbin:$PATH
+
+if [ -n "$DISPLAY" -a -n "$LANG" ]; then
+    INSTLANG="--lang $LANG"
+fi
+
+# eventually, we might want to allow a more "normal" install path
+ANACONDA="/usr/sbin/anaconda --liveinst --method=livecd://$LIVE_BLOCK $INSTLANG"
+
+if [ -x /usr/sbin/setenforce -a -e /selinux/enforce ]; then
+    current=$(cat /selinux/enforce)
+    /usr/sbin/setenforce 0
+fi
+
+if [ ! -e /selinux/load ]; then
+    ANACONDA="$ANACONDA --noselinux"
+fi
+
+# devkit-disks is now mounting lots of stuff.  for now, let's just try to unmount it all
+umount /media/*
+tac /proc/mounts | grep ^/dev | grep -v live | while read dev mntpoint rest; do
+    if [ -b $dev ]; then
+       umount $mntpoint 2>/dev/null
+    fi
+done
+
+/sbin/swapoff -a
+/sbin/lvm vgchange -an --ignorelockingfailure
+for i in /dev/md*; do
+    if [ ! -b $i ]; then
+        continue
+    fi
+
+    case "$i" in
+        /dev/md*p*)
+            ;;
+        *)
+            mdadm --stop $i >/dev/null 2>&1
+            ;;
+    esac
+done
+
+/sbin/udevadm control --env=ANACONDA=1
+
+if [ -x /usr/bin/devkit-disks ]; then
+    /usr/bin/devkit-disks --inhibit -- /usr/bin/hal-lock --interface org.freedesktop.Hal.Device.Storage --exclusive --run "$ANACONDA $*"
+elif [ -x /usr/bin/hal-lock -a -e /var/lock/subsys/haldaemon ]; then
+    /usr/bin/hal-lock --interface org.freedesktop.Hal.Device.Storage --exclusive --run "$ANACONDA $*"
+else
+    $ANACONDA $*
+fi
+
+if [ -n "$current" ]; then
+    /usr/sbin/setenforce $current
+fi
diff --git a/data/liveinst/liveinst.desktop.in b/data/liveinst/liveinst.desktop.in
new file mode 100644
index 0000000..b0ef188
--- /dev/null
+++ b/data/liveinst/liveinst.desktop.in
@@ -0,0 +1,12 @@
+[Desktop Entry]
+_Name=Install to Hard Drive
+_GenericName=Install
+_Comment=Install the live CD to your hard disk
+Categories=System;Utility;X-Red-Hat-Base;X-Fedora;GNOME;GTK;
+Exec=/usr/bin/liveinst
+Terminal=false
+Type=Application
+Icon=anaconda
+Encoding=UTF-8
+StartupNotify=true
+NoDisplay=true
diff --git a/data/liveinst/pam.d/Makefile.am b/data/liveinst/pam.d/Makefile.am
new file mode 100644
index 0000000..9b2bf06
--- /dev/null
+++ b/data/liveinst/pam.d/Makefile.am
@@ -0,0 +1,25 @@
+# liveinst/pam.d/Makefile.am for anaconda
+#
+# Copyright (C) 2009  Red Hat, Inc.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License as published
+# by the Free Software Foundation; either version 2.1 of the License, or
+# (at your option) any later version.
+#
+# 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 Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+#
+# Author: David Cantrell <dcantrell@xxxxxxxxxx>
+
+if IS_LIVEINST_ARCH
+pamdir        = /etc/pam.d
+dist_pam_DATA = liveinst
+endif
+
+MAINTAINERCLEANFILES = Makefile.in
diff --git a/data/liveinst/pam.d/liveinst b/data/liveinst/pam.d/liveinst
new file mode 100644
index 0000000..c7d67e3
--- /dev/null
+++ b/data/liveinst/pam.d/liveinst
@@ -0,0 +1,4 @@
+#%PAM-1.0
+auth		include		config-util
+account		include		config-util
+session		include		config-util
diff --git a/data/liveinst/zz-liveinst.sh b/data/liveinst/zz-liveinst.sh
new file mode 100755
index 0000000..c141290
--- /dev/null
+++ b/data/liveinst/zz-liveinst.sh
@@ -0,0 +1,14 @@
+#!/bin/bash
+# Set up a launcher on the desktop for the live installer if we're on
+# a live CD
+
+# don't run on geode (olpc)
+if [ `grep -c Geode /proc/cpuinfo` -eq 0 ]; then
+  if [ -b /dev/mapper/live-osimg-min ]; then
+    test -f ${XDG_CONFIG_HOME:-~/.config}/user-dirs.dirs && source ${XDG_CONFIG_HOME:-~/.config}/user-dirs.dirs
+    cp /usr/share/applications/liveinst.desktop "${XDG_DESKTOP_DIR:-$HOME/Desktop}"
+  elif [ -f /.livecd-configured ]; then  # FIXME: old way... this should go away
+    test -f ${XDG_CONFIG_HOME:-~/.config}/user-dirs.dirs && source ${XDG_CONFIG_HOME:-~/.config}/user-dirs.dirs
+    cp /usr/share/applications/liveinst.desktop "${XDG_DESKTOP_DIR:-$HOME/Desktop}"
+  fi
+fi
diff --git a/data/pixmaps/Makefile.am b/data/pixmaps/Makefile.am
new file mode 100644
index 0000000..00320b0
--- /dev/null
+++ b/data/pixmaps/Makefile.am
@@ -0,0 +1,23 @@
+# pixmaps/Makefile.am for anaconda
+#
+# Copyright (C) 2009  Red Hat, Inc.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License as published
+# by the Free Software Foundation; either version 2.1 of the License, or
+# (at your option) any later version.
+#
+# 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 Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+#
+# Author: David Cantrell <dcantrell@xxxxxxxxxx>
+
+pixmapsdir        = $(datadir)/$(PACKAGE_NAME)/pixmaps
+dist_pixmaps_DATA = *.png
+
+MAINTAINERCLEANFILES = Makefile.in
diff --git a/data/pixmaps/about-to-install.png b/data/pixmaps/about-to-install.png
new file mode 100644
index 0000000000000000000000000000000000000000..8343e3d188309ff4dd01f1869f8fb7b76aae83be
GIT binary patch
literal 10818
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

literal 0
HcmV?d00001

diff --git a/data/pixmaps/checkMark.png b/data/pixmaps/checkMark.png
new file mode 100644
index 0000000000000000000000000000000000000000..838f93700bad874ab55a880ae1c2cf4e563cd54d
GIT binary patch
literal 347
zcmeAS@N?(olHy`uVBq!ia0vp^LLkh+1|-AI^@Rf|#^NA%Cx&(BWL^R}Y)RhkE)4%c
zaKYZ?lYt_f1s;*b3=G`DAk4@xYmNj^kiEpy*OmPyhbTXb$%AXP%Yj0-JzX3_EKZ-D
zVk^YxDByPg5tFb-i}LI#(md`DIAj`?3s|aIoD_vmd8l9JTX0IQaY<<I%0ur|O0InV
z{;F1%=TEe0uzb|>-pt!;GjID9?v;`1oWNPY_D$%p(bbf+x%(rZvp@a2MlFT4r(xld
z0xzc8rYlAp&)tuIyyVQ2b<BQkJtCWal$mcnC!N6lrD5ff3ED@P+!suc*md85_W;A9
z*R4&A*Q(6cCC#6jBy%<EUklUDBL-`kvZnsp={D!(E)B<(Lc9!}iTra+`T}P!GV{=`
mzkHo7_sS}L!xR4h7PDtdx_3-p(9i?)CWEJ|pUXO@geCwVwS-^*

literal 0
HcmV?d00001

diff --git a/data/pixmaps/config-language.png b/data/pixmaps/config-language.png
new file mode 100644
index 0000000000000000000000000000000000000000..3fa4f1a9b269383ca7ac92be583dc79e37081cce
GIT binary patch
literal 3079
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
VD`w?)wd()?002ovPDHLkV1g{>&;tMf

literal 0
HcmV?d00001

diff --git a/data/pixmaps/done.png b/data/pixmaps/done.png
new file mode 100644
index 0000000000000000000000000000000000000000..f5dc63496ce988951f8e24849a9a3eb6f70c35bc
GIT binary patch
literal 25801
zcmXt91yEaU(+yVK-Q8V+7c1`W?k>fh77gxBad$879^AcnaVYLT?>F;j=H^cBJjvuH
z`|R#Hdk#ohQ3@G>00961Aj?RLtA3tGKaX0tFQ3o9%M<)QPtdMnGU{-j4?j5bh|kyX
z&eA%rpX-<ZJ0Qg9vb;Vo;=4&`yQw)@x_O#>w*Yv0da~F!+PRvUI9sqdeYeWG5G43q
zg!|tjQFk|Mr|$rH6K5x~ZzlF84knJ~-z{vm69^ap05X7#xTv~U_F0!rJkgQ&(bI>p
zlO?f#-t2EwRY7qb9OHQm^2o$ueAlIW>F@IPXY3+pgJC@436NYA@R0;|&Gk1BCo2&#
zF4kgA02K^TRr6@m?mAizGagH+mL*ufQ7lw#0viy1j727vDB9qn^{t9V#*@%=fEQ<F
zLq+8?pj|Y+KUmsLLsLUjbMa;3$S*g|GVJubL5*BsLhCbh&4hbfDz#6g(w`hU=#`Gk
z2~5O?l!Ib}r1KHa+!ecU6w&3~jhcz^eSWeuatpvXR1e<1@6AhxlKsWYv)Z~8ZZC(B
zyWPvZT!-edcp5phb+5aCZ_rgcY6HhA58rX*`saIs14g{M5QA<?8KIg-z<<YJ;x_$m
zHdpgIc4{BZ)8auOvx{N_D+uUn7=V!wmT?=3Li}k^l`;y^SCSM6I@I^AJ|Q6u1GdMb
zFvcj7K!dM`#gdsqErCic2&Dqb_X>*bn=8x!XWI%BK;2#p{wXY&m4j(np=u&t>u^e%
z{gKk`i$68~P`l5@4^vDwVN7>XjDvxIBJM?_$|8lc$6~ih*!`=GLu((~Otn2`LWfPX
zEhnu_4>LIwFgu`kYpii28~|o5@Mx<M)uhA39N9RlCS(wK_;X2o71QR(rn_jJmjP6F
zF?cW{4fuHF^j)4B<afUH!m_v<pRu+~BY+s*X@dr^0k=2+csXr-+>UZca0Hekgq&Xh
ztmphMh%giGBARs2kHUd3FW)Qxk$u|&GkP(rFv<%Ij<eP{fasjpEpYy~@Fl89iNxH1
zf3;y@M-)rpoKQilhrc0uXRLn*mM7@qr_W~OnS6fu87^|_X^?){#>@F7YHgAUJ(M!Z
zqf8^=Pu&gDNUBtr7sm3no~<4$Ti|pn(}SRYm9CTcqOJcRz*q=AvSMw#ij-~QNAX!}
z=e%F)snDp!=t|k+zB~pZLr&kN0F+@^P}8EdaG+xFo=Qx+Xo8UB0#X5xP#^lSu67B-
zUH%9|-F7RCct*anZ5ExX?7Pr)*>fH_)g;sSaJ5FYnKf6VY~fE$_sjuTc*6|D?ujR4
zvy~WT%|~Wm+Uf7R#L(jcU*aqAr*pF^%y)GmL;8%6UQK&TLCR=Q00tEqxqV4B9Oeb0
z(7_b9Nx!)5mu2Ca$=LMZ2{f(KQMAIu3Xl(Dkjs`H&X2|C2m^Tv3fsK3arrs$l9Xu2
zZ-sgd0&MYB9Z2hep9b!PxdgyJIS{Z{D0D#bUJ(4~)|d?a5#5q1$$AfMrDQCyyggH$
z7>L1&t!1woRm6}{DSKE3QpUVaZ051;56I$3l08|rHD)*1#;cH71PxON<v)hFt`&G@
zj4CtjGIH#nC^k{tBIA32c(?Nit2q)(+R_&XpYRjhBnzros!!5?D-2Xo6-GBS{u|%G
zhY0di#qM2K4MzKuM%$a_p}=8Y&12?wqIrQ=>$<&9^=q}mb27=ke-??~04j(HgN+np
z3+8;LLNa1Lwj^H6_jlh~Fv1FWBNM46Sn3yHtZ7UTv}$DrESiNa5EO52yNfviZEvx)
zo6kS77AmwalYN<Psw2}Vt~0|>n8kg%qqNmh@|0D{?8GR7z;=I;X^tOxL&zY{K+EUP
zv4i}(PeI;z(k?@{n$w0T1_i?83KuFDVbF##oXlC5yWD#7Y`8`bG;-Qf`|PbGFAwJt
zV5;3rVN><R+|6(j5zk@`Cb}%$$vlG5*7XDe)>4%eZeobaba6Vp*2d#8sg<_U|H7%c
zlNoRf`^95X=c~aEqbn`nFAW_T$sO*Y>|7A9?`d4+{<%V9b7OF8w#4b~l6qvH(oIgE
zVN87SnaJ!Ci+<i$-LJghr&W#R04K+%Np#rZg#`v?vY5&eXo}jU3Xh<ChDykyl+1dm
z4sf}Y@Z@f1Yn#bQ>w|yQ-J++l_-!W2O{zlqCM`EqN6YBbJT?wB@t&GSyTSmp*qmb#
z_t3EZpdf3)e_6+sdHT{w@UFjwE9JN6A1R%+?n?`DEC3oZTl26~xFX3~2cto?>&9pD
zb4>5D@P)9)$|^RzxlxCLWJ_RmtmLc3vDo3WDYhKCNt9=<DQo6%asgVWz>Nlc^!{3H
z?!@a#`L4i!4E@{b`<%b`ZhH1wfWC)WYxcHtu&>2M^k@8*Qx$IPb4yq9(<DwwpPCL>
zs0>hZFzF;m-XNoN6!}cgk5t%s|Dw+X%?a4jEXbQyM3u+ZV_Hy+OIycsjifUi#AMd5
zaNVie^Rl;95SaU&EV;{+pfh9Y(lDnu8=m~7#?hplQ@!3L24dS%jYq1LOIH$LLqO-#
zP&7-IC15Fbw~K!)zI(C|^#Z?0<3}4yIwaWI$&VX<26S{oyEH%L)O5(`xOK`DkMuU$
zEE;I6=upzZ-ph1%B~zlMVph9Q@Npuz3ol;MUDCarkDl9Nf1Hq#HagqOswETu)<4Pl
zZggp$C?$c-149jJ#y^POIKQ|7k4ZI3++b)}F~I4|WxVqRSsRUCe1GyYN9^^&ec!tT
z7pBS_JwNHSspj5HS+E^AaZ9C1>^hc%D%%dId>3m&A^1^K&km_(ho1H^ez~>f_Xz4S
zvF&?u7UO_iNP9(v%D#p6_{T{vj0&J@ur0v`*bBY%d*KZH_@V+-fH(qMvnS_8A>ESu
zDstM{*yr_nb85oe+K_lD7iubSJ?Ic*2zNZC91qy3qqs7U=^;q3J_$9yeeT}v1}Z!d
z5@(bp-&yil_MWo76@}O(!RR0zNtujBUeH2_O64(0z`s@Z-w%}Yc30>~2~7n|#8a1|
zU)Kw_u;0UBB)WP@kDu-te`+8mC=v-A7MzUoPR`pw7m8%-R9NPTsmIvjV1l{0hllYZ
z!Ij8ALn{si8|SkwGkq*CbL>cDdvNxdA&Phynh84&{Or7q#SLF<5ogoYO>p4%s>YZw
z=t3E=E#r4s1CB<<v;rRPhv%$XIj${{tvJ?5Ua64_M19?CFagTj!q^3FmE3<z0)@KA
z;w4Q@xs0sg#l;EniZir0>+OGdfL4*C)N~0(+MhP(k5G(4$Mi$v|7=;&z<Ak}Q1nm>
zNvD_iMDMA!HY`6~+_58!bX>6xYKe!LX3XOZ(PG5}?`cO-dD5&_NMa$QPy<&MCN*96
zeiV*qz5QexIOZ$n&%~WjXHv`emQ)9oiDAx#NYV}sOSf}N9TDYFYDxtY@%jjk&$&TO
z%GpxL9-)QyaG_^fSz*?1pvq1*`(xTlW>T8bF31PrOl7~Wu72~}_Fw#yp3ZwnBKW%L
z#p5w?fthtZS0ke+FY-M3WW?w#2jFvqd!DQ5P;rQ<X24^>K86Wij9B<nwDe<A`+)VK
zTxoNYW4a3OamY9vM7M}d2u1`)S)TZ`f;-I*Edo*ipd5P$wAl~{)oG#)7GrCQp*<**
zS$(LMmd+<|eplrQC350t(ZMD0Zt<{vu@>aiJ^IW#rpq|^x$P;e=b8JTWuOvfOb=(s
z$CCB+*g^Q#bpZQTvN#n=QiJ1&8q<P?0b50r2pGc1xH}}rG%oG8Yk(dpVcz`GbKO6@
z_|B9uuFw7$)#n)842us>$$z|AQGFH(`)6<;#QU!u{*XEdKhFa2lbTGtoCTO5TF3T1
z5l{wxo)0JObeL@1r}F+UjU4d^@?gc4>uJTUyBi)UY5g|qoT@|~(<3<ax4bkAbo=<F
zi34mRsxd&pdjpq=={2cGR_3yKsD_vV@A~mhQHkF6W*1+H3i$Pq-c9SmE9?0R`7#j{
zhAa*vkxLqk2SOQ1LabO6oF1mKLtTv_?D6p=KYyoS<9zQ5+He*_pS?=dKywAm8WA=`
z;g8YWm<2+W#Td=i^eAmCiLfYZx-cd(h*$$`>6#4r=dVhnm9a0j3Vsra+UYF>Ws>CT
zdZ3>-3JQO7*c3xEFo$gzc@Grhi;FzXlZ$V~Bo+U1QY0pCB{7K67Wr_LoUA<WXlXH;
zbva=;uHW8VruFlsO~qOIV;s+o$Z5IU-%a~n4Kd2JZ{FP2pICF>GVaQ_TNX?KdONNt
zqcRWRT_ZR#W8^zXIbFWgCJd=}?I$k(dcBo8VtMdOrNqR<{2nks8^)$uuC5An2XSLM
zefB3$8L5lmoLLUBdN@EgFP6RquL(zzt%9747|+_{jU+o7mB)qB3&)ro`$=v!r#C+&
z3+|a7Iy)o_s?ZiX47cI32|gfMW@bhYM5WuEw<W6}M+T3rqb_|6jU=WBj54}Y&5AJv
zA~!|HT=cCpM|-gClmN!Cz8Ul+c2hd^IS$M`>%?ULAJPNSVEsyPR%iE;v)@jFm7SV^
zF#AQ$!ki|Q3=@_S`fOwqK_e5_n6yKriY9KWP5Nh9#L1*;($&>d_&y1M1cak(o|ATc
ze47WxBpM$1wi(Yf{4tiSnW%{^D{y16Kk=*h_OV-z+fuXCCSaZx+2`opG)h*p(utUG
z3|X)hW8))%@{CK9TP^yElMa_>+C-$D0-4^QOb9IpAxrd>6nDPO*{Hj%P%AG_<O&=2
zdJtx>K1?-Vh5;Y-FNF$c$#jH+3b!#cdZC0@7_**~%I-KxUo8k=vis4q)?-CO;$R3F
zrp&v|2vc}wPk|vb(Cya~pAeyBF>%!Wl;mFNvL$rj#=c_mD=bgOTJ}gGk~uqTUntUb
zC@ivr;$y%l(h1xgjyG6emGj+rybf!vI4Cq>h66L^U|(yQrW^sl`{<NQn6W0*E)gzi
zTaXaa#+C0!tx)t8REadEJY>Qyy)@_2a|oc{uk;n3Bl2}U(LVzkII#8i!cW<$+ibdB
zje6o<9=0Iyz5X$1q`5tZKt<2z&FAGsAX-=St-VoHt3Ue(@wDq1pbu-$sPG*wh0Vx1
z&e2$Qt++~uiL(^=u(snX<h&!>6BWS0?oA=|IOwX!jvFIq&!VUY&aMlhQp{u`E0=VX
zkv<G##DgBQ{q+DughP|Bk-ER+LnO|mmnu$$EMzNWLLB2S#7w)Km(MwPq2NcK#v537
z)QMq?BPg|D2&?l}du|Zk9W~{QOm6*)z$MKn<H${#7hDJ+=B%ADWt$GD!?H~0^*^6g
z+VsAV?Flv{?+uoE|30u9)hMv2U22h7Y>z8>9~?q3rW%hmTYX*55QXN<m+@QoC{O`P
zbyVwe6L`*j<~Kjc2;5UOMw-KU5;}yEGG>r<FA3NTmil-OWBfX8+st8sMJ`S>giRP@
zx~1>U814ykf>BgG;XTdj|57>-<iOl}QxfV;>x`ApOP20talT8uZuzUME8wxaW2<v+
zdYjScbt>)@RrraAr$7}yt{j6eAGaZh%Ht;oRkiIPugxL)L|=R|@dE|4J{2aSwC2Qu
zkKSj98*Tc2yE$u5s->NpWHps#CPcy;5(ukgRJXpKf_<O7Ij!9%YCKj`8wz6m($hC+
zEJjXGMK{+$AEHB%1|vOS>ByW{s6sS^P9Z9n@t7xCRAqoLX{vlpQ7im!6}2aTI=4gX
zKNuUVB-jdc06NNdEvkoXB}qKVLdeKTjK>d_*CCCOxmFTw>T1RD@#yz~|H}LlHrOdY
zFWm4q<<y)Y^<D=+h79f&K5TfesRn+DP`PKPs9=Ic3U2yV9~5>~0`ihFp}6Gp+P6wO
zk0T1WN`j}#)R0~efut)rjI7pkO=oN==Q&|i9DZY!ii^v9cF2PZ<<fpxfnkGT3iY73
z!zu2*{@dmG`ubhiN!a`Gm^8*Qr~Pg-Z(Rh_B{6?=+*e65v4tGeko-n=e3bP02kQ>i
zBY}!I8)`^g{VK*YW|OK~hKm?qCm4hG9blx%je0)5;f@p{*HYZb<O5R?B_Tp*L(!Om
zd;WBSyeehgpVP+P=gre7#k$DYq&V5rIn#rc$?OHr9gc{R04jGG-x!s2r}#P)$WTg5
zZBg>*LSWcJxlcoftP95H<F+1l(pVo{@5j4AnAhLpzIrAVA1knt&UZp9%#Mw-;wA>f
z`l3VP7$ra^Y64BoSWY7C-TBY99X`2^TCUdH7HDVyivP*s((ruX;{(o++PE@QGZ7nt
z1H=syN)=pxFM45HbiixAQ>XLI!LKxsfKw43JrXXPm_i<ntt`;O!~;8vK+E3He`m~U
z#Cin<`jHGP6GXPGny2m9ja`S8Dbbb9*AO@z*tRjf!uSxl7pkz{qWICkR}~K0$3~<h
za}i^KkrB=<3Mxv>(v#p|xA~&Lq3&X>5nK)fpk>Xu<>`4oIyQTGFt60W={ZwPGDU%P
zj{am4qQ<&>?{trUd2T07$0Cylq<IZ9{M!At3Mwl_pl`D)fR^|gT|_rv2Ca}HD?-J#
z2M`}7HL#4+7rK2!B;_G%Nc2ey0MY`YWfPqO&bI^t>k@gquRyq$MXQ<<fg+Lnu0nvx
zMO;8xhRR?hW4X@#Vd0DLYtrK5`6p3hSc$j|(~N!zW>RC6)fQPSa2xu&a8S%7X|)Sx
zx;e?#DXGWr;sbI@5)4@`jaOMy<tN%C)5|m1Cfdxhi5;nF$Rwv)=x}9LE&4D_%#m5}
zDmsuJw9Jz_=lVQrAN(qf(^&pK_3-@w<SWe4<+3>w7-rtc#!}86g7F>QTM-cJmh9m+
zmdAqqvN&-oB|mnP$JZ~;WzR<aY>kQsKNR^Iw=Lk~mpwz=#(Y4A70jnSqpFN)#<o44
zIg}yX^Asce{GkbfBJ^5KdR8Uyh7A<{qUQ1|^u9!PxWLVVI<trflI0)O7EEpt(W+{i
zEkVcO5+`Yv|E;U%bnSuZw~0&<^{~P<f~5cAoT^a&bCU+{$)C$@zYERTT+=%7W*ElQ
zguU(0Y#Gpx^>lrlZf{T7x|snet&x6;hQbY%sdGk9mQx|CYb5s3aZoZ_r?eAhwiEY8
zF@DA6{3_>Mip~YGBIS$M+%=7_1uYHPi7H7D&Ba;&>Q82wh#J7D#z_ey8GkYz)8n!n
zheF(b8Yv$K^|_BVLt7JTYAk6iODNDZTnrZkMAY*VMg5>-#JLbreOyieUU$luWC@tL
z-ZA<JNpSdBG*qg+6r$NJ#u%J25bW9$Ji2-#JY1TM%yX&@RAiW#@t?%R_fNbC<NS&8
zV%j1co5nRAmK^w8)y{WH1NWErO#dDDUMSXh2&8Xp@Vfu`d!147XjG7ob7&UtoX2B<
zkHkq0P=y1A)#cHHdXwl|iTuvmJV}L|m$$3`3eG)oYT|zfkRjmUo^jANsVdnmS}4K1
zzhX{1aP8bXBe7GOa256$M;dA)eX01heI>c~n6h&4LbKzc`0=O27R%{dYQF&NQT_=)
zMFIjIicL2RTFeKP@tY|a{1QPU<`qiM92t^Y0xrOt5->+cqvwc5ns(r4U)8S!s^KI_
z_{Vb)2@IbyrINU2g>~#$gH@X-nt2DSzO~+%IN$4Y2y?AzpWfX+=f1Fe2CUCGxHT-Q
zf4kQWp3bl6doZ5C1HYk}T$DmHL(V&=SP=<#%wa@_lLYQyl1V}IHVG_fFOhuG#UHB)
zN`ZgC-(z2T_ohF>3hmiB&ED6`d#(Fm>5XkZ>L}C{4vdV(oUVqP-n_nX+ICBkX#nx^
z2t=Hnx44p*vhat*O-{hk1tz&Dw=&TcCIOulWtr@%xcDK`jjO}2!w!U2H6<;7X`vv<
zd%Kd7RNc6k2H1r$XP@x#p{2??6{w=13lfU36|yq9{@0$mq!7RSS9TV`Z;5Evrp6&<
zN<lx7EHwcV^fWhXf-gtmq_6u86QU$Oub~fFJ84lbEz*KQ>`xC9<-h!|)`d49bKfb+
ztWg1Zy=$@UIy_7z^I5}E@4Me&SNkZ1D_5?-zJK0uA~Py73e&@8vhX!vMIj@f@4FqP
z5u}JSDt<d}SL&E^lvdjxjs|;98ZbiSb<=3F5`AI~-e2wmvlWtVP=DZ1G=eBy#m4*`
zz#4W&UMEA>l8hN~^URG}W(c$ZqVCHYo}R}XQX|`zM5BD?s^w&gVyG|D(#}!<YA_)F
z7kB^K;a9*fgNv8BeT9gw+8GiFDa?CoR2Vkk`#-@tt1+`kB_~*k1tdu*<PrzoK{9Z2
zB>H}_*HYle%=<*}-j36oap}T7_f5niq#K2DErQe!1abz7lSKjAH*j@7ZGCjm1c3kW
z5W6!D4G~`4MjymtXj_!l{mZUxAkDSkjtY@Wn$J|D7u~|DI9*^XY=B3*k~gw;RE)PD
zENn~VvPMyfuE&6J(C3(oj+Xn()z)+e9<i*IWK08r;Q3nLNVmWI)<aN>Bzv(zVlaLZ
z!qF8M4gI)Icq7%(d^g^v+E|KWJuB>kcmu-8^xMB*SzWw($`N1QNX0p6{dMAKtppF!
zoh!3gTd(UEft!*8efYXSmmkCR<hZDp+>OW*UfOx0b`j~bZuAO}5pzg+<z<cE;qcsS
zGZ=_U!p-eZ9)#bvfH}$T#SMUXW%xEWQ)~-&{Bng)rX?vq63YKu<Z=CO5_X^Hgg7<T
zt@tEIa|Tmll-;I1!Dx>DZzHwEXH#RW%`Nd@8OcOT%W|cU+pOHTJBueu)UWTaPUT~<
zyWO|XB!C6yi_v$~H(@!_)1hs4Q%tm<=wK+aohtr1JhyI^W73az1S=?vKf#~noKa#6
ziY?k1Xn;cX=9g$F9bHkB1v_`MSIfgf!tZvs25SIvgP5D9zr?LCaFU*LL#o7}mdDIr
zpa3P&d_!GEA<`k(T_>M9*A6Qzn}?6{W{<P94LErnUM^kc(D%C<oo1-|6)60-C8ck4
zLTCjhl%h8&JP?Mz)#UB3XPViv@a>>$hr+?smJb<YN&}kLf!%}ul@hMN)aO15gi7gw
zfhKF(3v}x<HI1?Mc=wI-d%wV*{Nnd#_Gr2Arx9gaERG*RzIK8$muea!{NLz&-@*!B
z%*F-zDXr7%wr1;%)}^_7(TJI2wnyTF2#xF)Vgq!>ab+f(N{HF?6zNf-SYB+^Z=5jq
zz34LI3;IU93z*U7WhaF@4rz|7-XBTRiiJRri`nV(OrvvD;@8~uUp*fn(hUNgTSkUM
zYot&=GBPSG_5A>NX#@xu(b!)dydNfjz_x{#M;s$7ds1$wb`J95s6-4o!(;d}_VmJt
zK4Y=qgM<pfYf)vrrT*M1=-5w+PJpHRN(gsvlZ`B-rwls31Pv}32XeTm0zL#m1BMO@
z0?a55eN`l@O*=FQu{FtiZ8fa43B2<#Ok@`6f$T9WkH7{_Dlki3j?Tz*B8Mk8mgf)2
z6QZCiSss4Et0!e)b45a#lB1TcRsL2S+b2XNA%PNtKxq>*f8ZB*wRm+L8S%uB<s%f*
z#~GzG{`cUxo~vnSJo<~YW>^53T<+J`)woylnNw1qv$m|{f9oPMBqD#JD9)8@@bxsR
zUw5>Gd|w*A%^E!}1#V<=v_VaUi3w2`?I-}CnzfR!4snz>kP{dp@%`wmW|{1)?VU7P
zcfgC**ls{7NU@U693(Jq*(V80_e4xxDws^7<^K_ZP2IF(!`_R|M-FV-a#7(SI&lr|
zfey#~`AhveBtacXDuJ-A&i}ULzxeGQ`U|$@#(F&IBF*@f&U;^K)ruS#RB&mS$DRi*
zJ^6r`TtXH~%Kx~4I?a+oihgpc++B+trt^eKma;0L6yK?4%+j>V@ERSDg_QYC)%7B-
z=il)`pUYLpXTCkf6%t9v61TQwEBr~L{39Y$OdiJ?<41ahs(3VcCelws1+(9c-RyzS
zr?4M8$#?wCPOjwOFNXpw%a?Ql2MbK{sUUrnkW$Qs^gsI{A)uxmwgjTs&TdvN>>0H0
z1#~jweuw*RCwE|58gf*Uw^KsUUzT8XgcykY^e?a-IRYjE&p`j@1;&qMQ)WI=L7!I~
zRbhzRSrP!*#Wu1mhS2LEs^i_EkmHg}KWwi4Kcsw1$cIhgm7b%R1HW!qlE8OM3}53a
zEEU%LvICtF(M;%~Ft%nJl~?IC>YL+J!ja|NfXXCqJ9-ti>h>GrPex3<ZChpBvkpgK
zih1BNf{Dw?3`a64GXASG@7UT6uQ~^RQnz!+_y!7*GnR%h!;HJeiZ2Q8b8sWJRc);#
zZS25H;M*r-=Ca#a3HFm$Xn`!!o*^4`rK*sn*q4HfcG`5A7y-Pl=9x7B@7oty6D?KE
zyC)QVm$EM^Md7aUBt6j?p!1MuG?Z;6$vgYrdM1ACeRh4v&T3W{7<(uM3Q*P|ViI%&
ze(`xSV&|zkdP&-kc9N_GrE^VBYdr5yBP`XoFaDL((D}Waw6Qx2_bM!<*F+COH_@jt
zy46%g>)h2$DWU;V!li=h{)uox(uVN508x)Wc@aJ{|M&=t8_?4u(bVCH*{!yEw#;vz
z8LY8M{C1rjOD!%@6RO3`0I5p1Y>Dc{3AerVQo^oBfh2Bq;juy=N--N-m7>sB;h)!d
zo-?RXNxr_z6$Ny9N$ey;1^px$eg8Z99{2iIKnnTiO)9P@?v^wNR0vR>r{L26B+url
z+G<VmGPJUzCJp`l_v}iyD@+%#5m1S~UL=l3GY-2pat|SY&i!0nHQlTRL7eRi3&{Od
z=Xtr?GtSi~IP^p}-|1!OZK)Z7)nE7yEO-%0JJUygbjo)HeWMo7NCuFrhEbZo%8L<W
z%j>(XVG8%m;c$QM)kZzFqYD}~)gW{Zw>|?FFtf@X&PY=5)@2{9VJD^~DGY!<+z%PI
z=RQLqSNE|n2$jhH-4i|<3J#M@04*cK&#4?<2{!k60vUWl%4w<=;n9b*K*7bt#{BK)
zRl4Y+y0K|C=T4=o{hMF40Fxo;EGwjAXTQ-!u*9*%!f|wQGrNVCY0-mF?ee5W$kukY
zpQ{|)w4SCI(_<e6$<bT7J6Lb_Z=5lLyA3(fJEl`d-#SiIrBd`M_TZ72tr_SU^8Z=@
z>=a{J8zBwOTMyIparK{+Na~Z5b!^-D+4$kgaF}A2;1{g~eJ=-UcXf-lPoTHB<Mx*n
z?m#nL1{F^<361OE3FlE>`1~%^>20KXtN6pr+sIJnb#3R3)TiX(2{za7+F#iZgYF;6
z&IqO|#0RZW$7N00mz>LPncoh$M!%uz)`O?9Zj<)gq9GFlGNHx4T)EHm`0aCg=Cm#0
z9A&2qqEAoDYaABv#%8gkY8%K=vX3>bjWbm*$Y*6#6!9}@*p+OlW1Pc|{skj1RVbb=
zJWjN%^b0cD8h&MW0q>M#72a?<4X4;*wNilcZ7ldoG=zI7jYy1DN{RT;wvsVUii(h=
zU?Wh7Op%h3BKLDM;qTl<Zy(~$wq5VP2V{qn2JWO`Kf=lm8yIUlcbCg@_#E5iw(Z5?
z`i)VMdcB4QDy}#`q)n%F-)Eq{hhJQJiA`NT(mvq1Wt#{|p|}0yf19rjeEud(;1-)J
z?Bmzbcfq};y#v-G43QvHk%xHf$T)drRPsN$m^i6v$mC#$;A?*KqE_^u6fi0ts&}<P
zQa8S}#IVs&SF2?kwoNR*v874jCOgmxm!P!2lx(*CnIn<qz6f#b3kX6bd2-Yz?FKqJ
zcN0)nnnzb&>3rVrqU<XQfrQ2Y(J2N|U+@_!EMj`U{I|sPAA^BBl=F-vNU*Uaq_twg
zihYM1c*Fg#6r3x8e~;pb{66nZY{d~!=f@I}5a_?pNqQ#BOXBx$$f)?_QagQBW&bPE
zelBU-WiaclK&|gDAx+}D0n&Vz)`Ig&ZB{B{lZuRfDwWwZ;xns2=WT-{t$$yuO8%RR
z5Wt===N-;gs4xOqb%^Gh83QK{u3*TfvNF6lhjryAnE@b1+Y^Q*)cE{a@M{|%BY>Xh
zPBcjWI??<K-p{8*Ku*<F_n3^Q+D%uATuc)VNYl*K9RqmnmXRRQ4JBETcO}q2*we7B
z@_l?#tgZbJ4en-HkB-;8_RyGZ9Dx^r(8vCG8+_`v9~=J5ZwJWvwtm2^;A{W!tK2^+
zDQUgb>4^^Xkd+Zc@lzSu9y(`rB=GX@HIMI6W7gXCz_k`cQwK0(xyEnm^E<R|I=<71
z9J*j9e))E*C3VqJ$V!AN_}=eOi1&sp65d;2oiHxQEw2$@L?B8B;B%-D-hA9b?f(9k
zp#}&S;&`$8ycYlDCe2aqJ9dJN+qUXKZYHs){$r&RFaND}OC@y<@6Nvp10H!Tpi0w)
zXy51zuNKn@%v3?XWRE^AxHdc5+H#h~i+<TjUk=QQAwSaJ1R+<Z@e_w?Ry0i3j*|dx
zK#C$`^itRQWP&|O3yh9O9?Eq1W2kWRY{+pDlQ)`TjslO5QEAZkM&|zajkOmBf>7Ck
zH9e27JVt&BrhXgh;ooe-o?djSVcwi*Xky>8z8?k(DH`ElYh>zlpo*Lo)F>Y>$+d1c
zmJlMFCVSw&pvL+g#$G=B8tJ2)j;T9*XO!yHV`gfx$!oxrw*ChBEqG9=k?HAp5pG&h
zUVijxU5I_Z)MAj2SaLrM>=r>;pRR<B2DCzpB*;^YXz19ZDkQIR*rf`dW#5<hF$%BX
z|1##XRv@$C8NX~QC2`b7*-XzMsb$V#fQk4we*b;Muqtx+TYb?$EdSXLmBhOl>$V=7
z=3aU&kx<C=h@X9}s3~n&ElzrlDD2>%lFU%btX?&vn6CHI12@9gxz-+G!CZ-+Z|!<;
zp8_aY5@@g2D}T~g!>1=y68{|`gcjTf{}3mfH)mR!*fvA~sf+Mcelk{Ca>LiPPn0vT
zb$Rmc^!35c?J-<^5G>Q+p`Dr;9;Sw8=(4Nmcef>AI6$Bv@}Cq(-C?rUte67<H%?^U
z#FYa}$aonnCb6!MfLS@7(k%&`X|^IK$VsJD$2L%wr)XTTYlDiEsp{HPTF|J{jvvuC
zh#K<ZLcOz`wcPy8%%06#7<C|4126JL=AsH&svbp(Io38BUCrRAmtVvtOEd5GnYj7v
zY$<=K92HrrdR=1P69Ok0dFE-J`8+2K?c)m*HPgUuaMTwNa@8$K`i$iJ^XqTb$y`_f
z+T-f($`?%})$`6JRWZHIO9l2i%Rjx2Tp`CC(;ZsT`x7>q0Y(}hXL3fbMm@_fA)hSI
zaz$cH#!0$PlOjd5c38VK+bKXz%}(nD2dH~h0z)QI>?AA_sS^%EHq^Ay3@FM*^j?SL
zkp53wrD3Kc^?f08m49wHnOjnJv226uAxR18H1y-R#dACCe7!}3+hGGPp|w*$g_K?Y
zec8$1vHG?7{40Wfc6Ws9(bVxo;D_hUq~^a}3D3PW7WJ(~szP>J{n85d$i!sj{#6!H
zdH_5;#q4)JKL}}dqar|2dgeN6yea-~(I9gbdkqz0Xlce9&3&;N=y>3b=#uI`{ee(F
zyNS=SuU!w<ht`Kjk>Sgr@ca2kOM}G(w>kqhFK)gO{(}2)M26@h<pf9DO|WNd=OfRE
z@O@J5>%KOp?uWD7Qmz&@OrE;iPoxT_{+S&-a3SJ^moUb`b(xTx0l}>wc0S`1rk31R
zY7kPQUg^i*q{aN5xQ~aAO<`gJLOoQ~8Czhyh3jt*t^)>}7;MtQxFtG5C#r1Mh&_bi
z5uV*b(x*E(K;Ua`z;jztbH_UmS?;kAnYVT3GCPuw=RMjr&ctV74BIJo9l6943HV_A
z@MVrHpbb3b3H0^aY-dl$x3pTer>>t!wu6cds6{0ZPbi_+t)>|s9=`4qxNsJJS>5jT
zG`Mlv4s`kZRrsvw*XYp-YoZMga*7?}*LhKjil?*p0~!5lsN;V}HpmDtJq}q~4+#R2
zQp+w!Q#la@csDo8nor7xNbY>K;@9gL)o!EihU<KB#YP8RQjL6ZJ3A_`|9rRg%GbfQ
zHTwpvQiIiJNqm9s@;^N>$b4HIHg%&4@MPxNhvh3KzNRfM5=`8p0Pqs2M6rfe>P(>Q
zSbV2tx4TC7nl5Xv<g`)P%8gd#w^k3mmf4jQfT@0Qp3xwUa&@6PlY!w(SM)id%8a+y
zTQ2olZZ0iH)#_n<)*~Vhdje7F3w_qE=|9;6kIydYPUmO-LcT(}TW{v8{T70JZl-4&
z(_Gv<E0dzS<vPjkc{U|m3%-?0ustJk9aE+cpuV^sGXMk{C}hE>=kh)GZQ=uJYHXb>
z)17)}eIm({b6_^`N#JqO)9IqK6<=Cxuut9Wv5qMXAw^lKP)yvU0^ynp+p;1kOczxR
zVv)?YL>9MFS;I_if`YRwQVlrAqz07CoXrAFpH^ApSTJmXp>17;)H&QUbWOLy@O2tt
z?8fRe8Mk!d>kPx(xNo?*GFOWwZ3jRj3tpD9;0T8e&3ZL8WI}K6VZ$|do*<bsA(#Hx
z3t{tVrhgheNdO)7g&={zbICJrr^}%_!t{fydBoL*c(cn*7=ctDnOs-B=bSX3F*~c0
z>&p*w<2%2147oU>-!~un|0cII8*l;6)*vg1&o&~?BYN3e$Z3g92)ksXrZU_^m=ZV=
zwOWOwL8OZ;H7lv5mBfWm2@$#)nqeMWBw^B@Oj)iN`9wanU(RLJ8m!U{R|?YBtYZIr
z<K8KOM1Yfn6<Hp7Fi3|{5|oMeS6pF%j_3Pd137={Q>l~R7B69oj~?6X9NYT5Ij@;6
z+cglNf+|D4Kz=Yu6%PdsHtnJ|l><;4M3E6*$AHiLLwz;5ia{Q$Y6gA~L<P-^E~!YC
zXYTFY!3%1(x(F`~p>7wUpj1V_BrBj7OQXg{Eo1{H7Kn1?-qF?7y|>zK%`#Ul=q?yC
z9}W0u6uqCbncbd%mP4mr-H)ZyK#Pv2YHMk%V*-zW#JQK)Ee|mkAao3q#6ntXXR!3~
z-5*)Q?SLGJ_Y+#PS{s$goHgw5_&|0lf^vm=_EtZw&zYY+=x?UaTs2t`QN^I#Lx;Ea
zuMmW_p=n094WpeO+pBYxqBU}@`l(45#Q4>DPNT9vbQo2D=Bw_Ql}rI+`u(ijBK{CE
zddTX92S<0`$X8F`i#Hgmr}t8|idrvOF^E`YX2^P0guQB!mdKWSX#Wtv--I!pQiw?Z
zW#9T}-mGJyDQSsjJY-G1Rr+NZUKp<dA+C<R`vpbSWs|^!PiNuYbro3&9|sfgC8ADZ
zo;r)V62IY8rHbVm(XT;BqsRDm#*Ebu96etpkp{LeNjWKQH9a4zWcG&uRl4`0vcOCs
z4y6JLKK9n2qHe8&8tRL@w}0IG1I<Fhe87pv)T$+Vhb5#Po=P_fwQs8*Y*!%ywNf5m
zBNwTOMR0JqQ$x@k0rp)qAow9$F8@E*M}$~yRP>gO6_e)W;Bzmt>5X;owqQdYcg%@O
z{356z76>_SWEY?|dL&0Cf;~yZ;h%XOxx|bjez)U#U)GNbY_8G8w{uN`=#I5V7M{qI
zT5q&eK9S$d6dLIc>h;J8xUPzK{ZqJifA*G~d!u<W<bc1_WRBuU9*s}WSDyT3MCN2C
z%Vb_W6}x^G_rJ=UQ8sk%^;Y7`)p_Ci&_D%6HqL}Xv*p9`4S=V8SzR5qt$5zgP>-~J
zv)m^p>@-6b`BLz|TpIn*zWjRH8t86LFA_<v5G*=~^i-jCUc8EwTsNMakwIx<%p9yK
zZ~qNE7+vuYc<TKzgE<ZCbeZzqE?YdgsqN9V5pw;zc7a4X$vrY@Qu3zvDa^o-+ur7m
zsg#rx$QkP*K=(tfwQPz2>oI%BME^BM>mr~FsVGq_43k*Pi#jTdntXbXs@`a}C2fdb
zben^BGp75fhf&gfY~Q*$@vP+pmisj}I;B{D>fmmPgpDQ`n6~gVmn?i`xI?DQBvI)i
zL%&YKg}ftjagrYwlc-cosmyEsBwp|O4<@KbSjyU&mp3gf?j2S(=h7_8CY`Y$&&hYf
z^G|ssmdh-VrZPpwtQooT0@cj1qA+e`=JVHxC^FSZVn*%*ADLaxSoDIMAdF#=AlVqt
z`sQwA?~B|mGa5Q8wQ#H>eyKkEsKd&0(_GR4aV28mTHzXIJ@;wp+Km58DUomPGBoi`
zp?|K?aAIcqdtCL~fvXWrHYJu@AU~9i%-5dDS!=`Ccs|B_KQk{ZOChI6Ur^-ut$KK4
z;y3|TI0Gf~sa2C>X3*AR3!0dBPCLe=96`K3Lo0RoM};K|kf!{mW-+q3Z7)V3$!<~y
zQSo_Pk^WM3xy|Txd0r%9^W#AEXR*R)5D$U1q`M_1%NObEY(vhT4D)m+nsf)Mbi4h)
zEc(N&v7eWw?9~fS_}r<uH{eO8h>TfLBu&F}%^aPr-4U?PY~LUl{~rpC<rMf+U#DxY
zkY=sVQ_`%Hp{BKIiYj>B`IXK^b&^X#SEt>@%`Q^QXl&{G&;}gfWFW&pzQCiQHnF0(
z*oc1|OGqhHi-=R<SZ88xhe;t^QY!JA?}PrlhdKGgEZM=G75*C5;T|hikUMZ%3_{7u
zEe(InD90|#BHQ?dEobje@uh`DBLPa)$1u?+JL}g#Mmb-0PNoE>&aZwFBq^^?xTS1+
zuJ%Z5+SkOO*-ou&i)ICP?l1PiSQ{3R-=*}oi*W5_zg6XSXA&=KHVd&bH67GSr^cz0
zCOu5IG(NQ7xi-~K;&&2$ILh@sG3N&N_Ao1fxc$Y^;IOs3jA@1}C6njT*m9Bb`lh<g
zyi7JODnr<NAm^CVx7Ja3c`<niFs4PL4;PGWVF*KHBB?oBRM=I^tN4_z^~V60=+<=w
z`2fNpJwwU)VwY%2ae8l89<u~tVh26JPv|uzCS^)><_YqbNcye0NU5)>Z?&7*Z-=R@
z9|c=?nVOcn{S_iY8=oqR=9!Oi<8qy?kMXMF)L{+Iv8pxIeL3Rv$kr8zWBpy-L}!2h
zuAC1U#_o?n_{oAWO+72Oz0h_eTk3LA4CEL~4;C0ZolPrrxA95sA+1-l+&A|)4Kn9y
zi|zfQb?^6K2LYYU26dv!ToCpK=#Ltf)<^&J-#I)!k#kWaYmli?tHmNj=?E4fm4T7l
zazBxU!_StM^c<zD;V1m;4z4&$#tEaOU`EKphZuXP20vvSLE1R&14Zxdc4mL+jr&L9
zwe3qf0`;SFiJbh+ul4r2e2wyEoHv##_ETBKC3U}T6SUOSCQ6qwH5L{YRb&>M4ktGv
zCTU4d!#NrCD>G*Kc^ua%N=stbx5m<9qL@<Wl?oEloSgg*2yU=bDRW;AjjE&e9*3(v
zCQwMpThtlkx@eL+(u8b%XK-5~bRnXCEPeHjubYzZ73|qo{FmHy$!)$AHZ+dvk-ONh
zXECJqOy9*YWsp5Wh-=BtxotZ@A=aC27o%)#?49;S7u}M<4~qq2y#FoaNqg=Hb2<ld
z6^T7{J<|5V)9sIT|K(pd#U|`@&D3Gr#ngUr=CK9!PUK2m_J<9DI9tZXRVJonPQkRi
zHH5cXk4|<ofvpw0Bq*UfGEfar%7;DUlVQruZT}s^vV}j?>|P<8&rX^hT>aON4T~Uz
ziOd+~2LxQ@4wjHaH<^#4V(8usg2SwXA+z&>Tw2-Cj`m|T%q$($p)UQD;^fYm8`PFB
z-p^xofGUy~PW(PG_IO@XPRc)D<{<N{P@oZ&`*ZK?o(j?`hG=WXay}qjyH?HcqNC&Y
z_Rdf5W~TXyuE^w}wtMTTQq8eusnRZM%Xj^sGlpDTWhi#&hGC%QMA{x~u|!mo_b3-F
z;<eN{Cl6H@Wo$HAbQKMeFaCco{C;Hih2L@TTVgxp<BWmG1`cxDNHH!v{}>Bg#w7w5
z*(dsg&IP+iOV9o#2LEtM&ve*58{z{4=Kv7jb14FeLR*YcsT^*`l@ALW-LnjGJPmaJ
zJy)s$6p49#{F*9OamaZpyl@ns#CWr9uSC~G++K)tx;rwo8apo?PjES_{~ay>olJ=P
z`<n<_ne4PVwi;$L2+!0x9Mt~TCU-?~Tj5bHGm#m2?XT+E5w{3lO@7LIBTo#!N{se@
zVBs-`4>oNxmA#K~Ia%Aqw0!y7ZX_7Xf;`J!i)12erWDaiEOjzVcfKCwOCEYS!;N<%
zt%}Nd%DX0l0%Obs(1C+T+RWSkXsQ;~9BKCZWOVQWoSzOEL%y!&_Hv9dn(MOQsZVwn
zD%^G_IV}x%WxE+5)$OBh8`<A<!d0Sa$5V2_QGK#B-Gnef2t9u?5pEpLvd3wt79=k(
zQsN=RQ<Jg&Gr_Ct=GURLml{9%4FZ3!y1IhIzmzWeuEzT30h81;&m&#Ye}0lXzWbH=
z;XmsjF>qi^bG)!!r-RSUO`hsK$g1q{Sb!2Ml_s_&AVf|DbHk2axFf?aRGmH8LXr^3
zI6qalinNmGQk!bi_U4bgBX}S>y+3#qk@ESw#>h!r-Oj=a<J1&uGf@5sn4UipV>7?T
z{w9#Ge4nVSj<wMk1wxGC_T23GR3<p?qHLBq*GJH*g9m>c=0o;cQ$W@tpa<b#g)8Tu
z|3Z#RGsf%BcH?0673F~gOSwM<EO+;l(#tmx#a=`v_2(XUvhqDHkEy%3w1ghF(TJHs
zAokL|>(+Fw9isb^v%9(WNpM9#V&v&eYMR6aI4%nY<z8lGyAe)b5=BkMM18C7+>$~W
z5i9NNIvm*z2%jolo4)+LAk93M2IK`U{-&6(h;K#u&u!&sYvunH&57&g8zg#h!V-%)
z*L9F*Y=KY+y24;RGD!9!7%mOhiVe!okVNcUylyQ3P9V4qk*FoyUr!E@L%0;H?$T!#
z{70HI?zjz_GlnWW6OA4R^)DE;aih&qU_;z<1!pu(=k(Ox%?^!ukNjLOxVw@up)>Ua
zG6?Y#wA4yu)Ra1_Q=59LDB|AnALu}Y^9!$BvS}?VO7lDj{5!}|qMp|judd;O`{Y@l
z=2`>!1#9Q`R=Bw&BYRa<sPQuRF7tL%OcI1NN_Pbp1ZWGktSuSDg{5(HbPJe=jZLw2
zMgH|o-(Ov%%OsN4cd`n`IH;9ErML?w`_(<%eS_n|jFY>O5f~tDl6XP#m6bwJMz9i?
zcE5FL@~tX2G(ayJ3~74s%qrDFkQDa*3~HL7c}z^+o5R!|0v8vH9QH^kqRptC<Q=y1
z{SwWQOXW1{on+QSPb^U1#I?ZqcMSmFC+E~uLsC1TyXuo(o6hIL0<|bVRL;wqN$*GH
zyaiEWa&5_}2AfQ#qLL60&onXI<o6Q|M)eVgsX!y7>C*ER?tXo(Eiv(C>tF?!RxQZX
zx`hMWqFUrFhnEllHNTd>URSFgtv&9febw)(%wK0+dp`rwPElG21uu6rb0nun4X<?*
zX8`GZ{3jt-L)XW$$gmoTkIsiu6Y)>{31n&KnP>7cQKxE8A(Pz~I0zxH{Wg<w$wGE_
zUKtFGUlm*+aA%yzjfo{lA`F1k36+hDt)YS*!H^0CpL%V92dK@tVlKkl57D+}nCN$z
zPFqY-g{-SqktKu9%?qla6CF#5At0~`d(vDY@#`{9Mm79W_(;ga#K^ZzJvob+k~sGj
z>if1ryNJ!VxdWcNU^8TO85tB|FFnW&4~X7{uI=}CW#)>7J@LJ6^h(HB2)kdbZsS_1
z%trE>#POgp%<HH5BPmjna@6CxD1V&8DqlEj^qh%)u~?Km{H}0573>&s>fo~8@DZlR
zlQ(jR(SBN$c}w%-q2j4YG05Kz2-v{}a9$oSc!^RST&>mPB{<dVR`l8TVo6jPQjCjv
z%#nMkmdMGIHUDZ?4$=wR^New+5Dk#e_Y|9cpka}k=f^c&>FJ)>={wZZ3ct<r0bKtB
z;$fDA?!>F=5Ql7Vv5FjZjZ1%Q`3|}o7(O$Z{Ah-OuU$&{urp2f_z9YxtfWo_i^p!G
zv;?Qh51*JpnG!__KS#s6U~%e4vM3SLh`$o^^G?zJpY+A_hsE0E5sE5Or{69PlB5lk
zYE@uXZ9>$HdzrZ^d^^OLz_*6|Rxf1ZBArqi+3#7*Y)hOXxY-7*WI4)?Qb|~%`=MFA
z#s!EX#{hOXG{(w-p@2hRnjk#ix1UA<C)x+5P2F?ZavNg2lFbp?%}GD@Sl2HwwJwq$
z#<3y(lM@HrY=pLVT=&$Ncqk(E(|z(Iz24zWk)pXeSTbcWcL<VPmy~mzd;kk+ybMsB
zau_t#ONQRzt|Vh)8tMAS4nE*9cp!LcPPUcFbMEE`&PGBD2uq%p(I%w-Xw-!6KsNH5
zmxlRP-qI|M7`??&6q~bC2&1sbDh^%tIb^&lT`Oa>o;~6}Jjfq7;}qLT!d4JuOV}B{
zl{<8Dj|3Nv5Z33P`Hv^NlRUQ46=gt#FjmlX@pB?&D^c}476~!7%u+iDG>XD-)zC^q
z3c9hiK~k>7DP^u>5FwB+Mncey9xcAg&;n(bd0r9tp>4Y?Xiz3_P<07`D3cGjz4p5W
zluTxgnxVt61DW?lskDg_1vY3*$Y5?{&`q^>(8S+6{qicqqJJKe&({g3E1$22KBZI^
zvxxA2<jYHG#RelrA-}x;^Cl_mh|Tl;nMR%-Vob{r{`xg?`Zp4OQRcG#Kj(T_G21^W
zSuEmZAricZyqb)ri%O};qn`w5AzfDaN-ACCe55py9HX5!@Ta5>l{z&5Q$uc#VOJAT
z1t^v(dBTOsN|M2XiUFsSu9wOl=LkaJTfe%$84>b5O8i<E<T%pErpTcYfsQpst}^qT
zlLc0in#+<rxG=^8QgPs&1TUn^*^N8dWK5~(CDR~MUxzk%UBlfD2Q0*yPS6CKhJx0n
zNQZp%U9UdCd4;1rh>+~z>(ki^X1?(?bCRIhCA{<He$kmwJ${<Nv{_pN-KRtl^B;ys
zTb850Q<ISGxJ2~0@({lNK%%#`pn95SrAdKlN?CzQsx*!T!ISjdZ-nP$7p4|f>2V==
z{Vzr3N<g2z+38Jh$LqLx(BE4`olKZd+aj7qowhmzptGMU4$5XU0V@_HEyGxcN<;w#
zLH~zN3(Ygv1s09dtzowqPXiYPQn@3puZ7{S_<}M~oP7@}GBt0zoONm<c~Tas*S~Np
zp4`_SrP{i6a77eEn5tTM^9)hwEesV;AywNk&jzxZ2BZnZU`1}dchHn?<sv{PCttVp
zaWD}&UU#zpJ3K@pcqsE(eOJ4xxL!ghGDS=*E`w)_NT50Ko-H`hz*3|H2aG`ujli(u
zdY)g>CnH7o4W0gro(?5bND<PMvBS@eRvo1Hetaohe1jdG(~!idY4zk&&w<%lDob)L
zOk40jL}?Q1I%<~A^Q$HhPi}1P_C4r%aK1KM@U}b)mj(I>CAlU~5dPDq6l4bdGl%EX
zR2=9y6(-49i5k9^{^{b)1o60oH0P8d(X<wtGHmMO3uH?Yv^a+|eIzv08|kL(96K!t
z!k<6Dt&9ROnaiiVFb3ni0e5z=7e4M8&d&5|t3fT48y*p>_zg_Re;nDyTUWguO~mq1
z(J;7eoD!WvLYl+LD4d6cWS6;TYE3S^v2+WtJic_0F&tU8gR3RDq%S3CZZBQJMm0(r
z5P7~{{k=KGeQVezpM#0OKl^O(dN*4>P1<%ErOiS6s+7POsb-<<j9i;$@=uDFp<I{o
z29Zq0tocApmBlpp3DGIG=hZXL@8pfM^2r1jT360F&rT%t$lW6a5n~njhd<u94}h{J
zzLurDmiPOWbzP5?Y^_9xe!2mA<{)mac~q8ET2`RFyVQ{vA!d)O#8%sw8pf>k;Jwsv
zrN!y{cOc=5k!u54wH;i1XVWRue`tlUm71I1H5hrC`m=X(XyJ3TkXFZVC?U^R6Tz^^
zAFcY&AWbzajVLWo;W{O+&g@}7y!dPve%Wz4*=$3k`3T`pO228mOu64r%hE}36r580
zL$CWJjSIwRm(-x6*|`kq$3w^Y|5|_^>cCnQeE;b*|1Z7|PaeWEm%en%p`U(CTXp12
zA?ugOhi_S|n{_vcNwjwUD0i{(-R`JgRxU7o&p#dWKQKQrZ_8kVbtB3&^=LsD&i{3G
zm0fK;O+2`T;w5M)?hWoxq!fpyxVvj9R*JiOa403XmEszlQi>HPK+xju{_y__&waJ$
z?#`Ywv$He5y?16d@ed2_16{2K_jovLb}@QQV_~14HDO9FiSc8?qVJ%C$;}diN@uI^
z%J?1mqT#*3rUaVt)IdZof`+7WeXa@1p`hiZ&yzo;%Z-irwZQ8qNayT>D+O@4ec;@l
zm|{8#e*DyQwQ2UraJmET>#*nX<%{5m!q3DcD+eB^BjYfhF+Fg!w`;I>>>mbg)Q~v~
zx_9l%P$}ad5u7X7Vgope<5(FsJ;~T&D74l*F~L5yaYS=J8Qbkm<m)cZAx6VSqj!bn
zHeVWNY#U&+@S}>I^6H|B!$p(a%{<@HZas(2W<H@pD$!xE(^5&>QFwLIhDLYc<zXW3
zP2jHLU;EouBE{l5Mb<=31{|9Wk4EbklGm#a;p%A>&bz~ZC$vkhKb;z9t?f-@lrNZ+
zdq`5^volr=E;cvtl|JsXwe2)Z_h$xDI;#4ePYuR0VDdH4RV%WpE>88S;2V!Dx7az@
zxEw*<l{W2lK?iwl42qCnN8e>J68@F6eU4)+b0m#GMlw!P9QJ%tz$;FKhG9LqPA9dw
zh@|1f+TGvsb5f55ebG7bmKw7a{xyf<AuknoS<6#1HTPXW+5x}nIk<PCH6BNHy+c>i
zf^6C(;GCIq`ACyM(1%?0Wa+$=1(QWY2^is^YWVI<80bu9vne*?=zp5?p@otdW}Tq&
zE;-Alf=F?<!=TT}hykZY`~H6Q(^JTiftE<a81M95ow1?HgM2ZY=+ZW+wkc<Z>*tP_
z^ua?gx?pA+u2$y{CoDS(SyPIns;$mlu8y5pyR+-aVzysAhj}dGCK9zJ4kcydk)S?K
z)y2O#G8me#e@8(RoEEYq$_-99yFR@Ci$mur<f?we1!!C$47|DF?!bBwm%@gL{w+;C
zvsERn*AdK28KFC7UmzD$2ViqiW%-gS#TW>tTkEx5A$>+-<$DrdrD%nHX$Xs>Ql&Mh
z8JV*vw7_k6L7q@PSQ$A$YQOhUfrO5-+4Mr0^sDf4BCT)CY{ZX*>OCAtsVAI&=Eebr
zKCo7Azt>=rVZ5uFnt-pLnw=H-YgJTf<E1VAaDgyqZgV2+k6fx{clrim;c;^8fqqs@
zmn;AGVoM1nAFcoe!_Y;BpEs|f<w9|E{#NE^6l03gBsnU~y0DQ|Mhf<Vd@1ig0#a(A
zLNueC0vBXgXvd^)gBr!|0Ij^(7TeGEU7m)GNV){bY&ME(^UOyg*%W3qL82{~ABAe%
zW^{d$T+iQ1;n|_DE5io&5zcLomDIX9Zk*b($)sJ2{O5AX*TxuX8c=EWJ-^4^ijA_;
z8=f8Ry{28kSH3F}`1=bxzS|Q{s{>g4k^$i^M?*8Wv7_0y$7N%xOqB!a*c*)IvDQ>L
zgCq=90ykRHTD10qqlq*Nmo(XpKUJIHJQ)M%;udZy6YUp_Y#TyoVY3$goyr7hPEb#*
z=IrnpZ79>E)nOXS8;;(9`xTckx%WrbEYYm;LdGRSx$G%9+<ZIy#@Qr{^6L)NZ+NWz
z52t2@I|I;A=$v<=`mpPnhf`A`3rH+JT4;%U6Rt&t`%P+Z&D?Xl6_XBT;!slVd^BV4
z?GRKWUa(^K36@K$xLnnm{!a$=Q$=^bkR9eE*F0a;m=SD+zG}f!!garR9_nZxC?{ax
zYT1#Ysc=D$Z>sMM?MK39!f8Y-%ViuGrm`ZkVqt<sMFy%S91Il=Y10jTxJ!QNlugb9
zdh587*1>=jMF^G3AE-o@Uo+<+{7mWT^X7d=gI66!NdT1j8lq%dRg!;Y^o0J=5Anl7
zNV4gXax&kGo_+eybA-m0u%x-GvkV&s8xzPv(#_!g@~=XY-kC#T^HS+_nKqTb`%^(5
zr<A>%rAg1c{;fCLkP^RbrkX<d;vs7-`Oq-W|0OJbw<~r|N(o%%GKj5iA^$96ho0;S
z#K%XHh6kmn*$}G6XR!{A2^v_my4&1R4?fnEhW%nmVZ$c+zN^*U%tK9NVXqY(3(VxD
zGicM~IfZd4LcYK-WkYWQb4;C6HO-DtXu`lW0qo<GaU^*uw2ILN-{U52{g+xP<h^+2
z&4vOMQ&Q^n^X58iW?LaX7{WrPh!?>1N^eCPtoVOk6%P#YV^Z(s2<b!jw14<s9lo`5
zoCsGPRF0K3OY$@&=j!LGzj-+hU)!g{0{oaXrO)}i*y>X^Ap(|4U{q0dWyT-nB>FMm
zJ?X$zeAv9PCd8<J<}>O*@@-e+)y~xR(EJ?s`-2#^gv_b0g@Y5#>&3z%qU9&*e<~9`
zJ_NmoZ<YBMcD_nvZq_2lBA_|HI$YW!o3GSz9u9l(Fa4z`|IR*#F6&X_<Sg~Kyq(mf
zb1J!zK|FCY4ZF9d6w{^SnJJ3RYw0h(zBl9TUX8@vvCKAZtRZ!jA4G@YhEUk)2y}>?
zhfbiM>HA4{tE&`c)5nOD>y^Gd&Djf_&Lb}rM>Wyhe;;Y6b9vah{C{r`4BZu`l~q%O
zzm_42*M)kRw%&;)9euCtPXvg8lpgkeO57cV$DSz-%EqST7Vb85Q6#nBg1VyJky)GU
zmh>B0D%nI^e{jA6=tf0u-G>95a2_l9zsqStu`^<o^$aj0NI%qQ$)DT(E<J2pi^buM
z&WAt5VF(H)efQ_2zQ`A9_qfP6X?46=z%vez{&XK&RAxgOAG49`x_IrEl2Cz!yC99l
z&niruANC&zmPwI#0@u_Hhb3psk2_NPe;7ZSTj;7i&4;||q`U4)ZxZ&|WW3iP;_Oni
zRtUo_Jk+1pP3sxuC4&M@Cl73dc<hB8uzNsr;bSf%u5*U^Is8|V&E5556q%lkWXy^0
zC~}CJG73=aT;-*^fPt_f3YJ7G*K3FylMLqddCIG=jlU1CJEO{?c$_;b9A=Ua^JqD;
zoih2?e>^*aovS#cl)!weul4KP5tE04v4{P9Q%bDNaKL&F56CnpBr?P;#7#GchssnC
zR5vSm?vVXfkU_z`6wr=3V90`#9++m`c#4nNp6%Qw*=#YXjfn;&QTW-QT<|All3fwa
zHToT;3I;kA$mXjTfvKJ2*L=Lb($z|hT9C#575w@vl_W9g2mZ@jOl4h6yeb9W$gU6z
zN|n%@`P%wKW*hD8*_i_KsGh~dJAGFs)B*8y4hosKXWeKunzT=AOH3+}-^!O{9xivM
zXSq%M=dGlgPq>7b|L&;tzMw%qeMpxlwxzeD^*K*kiL|}@l4$T(of;F%4mD<S9X#?j
zxl4vnCiq1pA+Nk-1W~YC3Y9!A=3kXM{&miGIUerES3%N&+imFgzreAtw1@w#s7#d>
ziH%8^Pq}InT8{i<A^Dk*9c1w{)#=$ua+<v_D&HHT54Nq=isJ;BX6N{@ukfBzxGRg(
zb;GbTpJRD|6nOmPJw+_=$FhQ;Ae5f-K2yNlh!A{lH;ml4+3x1lDmR8(-;p|>T_ATO
zgCaBj{8jf==acTm_$ot_gewwFsvq6MzUQ*f>i0vydDr^c&z5+WsAEz<I!}A1Ld|BZ
zlq~QFbM*j#2|70QJo*JCVH&utaomGsK|^dQ(4b&U`o!TtqLFK<rKh&x7qoi<>KLQm
z!CyCgYvx8xr%R!#P({*=t*lCUQov*~2B5tE^?>Ftt8E@Qy9mor8g}LzziODN_<1uV
z`Qiwn<@XQEq}&{p;w7i9X~%(+5ck-|Pvw-T4U8c<^CB}!@*3}TT$_n^F(QFDNeyv`
zPwY{j+J#+@0eROqV~br^CfsQp28K<if0Kf`$se80;2pYE+IuNJ>eN;_Q1Pb98^hTg
zCY^f;p*cw40oo7ZK!S0h&#dsGX3;TTl6>^z?mHKQ$6qRu6Nt8c&aq)5Y*PvzPPA)Y
zz;IN3VbS91T@g7)$U|FH<bG(%XWlCJ$@xpK;EzXsaIc;E8(wwtQQP3fTDuC01uF&<
z*Np7OiR60S21j0itsL~5zL_)63TBugy5!kw9}O-ZHW}-;e5*Pwgnjs!wBcl5E^FV!
zK0knq<TWqnJm1aeG^A3|U#HyMTy0-p-|t05VI#SG<l#Jiu)ZBfwJL$jLqtqL!D|72
zeq9<$TK>?)qAjoeuVcL?U#^9OTN%p|Jn7_;$nIwnob_{ldvVnh+p%OjJf&*(D<fVQ
z2W;o%8;>EMpadq%B3l;(e8)DV+tpak2AxgvsTU^mGexl0P#%9AG$WZ%<*pwYk+-SX
z{_AOYZ}4fqdR*a+eGNdm_&+W&0N78~2H-9L1*2Q&liSS&yzbxG_~`xJlj+d0o$YTs
zw*ktXj*gXWlz%0KroYA|yQaROVbKXW$r|Vt15+BZFfj4GtA|ok`drJfxzW5I38T6u
zF-dEn;;a<O-H|u38Bkm^U8X7+_u(?lvv5=(McSP3dasG^{aZ$zr=JSp0h}uSuCCjm
zd3%;5tZ6C?0zytXLSDv#>BDBoM+wEiM~VqVKq{fjW0#Q;Uiy+N1793EL%DrX1^syf
z@Vuk>3~^N>Lj8&bFb;nlIe?@7APc-n8k4#~IM2gxx_#$D<QOR|)Zgg2EoEyzJ(?ix
zSU!$b-<;NEHoPSQQljI*JVX62-g#Lb_sja`J*~P+-KU56`8K8lt|KEgP&8hDCyZoN
zu`_;80GyT%RU`D+9yd{dW#Zx~qlmkGGT5JUl_w5G*{21B-E(Jk)TIRHac1Wqn#*qf
zGSFg(Q9<z2lh`Wit57iWF`1r8N`k?b*hr>)JL~O4ei<gqG-aCPWEo|Y>NIq_{6=^^
z6X<T<R_~@bjjP!1@sf($KSWxNFY-XNMcAL1h+FqZqQuprdsV<~l34Z4Vn}`fDq#8S
zB!WA;!*pH<h8>`w1VrPsnv?&lXyf~drY^nGXIn?bVF9JeQ;EsTe#a@j(|7!LJ$$)7
zS9?&&5>Sr<qNm6BmcVnF4v^g2_%w7zZZesr!jfb1be$~==<&t@cmu@gDaq5DE(>gG
z^zY#L4}^hf-bQ<di6CahUi}I)uKq~U$6qy_7YziG4|C-CzQ^ju2KZaCj0#+%F{>{d
z>&Yt<k+G<6l_SL5O5-`z0I7BBOv)O^x}`uG_EF+WY@%Bg?I`7t6l~Z(SmsPH4CwQ;
znvNdbpJmSzy;to$Iel<&K%X+ie0t;g+0zp)&*ipXs%>QWdE&cD0r>t!p9@m&>}5cy
z_~+~8H<j=mMC24GjAy6kjh>(TU>JvsIK08(5MxMlSj&^%D?7z`59ORgsf;|&cXuKJ
zV2KhNtxnI5#)_7dP6S98nk3xoyx&icI@fyeHNL)em-4eb<4}M4v2vHjPQSwh_;p>E
z5V@E#$3GaxmrN%xMS=max6FKA^o1ZdOBDJc^Dw9yBokG+wu=S3K#vt=2V(<-qN4;R
z<9%ssa<p_SCw%$QVg+i3fX0D=<H&&PbIEg@;7C)1AfHnOJ`WDaV&~BhUIr*dWgS4y
z0(}-PQ{KODz8hi?1L&TZqyAV|k7K1b(>I`_4Hah>nUSh@N}D<zh>&tS3*ew$xMB|^
z0+d)O^_{H6GArO0E+=PjW}__f;p@4&rTbsp^yci4Hxm%P`hZCwo~#0fQ`!&mHc!P8
z9DY%xyDi~WNu<LxC63gon6^8NkawwEeUu+mnPjp4eE1=rh(5GC7V7<G2z+hTd3T=%
z=!_OMpW;GI(wCduFG-n*l7QcPHVI#^_Z0Z4t7*24YUYrkm%V5BNea+!ts}t$%C@l&
z8hm8-LKMWvvN_*a6+?p0*co0i?2gBbg@WqDb_b<E!s&i~ey0-w0sN5H_N$bDK>dZQ
zS{JZcNWWbH%7E>cnD3J1iOiMqs}cO#lZDGgzX#IKr$G|d`=T;K43S!8tG#XTC6S}=
z0l7`vKl?h#{k5bmj%MV{b5i5KBGIT^@<;S%px<)UUG6_qbmiy7?&aC%OgJxFV4%%O
zbbQ!~`&SCs8GP{*&9kebUmEHmd{tp}xf^6M8B~&&mFi^~jlp+MOESxMAYonY1SP{I
zB1l##)guhq8#;KC5gQ}ZPa|oGKES&0q8r38AdC^D-v9W3$_HY+UqL<$3iWpRJ>u;x
zUq;Cft}+r?JcKu}0mylNgrVPtK+m{+&VrSzg*u;NBv=oS;bB7(QVel#_`(kW#tYs@
zel>OnNjt7;L@-*;!^(?Lin-bls{k!)<jv^AWD*+ReWyRwydyMyc=N;1-|1;9bOmq;
zlLP8ohw3nLTn2OiPTt!dw>gDc7z$ld<ZtC`|F=o&Sf;Tg0Q4aBhDBLU?6nue3UeRI
zj0Zqkx3|0a&Zb}AzgqG~&|GmhAD>REQ_t6}@76r^JH1hN+gJQhG~=RsCy!{HC7fsz
z6%~~;Frb>%FL`%o_4RPy`9A+?G0sWsY9+pc2}61X8vRayU)+*!z@IXF^#S1j^JMvM
zG(*j2l-QE}>k|voH)3cG4WJCBWmA(wcXl11uux*7r`Lt{i)<aQt7WP%;uEgi<gH=8
z?@`Q>ixwZ#DYp9|M{kGyniU(>2_e`-6A>Z(trt9w!(#VLB!Ntk!Br}O6nCp?yKz8L
ziXBBAf_YLom?)6U2Z(?b1~3185(B`>p2_Xtm~gy10{~P!#5rlMq{IaawWC}K?}ib=
z1d<ZhCbFHsZoNl&PNq4laB+5VLBiHWHUV_}!^AuY!Sj_2sKR^UZRm8x({KgL-^M+m
zN~Z>=JF1<}w^>3)eyZjZ-`_3rt0pqXriLH)DZjo<7tWh+Bo{GQ?<O$9mpTT}W3wIq
z=BOEelXnwlz@B!A{d&3fSumG5zaDZpb36opotO_p16&03)+(H;4)g|4dcofsFk^xP
zO+lEc$t!M(2BSXWR_WbfAR&>yzW!U7S?0@BZCfY1u)mazPO`WtFZ0*uUIc?f?OeC7
zuQhpbXiWzBRbk0P!s~4)m~^>HD0Hd6nRfTL4Yi5Zut1dbgPz)rmhMYXt6-iNh{o4)
z!lGBp{9M>XGD>0QWv(270sz*u-!P|PXD2&5#ogvevjaVpEF)zwIl5Vsfd?FSC3@Wn
zaX~dx{eyF_ZPv)wZ*Mc*#Mz;WE>sSL4nX4^?*6W)MNR3-!!mgCUdRZwhzv&P_EK>r
z7?0Z&?@c?n&hPHBUtRp9Zfo{gw|uFNI*ukt?wj(#qjor_J8=OIca2UDg4i6s)>nTd
z0v>OyZEVOxv0sP2?NRLd>FDiG22p}dQe+fIeQH6k63}<|0S{<^C@^iPZ@yBcLO^UU
zO|zJv--en+LRun2Q{D<@%TBwmwvs&)!9G%?{(g7e8DXf*LCq2*V}>n*Ti@W(#Sa7m
zFGC{7=O@S_;-8Bm8ntaa7w%*NJUgDS%l&!x=5=BG{Ip0{7@S~CqHQFhh|b{432}+9
zHbL@`?Q+JJRyQcbNo-tSHuBf-lGg^<6W;2p-eR~+%-(TRec>e`I4NihH#;yNbj$O9
zx?9da*vZ6~%5nz3^a`I-WtIVwW7V#BkoTOGWB1UNH|eG)3nc%;l*h#oKiy`i-tuX3
zZolfJKn|C6i6|zHWD8OGULAcAPE+b|SnUZbgBs!)HpS}YN+>WUYbXs6%Xaf~DX^J>
znCrE{sw9x|i3#@sko}G%KHu+iGuIboQ`?9|UanAjxgNzH0`a-V5HK)NfpPV2qLC1_
z(TM>lo6)e>ccp=6$Vh)qK#dYKo)uG$1H>ngR>T=i;NE}elD(>Q&anQxzuMVrJKV%T
zMgn`OI|RZ?!bA&Uj)Sy>mT&c3p|&6Q;8g?P9kqJALU`9B4d7-@C02Tf<vX#XY=NV8
zA5QF$*6-4efArA+sJECe)`HL8$dnldL+oQg9wISm+NQCEU`Uq`yrqRRwE5F|$JK%G
zjHK&N*U>WFj*brT6lMRCs;Y;DY50Xf+2P^*^$4C=7oP~I80R%caug$R6l1v-xip9_
z+b(Eb7{nG&hb>#biFn>Rw^#{*k>h+0g8X*WJ4YdQS++;pp@gUpXzvqM7$=q|!tAH}
z$B*gs^*=r544GM4g8CsuGzYoAV0GKCwnGd&CMG4Q;ty6<R?&{X5^Rm+Vhspi9w5=^
zAP3JR&9<xNfVYI#tg)ol=lkJi-|7k-J{w?%(VZ8VlRY1|QS9QP4N$hIhvbMMY?dg^
z)41Bzx?wkGTO|Sa>#qXVI^i8n9tXKplFQpyoWr*WDsAMr|Kt5x=FuG($iV)J9OI*`
z;xmV-+8X-OBn1J-*s$c%A@UHa6>-Yw@7FaDVy7GN<xjl^yi$)t3A89bZ2w8DY^>#^
z&`}Bb@2c~*K;w>@cMf*)4n>5$uK~tO7rg(@<vujWAH1Dn42S%XNA6<QGwT*dX<&mI
z{@TV$J7Cav{j8i2>VyzS$q`EvcJXqdn?-&W#UFDwL*Rr;2R=8O^n)x|=wKkGA}c+*
zDzgmc9x%Fvqh>J8p%{9wyv|l7iF1s(8+uxF%)CS$3fQ(PNVrjD(0Fkn+ZQH`ig5dJ
z-NQ5&;QFTX;lM@9@3l*_!;+D@n#aMjiMeDX8Pb`pGRUvg=D_X&D6wI)5u!^jmg7zS
zNF1rBOH=7~BYxI#%&q6O$lK~ZlV~<(()Oa6YsBxZ|K5lt%bV1v1HZgD9Uot56I%8~
zCa5(_$D?hfqTl?n`O=n=H0OPxrBfs(W?irbt@S$MuHQnKWidM<q<a(tF@VqNlcv(^
zIdFagg;H})hO@qqRS3GgRC68W0lPB#*Ll5F4C^lN*M-JG9ba^AS~P<rHQArrc%VRY
zJM<PqS}raTY&H$I;qCox8Q#qBEv*k#t=l_!Xp{VI$K(FCRXjGM;;cpgSrv$?nm<dL
zOp9iY=NwOx0$mzqej$C@sHv?tXvh*52;5Y{iRED=R<x~JxiMBzL#t}h-WU5pzTAGs
zQ&EAHZqmtqGc~CmP}J1qHL>J{<YIZuv&-7kuJNxkbB$MFj)3aEv*cvwvzhnYIDV_z
zFsY#wqQH=;5_I~O%RM#~*MCL2KkCUIBm5rRRj!q8LmO~^0tXyt5pLutQTNA9NpTrA
zk7qr#&W7-WheW&pnEu*4RbYhB(O*jgRNu0vg%c9z>4ZUWbEuBR3CNm&^nvbZo1bus
z%!zWS0HA0F2G+Dfry^2ZhF(@3rIp3Egy<k{U~g6H%3|Q2Hkh9u8+p~;5|m_46e9Zo
zR>gZ3U04qo6B8>@$trQ=-}8V#88g;P`*-E<A3j|lzxFl`bQHv+mm$O)ms2Q$Br2_T
zb)#Vin=Xo!$r0;2G*{zEMIMIm#DjsaVWCberdgh;@Be&C9BZ;bJ}xORLv-71aU8~)
zJW6<@1V|7*&+v>ZwifZG?VMMP6qO#x&=B>`Si~7r==sj?<Qt`8C?R$*VA_6T{Mhf!
z3p49+xkN}8fjBmi`QzR{zCkzc|4e)I<Z^-Q3!;t5{F~wFaJyyielnf;%+D_w`cdP7
z=VsbELMpwXb|5f58ceI*xd$x#+3_<~4w~G0V`0GQTqA@R61V2WhW?h6Y||1*59|um
zeFx~7vyH2+dfh{aGZ<un_+XQiWS``kvwcAEB>0-%)`?Ar9lMusYa}z~Yc<W1k;L}l
zzP!2)!NM8M_Rg;SSS9T~68^^XDLyw_?VY{Jfn=Pp4#>u_UKKcM2BJQ=5d=PeoPbcv
zJ8&oLRkulw2p>LH+&%5K-!}fsc{<6i{*t2St`CS*By7-$1I0-fZm~Uk_{e=SGR33?
z$=B%G)rOh8s%I%IO@n`cTcOd@2!w-;ds#$H+vS4hdjl-PCg4~Fs;Ir?tb6wZPX|@d
ztDV)`^TA;ZdUP9V$UA*yurOc%yf6_;YWl62;k{r_LGRr}mV@kk)wkWdT2)d-S!X$m
zH{o_Yii|(JkhGkJuB)Zl0x3h^*0fFaQ|b_W|I`&g<Q=O<O~IPHVIp-~<~K~k2To%y
zzSv#(4eO4G$F68H4if2=_q39+T9f9rUtmO7mOmE)9aX=_DyD6V$C6>m7_H`C-_f1d
zns%dhS`7!ZTRp47%z*EaSlH$*^Lh@Q0=-rB-r=F0!RLwOUmB#S^D21Hprl)&7AzlI
zhfd>^TdPmrVUrR?Dh|gT%NK2JriEG!mTSr-HqLlHr@aC3)j4VTDRSKY>|}<hh~kZ%
zB@Q>NMQiC~zUjPPOUu9R8$_NAsXtD8J)`VlU~dNU@84kaGEhrt17=Xrx5DjTlzO^G
z{z{Y_#*{6d>lYt-rifUe@-P9I<_{;j+2o7&(fu(1N2z5`3EG?sbiG>hunQ#8cdwO0
z$LJYOClk`kJ?~8juDf-9gh<_(*zLPfS5Bj^LvHyFh!;?9|6ZQl-gVJKQiMH+PPNLz
z{g(Run}Iok8NbgXIivAvICPCm=CafuK$0cRFeB<Bjb2;37H?PASk{IMQ86Y@JdUbw
z9;s%Xg>`5Q{cHWU#2a%O>}kRljLMtDN=4=yF<aD7t6Ytl#HaiZ?hlwj1VxO7O-f21
zBTM0iUmtI3Y#JaWg{2)2nR%YyTn&@{&KU^gF`k$fXlf|Qu#wq4JDSVO_^D?w21U6Z
z*l~=h%cFY(zyB$@ID6GS7;t_qRXka?ku&dppu+6Ll)|R_Pw&aQ2Im<GANgvsr}YPg
z+`(Rj`XRgy?}Y)Xa_J+vVk~T-fioZIc!+|8(HMfQfw4P^1<ZhfGL0lvnZiazCnA}*
zN+@hr^{hDbGTgI06k9rZhmFE}zJx?L19M({nScIXbzVuh`0W(n(cb|8Xixv$5m1y4
z)rCrMq$yqMLQ|L^HV=GxYG5!0x>>i!5(8xDvAbZk%H;0%>?6qs`Q*1snat7lm+VDr
zwFEMnIJ$$LSZL;V7Wa-dLmul6=pU4%%QHwJeR5HanLMHvT-_jx68GpskqMv3Uly@t
zs@a{_G=Kz#EOjRow{sbiLDaC)5z^hCDSb|V!U)lxf5{Lkr*k&Q67}%Yd;OeAs-W`7
zWMHAE$JAi>U8+>XXlXd2q=-|7E~i4u#z;LFwAZSkgip6yS2B{~p+<-fSQA%%ZBZE;
zNj<T>?5)}yRakiGsSRKxnojs$2PwP1zdS(ntGf6`aP<&IySw&AT9nhT`-_Y0rg6qH
zgwG_!6|AYVS;;{~FO(ec5kDuqn#U?M+0|d)!Ub_YwMUjj=cNg>jG>N8N!?GId_A|=
zEAQ=<-I<vYzr~90i%-g+^O$I_R2z&YzWyt`-Y!_G%QxVVEZ4sQ01PSuOy`<hULiXD
z1{pG>FH=*Zif<?SVu|2i`+^>@9`}_A{Mc+qHj|W!SFt4TyF!k9E%t)2#;#WHPHZ0h
zk+Ou>*r>1k?<qnhgTZe>n1vh9u;FG#(D7#HWsM<sz|NM`9o#SS)H+u%$9<w*HAf#j
zpaQ6BdOCSkt=IYWCJX8J<TP4Q(-{hB!4_nfwwJ&4mU=TSKedMmEEJ&=y^M@|M%|z5
zz0CJ!s#Y7F5P7$E&y`vvWFm>^Pu2I%1abcM)durG0f~3{UjEm3>Be8?4P3q;R2x%K
zeJ>B=%hzUr9#aIQ=ASF&X5+Hd<w*5%A}qwbFI%>z>c%8}R}7vm4}{?NryMnk#r@3E
zS;E}lfgHWM)`h3NHe>_$?852btg(BpM}Ikos?_mHEB7-<8jE3u#RU&!?g8j!<{Hru
zKh5+69ft>oYuaJ?Uv_tXJo9~(X>xyh$ntbnCQ+kB`S-txoxuY@!2IyC_s$|mP3u~<
zA-C6AKe<Vz@0Tw*myMoz!<#F@QEnl@g~pW&ISF0w-7L|2dogxjZ4-DMEmsY1p7J4@
zj;_xJ1C9%607`P7_0dQNB`i|tRC8EC7J`B24YNk>kL^BNMrkU{>6Sk;t%~i80dx@q
z)tBWEd-aB0C-<e_XCY{^@cU&8WB_fTZ|gx^**K#D2@8HK&x<aU#J)Mxswmt2V2eKv
zN|BIa_E;<TnpdgfRn?2~w#2ZgkKxUn!5^BYuptZ)nBPV><YrWZ`6uMi__1)aZNH;r
xq1%0r!u)R_GvznMMCL5pz-O-iua3u8G<pgh-acM}&o_zy6yK@IRm+$L{}0<tlb`?q

literal 0
HcmV?d00001

diff --git a/data/pixmaps/filter-menu.png b/data/pixmaps/filter-menu.png
new file mode 100644
index 0000000000000000000000000000000000000000..037519f9dcd2e216430a8a6a64974cfef9f68aa0
GIT binary patch
literal 456
zcmV;(0XP1MP)<h;3K|Lk000e1NJLTq000;O000;W1^@s6;CDUv00004b3#c}2nYxW
zd<bNS00009a7bBm000fw000fw0YWI7cmMzZ8FWQhbW?9;ba!ELWdL_~cP?peYja~^
zaAhuUa%Y?FJQ@H10YynfK~zYI?NmKW!%!4G_tD`MD!4hj8GKMkLWyMTl7hdY{s9-q
z(3Fgw-Q4^G?!_?>2^~bFV}F8zgBc9hsUb~YqK$1)@W6$0&%M0!xbK6Q8M}no>FWD1
zXqAQWczjsQN2Aee6TQ*^z{`@vag4!WkQW@sDQ=`{(^O2fBkCFkx`qJ&ShV|CwEJs%
z6)$7|X8-_?^LfsX-|w}06<-50uS5_8yoBd@Je*8<IGM8NdAVNf(eRb^{{B1oH~13T
zYnrC1ws}(>0I2+3hhg|eL@fY_qDU5NuIr`%kY!n}3n4&6DF86@hwu9bwFcWp<1<i7
zb?WjT87QSXQp#t`vd#g(w(S!s<x{WMJ1zG%9+7F9XF`ZOBD!Jb3nIEolH_)41^{5&
ywh7>YnJ;Iv*|oN*{5fqJN~xo|`tQ9(-^C~Aq4s7|cda@A0000<MNUMnLSTZTzQq;*

literal 0
HcmV?d00001

diff --git a/data/pixmaps/gnome-lock.png b/data/pixmaps/gnome-lock.png
new file mode 100644
index 0000000000000000000000000000000000000000..7c2c69158b31e9c1b245ad4a6d26a6e2e42b9d93
GIT binary patch
literal 810
zcmV+_1J(SAP)<h;3K|Lk000e1NJLTq000&M000&U1^@s6#I$TX00004b3#c}2nYxW
zd<bNS00009a7bBm000fw000fw0YWI7cmMzZ8FWQhbW?9;ba!ELWdL_~cP?peYja~^
zaAhuUa%Y?FJQ@H10;fqtK~y-6wUxVX6G0Hhzd8HtIF5<)5>dK{mWql7QW1I*0S!V(
z5fLq5h)jVfurPikiV`6Kp+ibThlmnH0}V7(`~f%;j>$uI67QWI-|kTO?(EpknF2;S
z-D+p&H#^_Hh?(&}%zu(2l}eoR2ZB#nsS7o$*5B;Y{rWy>+867n`ZyMgfA0uj=C&`h
zkeXduUNpA0@+_s~R+G}={MIjCT3$3V3#r*o3~H4kkxrbAMj~Ht&)f+EfMwO7l(J_5
zFc?G{bX^C5@N(saC><W2kKd2~@RXvjCzQE5bv?|?*v$Rpwe=4|2+`L(CKT!wlb0rY
z$H&jm^p$Jj)z!Bd0GB<%)uZaf(9kdpQ(%2#ty~u7^js{y(L5%Zd3y2Vr;YbFZ`_KE
z43D6CRGnz$XssQ7pFaoyN-3BXGeC;IwT^js@6l&N7!j#tJ;q;;@dOhQ06?)qw~ffQ
z_D+l^_*hUEva)wTr*W>vsqC{UANgJff&n*3N*RQPQZkh|F*&n>=JO#tpDIe0GqJmK
z@9IuFYdV`Onx@Ij%)%)1?%sCW{%y6wcAgIoOI)*RyuV-KbT(OZc<ziX%Zdhr0qhlb
zpcDgO?CkyqH`VFvdG`-SS(G6Rfr01{EX#_vN#O)2rP={aASX|w&0vtbkR8F!VmK%5
zWDo#u)I!Wq>;Yz0?u@-aZrlD7p>gaxf)&@{%$^|o(r9XvH(1$FR;mlgt)qUE5qV3Y
zlp}>Y24Y(h2h=E}(Wj(r2NO~FdHR{CR4U<t{y{sSseDIky8_1#Zom!GfTsBb5rvsq
z_=#u`Ks1-j&9A(9^+4D4W10Wv>Eik+MJ~5F58yNrl?Xr&fIa}B(a}-g*x1;quA~l@
o&*u*cg@OcN0w}k=Apgq#04yvgeQPwSNB{r;07*qoM6N<$f^>yyOaK4?

literal 0
HcmV?d00001

diff --git a/data/pixmaps/gnome-mouse.png b/data/pixmaps/gnome-mouse.png
new file mode 100644
index 0000000000000000000000000000000000000000..0d90a36e826265342e13c9fa81ce6d0561539072
GIT binary patch
literal 2744
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

literal 0
HcmV?d00001

diff --git a/data/pixmaps/install.png b/data/pixmaps/install.png
new file mode 100644
index 0000000000000000000000000000000000000000..24612cc208d7bf42df506453cca79d17afbfa13e
GIT binary patch
literal 4180
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

literal 0
HcmV?d00001

diff --git a/data/pixmaps/network.png b/data/pixmaps/network.png
new file mode 100644
index 0000000000000000000000000000000000000000..8808d0eab2ad59fc5df04661862e67251cd0ccbc
GIT binary patch
literal 2458
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
Y11C>u;LlnJv;Y7A07*qoM6N<$f_k=DIsgCw

literal 0
HcmV?d00001

diff --git a/data/pixmaps/partscheme-all.png b/data/pixmaps/partscheme-all.png
new file mode 100644
index 0000000000000000000000000000000000000000..9c7398a66e7adc375bdb5105a8436dfdd2b32fb7
GIT binary patch
literal 1594
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

literal 0
HcmV?d00001

diff --git a/data/pixmaps/partscheme-custom.png b/data/pixmaps/partscheme-custom.png
new file mode 100644
index 0000000000000000000000000000000000000000..ac4501fd84c963bed888e38d50e7f27dff7d92b2
GIT binary patch
literal 805
zcmV+=1KRwFP)<h;3K|Lk000e1NJLTq001BW000*V1^@s6Y6VT<00004b3#c}2nYxW
zd<bNS00009a7bBm000fw000fw0YWI7cmMzZ8FWQhbW?9;ba!ELWdL_~cP?peYja~^
zaAhuUa%Y?FJQ@H10-{MoK~zYIy_UUe8!;HhAAKDJ4q_aaWC`&Q@L;g#e#C2_B^~ky
zv>x(TgqBQ&QVgC-CU<Gc9z1k#9ZzYyWXYPzkYEz7375%;oYcYS(B0{r8dJX@?s(DZ
z`Mr-`$tE8^eJBt@zA?sLK0G`SEFgpsN-5QgqUbHBlzv$$uDsfMv4v9U$&5>BX#KDG
zNkVHN_!H1yzkhBALD1ox^ViRwKF9w4``JsGBMuJUq1W$ib15ZTU0nqLEH5uFL_7>b
ztgWp<O3CR$6dhr<XfA-Ir6qWtHx~$>^#kAcvAesATCIjcp#T5~f&kra7pJGEGpsbR
zU?v9$AsCOx*xcMi7={=O1~@xAL#b3kv)RPP#s&zP?IcfifDi&g2q>lTJ0S$ERtr+f
zSgca1!1sNuudib?8bNCftu>TV@q0Q<$_ZdZ?O_9Gt>Jkd7-QJk*@5r-xWB*0#l;1L
z5D5T#xIi)hlu|IpG5~1^&-1Xiw}*1MjNx#IqoX58DPw@NxKavH6hSFvJjent#^T`u
zu>tD!I?ClTE-x?9>2wf9QEv4{m=J;}in0zEYdGhz@H7ZYDXy=taeRD?+uPfCzOgwi
zZVQ{farS^Mp67-EV2q(yEJ8{N&+`&Z_gK}rJ>U}0bEDB{pjxd$DTQ{sJ+*3gBzi!{
z4&=FDgHTFwetr%i1V*C~IOhp~JaN~N<o15pXWrg-7s%b+9s2z~06+*4S8fX%L9;EC
zQtK2rw!rT4^d;nip>%SQ8gX0H7EG^c=4AlVVJ5qt2F8S`Ebp7VNc2ED45j_FyWHgM
zo6hykqX1^ka5$Vg`F{i#La3{&D|&eN8MYHia92KA*(9I$qm#|w+}wb3uDMd`>yMM(
jn??O2Ho-a90KWePG6%Bq>?(fW00000NkvXXu0mjfz5rn0

literal 0
HcmV?d00001

diff --git a/data/pixmaps/partscheme-freespace.png b/data/pixmaps/partscheme-freespace.png
new file mode 100644
index 0000000000000000000000000000000000000000..47726bdf8ac2a329166a4f3de8830c83a45781a3
GIT binary patch
literal 1724
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
Sqx(|;0000<MNUMnLSTaEojtbz

literal 0
HcmV?d00001

diff --git a/data/pixmaps/partscheme-replace.png b/data/pixmaps/partscheme-replace.png
new file mode 100644
index 0000000000000000000000000000000000000000..6490d7279e899f4c529558bea1231abcc32b6c8d
GIT binary patch
literal 1783
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
Z^8fxBcL8dXm`VTu002ovPDHLkV1i3^W#|9^

literal 0
HcmV?d00001

diff --git a/data/pixmaps/partscheme-shrink.png b/data/pixmaps/partscheme-shrink.png
new file mode 100644
index 0000000000000000000000000000000000000000..d86d40fa3a01bf957d632e7f7c7688227afc5925
GIT binary patch
literal 1875
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
N002ovPDHLkV1hegbOZnZ

literal 0
HcmV?d00001

diff --git a/data/pixmaps/root-password.png b/data/pixmaps/root-password.png
new file mode 100644
index 0000000000000000000000000000000000000000..0125821ec86d6501fe9f5fa7215b4f634797a20d
GIT binary patch
literal 4316
zcmV<25F_u2P)<h;3K|Lk000e1NJLTq001xm001xu1^@s6R|5Hm00004b3#c}2nYxW
zd<bNS00009a7bBm000fw000fw0YWI7cmMzZ8FWQhbW?9;ba!ELWdL_~cP?peYja~^
zaAhuUa%Y?FJQ@H102FjZSad;kbZBpK07_wNbz&e>bY*F7Wpd{G_b&hd03mcmSaefw
zb#h~60BCe{a5^t9YH4k4VPh_Bb#rNBXklz@E@OIWX5(G}01ymGL_t(&fz_FLkQ~*0
z$3O4A?&-O9XD{upjul8k2LcNrV-P|Z8-pQ%U^@i69G`!YA`W&!rIOf{GA4h-7Y^m4
zD3|THTy}7r$SEIj;sR_-GB*VZ2oSo^wTG_RonvQqru$v_V`jxl+SMvns#58yH&Zj+
zZ~FIn-{0~2H^O_*|K~&gUmI|tM{vFue);QPUP0nMDv<?n9o~z)wJv9!&Xd@jY&LQ-
zj<Y05nz$K>I7!JQ4ioEwrj)*^q-n|^Zc35FQZ}9Q4QEW#c{gROo3hr{tu-}gY|R)u
z>2M|Q#Wx>)^wAUNvP+zg3qADELzkqY;H4|qZOCLYS*esn$$%gX7~Hm%lr>N&AUZn{
zg#x0x8(AnIJ3A5iJl+^wsf3xBz)nnHibdj5iMU+m^;K&qHyYHclT6lX)M}H|>vbk4
ztLBXZ`%hl8@!BQ#-+#ZmFa-h@c64;|whdQHYb@GmthHEcp*W5{upehFuGz#T3AR?l
z)@qn?8B?j?Gnp1#E(hr}q|<n%@KVxTzKTGGWV3m~AVoIHP|r44vS=t6Jv!3)+;h(@
z0!A(fAQ$DHtyZf$pL*`e4I8hzHnPT|6OGmyd*A@-si$zxVXehE*Mez(Hr7HM<HyI(
zI;VqxH#WT!t@T-B$<Pv<n{(k$9p@Fqci(-t_KsU$dgZ0VyY}odN~t$b<~!z`7kf|7
z<Kx8H*$uJj%$#$TQfRHCMx#+Ymu>SZ@bJU`Fl3C_5DW9FNZft9_w0IP^@`Pn>DckP
z+*xxxpuOj~bM&WR)H@a;&bpat0|@MC-wPq|-s7BeTeog){>}go{@}q}Mntc#Saz`+
zJvOQuG*XwZeT%cs5;tDQHlK%7MC3g)G@+TdbpPlWxrPAX>c=JlIP`m2QpFaa1LAa=
zLUuR3g}v<DcjKw~N-2y<5Qxch**7mhb~3xR(AD8@yY&w`y!TjR(ONS#HO28_jt=_}
z3*LW}ld6;a_xn(7!^S7!Yqw<?YgoSic+4m72w7kSch+H`eND2_v-r=Bv2N{m`1ZeS
zLOYEVEsvH;k|YUIh|+uj=Zpa%#QsXPl7`k@opm_tkV2BlWZ3%rMIhkiM^kS)fq;G_
zAGaNRge*}6?@!WvXewerg$UWY<;b&wZO`OEWEeehF-pFvVW0wHo#2Hyr~l6jaL+yW
zl!OqCsi~<m!N}+GkoqGU4Z$TJnxyGH4eyEnxP<>$mAnuXG7=$EbY-)2b###X^TntS
z_F|)m&M3u=?~QnUf0|r=Au|($R1%$Nz#pFvVBR1Og5W^4TDc<Ae|pA9r_;RU@{MeN
zx|dsSEMl)dgixR&4<barM^dnP!t6RWZeN9v8D!AF>SM&87-q<i6K3i>{%n>giV#8|
zL~C)BQq-F@y!S^h7{FS$vs5WvG0;DF+V@gQdV6|#W@HmW{G1@$uIM5_MVAtFZzhN?
z10>F##3lQ&@qU~hA&822pWv<I@Yovig%AX^Us@?NNu2k7^nwAjj(3cg#y<e0&ODdR
zW?8%JcJ96DH<YXaz<W;+9w11KB7*?DZ&mFi!5ED-rd6Q4M=o5<+MBK-3`0B~DFs3Z
zf*>H#aSZ<C1p^4rp5l11i8vcTDaGpLEBM=NKYF?fPgmQ9!#Rt$7V8|&fpZFPX;ot9
zIC%MHs*73`*LjB!5-BA?portxc<<*8;`7)__>=Xi`s{E*5T+u!l)?$o+DZt4gE!y3
z$F|>{5T}L(PWJRL6$BV#z=4;(9RmSz96KrJ&qDJ8IHxK}5{tRcPp3ugJ<j`crZo#B
zGj3`#nNtfPq(C8&s;xj0OXuW;rBQ%XDyhVAJSV6Zg4lb?H&5ceIYRBjB}&nZt$`4j
zAfSG=B=emCdVic|s{L!zdm$kNN-C66NGXv@ktA_ojJa?Hw2mrBeU|^9I+Q|t&%s{U
zyz(;gLp!OyqfX_E1+uS%*fq<^e`1KC>ryy#gl6>(PO20`ZGcw#Y$*T|sWo8`kR(ZD
ztsS4wzIhe6_uhMB=bWE&Ybzw$d&<ukRI~;aT}tO7$H13L)HZk1`>j7=;d}lP?<<(b
zv%LI*K)1JNrtLyf3If$qAP9oia|Xm)w{A5T3;+-))zDhcdd^Ehw^HQyWO(hx-Kg|>
zRO%9Bl&9-+H_?5`&B$N?sRqD1c6?W|PzaC`J6*t}L<IqXQUpq2j6q6KJs;c7^Pyf?
z=jT#DfDo)tr`h_&!|1qz%3Q^0aTSA0--)*+ASB3K#f}#ivUEpCS_n)g+n(O?{~%DP
zAV4aGbrz8E{~CaGHk%4&4+Gh3f)J#n<hqeg9)92@#*Wq)TDlgikCRO8Ku<kKxdLx|
zwUZ$!34{Qp5JDiOKm{$=QA!~Ir2_DN?zo$A%p1g8wro+}`%nc6XU|YU0BwLkN`}Ia
zOOHT48{(X&Ir%h7rl~a~Kl`@|m)R6OO5vPC(8~ERtw4x#7KA`af#>`H=2hUti4$F^
zR4O^^gaCm+#!ZA$2&I_p6I}86x1ho_COJWU{O43Be#_%qPqOLOkFogE@4|O>f|LmF
zTe)A!)(Bcvc)E}YA;SL+01<{^S1L@M7Qv;7*EqcAuPIOL#5EeA6cZ7s`<IjHDqu~6
zsmc>1y2jK0bum|7^Fc1V{4xe_zKQxDE=8o%C?W99k`I4PK6<?6|FY#mLP@;$A=A6N
z-w{9nXmlZ+&YWr<HR1+`5B!=!em~Wt@1t1z4OJ<q-nW2`rF}SOsh56>(M`Vla7a)8
z+gZK(tyo<lX&k2WgHTyzn2H1goe#2p&9kh$c#_h@1X7B&J1PVsXxng3h<O!|LUw1;
zX*Z1&g%NeVftPm+dIvV+7Jrw+cb}kl-9ns)dii;hWP(S35;FMfUiSR(Nv0-W#l)j{
z1h^{pQ&lEEQ)bnQfFQGxAO6&k%jFPKwhEd6sbsKy`}TQVe69<osfBcY?SkF~5p4~W
zQf#>LtvL0k{AzoHLhoieSJbE!w=q?Hl}7y#FFd0VKUu`}U0rN=;Q-(J^g~RRcak)Z
zAybP;=NwDcUrOxO^5DZIhAz5|Y&M60)^o8J1VLba`O9DC=2Kx_7Yf60Q-A+Jdgh5-
zHpjIaH_^Z3FL>;+gnakac&DjVUSZ!pN%;p$d3$#ceVGh>nGBadeUu-3;h(8aJVSN-
zDRQ0bn2MM3?e7PyTXzQo{rv>(v?|)W+I+sFF+6;5)qDz^GmY-pu|ooH>+9(|9ZNti
zmt*y+Wvp9q9bt5sOvhT9^}R%5g7y7*`fL{O9GM_sSs2o6j#4?fi;nKgNM)AMJ-C+l
z+@57(vX4}hY86CUh0U0RuFftwdUW`5U<WW~19w&h9(dpZv3>h?dEmf-DA9Upp|h)P
z`<qI}NlZF?lELLSuy0R=FMVo1wfX=TU)qPfdpDH@O<WLQ!jO@74723JB|5s+@Qa_7
zdGN2EB}^@3({*d;?``cEymvV7L4ZySot=fObAJ8y?c1kaXjV5m3qZ803){ABlgE#b
ztnKXRjDz5Gp}hATIrvlh7GyX!@*I1=a)b{@D|zDY6OJ57)3vyl(c4~SQc4akJ5Kkz
ztEAEw@vq+=XYk)M+&J3BcfRl~@FfO&o+n8Xob_01aK@4(ntVrx@LpWCZQC}vWy==v
zzylA=3UHcbZR5qZZQEpjf4|zadE<tG{y}-BfW{c=&82+*d!NVdNONQ7AWO1Y2B$JS
z`t>n(URP#Oz5{6the|N^QjVwpqsX0&6)f%wkU;cgjnDtxH^}uaW^nN&9UYzRhOwd9
zY>?~B<E>e}Yu7F{Ha6xLEm~xS5W=7Ff52=pAVx<=Rin`eZ@A(5w+-|Up4EX3f`HYl
z)|1PBg|6X$Vo;Cbfc|Wj_k|a6aAzM)V_2BYu%LMnuWsq$W0?$vtR&?<&RSOG^Gt--
zB9^U3NktMT#Lbu_Nod9~Jz)=C&^bOn-g)B0iOSx+dp(@dM4bsRz50Nx*Xyd;YzAJ4
zp6PZUfNx77gdmg2u<W8`q?7{hL9`+yABJ33C}7*22j?8u_4eYO!&{4M?e!7Pu{4S}
z9;VPn6UQ-e9Am5@iXxn|D5=o8-noDOk;$>KF)?lCOcl;lKma015~Y+1cD=gm9|NUs
z7E)x^tXv~!4Wp?#-k4Ka1R+{2llC*R@V+(8d%X9w+Y?|6s#e7qgGn?=5~GbKpU;s_
zr+NN`XPa>|esu5NLuF%(0!-V!`CX`3ERxIR#3PS9vTJ1IhW95)^39R4;eqQny*)ME
z`ko%tYM?d9R;c(kfCq36-!|CWR*S`JjW-6bHL_emYfX}9jJ5RjEg;cNw*L0<#zd+7
zlh<C`^*QI9bk5D0g=Pb2+abIV!aw=slSg*#-Sv@=f8?W|9UB|nbo;G$q@z@X(WZ4}
zwTe#?e7ig0+kmY__bsEnZy7xepfx^@5feqMu?Qhpv}h5>j*YSHiLK3IvG}Dud-nb~
zj$>_%akW~_ow@RJ0r>WCwOUPQv)MQZf}nV;SpM2qzwz0-K5*xq<!bq!cfa$NXvv}>
z;hP@nb<i3=tw7swHxpo50b^Q!_-T#PnqYF0?w&3(*(@);yu<Ez>4o~?!^8It4-dcK
zy^oV5iNi27w1Ri~=TCQ+nOUhF$P!RM2t?UzHXVjxMoO8LQf4+?zv+r=ues(ky*<5y
zH(awhJ+$RV=-s<9!^2qT@ItgYZGdlg>a24(WAM&llcd#tT)rH6<&|u|^m3kl=85J+
zX?*X#eFy&L`0?W--up(qUatp15Lc_!7|?A9cV-%$4Pbf%?Gfhl`INOb3d1n1luAcY
zl)mMbo8Pr^)yhw<6RKxpHWy_kCP)q*#0(E(ibb6FEdXn=-s6lxc6XzeEFoOJoN}$s
zb4L#AU-kBkj2%7p;QsylpYYx{r>3T2t#va9f}~t7C$xh1lmh1jm<3{5ji68{gx1<1
zilUUYHVlFwl}@Ll+i(B<I|c>^@4F=5k-5f^=}V`P&f-cXY^Bn=Yc`AT?x86qM@nV?
zRB61qyH+h1Cnmo9+AFX9r*lp_=Mt@T(rh+$7>1@;ES_5R_TWt8X9bu6!3>B~Fg-mz
zfwfjS=TthK4x%Uu3WY*+?X}muy|=gby$IfwNoV9>Hg5;RFl<`qM|9JiD3w&DQn5**
zw@yx0f3a`h8;`|toM^3$)>_wUH5-PZJ%0SSnPK!Pzn{(cIRWMXIa3)iFfgE;bE2c8
zLpkR}CX-RAR7$N~yLKR(O<gQyFl4PUS|?+1+!#B0bbPp6E*qtkZ!{V<2m)WJRBR9g
z{?MUAGXr&A!_Ny~7LaL}nNR>?<;s;3Kx-`)E?hWk&W@tUkB*M|R4V1u>9hxU@x>Qs
zrpQyq%xC!j2;i(qrvt$pMdq%%?mG4TmMvS(ywPc&&)48HkN*Z@>{IOEPM`e%0000<
KMNUMnLSTZRf=40%

literal 0
HcmV?d00001

diff --git a/data/pixmaps/upgrade.png b/data/pixmaps/upgrade.png
new file mode 100644
index 0000000000000000000000000000000000000000..f0fb9f2c3edf9338f2c2dc41ebe5faa3dd6b6b60
GIT binary patch
literal 4632
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
O0000<MNUMnLSTY>sJ#aO

literal 0
HcmV?d00001

diff --git a/data/ui/GroupSelector.glade b/data/ui/GroupSelector.glade
new file mode 100644
index 0000000..956b020
--- /dev/null
+++ b/data/ui/GroupSelector.glade
@@ -0,0 +1,394 @@
+<?xml version="1.0" standalone="no"?> <!--*- mode: xml -*-->
+<!DOCTYPE glade-interface SYSTEM "http://glade.gnome.org/glade-2.0.dtd";>
+
+<glade-interface>
+
+<widget class="GtkWindow" id="groupSelectionWindow">
+  <property name="visible">True</property>
+  <property name="title" translatable="yes">window1</property>
+  <property name="type">GTK_WINDOW_TOPLEVEL</property>
+  <property name="window_position">GTK_WIN_POS_NONE</property>
+  <property name="modal">False</property>
+  <property name="resizable">True</property>
+  <property name="destroy_with_parent">False</property>
+  <property name="decorated">True</property>
+  <property name="skip_taskbar_hint">False</property>
+  <property name="skip_pager_hint">False</property>
+  <property name="type_hint">GDK_WINDOW_TYPE_HINT_NORMAL</property>
+  <property name="gravity">GDK_GRAVITY_NORTH_WEST</property>
+  <property name="focus_on_map">True</property>
+  <property name="urgency_hint">False</property>
+  <signal name="destroy_event" handler="on_groupSelectionWindow_destroy_event" last_modification_time="Fri, 02 Dec 2005 21:41:59 GMT"/>
+  <signal name="delete_event" handler="on_groupSelectionWindow_delete_event" last_modification_time="Fri, 02 Dec 2005 21:42:23 GMT"/>
+
+  <child>
+    <widget class="GtkVBox" id="groupSelectionBox">
+      <property name="border_width">12</property>
+      <property name="width_request">700</property>
+      <property name="visible">True</property>
+      <property name="homogeneous">False</property>
+      <property name="spacing">6</property>
+
+      <child>
+	<widget class="GtkHBox" id="hbox1">
+	  <property name="border_width">12</property>
+	  <property name="visible">True</property>
+	  <property name="homogeneous">False</property>
+	  <property name="spacing">12</property>
+
+	  <child>
+	    <widget class="GtkScrolledWindow" id="categorySW">
+	      <property name="visible">True</property>
+	      <property name="can_focus">True</property>
+	      <property name="hscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
+	      <property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
+	      <property name="shadow_type">GTK_SHADOW_IN</property>
+	      <property name="window_placement">GTK_CORNER_TOP_LEFT</property>
+
+	      <child>
+		<widget class="GtkTreeView" id="categoryList">
+		  <property name="width_request">275</property>
+		  <property name="visible">True</property>
+		  <property name="can_focus">True</property>
+		  <property name="headers_visible">False</property>
+		  <property name="rules_hint">False</property>
+		  <property name="reorderable">False</property>
+		  <property name="enable_search">True</property>
+		  <property name="fixed_height_mode">False</property>
+		  <property name="hover_selection">False</property>
+		  <property name="hover_expand">False</property>
+		</widget>
+	      </child>
+	    </widget>
+	    <packing>
+	      <property name="padding">0</property>
+	      <property name="expand">True</property>
+	      <property name="fill">True</property>
+	    </packing>
+	  </child>
+
+	  <child>
+	    <widget class="GtkScrolledWindow" id="groupSW">
+	      <property name="visible">True</property>
+	      <property name="can_focus">True</property>
+	      <property name="hscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
+	      <property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
+	      <property name="shadow_type">GTK_SHADOW_IN</property>
+	      <property name="window_placement">GTK_CORNER_TOP_LEFT</property>
+
+	      <child>
+		<widget class="GtkTreeView" id="groupList">
+		  <property name="width_request">325</property>
+		  <property name="visible">True</property>
+		  <property name="can_focus">True</property>
+		  <property name="headers_visible">False</property>
+		  <property name="rules_hint">False</property>
+		  <property name="reorderable">False</property>
+		  <property name="enable_search">True</property>
+		  <property name="fixed_height_mode">False</property>
+		  <property name="hover_selection">False</property>
+		  <property name="hover_expand">False</property>
+		  <signal name="button_press_event" handler="on_groupList_button_press" last_modification_time="Sat, 04 Feb 2006 01:22:04 GMT"/>
+		  <signal name="popup_menu" handler="on_groupList_popup_menu" last_modification_time="Sat, 04 Feb 2006 01:22:13 GMT"/>
+		</widget>
+	      </child>
+	    </widget>
+	    <packing>
+	      <property name="padding">0</property>
+	      <property name="expand">True</property>
+	      <property name="fill">True</property>
+	    </packing>
+	  </child>
+	</widget>
+	<packing>
+	  <property name="padding">0</property>
+	  <property name="expand">True</property>
+	  <property name="fill">True</property>
+	</packing>
+      </child>
+
+      <child>
+	<widget class="GtkAlignment" id="alignment1">
+	  <property name="visible">True</property>
+	  <property name="xalign">0.5</property>
+	  <property name="yalign">0.5</property>
+	  <property name="xscale">0.75</property>
+	  <property name="yscale">1</property>
+	  <property name="top_padding">0</property>
+	  <property name="bottom_padding">0</property>
+	  <property name="left_padding">0</property>
+	  <property name="right_padding">0</property>
+
+	  <child>
+	    <widget class="GtkVBox" id="vbox2">
+	      <property name="border_width">12</property>
+	      <property name="visible">True</property>
+	      <property name="homogeneous">False</property>
+	      <property name="spacing">6</property>
+
+	      <child>
+		<widget class="GtkScrolledWindow" id="scrolledwindow3">
+		  <property name="height_request">82</property>
+		  <property name="visible">True</property>
+		  <property name="can_focus">True</property>
+		  <property name="hscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
+		  <property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
+		  <property name="shadow_type">GTK_SHADOW_IN</property>
+		  <property name="window_placement">GTK_CORNER_TOP_LEFT</property>
+
+		  <child>
+		    <widget class="GtkTextView" id="groupDescriptionTextView">
+		      <property name="visible">True</property>
+		      <property name="can_focus">True</property>
+		      <property name="editable">False</property>
+		      <property name="overwrite">False</property>
+		      <property name="accepts_tab">True</property>
+		      <property name="justification">GTK_JUSTIFY_LEFT</property>
+		      <property name="wrap_mode">GTK_WRAP_WORD</property>
+		      <property name="cursor_visible">False</property>
+		      <property name="pixels_above_lines">0</property>
+		      <property name="pixels_below_lines">0</property>
+		      <property name="pixels_inside_wrap">0</property>
+		      <property name="left_margin">0</property>
+		      <property name="right_margin">0</property>
+		      <property name="indent">0</property>
+		      <property name="text" translatable="yes"></property>
+		    </widget>
+		  </child>
+		</widget>
+		<packing>
+		  <property name="padding">0</property>
+		  <property name="expand">False</property>
+		  <property name="fill">False</property>
+		</packing>
+	      </child>
+
+	      <child>
+		<widget class="GtkLabel" id="optionalLabel">
+		  <property name="visible">True</property>
+		  <property name="label" translatable="yes"></property>
+		  <property name="use_underline">False</property>
+		  <property name="use_markup">False</property>
+		  <property name="justify">GTK_JUSTIFY_RIGHT</property>
+		  <property name="wrap">False</property>
+		  <property name="selectable">False</property>
+		  <property name="xalign">0.949999988079</property>
+		  <property name="yalign">1</property>
+		  <property name="xpad">0</property>
+		  <property name="ypad">0</property>
+		  <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+		  <property name="width_chars">-1</property>
+		  <property name="single_line_mode">False</property>
+		  <property name="angle">0</property>
+		</widget>
+		<packing>
+		  <property name="padding">0</property>
+		  <property name="expand">False</property>
+		  <property name="fill">False</property>
+		</packing>
+	      </child>
+
+	      <child>
+		<widget class="GtkHButtonBox" id="hbuttonbox2">
+		  <property name="border_width">6</property>
+		  <property name="visible">True</property>
+		  <property name="layout_style">GTK_BUTTONBOX_END</property>
+		  <property name="spacing">0</property>
+
+		  <child>
+		    <widget class="GtkButton" id="detailsButton">
+		      <property name="visible">True</property>
+		      <property name="can_default">True</property>
+		      <property name="can_focus">True</property>
+		      <property name="label" translatable="yes">_Optional packages</property>
+		      <property name="use_underline">True</property>
+		      <property name="relief">GTK_RELIEF_NORMAL</property>
+		      <property name="focus_on_click">True</property>
+		      <signal name="clicked" handler="on_detailsButton_clicked" last_modification_time="Fri, 02 Dec 2005 21:39:06 GMT"/>
+		    </widget>
+		  </child>
+		</widget>
+		<packing>
+		  <property name="padding">0</property>
+		  <property name="expand">True</property>
+		  <property name="fill">True</property>
+		</packing>
+	      </child>
+	    </widget>
+	  </child>
+	</widget>
+	<packing>
+	  <property name="padding">0</property>
+	  <property name="expand">False</property>
+	  <property name="fill">False</property>
+	</packing>
+      </child>
+    </widget>
+  </child>
+</widget>
+
+<widget class="GtkDialog" id="groupDetailsDialog">
+  <property name="width_request">550</property>
+  <property name="height_request">300</property>
+  <property name="title" translatable="yes">dialog1</property>
+  <property name="type">GTK_WINDOW_TOPLEVEL</property>
+  <property name="window_position">GTK_WIN_POS_CENTER_ON_PARENT</property>
+  <property name="modal">True</property>
+  <property name="resizable">True</property>
+  <property name="destroy_with_parent">False</property>
+  <property name="decorated">True</property>
+  <property name="skip_taskbar_hint">False</property>
+  <property name="skip_pager_hint">False</property>
+  <property name="type_hint">GDK_WINDOW_TYPE_HINT_DIALOG</property>
+  <property name="gravity">GDK_GRAVITY_NORTH_WEST</property>
+  <property name="focus_on_map">True</property>
+  <property name="urgency_hint">False</property>
+  <property name="has_separator">True</property>
+  <signal name="destroy" handler="on_groupDetailsDialog_destroy" last_modification_time="Tue, 06 Dec 2005 21:31:56 GMT"/>
+  <signal name="delete_event" handler="on_groupDetailsDialog_delete_event" last_modification_time="Tue, 06 Dec 2005 21:32:34 GMT"/>
+
+  <child internal-child="vbox">
+    <widget class="GtkVBox" id="dialog-vbox1">
+      <property name="visible">True</property>
+      <property name="homogeneous">False</property>
+      <property name="spacing">0</property>
+
+      <child internal-child="action_area">
+	<widget class="GtkHButtonBox" id="dialog-action_area1">
+	  <property name="visible">True</property>
+	  <property name="layout_style">GTK_BUTTONBOX_END</property>
+
+	  <child>
+	    <widget class="GtkButton" id="groupDetailsCloseButton">
+	      <property name="visible">True</property>
+	      <property name="can_default">True</property>
+	      <property name="can_focus">True</property>
+	      <property name="label">gtk-close</property>
+	      <property name="use_stock">True</property>
+	      <property name="relief">GTK_RELIEF_NORMAL</property>
+	      <property name="focus_on_click">True</property>
+	      <property name="response_id">-7</property>
+	      <signal name="clicked" handler="on_groupDetailsCloseButton_clicked" last_modification_time="Tue, 06 Dec 2005 21:31:46 GMT"/>
+	    </widget>
+	  </child>
+	</widget>
+	<packing>
+	  <property name="padding">0</property>
+	  <property name="expand">False</property>
+	  <property name="fill">True</property>
+	  <property name="pack_type">GTK_PACK_END</property>
+	</packing>
+      </child>
+
+      <child>
+	<widget class="GtkVBox" id="vbox4">
+	  <property name="border_width">12</property>
+	  <property name="visible">True</property>
+	  <property name="homogeneous">False</property>
+	  <property name="spacing">6</property>
+
+	  <child>
+	    <widget class="GtkLabel" id="label1">
+	      <property name="visible">True</property>
+	      <property name="label" translatable="yes">Some packages associated with this group are not required to be installed but may provide additional functionality.  Please choose the packages which you would like to have installed.</property>
+	      <property name="use_underline">False</property>
+	      <property name="use_markup">False</property>
+	      <property name="justify">GTK_JUSTIFY_LEFT</property>
+	      <property name="wrap">True</property>
+	      <property name="selectable">False</property>
+	      <property name="xalign">0</property>
+	      <property name="yalign">0.5</property>
+	      <property name="xpad">0</property>
+	      <property name="ypad">0</property>
+	      <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+	      <property name="width_chars">-1</property>
+	      <property name="single_line_mode">False</property>
+	      <property name="angle">0</property>
+	    </widget>
+	    <packing>
+	      <property name="padding">0</property>
+	      <property name="expand">False</property>
+	      <property name="fill">False</property>
+	    </packing>
+	  </child>
+
+	  <child>
+	    <widget class="GtkScrolledWindow" id="packageSW">
+	      <property name="visible">True</property>
+	      <property name="can_focus">True</property>
+	      <property name="hscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
+	      <property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
+	      <property name="shadow_type">GTK_SHADOW_IN</property>
+	      <property name="window_placement">GTK_CORNER_TOP_LEFT</property>
+
+	      <child>
+		<widget class="GtkTreeView" id="packageList">
+		  <property name="visible">True</property>
+		  <property name="can_focus">True</property>
+		  <property name="headers_visible">False</property>
+		  <property name="rules_hint">False</property>
+		  <property name="reorderable">False</property>
+		  <property name="enable_search">True</property>
+		  <property name="fixed_height_mode">False</property>
+		  <property name="hover_selection">False</property>
+		  <property name="hover_expand">False</property>
+		</widget>
+	      </child>
+	    </widget>
+	    <packing>
+	      <property name="padding">0</property>
+	      <property name="expand">True</property>
+	      <property name="fill">True</property>
+	    </packing>
+	  </child>
+	</widget>
+	<packing>
+	  <property name="padding">0</property>
+	  <property name="expand">True</property>
+	  <property name="fill">True</property>
+	</packing>
+      </child>
+    </widget>
+  </child>
+</widget>
+
+<widget class="GtkMenu" id="groupPopupMenu">
+
+  <child>
+    <widget class="GtkMenuItem" id="selectgrp">
+      <property name="visible">True</property>
+      <property name="label" translatable="yes">_Select</property>
+      <property name="use_underline">True</property>
+      <signal name="activate" handler="on_selectgrp_activate" last_modification_time="Wed, 13 Sep 2006 16:57:47 GMT"/>
+    </widget>
+  </child>
+
+  <child>
+    <widget class="GtkMenuItem" id="select">
+      <property name="visible">True</property>
+      <property name="label" translatable="yes">_Select all optional packages</property>
+      <property name="use_underline">True</property>
+      <signal name="activate" handler="on_select_activate" last_modification_time="Sat, 04 Feb 2006 00:26:28 GMT"/>
+    </widget>
+  </child>
+
+  <child>
+    <widget class="GtkMenuItem" id="deselectgrp">
+      <property name="visible">True</property>
+      <property name="label" translatable="yes">_Deselect</property>
+      <property name="use_underline">True</property>
+      <signal name="activate" handler="on_deselectgrp_activate" last_modification_time="Wed, 13 Sep 2006 16:57:47 GMT"/>
+    </widget>
+  </child>
+
+  <child>
+    <widget class="GtkMenuItem" id="deselect">
+      <property name="visible">True</property>
+      <property name="label" translatable="yes">_Deselect all optional packages</property>
+      <property name="use_underline">True</property>
+      <signal name="activate" handler="on_deselect_activate" last_modification_time="Sat, 04 Feb 2006 00:26:28 GMT"/>
+    </widget>
+  </child>
+</widget>
+
+</glade-interface>
diff --git a/data/ui/Makefile.am b/data/ui/Makefile.am
new file mode 100644
index 0000000..39e1c56
--- /dev/null
+++ b/data/ui/Makefile.am
@@ -0,0 +1,25 @@
+# ui/Makefile.am for anaconda
+#
+# Copyright (C) 2009  Red Hat, Inc.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License as published
+# by the Free Software Foundation; either version 2.1 of the License, or
+# (at your option) any later version.
+#
+# 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 Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+#
+# Author: David Cantrell <dcantrell@xxxxxxxxxx>
+
+uidir = $(datadir)/$(PACKAGE_NAME)/ui
+dist_ui_DATA = *.glade
+
+MAINTAINERCLEANFILES = Makefile.in
+
+CLEANFILES = *.h
diff --git a/data/ui/account.glade b/data/ui/account.glade
new file mode 100644
index 0000000..ca7c6be
--- /dev/null
+++ b/data/ui/account.glade
@@ -0,0 +1,278 @@
+<?xml version="1.0" standalone="no"?> <!--*- mode: xml -*-->
+<!DOCTYPE glade-interface SYSTEM "http://glade.gnome.org/glade-2.0.dtd";>
+
+<glade-interface>
+
+<widget class="GtkWindow" id="account_window">
+  <property name="border_width">18</property>
+  <property name="title" translatable="yes" context="yes"></property>
+  <property name="type">GTK_WINDOW_TOPLEVEL</property>
+  <property name="window_position">GTK_WIN_POS_NONE</property>
+  <property name="modal">False</property>
+  <property name="resizable">True</property>
+  <property name="destroy_with_parent">False</property>
+  <property name="decorated">True</property>
+  <property name="skip_taskbar_hint">False</property>
+  <property name="skip_pager_hint">False</property>
+  <property name="type_hint">GDK_WINDOW_TYPE_HINT_NORMAL</property>
+  <property name="gravity">GDK_GRAVITY_NORTH_WEST</property>
+  <property name="focus_on_map">True</property>
+  <property name="urgency_hint">False</property>
+
+  <child>
+    <widget class="GtkAlignment" id="account_align">
+      <property name="width_request">400</property>
+      <property name="visible">True</property>
+      <property name="xalign">0</property>
+      <property name="yalign">0</property>
+      <property name="xscale">1</property>
+      <property name="yscale">1</property>
+      <property name="top_padding">0</property>
+      <property name="bottom_padding">0</property>
+      <property name="left_padding">0</property>
+      <property name="right_padding">0</property>
+
+      <child>
+	<widget class="GtkVBox" id="account_box">
+	  <property name="border_width">5</property>
+	  <property name="visible">True</property>
+	  <property name="homogeneous">False</property>
+	  <property name="spacing">10</property>
+
+	  <child>
+	    <widget class="GtkAlignment" id="alignment2">
+	      <property name="visible">True</property>
+	      <property name="xalign">0</property>
+	      <property name="yalign">0</property>
+	      <property name="xscale">1</property>
+	      <property name="yscale">1</property>
+	      <property name="top_padding">0</property>
+	      <property name="bottom_padding">0</property>
+	      <property name="left_padding">0</property>
+	      <property name="right_padding">0</property>
+
+	      <child>
+		<widget class="GtkHBox" id="desc_box">
+		  <property name="visible">True</property>
+		  <property name="homogeneous">False</property>
+		  <property name="spacing">0</property>
+
+		  <child>
+		    <widget class="GtkImage" id="icon">
+		      <property name="visible">True</property>
+		      <property name="xalign">0.5</property>
+		      <property name="yalign">0.5</property>
+		      <property name="xpad">0</property>
+		      <property name="ypad">0</property>
+		    </widget>
+		    <packing>
+		      <property name="padding">0</property>
+		      <property name="expand">False</property>
+		      <property name="fill">False</property>
+		    </packing>
+		  </child>
+
+		  <child>
+		    <widget class="GtkLabel" id="desc">
+		      <property name="visible">True</property>
+		      <property name="label" translatable="yes">The root account is used for administering the system.  Enter a password for the root user.</property>
+		      <property name="use_underline">False</property>
+		      <property name="use_markup">False</property>
+		      <property name="justify">GTK_JUSTIFY_LEFT</property>
+		      <property name="wrap">True</property>
+		      <property name="selectable">False</property>
+		      <property name="xalign">0</property>
+		      <property name="yalign">0.5</property>
+		      <property name="xpad">0</property>
+		      <property name="ypad">0</property>
+		      <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+		      <property name="width_chars">-1</property>
+		      <property name="single_line_mode">False</property>
+		      <property name="angle">0</property>
+		    </widget>
+		    <packing>
+		      <property name="padding">0</property>
+		      <property name="expand">False</property>
+		      <property name="fill">False</property>
+		    </packing>
+		  </child>
+		</widget>
+	      </child>
+	    </widget>
+	    <packing>
+	      <property name="padding">0</property>
+	      <property name="expand">False</property>
+	      <property name="fill">False</property>
+	    </packing>
+	  </child>
+
+	  <child>
+	    <widget class="GtkAlignment" id="alignment4">
+	      <property name="visible">True</property>
+	      <property name="xalign">0.5</property>
+	      <property name="yalign">0.5</property>
+	      <property name="xscale">1</property>
+	      <property name="yscale">1</property>
+	      <property name="top_padding">0</property>
+	      <property name="bottom_padding">0</property>
+	      <property name="left_padding">0</property>
+	      <property name="right_padding">0</property>
+
+	      <child>
+		<widget class="GtkTable" id="table1">
+		  <property name="width_request">365</property>
+		  <property name="visible">True</property>
+		  <property name="n_rows">3</property>
+		  <property name="n_columns">2</property>
+		  <property name="homogeneous">False</property>
+		  <property name="row_spacing">5</property>
+		  <property name="column_spacing">5</property>
+
+		  <child>
+		    <widget class="GtkLabel" id="pwlabel">
+		      <property name="visible">True</property>
+		      <property name="label" translatable="yes">Root Password:</property>
+		      <property name="use_underline">False</property>
+		      <property name="use_markup">True</property>
+		      <property name="justify">GTK_JUSTIFY_LEFT</property>
+		      <property name="wrap">False</property>
+		      <property name="selectable">False</property>
+		      <property name="xalign">0</property>
+		      <property name="yalign">0.5</property>
+		      <property name="xpad">0</property>
+		      <property name="ypad">0</property>
+		      <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+		      <property name="width_chars">-1</property>
+		      <property name="single_line_mode">False</property>
+		      <property name="angle">0</property>
+		    </widget>
+		    <packing>
+		      <property name="left_attach">0</property>
+		      <property name="right_attach">1</property>
+		      <property name="top_attach">0</property>
+		      <property name="bottom_attach">1</property>
+		      <property name="x_options">fill</property>
+		      <property name="y_options"></property>
+		    </packing>
+		  </child>
+
+		  <child>
+		    <widget class="GtkLabel" id="confirmlabel">
+		      <property name="visible">True</property>
+		      <property name="label" translatable="yes">Confirm:</property>
+		      <property name="use_underline">False</property>
+		      <property name="use_markup">True</property>
+		      <property name="justify">GTK_JUSTIFY_LEFT</property>
+		      <property name="wrap">False</property>
+		      <property name="selectable">False</property>
+		      <property name="xalign">0</property>
+		      <property name="yalign">0.5</property>
+		      <property name="xpad">0</property>
+		      <property name="ypad">0</property>
+		      <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+		      <property name="width_chars">-1</property>
+		      <property name="single_line_mode">False</property>
+		      <property name="angle">0</property>
+		    </widget>
+		    <packing>
+		      <property name="left_attach">0</property>
+		      <property name="right_attach">1</property>
+		      <property name="top_attach">1</property>
+		      <property name="bottom_attach">2</property>
+		      <property name="x_options">fill</property>
+		      <property name="y_options"></property>
+		    </packing>
+		  </child>
+
+		  <child>
+		    <widget class="GtkLabel" id="capslock">
+		      <property name="visible">True</property>
+		      <property name="label" translatable="yes"></property>
+		      <property name="use_underline">False</property>
+		      <property name="use_markup">True</property>
+		      <property name="justify">GTK_JUSTIFY_LEFT</property>
+		      <property name="wrap">False</property>
+		      <property name="selectable">False</property>
+		      <property name="xalign">0</property>
+		      <property name="yalign">0.5</property>
+		      <property name="xpad">0</property>
+		      <property name="ypad">0</property>
+		      <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+		      <property name="width_chars">-1</property>
+		      <property name="single_line_mode">False</property>
+		      <property name="angle">0</property>
+		    </widget>
+		    <packing>
+		      <property name="left_attach">1</property>
+		      <property name="right_attach">2</property>
+		      <property name="top_attach">2</property>
+		      <property name="bottom_attach">3</property>
+		      <property name="x_options">fill</property>
+		      <property name="y_options"></property>
+		    </packing>
+		  </child>
+
+		  <child>
+		    <widget class="GtkEntry" id="pw">
+		      <property name="width_request">256</property>
+		      <property name="visible">True</property>
+		      <property name="can_focus">True</property>
+		      <property name="has_focus">True</property>
+		      <property name="editable">True</property>
+		      <property name="visibility">False</property>
+		      <property name="max_length">0</property>
+		      <property name="text" translatable="yes"></property>
+		      <property name="has_frame">True</property>
+		      <property name="invisible_char">â?¢</property>
+		      <property name="activates_default">False</property>
+		    </widget>
+		    <packing>
+		      <property name="left_attach">1</property>
+		      <property name="right_attach">2</property>
+		      <property name="top_attach">0</property>
+		      <property name="bottom_attach">1</property>
+		      <property name="x_options">fill</property>
+		      <property name="y_options"></property>
+		    </packing>
+		  </child>
+
+		  <child>
+		    <widget class="GtkEntry" id="confirm">
+		      <property name="width_request">256</property>
+		      <property name="visible">True</property>
+		      <property name="can_default">True</property>
+		      <property name="has_default">True</property>
+		      <property name="can_focus">True</property>
+		      <property name="editable">True</property>
+		      <property name="visibility">False</property>
+		      <property name="max_length">0</property>
+		      <property name="text" translatable="yes"></property>
+		      <property name="has_frame">True</property>
+		      <property name="invisible_char">â?¢</property>
+		      <property name="activates_default">True</property>
+		    </widget>
+		    <packing>
+		      <property name="left_attach">1</property>
+		      <property name="right_attach">2</property>
+		      <property name="top_attach">1</property>
+		      <property name="bottom_attach">2</property>
+		      <property name="x_options">fill</property>
+		      <property name="y_options"></property>
+		    </packing>
+		  </child>
+		</widget>
+	      </child>
+	    </widget>
+	    <packing>
+	      <property name="padding">0</property>
+	      <property name="expand">False</property>
+	      <property name="fill">False</property>
+	    </packing>
+	  </child>
+	</widget>
+      </child>
+    </widget>
+  </child>
+</widget>
+
+</glade-interface>
diff --git a/data/ui/adddrive.glade b/data/ui/adddrive.glade
new file mode 100644
index 0000000..289c71b
--- /dev/null
+++ b/data/ui/adddrive.glade
@@ -0,0 +1,196 @@
+<?xml version="1.0" standalone="no"?> <!--*- mode: xml -*-->
+<!DOCTYPE glade-interface SYSTEM "http://glade.gnome.org/glade-2.0.dtd";>
+
+<glade-interface>
+
+<widget class="GtkDialog" id="addDriveDialog">
+  <property name="visible">True</property>
+  <property name="title" translatable="yes" context="yes">Advanced Storage Options</property>
+  <property name="type">GTK_WINDOW_TOPLEVEL</property>
+  <property name="window_position">GTK_WIN_POS_CENTER</property>
+  <property name="modal">False</property>
+  <property name="resizable">True</property>
+  <property name="destroy_with_parent">False</property>
+  <property name="decorated">True</property>
+  <property name="skip_taskbar_hint">False</property>
+  <property name="skip_pager_hint">False</property>
+  <property name="type_hint">GDK_WINDOW_TYPE_HINT_DIALOG</property>
+  <property name="gravity">GDK_GRAVITY_NORTH_WEST</property>
+  <property name="focus_on_map">True</property>
+  <property name="urgency_hint">False</property>
+  <property name="has_separator">True</property>
+
+  <child internal-child="vbox">
+    <widget class="GtkVBox" id="dialog1-vbox">
+      <property name="visible">True</property>
+      <property name="homogeneous">False</property>
+      <property name="spacing">0</property>
+
+      <child internal-child="action_area">
+	<widget class="GtkHButtonBox" id="dialog1-action_area">
+	  <property name="visible">True</property>
+	  <property name="layout_style">GTK_BUTTONBOX_END</property>
+
+	  <child>
+	    <widget class="GtkButton" id="cancelButton">
+	      <property name="visible">True</property>
+	      <property name="label">gtk-cancel</property>
+	      <property name="use_stock">True</property>
+	      <property name="relief">GTK_RELIEF_NORMAL</property>
+	      <property name="focus_on_click">True</property>
+	      <property name="response_id">-6</property>
+	      <signal name="clicked" handler="on_cancelButton_clicked"/>
+	    </widget>
+	  </child>
+
+	  <child>
+	    <widget class="GtkButton" id="okButton">
+	      <property name="visible">True</property>
+	      <property name="relief">GTK_RELIEF_NORMAL</property>
+	      <property name="focus_on_click">True</property>
+	      <property name="response_id">-5</property>
+	      <signal name="clicked" handler="on_okButton_clicked"/>
+
+	      <child>
+		<widget class="GtkLabel" id="label2">
+		  <property name="visible">True</property>
+		  <property name="label" translatable="yes">_Add drive</property>
+		  <property name="use_underline">True</property>
+		  <property name="use_markup">False</property>
+		  <property name="justify">GTK_JUSTIFY_LEFT</property>
+		  <property name="wrap">False</property>
+		  <property name="selectable">False</property>
+		  <property name="xalign">0.5</property>
+		  <property name="yalign">0.5</property>
+		  <property name="xpad">0</property>
+		  <property name="ypad">0</property>
+		  <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+		  <property name="width_chars">-1</property>
+		  <property name="single_line_mode">False</property>
+		  <property name="angle">0</property>
+		</widget>
+	      </child>
+	    </widget>
+	  </child>
+	</widget>
+	<packing>
+	  <property name="padding">0</property>
+	  <property name="expand">False</property>
+	  <property name="fill">True</property>
+	  <property name="pack_type">GTK_PACK_END</property>
+	</packing>
+      </child>
+
+      <child>
+	<widget class="GtkVBox" id="vbox1">
+	  <property name="border_width">18</property>
+	  <property name="visible">True</property>
+	  <property name="homogeneous">False</property>
+	  <property name="spacing">12</property>
+
+	  <child>
+	    <widget class="GtkLabel" id="label1">
+	      <property name="visible">True</property>
+	      <property name="label" translatable="yes" context="yes">How would you like to modify your drive configuration?</property>
+	      <property name="use_underline">False</property>
+	      <property name="use_markup">False</property>
+	      <property name="justify">GTK_JUSTIFY_LEFT</property>
+	      <property name="wrap">True</property>
+	      <property name="selectable">False</property>
+	      <property name="xalign">0.5</property>
+	      <property name="yalign">0.5</property>
+	      <property name="xpad">0</property>
+	      <property name="ypad">0</property>
+	      <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+	      <property name="width_chars">-1</property>
+	      <property name="single_line_mode">False</property>
+	      <property name="angle">0</property>
+	    </widget>
+	    <packing>
+	      <property name="padding">0</property>
+	      <property name="expand">False</property>
+	      <property name="fill">False</property>
+	    </packing>
+	  </child>
+
+	  <child>
+	    <widget class="GtkVBox" id="vbox2">
+	      <property name="visible">True</property>
+	      <property name="homogeneous">False</property>
+	      <property name="spacing">6</property>
+
+	      <child>
+		<widget class="GtkRadioButton" id="iscsiRadio">
+		  <property name="visible">True</property>
+		  <property name="label" translatable="yes" context="yes">Add _iSCSI target</property>
+		  <property name="use_underline">True</property>
+		  <property name="relief">GTK_RELIEF_NORMAL</property>
+		  <property name="focus_on_click">True</property>
+		  <property name="active">False</property>
+		  <property name="inconsistent">False</property>
+		  <property name="draw_indicator">True</property>
+		  <signal name="group-changed" handler="on_radio_changed"/>
+		</widget>
+		<packing>
+		  <property name="padding">0</property>
+		  <property name="expand">True</property>
+		  <property name="fill">True</property>
+		</packing>
+	      </child>
+
+	      <child>
+		<widget class="GtkRadioButton" id="zfcpRadio">
+		  <property name="visible">True</property>
+		  <property name="label" translatable="yes" context="yes">Add _ZFCP LUN</property>
+		  <property name="use_underline">True</property>
+		  <property name="relief">GTK_RELIEF_NORMAL</property>
+		  <property name="focus_on_click">True</property>
+		  <property name="active">False</property>
+		  <property name="inconsistent">False</property>
+		  <property name="draw_indicator">True</property>
+		  <property name="group">iscsiRadio</property>
+		</widget>
+		<packing>
+		  <property name="padding">0</property>
+		  <property name="expand">True</property>
+		  <property name="fill">True</property>
+		</packing>
+	      </child>
+
+	      <child>
+		<widget class="GtkRadioButton" id="fcoeRadio">
+		  <property name="visible">True</property>
+		  <property name="label" translatable="yes" context="yes">Add _FCoE SAN</property>
+		  <property name="use_underline">True</property>
+		  <property name="relief">GTK_RELIEF_NORMAL</property>
+		  <property name="focus_on_click">True</property>
+		  <property name="active">False</property>
+		  <property name="inconsistent">False</property>
+		  <property name="draw_indicator">True</property>
+		  <property name="group">iscsiRadio</property>
+		</widget>
+		<packing>
+		  <property name="padding">0</property>
+		  <property name="expand">True</property>
+		  <property name="fill">True</property>
+		</packing>
+	      </child>
+	    </widget>
+	    <packing>
+	      <property name="padding">0</property>
+	      <property name="expand">True</property>
+	      <property name="fill">True</property>
+	    </packing>
+	  </child>
+	</widget>
+	<packing>
+	  <property name="padding">0</property>
+	  <property name="expand">True</property>
+	  <property name="fill">False</property>
+	</packing>
+      </child>
+    </widget>
+  </child>
+</widget>
+
+</glade-interface>
diff --git a/data/ui/addrepo.glade b/data/ui/addrepo.glade
new file mode 100644
index 0000000..7a6637e
--- /dev/null
+++ b/data/ui/addrepo.glade
@@ -0,0 +1,1016 @@
+<?xml version="1.0" standalone="no"?> <!--*- mode: xml -*-->
+<!DOCTYPE glade-interface SYSTEM "http://glade.gnome.org/glade-2.0.dtd";>
+
+<glade-interface>
+
+<widget class="GtkDialog" id="addRepoDialog">
+  <property name="width_request">440</property>
+  <property name="height_request">400</property>
+  <property name="visible">True</property>
+  <property name="title" translatable="yes">Add Repository</property>
+  <property name="type">GTK_WINDOW_TOPLEVEL</property>
+  <property name="window_position">GTK_WIN_POS_CENTER</property>
+  <property name="modal">False</property>
+  <property name="resizable">True</property>
+  <property name="destroy_with_parent">False</property>
+  <property name="decorated">True</property>
+  <property name="skip_taskbar_hint">False</property>
+  <property name="skip_pager_hint">False</property>
+  <property name="type_hint">GDK_WINDOW_TYPE_HINT_DIALOG</property>
+  <property name="gravity">GDK_GRAVITY_NORTH_WEST</property>
+  <property name="focus_on_map">True</property>
+  <property name="urgency_hint">False</property>
+  <property name="has_separator">True</property>
+  <signal name="destroy" handler="on_addRepoDialog_destroy" last_modification_time="Thu, 24 Apr 2008 14:22:26 GMT"/>
+
+  <child internal-child="vbox">
+    <widget class="GtkVBox" id="dialog-vbox1">
+      <property name="visible">True</property>
+      <property name="homogeneous">False</property>
+      <property name="spacing">0</property>
+
+      <child internal-child="action_area">
+	<widget class="GtkHButtonBox" id="dialog-action_area1">
+	  <property name="visible">True</property>
+	  <property name="layout_style">GTK_BUTTONBOX_END</property>
+
+	  <child>
+	    <widget class="GtkButton" id="cancelButton">
+	      <property name="visible">True</property>
+	      <property name="can_default">True</property>
+	      <property name="can_focus">True</property>
+	      <property name="label">gtk-cancel</property>
+	      <property name="use_stock">True</property>
+	      <property name="relief">GTK_RELIEF_NORMAL</property>
+	      <property name="focus_on_click">True</property>
+	      <property name="response_id">-6</property>
+	      <signal name="clicked" handler="on_cancelButton_clicked" last_modification_time="Thu, 24 Apr 2008 14:25:58 GMT"/>
+	    </widget>
+	  </child>
+
+	  <child>
+	    <widget class="GtkButton" id="okButton">
+	      <property name="visible">True</property>
+	      <property name="can_default">True</property>
+	      <property name="can_focus">True</property>
+	      <property name="label">gtk-ok</property>
+	      <property name="use_stock">True</property>
+	      <property name="relief">GTK_RELIEF_NORMAL</property>
+	      <property name="focus_on_click">True</property>
+	      <property name="response_id">-5</property>
+	      <signal name="clicked" handler="on_okButton_clicked" last_modification_time="Thu, 24 Apr 2008 14:25:51 GMT"/>
+	    </widget>
+	  </child>
+	</widget>
+	<packing>
+	  <property name="padding">0</property>
+	  <property name="expand">False</property>
+	  <property name="fill">True</property>
+	  <property name="pack_type">GTK_PACK_END</property>
+	</packing>
+      </child>
+
+      <child>
+	<widget class="GtkVBox" id="vbox1">
+	  <property name="visible">True</property>
+	  <property name="homogeneous">False</property>
+	  <property name="spacing">5</property>
+
+	  <child>
+	    <widget class="GtkLabel" id="descLabel">
+	      <property name="visible">True</property>
+	      <property name="label" translatable="yes">Please provide the configuration information for this software repository.</property>
+	      <property name="use_underline">False</property>
+	      <property name="use_markup">False</property>
+	      <property name="justify">GTK_JUSTIFY_LEFT</property>
+	      <property name="wrap">True</property>
+	      <property name="selectable">False</property>
+	      <property name="xalign">0.5</property>
+	      <property name="yalign">0.5</property>
+	      <property name="xpad">0</property>
+	      <property name="ypad">5</property>
+	      <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+	      <property name="width_chars">-1</property>
+	      <property name="single_line_mode">False</property>
+	      <property name="angle">0</property>
+	    </widget>
+	    <packing>
+	      <property name="padding">0</property>
+	      <property name="expand">False</property>
+	      <property name="fill">False</property>
+	    </packing>
+	  </child>
+
+	  <child>
+	    <widget class="GtkTable" id="table5">
+	      <property name="visible">True</property>
+	      <property name="n_rows">2</property>
+	      <property name="n_columns">2</property>
+	      <property name="homogeneous">False</property>
+	      <property name="row_spacing">5</property>
+	      <property name="column_spacing">5</property>
+
+	      <child>
+		<widget class="GtkLabel" id="nameLabel">
+		  <property name="visible">True</property>
+		  <property name="label" translatable="yes">&lt;b&gt;Repository _name:&lt;/b&gt;</property>
+		  <property name="use_underline">True</property>
+		  <property name="use_markup">True</property>
+		  <property name="justify">GTK_JUSTIFY_LEFT</property>
+		  <property name="wrap">False</property>
+		  <property name="selectable">False</property>
+		  <property name="xalign">0.5</property>
+		  <property name="yalign">0.5</property>
+		  <property name="xpad">0</property>
+		  <property name="ypad">0</property>
+		  <property name="mnemonic_widget">nameEntry</property>
+		  <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+		  <property name="width_chars">-1</property>
+		  <property name="single_line_mode">False</property>
+		  <property name="angle">0</property>
+		</widget>
+		<packing>
+		  <property name="left_attach">0</property>
+		  <property name="right_attach">1</property>
+		  <property name="top_attach">0</property>
+		  <property name="bottom_attach">1</property>
+		  <property name="x_options">fill</property>
+		  <property name="y_options"></property>
+		</packing>
+	      </child>
+
+	      <child>
+		<widget class="GtkEntry" id="nameEntry">
+		  <property name="visible">True</property>
+		  <property name="can_focus">True</property>
+		  <property name="editable">True</property>
+		  <property name="visibility">True</property>
+		  <property name="max_length">0</property>
+		  <property name="text" translatable="yes"></property>
+		  <property name="has_frame">True</property>
+		  <property name="invisible_char">â?¢</property>
+		  <property name="activates_default">False</property>
+		</widget>
+		<packing>
+		  <property name="left_attach">1</property>
+		  <property name="right_attach">2</property>
+		  <property name="top_attach">0</property>
+		  <property name="bottom_attach">1</property>
+		  <property name="y_options"></property>
+		</packing>
+	      </child>
+
+	      <child>
+		<widget class="GtkLabel" id="typeLabel">
+		  <property name="visible">True</property>
+		  <property name="label" translatable="yes">&lt;b&gt;Repository _type:&lt;/b&gt;</property>
+		  <property name="use_underline">True</property>
+		  <property name="use_markup">True</property>
+		  <property name="justify">GTK_JUSTIFY_LEFT</property>
+		  <property name="wrap">False</property>
+		  <property name="selectable">False</property>
+		  <property name="xalign">0.5</property>
+		  <property name="yalign">0.5</property>
+		  <property name="xpad">0</property>
+		  <property name="ypad">0</property>
+		  <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+		  <property name="width_chars">-1</property>
+		  <property name="single_line_mode">False</property>
+		  <property name="angle">0</property>
+		</widget>
+		<packing>
+		  <property name="left_attach">0</property>
+		  <property name="right_attach">1</property>
+		  <property name="top_attach">1</property>
+		  <property name="bottom_attach">2</property>
+		  <property name="x_options">fill</property>
+		  <property name="y_options"></property>
+		</packing>
+	      </child>
+
+	      <child>
+		<widget class="GtkComboBox" id="typeComboBox">
+		  <property name="visible">True</property>
+		  <property name="items" translatable="yes">HTTP/FTP
+CD/DVD
+NFS
+Hard Drive</property>
+		  <property name="add_tearoffs">False</property>
+		  <property name="focus_on_click">True</property>
+		  <signal name="changed" handler="on_typeComboBox_changed" last_modification_time="Thu, 24 Apr 2008 13:48:24 GMT"/>
+		</widget>
+		<packing>
+		  <property name="left_attach">1</property>
+		  <property name="right_attach">2</property>
+		  <property name="top_attach">1</property>
+		  <property name="bottom_attach">2</property>
+		  <property name="x_options">fill</property>
+		  <property name="y_options">fill</property>
+		</packing>
+	      </child>
+	    </widget>
+	    <packing>
+	      <property name="padding">0</property>
+	      <property name="expand">False</property>
+	      <property name="fill">True</property>
+	    </packing>
+	  </child>
+
+	  <child>
+	    <widget class="GtkNotebook" id="typeNotebook">
+	      <property name="visible">True</property>
+	      <property name="show_tabs">False</property>
+	      <property name="show_border">False</property>
+	      <property name="tab_pos">GTK_POS_TOP</property>
+	      <property name="scrollable">False</property>
+	      <property name="enable_popup">False</property>
+
+	      <child>
+		<widget class="GtkVBox" id="urlVBox">
+		  <property name="visible">True</property>
+		  <property name="homogeneous">False</property>
+		  <property name="spacing">5</property>
+
+		  <child>
+		    <widget class="GtkHBox" id="hbox3">
+		      <property name="visible">True</property>
+		      <property name="homogeneous">False</property>
+		      <property name="spacing">5</property>
+
+		      <child>
+			<widget class="GtkLabel" id="label20">
+			  <property name="visible">True</property>
+			  <property name="label" translatable="yes">Repository _URL</property>
+			  <property name="use_underline">True</property>
+			  <property name="use_markup">False</property>
+			  <property name="justify">GTK_JUSTIFY_LEFT</property>
+			  <property name="wrap">False</property>
+			  <property name="selectable">False</property>
+			  <property name="xalign">0.5</property>
+			  <property name="yalign">0.5</property>
+			  <property name="xpad">0</property>
+			  <property name="ypad">0</property>
+			  <property name="mnemonic_widget">baseurlEntry</property>
+			  <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+			  <property name="width_chars">-1</property>
+			  <property name="single_line_mode">False</property>
+			  <property name="angle">0</property>
+			</widget>
+			<packing>
+			  <property name="padding">0</property>
+			  <property name="expand">False</property>
+			  <property name="fill">False</property>
+			</packing>
+		      </child>
+
+		      <child>
+			<widget class="GtkEntry" id="baseurlEntry">
+			  <property name="visible">True</property>
+			  <property name="can_focus">True</property>
+			  <property name="editable">True</property>
+			  <property name="visibility">True</property>
+			  <property name="max_length">0</property>
+			  <property name="text" translatable="yes"></property>
+			  <property name="has_frame">True</property>
+			  <property name="invisible_char">â?¢</property>
+			  <property name="activates_default">False</property>
+			</widget>
+			<packing>
+			  <property name="padding">0</property>
+			  <property name="expand">True</property>
+			  <property name="fill">True</property>
+			</packing>
+		      </child>
+		    </widget>
+		    <packing>
+		      <property name="padding">0</property>
+		      <property name="expand">True</property>
+		      <property name="fill">True</property>
+		    </packing>
+		  </child>
+
+		  <child>
+		    <widget class="GtkCheckButton" id="mirrorlistCheckbox">
+		      <property name="visible">True</property>
+		      <property name="can_focus">True</property>
+		      <property name="label" translatable="yes">URL is a _mirror list</property>
+		      <property name="use_underline">True</property>
+		      <property name="relief">GTK_RELIEF_NORMAL</property>
+		      <property name="focus_on_click">True</property>
+		      <property name="active">False</property>
+		      <property name="inconsistent">False</property>
+		      <property name="draw_indicator">True</property>
+		      <signal name="toggled" handler="on_mirrorlistCheckbox_toggled" last_modification_time="Thu, 24 Apr 2008 15:23:14 GMT"/>
+		    </widget>
+		    <packing>
+		      <property name="padding">0</property>
+		      <property name="expand">False</property>
+		      <property name="fill">False</property>
+		    </packing>
+		  </child>
+
+		  <child>
+		    <widget class="GtkCheckButton" id="proxyCheckbox">
+		      <property name="visible">True</property>
+		      <property name="can_focus">True</property>
+		      <property name="label" translatable="yes">Configure _proxy</property>
+		      <property name="use_underline">True</property>
+		      <property name="relief">GTK_RELIEF_NORMAL</property>
+		      <property name="focus_on_click">True</property>
+		      <property name="active">False</property>
+		      <property name="inconsistent">False</property>
+		      <property name="draw_indicator">True</property>
+		      <signal name="toggled" handler="on_proxyCheckbox_toggled" last_modification_time="Thu, 24 Apr 2008 13:49:32 GMT"/>
+		    </widget>
+		    <packing>
+		      <property name="padding">0</property>
+		      <property name="expand">False</property>
+		      <property name="fill">False</property>
+		    </packing>
+		  </child>
+
+		  <child>
+		    <widget class="GtkTable" id="proxyTable">
+		      <property name="visible">True</property>
+		      <property name="n_rows">3</property>
+		      <property name="n_columns">2</property>
+		      <property name="homogeneous">False</property>
+		      <property name="row_spacing">10</property>
+		      <property name="column_spacing">5</property>
+
+		      <child>
+			<widget class="GtkLabel" id="label11">
+			  <property name="visible">True</property>
+			  <property name="label" translatable="yes">Proxy U_RL (host:port)</property>
+			  <property name="use_underline">True</property>
+			  <property name="use_markup">False</property>
+			  <property name="justify">GTK_JUSTIFY_LEFT</property>
+			  <property name="wrap">False</property>
+			  <property name="selectable">False</property>
+			  <property name="xalign">0</property>
+			  <property name="yalign">0.5</property>
+			  <property name="xpad">10</property>
+			  <property name="ypad">0</property>
+			  <property name="mnemonic_widget">proxyEntry</property>
+			  <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+			  <property name="width_chars">-1</property>
+			  <property name="single_line_mode">False</property>
+			  <property name="angle">0</property>
+			</widget>
+			<packing>
+			  <property name="left_attach">0</property>
+			  <property name="right_attach">1</property>
+			  <property name="top_attach">0</property>
+			  <property name="bottom_attach">1</property>
+			  <property name="x_options">fill</property>
+			  <property name="y_options"></property>
+			</packing>
+		      </child>
+
+		      <child>
+			<widget class="GtkLabel" id="label12">
+			  <property name="visible">True</property>
+			  <property name="label" translatable="yes">Proxy u_sername</property>
+			  <property name="use_underline">True</property>
+			  <property name="use_markup">False</property>
+			  <property name="justify">GTK_JUSTIFY_LEFT</property>
+			  <property name="wrap">False</property>
+			  <property name="selectable">False</property>
+			  <property name="xalign">0</property>
+			  <property name="yalign">0.5</property>
+			  <property name="xpad">10</property>
+			  <property name="ypad">0</property>
+			  <property name="mnemonic_widget">usernameEntry</property>
+			  <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+			  <property name="width_chars">-1</property>
+			  <property name="single_line_mode">False</property>
+			  <property name="angle">0</property>
+			</widget>
+			<packing>
+			  <property name="left_attach">0</property>
+			  <property name="right_attach">1</property>
+			  <property name="top_attach">1</property>
+			  <property name="bottom_attach">2</property>
+			  <property name="x_options">fill</property>
+			  <property name="y_options"></property>
+			</packing>
+		      </child>
+
+		      <child>
+			<widget class="GtkLabel" id="label13">
+			  <property name="visible">True</property>
+			  <property name="label" translatable="yes">Proxy pass_word</property>
+			  <property name="use_underline">True</property>
+			  <property name="use_markup">False</property>
+			  <property name="justify">GTK_JUSTIFY_LEFT</property>
+			  <property name="wrap">False</property>
+			  <property name="selectable">False</property>
+			  <property name="xalign">0</property>
+			  <property name="yalign">0.5</property>
+			  <property name="xpad">10</property>
+			  <property name="ypad">0</property>
+			  <property name="mnemonic_widget">passwordEntry</property>
+			  <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+			  <property name="width_chars">-1</property>
+			  <property name="single_line_mode">False</property>
+			  <property name="angle">0</property>
+			</widget>
+			<packing>
+			  <property name="left_attach">0</property>
+			  <property name="right_attach">1</property>
+			  <property name="top_attach">2</property>
+			  <property name="bottom_attach">3</property>
+			  <property name="x_options">fill</property>
+			  <property name="y_options"></property>
+			</packing>
+		      </child>
+
+		      <child>
+			<widget class="GtkEntry" id="proxyEntry">
+			  <property name="visible">True</property>
+			  <property name="can_focus">True</property>
+			  <property name="editable">True</property>
+			  <property name="visibility">True</property>
+			  <property name="max_length">0</property>
+			  <property name="text" translatable="yes"></property>
+			  <property name="has_frame">True</property>
+			  <property name="invisible_char">â?¢</property>
+			  <property name="activates_default">False</property>
+			</widget>
+			<packing>
+			  <property name="left_attach">1</property>
+			  <property name="right_attach">2</property>
+			  <property name="top_attach">0</property>
+			  <property name="bottom_attach">1</property>
+			  <property name="y_options"></property>
+			</packing>
+		      </child>
+
+		      <child>
+			<widget class="GtkEntry" id="usernameEntry">
+			  <property name="visible">True</property>
+			  <property name="can_focus">True</property>
+			  <property name="editable">True</property>
+			  <property name="visibility">True</property>
+			  <property name="max_length">0</property>
+			  <property name="text" translatable="yes"></property>
+			  <property name="has_frame">True</property>
+			  <property name="invisible_char">â?¢</property>
+			  <property name="activates_default">False</property>
+			</widget>
+			<packing>
+			  <property name="left_attach">1</property>
+			  <property name="right_attach">2</property>
+			  <property name="top_attach">1</property>
+			  <property name="bottom_attach">2</property>
+			  <property name="y_options"></property>
+			</packing>
+		      </child>
+
+		      <child>
+			<widget class="GtkEntry" id="passwordEntry">
+			  <property name="visible">True</property>
+			  <property name="can_focus">True</property>
+			  <property name="editable">True</property>
+			  <property name="visibility">True</property>
+			  <property name="max_length">0</property>
+			  <property name="text" translatable="yes"></property>
+			  <property name="has_frame">True</property>
+			  <property name="invisible_char">â?¢</property>
+			  <property name="activates_default">False</property>
+			</widget>
+			<packing>
+			  <property name="left_attach">1</property>
+			  <property name="right_attach">2</property>
+			  <property name="top_attach">2</property>
+			  <property name="bottom_attach">3</property>
+			  <property name="y_options"></property>
+			</packing>
+		      </child>
+		    </widget>
+		    <packing>
+		      <property name="padding">0</property>
+		      <property name="expand">True</property>
+		      <property name="fill">True</property>
+		    </packing>
+		  </child>
+		</widget>
+		<packing>
+		  <property name="tab_expand">False</property>
+		  <property name="tab_fill">True</property>
+		</packing>
+	      </child>
+
+	      <child>
+		<widget class="GtkLabel" id="label21">
+		  <property name="visible">True</property>
+		  <property name="label" translatable="yes"></property>
+		  <property name="use_underline">False</property>
+		  <property name="use_markup">False</property>
+		  <property name="justify">GTK_JUSTIFY_LEFT</property>
+		  <property name="wrap">False</property>
+		  <property name="selectable">False</property>
+		  <property name="xalign">0.5</property>
+		  <property name="yalign">0.5</property>
+		  <property name="xpad">0</property>
+		  <property name="ypad">0</property>
+		  <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+		  <property name="width_chars">-1</property>
+		  <property name="single_line_mode">False</property>
+		  <property name="angle">0</property>
+		</widget>
+		<packing>
+		  <property name="type">tab</property>
+		</packing>
+	      </child>
+
+	      <child>
+		<placeholder/>
+	      </child>
+
+	      <child>
+		<widget class="GtkLabel" id="label22">
+		  <property name="visible">True</property>
+		  <property name="label" translatable="yes"></property>
+		  <property name="use_underline">False</property>
+		  <property name="use_markup">False</property>
+		  <property name="justify">GTK_JUSTIFY_LEFT</property>
+		  <property name="wrap">False</property>
+		  <property name="selectable">False</property>
+		  <property name="xalign">0.5</property>
+		  <property name="yalign">0.5</property>
+		  <property name="xpad">0</property>
+		  <property name="ypad">0</property>
+		  <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+		  <property name="width_chars">-1</property>
+		  <property name="single_line_mode">False</property>
+		  <property name="angle">0</property>
+		</widget>
+		<packing>
+		  <property name="type">tab</property>
+		</packing>
+	      </child>
+
+	      <child>
+		<widget class="GtkLabel" id="label19">
+		  <property name="visible">True</property>
+		  <property name="label" translatable="yes"></property>
+		  <property name="use_underline">False</property>
+		  <property name="use_markup">False</property>
+		  <property name="justify">GTK_JUSTIFY_LEFT</property>
+		  <property name="wrap">False</property>
+		  <property name="selectable">False</property>
+		  <property name="xalign">0.5</property>
+		  <property name="yalign">0.5</property>
+		  <property name="xpad">0</property>
+		  <property name="ypad">0</property>
+		  <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+		  <property name="width_chars">-1</property>
+		  <property name="single_line_mode">False</property>
+		  <property name="angle">0</property>
+		</widget>
+		<packing>
+		  <property name="tab_expand">False</property>
+		  <property name="tab_fill">True</property>
+		</packing>
+	      </child>
+
+	      <child>
+		<widget class="GtkLabel" id="label23">
+		  <property name="visible">True</property>
+		  <property name="label" translatable="yes"></property>
+		  <property name="use_underline">False</property>
+		  <property name="use_markup">False</property>
+		  <property name="justify">GTK_JUSTIFY_LEFT</property>
+		  <property name="wrap">False</property>
+		  <property name="selectable">False</property>
+		  <property name="xalign">0.5</property>
+		  <property name="yalign">0.5</property>
+		  <property name="xpad">0</property>
+		  <property name="ypad">0</property>
+		  <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+		  <property name="width_chars">-1</property>
+		  <property name="single_line_mode">False</property>
+		  <property name="angle">0</property>
+		</widget>
+		<packing>
+		  <property name="type">tab</property>
+		</packing>
+	      </child>
+
+	      <child>
+		<placeholder/>
+	      </child>
+
+	      <child>
+		<widget class="GtkLabel" id="label24">
+		  <property name="visible">True</property>
+		  <property name="label" translatable="yes"></property>
+		  <property name="use_underline">False</property>
+		  <property name="use_markup">False</property>
+		  <property name="justify">GTK_JUSTIFY_LEFT</property>
+		  <property name="wrap">False</property>
+		  <property name="selectable">False</property>
+		  <property name="xalign">0.5</property>
+		  <property name="yalign">0.5</property>
+		  <property name="xpad">0</property>
+		  <property name="ypad">0</property>
+		  <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+		  <property name="width_chars">-1</property>
+		  <property name="single_line_mode">False</property>
+		  <property name="angle">0</property>
+		</widget>
+		<packing>
+		  <property name="type">tab</property>
+		</packing>
+	      </child>
+
+	      <child>
+		<widget class="GtkTable" id="table3">
+		  <property name="visible">True</property>
+		  <property name="n_rows">3</property>
+		  <property name="n_columns">2</property>
+		  <property name="homogeneous">False</property>
+		  <property name="row_spacing">10</property>
+		  <property name="column_spacing">5</property>
+
+		  <child>
+		    <widget class="GtkLabel" id="label14">
+		      <property name="visible">True</property>
+		      <property name="label" translatable="yes">_Server</property>
+		      <property name="use_underline">True</property>
+		      <property name="use_markup">False</property>
+		      <property name="justify">GTK_JUSTIFY_LEFT</property>
+		      <property name="wrap">False</property>
+		      <property name="selectable">False</property>
+		      <property name="xalign">0</property>
+		      <property name="yalign">0.5</property>
+		      <property name="xpad">0</property>
+		      <property name="ypad">0</property>
+		      <property name="mnemonic_widget">nfsServerEntry</property>
+		      <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+		      <property name="width_chars">-1</property>
+		      <property name="single_line_mode">False</property>
+		      <property name="angle">0</property>
+		    </widget>
+		    <packing>
+		      <property name="left_attach">0</property>
+		      <property name="right_attach">1</property>
+		      <property name="top_attach">0</property>
+		      <property name="bottom_attach">1</property>
+		      <property name="x_options">fill</property>
+		      <property name="y_options"></property>
+		    </packing>
+		  </child>
+
+		  <child>
+		    <widget class="GtkLabel" id="label15">
+		      <property name="visible">True</property>
+		      <property name="label" translatable="yes">_Path</property>
+		      <property name="use_underline">True</property>
+		      <property name="use_markup">False</property>
+		      <property name="justify">GTK_JUSTIFY_LEFT</property>
+		      <property name="wrap">False</property>
+		      <property name="selectable">False</property>
+		      <property name="xalign">0</property>
+		      <property name="yalign">0.5</property>
+		      <property name="xpad">0</property>
+		      <property name="ypad">0</property>
+		      <property name="mnemonic_widget">nfsPathEntry</property>
+		      <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+		      <property name="width_chars">-1</property>
+		      <property name="single_line_mode">False</property>
+		      <property name="angle">0</property>
+		    </widget>
+		    <packing>
+		      <property name="left_attach">0</property>
+		      <property name="right_attach">1</property>
+		      <property name="top_attach">1</property>
+		      <property name="bottom_attach">2</property>
+		      <property name="x_options">fill</property>
+		      <property name="y_options"></property>
+		    </packing>
+		  </child>
+
+		  <child>
+		    <widget class="GtkLabel" id="label16">
+		      <property name="visible">True</property>
+		      <property name="label" translatable="yes">_Options</property>
+		      <property name="use_underline">True</property>
+		      <property name="use_markup">False</property>
+		      <property name="justify">GTK_JUSTIFY_LEFT</property>
+		      <property name="wrap">False</property>
+		      <property name="selectable">False</property>
+		      <property name="xalign">0</property>
+		      <property name="yalign">0.5</property>
+		      <property name="xpad">0</property>
+		      <property name="ypad">0</property>
+		      <property name="mnemonic_widget">nfsOptionsEntry</property>
+		      <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+		      <property name="width_chars">-1</property>
+		      <property name="single_line_mode">False</property>
+		      <property name="angle">0</property>
+		    </widget>
+		    <packing>
+		      <property name="left_attach">0</property>
+		      <property name="right_attach">1</property>
+		      <property name="top_attach">2</property>
+		      <property name="bottom_attach">3</property>
+		      <property name="x_options">fill</property>
+		      <property name="y_options"></property>
+		    </packing>
+		  </child>
+
+		  <child>
+		    <widget class="GtkEntry" id="nfsServerEntry">
+		      <property name="visible">True</property>
+		      <property name="can_focus">True</property>
+		      <property name="editable">True</property>
+		      <property name="visibility">True</property>
+		      <property name="max_length">0</property>
+		      <property name="text" translatable="yes"></property>
+		      <property name="has_frame">True</property>
+		      <property name="invisible_char">â?¢</property>
+		      <property name="activates_default">False</property>
+		    </widget>
+		    <packing>
+		      <property name="left_attach">1</property>
+		      <property name="right_attach">2</property>
+		      <property name="top_attach">0</property>
+		      <property name="bottom_attach">1</property>
+		      <property name="y_options"></property>
+		    </packing>
+		  </child>
+
+		  <child>
+		    <widget class="GtkEntry" id="nfsPathEntry">
+		      <property name="visible">True</property>
+		      <property name="can_focus">True</property>
+		      <property name="editable">True</property>
+		      <property name="visibility">True</property>
+		      <property name="max_length">0</property>
+		      <property name="text" translatable="yes"></property>
+		      <property name="has_frame">True</property>
+		      <property name="invisible_char">â?¢</property>
+		      <property name="activates_default">False</property>
+		    </widget>
+		    <packing>
+		      <property name="left_attach">1</property>
+		      <property name="right_attach">2</property>
+		      <property name="top_attach">1</property>
+		      <property name="bottom_attach">2</property>
+		      <property name="y_options"></property>
+		    </packing>
+		  </child>
+
+		  <child>
+		    <widget class="GtkEntry" id="nfsOptionsEntry">
+		      <property name="visible">True</property>
+		      <property name="can_focus">True</property>
+		      <property name="editable">True</property>
+		      <property name="visibility">True</property>
+		      <property name="max_length">0</property>
+		      <property name="text" translatable="yes"></property>
+		      <property name="has_frame">True</property>
+		      <property name="invisible_char">â?¢</property>
+		      <property name="activates_default">False</property>
+		    </widget>
+		    <packing>
+		      <property name="left_attach">1</property>
+		      <property name="right_attach">2</property>
+		      <property name="top_attach">2</property>
+		      <property name="bottom_attach">3</property>
+		      <property name="y_options"></property>
+		    </packing>
+		  </child>
+		</widget>
+		<packing>
+		  <property name="tab_expand">False</property>
+		  <property name="tab_fill">True</property>
+		</packing>
+	      </child>
+
+	      <child>
+		<widget class="GtkLabel" id="label25">
+		  <property name="visible">True</property>
+		  <property name="label" translatable="yes"></property>
+		  <property name="use_underline">False</property>
+		  <property name="use_markup">False</property>
+		  <property name="justify">GTK_JUSTIFY_LEFT</property>
+		  <property name="wrap">False</property>
+		  <property name="selectable">False</property>
+		  <property name="xalign">0.5</property>
+		  <property name="yalign">0.5</property>
+		  <property name="xpad">0</property>
+		  <property name="ypad">0</property>
+		  <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+		  <property name="width_chars">-1</property>
+		  <property name="single_line_mode">False</property>
+		  <property name="angle">0</property>
+		</widget>
+		<packing>
+		  <property name="type">tab</property>
+		</packing>
+	      </child>
+
+	      <child>
+		<placeholder/>
+	      </child>
+
+	      <child>
+		<widget class="GtkLabel" id="label26">
+		  <property name="visible">True</property>
+		  <property name="label" translatable="yes"></property>
+		  <property name="use_underline">False</property>
+		  <property name="use_markup">False</property>
+		  <property name="justify">GTK_JUSTIFY_LEFT</property>
+		  <property name="wrap">False</property>
+		  <property name="selectable">False</property>
+		  <property name="xalign">0.5</property>
+		  <property name="yalign">0.5</property>
+		  <property name="xpad">0</property>
+		  <property name="ypad">0</property>
+		  <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+		  <property name="width_chars">-1</property>
+		  <property name="single_line_mode">False</property>
+		  <property name="angle">0</property>
+		</widget>
+		<packing>
+		  <property name="type">tab</property>
+		</packing>
+	      </child>
+
+	      <child>
+		<widget class="GtkTable" id="table4">
+		  <property name="visible">True</property>
+		  <property name="n_rows">2</property>
+		  <property name="n_columns">2</property>
+		  <property name="homogeneous">False</property>
+		  <property name="row_spacing">10</property>
+		  <property name="column_spacing">5</property>
+
+		  <child>
+		    <widget class="GtkLabel" id="label17">
+		      <property name="visible">True</property>
+		      <property name="label" translatable="yes">_Partition</property>
+		      <property name="use_underline">True</property>
+		      <property name="use_markup">False</property>
+		      <property name="justify">GTK_JUSTIFY_LEFT</property>
+		      <property name="wrap">False</property>
+		      <property name="selectable">False</property>
+		      <property name="xalign">0</property>
+		      <property name="yalign">0.5</property>
+		      <property name="xpad">0</property>
+		      <property name="ypad">0</property>
+		      <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+		      <property name="width_chars">-1</property>
+		      <property name="single_line_mode">False</property>
+		      <property name="angle">0</property>
+		    </widget>
+		    <packing>
+		      <property name="left_attach">0</property>
+		      <property name="right_attach">1</property>
+		      <property name="top_attach">0</property>
+		      <property name="bottom_attach">1</property>
+		      <property name="x_options">fill</property>
+		      <property name="y_options"></property>
+		    </packing>
+		  </child>
+
+		  <child>
+		    <widget class="GtkLabel" id="label18">
+		      <property name="visible">True</property>
+		      <property name="label" translatable="yes">_Directory</property>
+		      <property name="use_underline">True</property>
+		      <property name="use_markup">False</property>
+		      <property name="justify">GTK_JUSTIFY_LEFT</property>
+		      <property name="wrap">False</property>
+		      <property name="selectable">False</property>
+		      <property name="xalign">0</property>
+		      <property name="yalign">0.5</property>
+		      <property name="xpad">0</property>
+		      <property name="ypad">0</property>
+		      <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+		      <property name="width_chars">-1</property>
+		      <property name="single_line_mode">False</property>
+		      <property name="angle">0</property>
+		    </widget>
+		    <packing>
+		      <property name="left_attach">0</property>
+		      <property name="right_attach">1</property>
+		      <property name="top_attach">1</property>
+		      <property name="bottom_attach">2</property>
+		      <property name="x_options">fill</property>
+		      <property name="y_options"></property>
+		    </packing>
+		  </child>
+
+		  <child>
+		    <widget class="GtkComboBox" id="partitionComboBox">
+		      <property name="visible">True</property>
+		      <property name="add_tearoffs">False</property>
+		      <property name="focus_on_click">True</property>
+		    </widget>
+		    <packing>
+		      <property name="left_attach">1</property>
+		      <property name="right_attach">2</property>
+		      <property name="top_attach">0</property>
+		      <property name="bottom_attach">1</property>
+		      <property name="y_options">fill</property>
+		    </packing>
+		  </child>
+
+		  <child>
+		    <widget class="GtkFileChooserButton" id="directoryChooserButton">
+		      <property name="visible">True</property>
+		      <property name="title" translatable="yes">Select A Directory</property>
+		      <property name="action">GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER</property>
+		      <property name="local_only">True</property>
+		      <property name="show_hidden">False</property>
+		      <property name="do_overwrite_confirmation">False</property>
+		      <property name="width_chars">-1</property>
+		    </widget>
+		    <packing>
+		      <property name="left_attach">1</property>
+		      <property name="right_attach">2</property>
+		      <property name="top_attach">1</property>
+		      <property name="bottom_attach">2</property>
+		      <property name="x_options">fill</property>
+		      <property name="y_options">fill</property>
+		    </packing>
+		  </child>
+		</widget>
+		<packing>
+		  <property name="tab_expand">False</property>
+		  <property name="tab_fill">True</property>
+		</packing>
+	      </child>
+
+	      <child>
+		<widget class="GtkLabel" id="label27">
+		  <property name="visible">True</property>
+		  <property name="label" translatable="yes"></property>
+		  <property name="use_underline">False</property>
+		  <property name="use_markup">False</property>
+		  <property name="justify">GTK_JUSTIFY_LEFT</property>
+		  <property name="wrap">False</property>
+		  <property name="selectable">False</property>
+		  <property name="xalign">0.5</property>
+		  <property name="yalign">0.5</property>
+		  <property name="xpad">0</property>
+		  <property name="ypad">0</property>
+		  <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+		  <property name="width_chars">-1</property>
+		  <property name="single_line_mode">False</property>
+		  <property name="angle">0</property>
+		</widget>
+		<packing>
+		  <property name="type">tab</property>
+		</packing>
+	      </child>
+
+	      <child>
+		<placeholder/>
+	      </child>
+
+	      <child>
+		<widget class="GtkLabel" id="label28">
+		  <property name="visible">True</property>
+		  <property name="label" translatable="yes"></property>
+		  <property name="use_underline">False</property>
+		  <property name="use_markup">False</property>
+		  <property name="justify">GTK_JUSTIFY_LEFT</property>
+		  <property name="wrap">False</property>
+		  <property name="selectable">False</property>
+		  <property name="xalign">0.5</property>
+		  <property name="yalign">0.5</property>
+		  <property name="xpad">0</property>
+		  <property name="ypad">0</property>
+		  <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+		  <property name="width_chars">-1</property>
+		  <property name="single_line_mode">False</property>
+		  <property name="angle">0</property>
+		</widget>
+		<packing>
+		  <property name="type">tab</property>
+		</packing>
+	      </child>
+	    </widget>
+	    <packing>
+	      <property name="padding">0</property>
+	      <property name="expand">True</property>
+	      <property name="fill">False</property>
+	    </packing>
+	  </child>
+	</widget>
+	<packing>
+	  <property name="padding">0</property>
+	  <property name="expand">True</property>
+	  <property name="fill">True</property>
+	</packing>
+      </child>
+    </widget>
+  </child>
+</widget>
+
+</glade-interface>
diff --git a/data/ui/anaconda.glade b/data/ui/anaconda.glade
new file mode 100644
index 0000000..08e9e64
--- /dev/null
+++ b/data/ui/anaconda.glade
@@ -0,0 +1,270 @@
+<?xml version="1.0" standalone="no"?> <!--*- mode: xml -*-->
+<!DOCTYPE glade-interface SYSTEM "http://glade.gnome.org/glade-2.0.dtd";>
+
+<glade-interface>
+
+<widget class="GtkWindow" id="mainWindow">
+  <property name="width_request">610</property>
+  <property name="height_request">450</property>
+  <property name="title" translatable="yes"></property>
+  <property name="type">GTK_WINDOW_TOPLEVEL</property>
+  <property name="window_position">GTK_WIN_POS_CENTER</property>
+  <property name="modal">False</property>
+  <property name="default_width">800</property>
+  <property name="default_height">600</property>
+  <property name="resizable">False</property>
+  <property name="destroy_with_parent">False</property>
+  <property name="decorated">True</property>
+  <property name="skip_taskbar_hint">False</property>
+  <property name="skip_pager_hint">False</property>
+  <property name="type_hint">GDK_WINDOW_TYPE_HINT_NORMAL</property>
+  <property name="gravity">GDK_GRAVITY_CENTER</property>
+  <property name="focus_on_map">True</property>
+  <property name="urgency_hint">False</property>
+  <signal name="key_release_event" handler="on_mainWindow_key_release_event" last_modification_time="Wed, 12 Jan 2005 20:53:20 GMT"/>
+  <signal name="delete_event" handler="on_mainWindow_delete_event" last_modification_time="Wed, 12 Jan 2005 21:03:14 GMT"/>
+
+  <child>
+    <widget class="GtkVBox" id="mainBox">
+      <property name="visible">True</property>
+      <property name="homogeneous">False</property>
+      <property name="spacing">12</property>
+
+      <child>
+	<widget class="GtkImage" id="headerImage">
+	  <property name="visible">True</property>
+	  <property name="xalign">0.5</property>
+	  <property name="yalign">0.5</property>
+	  <property name="xpad">0</property>
+	  <property name="ypad">0</property>
+	</widget>
+	<packing>
+	  <property name="padding">0</property>
+	  <property name="expand">False</property>
+	  <property name="fill">True</property>
+	</packing>
+      </child>
+
+      <child>
+	<widget class="GtkTable" id="mainTable">
+	  <property name="border_width">12</property>
+	  <property name="visible">True</property>
+	  <property name="n_rows">1</property>
+	  <property name="n_columns">2</property>
+	  <property name="homogeneous">False</property>
+	  <property name="row_spacing">0</property>
+	  <property name="column_spacing">0</property>
+
+	  <child>
+	    <widget class="GtkFrame" id="installFrame">
+	      <property name="visible">True</property>
+	      <property name="label_xalign">0</property>
+	      <property name="label_yalign">0.5</property>
+	      <property name="shadow_type">GTK_SHADOW_NONE</property>
+
+	      <child>
+		<widget class="GtkAlignment" id="alignment5">
+		  <property name="visible">True</property>
+		  <property name="xalign">0.5</property>
+		  <property name="yalign">0.5</property>
+		  <property name="xscale">1</property>
+		  <property name="yscale">1</property>
+		  <property name="top_padding">0</property>
+		  <property name="bottom_padding">0</property>
+		  <property name="left_padding">12</property>
+		  <property name="right_padding">0</property>
+
+		  <child>
+		    <placeholder/>
+		  </child>
+		</widget>
+	      </child>
+	    </widget>
+	    <packing>
+	      <property name="left_attach">1</property>
+	      <property name="right_attach">2</property>
+	      <property name="top_attach">0</property>
+	      <property name="bottom_attach">1</property>
+	    </packing>
+	  </child>
+	</widget>
+	<packing>
+	  <property name="padding">0</property>
+	  <property name="expand">True</property>
+	  <property name="fill">True</property>
+	</packing>
+      </child>
+
+      <child>
+	<widget class="GtkHBox" id="buttonBar">
+	  <property name="border_width">12</property>
+	  <property name="visible">True</property>
+	  <property name="homogeneous">False</property>
+	  <property name="spacing">6</property>
+
+	  <child>
+	    <placeholder/>
+	  </child>
+
+	  <child>
+	    <widget class="GtkButton" id="debugButton">
+	      <property name="can_focus">True</property>
+	      <property name="relief">GTK_RELIEF_NORMAL</property>
+	      <property name="focus_on_click">True</property>
+	      <signal name="clicked" handler="on_debugButton_clicked" last_modification_time="Wed, 12 Jan 2005 20:02:25 GMT"/>
+
+	      <child>
+		<widget class="GtkLabel" id="label4">
+		  <property name="visible">True</property>
+		  <property name="label" translatable="yes">_Debug</property>
+		  <property name="use_underline">True</property>
+		  <property name="use_markup">False</property>
+		  <property name="justify">GTK_JUSTIFY_LEFT</property>
+		  <property name="wrap">False</property>
+		  <property name="selectable">False</property>
+		  <property name="xalign">0.5</property>
+		  <property name="yalign">0.5</property>
+		  <property name="xpad">0</property>
+		  <property name="ypad">0</property>
+		  <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+		  <property name="width_chars">-1</property>
+		  <property name="single_line_mode">False</property>
+		  <property name="angle">0</property>
+		</widget>
+	      </child>
+	    </widget>
+	    <packing>
+	      <property name="padding">0</property>
+	      <property name="expand">False</property>
+	      <property name="fill">False</property>
+	    </packing>
+	  </child>
+
+	  <child>
+	    <widget class="GtkHButtonBox" id="hbuttonbox2">
+	      <property name="visible">True</property>
+	      <property name="layout_style">GTK_BUTTONBOX_END</property>
+	      <property name="spacing">18</property>
+
+	      <child>
+		<widget class="GtkButton" id="backButton">
+		  <property name="visible">True</property>
+		  <property name="can_default">True</property>
+		  <property name="can_focus">True</property>
+		  <property name="relief">GTK_RELIEF_NORMAL</property>
+		  <property name="focus_on_click">True</property>
+		  <signal name="clicked" handler="on_backButton_clicked" last_modification_time="Wed, 12 Jan 2005 20:02:34 GMT"/>
+
+		  <child>
+		    <widget class="GtkLabel" id="label8">
+		      <property name="visible">True</property>
+		      <property name="label" translatable="yes">_Back</property>
+		      <property name="use_underline">True</property>
+		      <property name="use_markup">False</property>
+		      <property name="justify">GTK_JUSTIFY_LEFT</property>
+		      <property name="wrap">False</property>
+		      <property name="selectable">False</property>
+		      <property name="xalign">0.5</property>
+		      <property name="yalign">0.5</property>
+		      <property name="xpad">0</property>
+		      <property name="ypad">0</property>
+		      <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+		      <property name="width_chars">-1</property>
+		      <property name="single_line_mode">False</property>
+		      <property name="angle">0</property>
+		    </widget>
+		  </child>
+		</widget>
+	      </child>
+
+	      <child>
+		<widget class="GtkButton" id="nextButton">
+		  <property name="visible">True</property>
+		  <property name="can_default">True</property>
+		  <property name="can_focus">True</property>
+		  <property name="relief">GTK_RELIEF_NORMAL</property>
+		  <property name="focus_on_click">True</property>
+		  <signal name="clicked" handler="on_nextButton_clicked" last_modification_time="Wed, 12 Jan 2005 20:01:46 GMT"/>
+
+		  <child>
+		    <widget class="GtkLabel" id="label6">
+		      <property name="visible">True</property>
+		      <property name="label" translatable="yes">_Next</property>
+		      <property name="use_underline">True</property>
+		      <property name="use_markup">False</property>
+		      <property name="justify">GTK_JUSTIFY_LEFT</property>
+		      <property name="wrap">False</property>
+		      <property name="selectable">False</property>
+		      <property name="xalign">0.5</property>
+		      <property name="yalign">0.5</property>
+		      <property name="xpad">0</property>
+		      <property name="ypad">0</property>
+		      <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+		      <property name="width_chars">-1</property>
+		      <property name="single_line_mode">False</property>
+		      <property name="angle">0</property>
+		    </widget>
+		  </child>
+		</widget>
+	      </child>
+
+	      <child>
+		<widget class="GtkButton" id="rebootButton">
+		  <property name="can_default">True</property>
+		  <property name="can_focus">True</property>
+		  <property name="relief">GTK_RELIEF_NORMAL</property>
+		  <property name="focus_on_click">True</property>
+		  <signal name="clicked" handler="on_rebootButton_clicked" last_modification_time="Wed, 12 Jan 2005 21:46:55 GMT"/>
+
+		  <child>
+		    <widget class="GtkLabel" id="label7">
+		      <property name="visible">True</property>
+		      <property name="label" translatable="yes">Reboo_t</property>
+		      <property name="use_underline">True</property>
+		      <property name="use_markup">False</property>
+		      <property name="justify">GTK_JUSTIFY_LEFT</property>
+		      <property name="wrap">False</property>
+		      <property name="selectable">False</property>
+		      <property name="xalign">0.5</property>
+		      <property name="yalign">0.5</property>
+		      <property name="xpad">0</property>
+		      <property name="ypad">0</property>
+		      <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+		      <property name="width_chars">-1</property>
+		      <property name="single_line_mode">False</property>
+		      <property name="angle">0</property>
+		    </widget>
+		  </child>
+		</widget>
+	      </child>
+
+	      <child>
+		<widget class="GtkButton" id="closeButton">
+		  <property name="can_default">True</property>
+		  <property name="can_focus">True</property>
+		  <property name="label">gtk-close</property>
+		  <property name="use_stock">True</property>
+		  <property name="relief">GTK_RELIEF_NORMAL</property>
+		  <property name="focus_on_click">True</property>
+		  <signal name="clicked" handler="on_closeButton_clicked" last_modification_time="Wed, 04 Apr 2007 20:23:13 GMT"/>
+		</widget>
+	      </child>
+	    </widget>
+	    <packing>
+	      <property name="padding">0</property>
+	      <property name="expand">True</property>
+	      <property name="fill">True</property>
+	    </packing>
+	  </child>
+	</widget>
+	<packing>
+	  <property name="padding">0</property>
+	  <property name="expand">False</property>
+	  <property name="fill">True</property>
+	</packing>
+      </child>
+    </widget>
+  </child>
+</widget>
+
+</glade-interface>
diff --git a/data/ui/autopart.glade b/data/ui/autopart.glade
new file mode 100644
index 0000000..f58ebd1
--- /dev/null
+++ b/data/ui/autopart.glade
@@ -0,0 +1,300 @@
+<?xml version="1.0" standalone="no"?> <!--*- mode: xml -*-->
+<!DOCTYPE glade-interface SYSTEM "http://glade.gnome.org/glade-2.0.dtd";>
+
+<glade-interface>
+
+<widget class="GtkWindow" id="unused1">
+  <property name="border_width">18</property>
+  <property name="title" translatable="yes" context="yes"></property>
+  <property name="type">GTK_WINDOW_TOPLEVEL</property>
+  <property name="window_position">GTK_WIN_POS_NONE</property>
+  <property name="modal">False</property>
+  <property name="default_width">440</property>
+  <property name="default_height">250</property>
+  <property name="resizable">True</property>
+  <property name="destroy_with_parent">False</property>
+  <property name="decorated">True</property>
+  <property name="skip_taskbar_hint">False</property>
+  <property name="skip_pager_hint">False</property>
+  <property name="type_hint">GDK_WINDOW_TYPE_HINT_NORMAL</property>
+  <property name="gravity">GDK_GRAVITY_NORTH_WEST</property>
+  <property name="focus_on_map">True</property>
+  <property name="urgency_hint">False</property>
+
+  <child>
+    <widget class="GtkTable" id="parttypeTable">
+      <property name="visible">True</property>
+      <property name="n_rows">4</property>
+      <property name="n_columns">1</property>
+      <property name="homogeneous">False</property>
+      <property name="row_spacing">0</property>
+      <property name="column_spacing">0</property>
+
+      <child>
+	<widget class="GtkLabel" id="mainlabel">
+	  <property name="visible">True</property>
+	  <property name="label" translatable="yes">Which type of installation would you like?</property>
+	  <property name="use_underline">False</property>
+	  <property name="use_markup">False</property>
+	  <property name="justify">GTK_JUSTIFY_LEFT</property>
+	  <property name="wrap">True</property>
+	  <property name="selectable">False</property>
+	  <property name="xalign">0</property>
+	  <property name="yalign">0</property>
+	  <property name="xpad">0</property>
+	  <property name="ypad">0</property>
+	  <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+	  <property name="width_chars">-1</property>
+	  <property name="single_line_mode">False</property>
+	  <property name="angle">0</property>
+	</widget>
+	<packing>
+	  <property name="left_attach">0</property>
+	  <property name="right_attach">1</property>
+	  <property name="top_attach">0</property>
+	  <property name="bottom_attach">1</property>
+	  <property name="x_options">fill</property>
+	  <property name="y_options"></property>
+	</packing>
+      </child>
+
+      <child>
+	<widget class="GtkCheckButton" id="encryptButton">
+	  <property name="visible">True</property>
+	  <property name="can_focus">True</property>
+	  <property name="label" translatable="yes">_Encrypt system</property>
+	  <property name="use_underline">True</property>
+	  <property name="relief">GTK_RELIEF_NORMAL</property>
+	  <property name="focus_on_click">True</property>
+	  <property name="active">False</property>
+	  <property name="inconsistent">False</property>
+	  <property name="draw_indicator">True</property>
+	</widget>
+	<packing>
+	  <property name="left_attach">0</property>
+	  <property name="right_attach">1</property>
+	  <property name="top_attach">2</property>
+	  <property name="bottom_attach">3</property>
+	  <property name="x_options">fill</property>
+	  <property name="y_options"></property>
+	</packing>
+      </child>
+
+      <child>
+	<widget class="GtkCheckButton" id="reviewButton">
+	  <property name="label" translatable="yes" context="yes">Re_view and modify partitioning layout</property>
+	  <property name="use_underline">True</property>
+	  <property name="relief">GTK_RELIEF_NORMAL</property>
+	  <property name="focus_on_click">True</property>
+	  <property name="active">False</property>
+	  <property name="inconsistent">False</property>
+	  <property name="draw_indicator">True</property>
+	</widget>
+	<packing>
+	  <property name="left_attach">0</property>
+	  <property name="right_attach">1</property>
+	  <property name="top_attach">3</property>
+	  <property name="bottom_attach">4</property>
+	  <property name="x_options">fill</property>
+	  <property name="y_options"></property>
+	</packing>
+      </child>
+    </widget>
+  </child>
+</widget>
+
+<widget class="GtkDialog" id="shrinkDialog">
+  <property name="border_width">12</property>
+  <property name="visible">True</property>
+  <property name="title" translatable="yes">Volume to Shrink</property>
+  <property name="type">GTK_WINDOW_TOPLEVEL</property>
+  <property name="window_position">GTK_WIN_POS_CENTER</property>
+  <property name="modal">False</property>
+  <property name="resizable">True</property>
+  <property name="destroy_with_parent">False</property>
+  <property name="decorated">True</property>
+  <property name="skip_taskbar_hint">False</property>
+  <property name="skip_pager_hint">False</property>
+  <property name="type_hint">GDK_WINDOW_TYPE_HINT_DIALOG</property>
+  <property name="gravity">GDK_GRAVITY_NORTH_WEST</property>
+  <property name="focus_on_map">True</property>
+  <property name="urgency_hint">False</property>
+  <property name="has_separator">True</property>
+
+  <child internal-child="vbox">
+    <widget class="GtkVBox" id="dialog-vbox1">
+      <property name="visible">True</property>
+      <property name="homogeneous">False</property>
+      <property name="spacing">0</property>
+
+      <child internal-child="action_area">
+	<widget class="GtkHButtonBox" id="dialog-action_area1">
+	  <property name="visible">True</property>
+	  <property name="layout_style">GTK_BUTTONBOX_END</property>
+
+	  <child>
+	    <widget class="GtkButton" id="button4">
+	      <property name="visible">True</property>
+	      <property name="can_default">True</property>
+	      <property name="can_focus">True</property>
+	      <property name="label">gtk-cancel</property>
+	      <property name="use_stock">True</property>
+	      <property name="relief">GTK_RELIEF_NORMAL</property>
+	      <property name="focus_on_click">True</property>
+	      <property name="response_id">-6</property>
+	    </widget>
+	  </child>
+
+	  <child>
+	    <widget class="GtkButton" id="button5">
+	      <property name="visible">True</property>
+	      <property name="can_default">True</property>
+	      <property name="can_focus">True</property>
+	      <property name="relief">GTK_RELIEF_NORMAL</property>
+	      <property name="focus_on_click">True</property>
+	      <property name="response_id">-5</property>
+
+	      <child>
+		<widget class="GtkLabel" id="label7">
+		  <property name="visible">True</property>
+		  <property name="label" translatable="yes">_Shrink</property>
+		  <property name="use_underline">True</property>
+		  <property name="use_markup">False</property>
+		  <property name="justify">GTK_JUSTIFY_LEFT</property>
+		  <property name="wrap">False</property>
+		  <property name="selectable">False</property>
+		  <property name="xalign">0.5</property>
+		  <property name="yalign">0.5</property>
+		  <property name="xpad">0</property>
+		  <property name="ypad">0</property>
+		  <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+		  <property name="width_chars">-1</property>
+		  <property name="single_line_mode">False</property>
+		  <property name="angle">0</property>
+		</widget>
+	      </child>
+	    </widget>
+	  </child>
+	</widget>
+	<packing>
+	  <property name="padding">0</property>
+	  <property name="expand">False</property>
+	  <property name="fill">True</property>
+	  <property name="pack_type">GTK_PACK_END</property>
+	</packing>
+      </child>
+
+      <child>
+	<widget class="GtkVBox" id="vbox2">
+	  <property name="visible">True</property>
+	  <property name="homogeneous">False</property>
+	  <property name="spacing">6</property>
+
+	  <child>
+	    <widget class="GtkLabel" id="label5">
+	      <property name="visible">True</property>
+	      <property name="label" translatable="yes">Which partition would you like to shrink to make room for your installation?</property>
+	      <property name="use_underline">False</property>
+	      <property name="use_markup">False</property>
+	      <property name="justify">GTK_JUSTIFY_LEFT</property>
+	      <property name="wrap">True</property>
+	      <property name="selectable">False</property>
+	      <property name="xalign">0.5</property>
+	      <property name="yalign">0.5</property>
+	      <property name="xpad">0</property>
+	      <property name="ypad">0</property>
+	      <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+	      <property name="width_chars">-1</property>
+	      <property name="single_line_mode">False</property>
+	      <property name="angle">0</property>
+	    </widget>
+	    <packing>
+	      <property name="padding">0</property>
+	      <property name="expand">False</property>
+	      <property name="fill">False</property>
+	    </packing>
+	  </child>
+
+	  <child>
+	    <widget class="GtkComboBox" id="shrinkPartCombo">
+	      <property name="visible">True</property>
+	      <property name="add_tearoffs">False</property>
+	      <property name="focus_on_click">True</property>
+	      <signal name="changed" handler="on_resizePartCombo_changed" last_modification_time="Tue, 05 Feb 2008 18:27:52 GMT"/>
+	    </widget>
+	    <packing>
+	      <property name="padding">0</property>
+	      <property name="expand">False</property>
+	      <property name="fill">True</property>
+	    </packing>
+	  </child>
+
+	  <child>
+	    <widget class="GtkHBox" id="hbox4">
+	      <property name="visible">True</property>
+	      <property name="homogeneous">False</property>
+	      <property name="spacing">6</property>
+
+	      <child>
+		<widget class="GtkLabel" id="label6">
+		  <property name="visible">True</property>
+		  <property name="label" translatable="yes">&lt;b&gt;Shrink partition _to size (in MB):&lt;/b&gt;</property>
+		  <property name="use_underline">True</property>
+		  <property name="use_markup">True</property>
+		  <property name="justify">GTK_JUSTIFY_LEFT</property>
+		  <property name="wrap">False</property>
+		  <property name="selectable">False</property>
+		  <property name="xalign">0.5</property>
+		  <property name="yalign">0.5</property>
+		  <property name="xpad">0</property>
+		  <property name="ypad">0</property>
+		  <property name="mnemonic_widget">shrinkSB</property>
+		  <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+		  <property name="width_chars">-1</property>
+		  <property name="single_line_mode">False</property>
+		  <property name="angle">0</property>
+		</widget>
+		<packing>
+		  <property name="padding">0</property>
+		  <property name="expand">False</property>
+		  <property name="fill">False</property>
+		</packing>
+	      </child>
+
+	      <child>
+		<widget class="GtkSpinButton" id="shrinkSB">
+		  <property name="visible">True</property>
+		  <property name="can_focus">True</property>
+		  <property name="climb_rate">1</property>
+		  <property name="digits">0</property>
+		  <property name="numeric">True</property>
+		  <property name="update_policy">GTK_UPDATE_IF_VALID</property>
+		  <property name="snap_to_ticks">False</property>
+		  <property name="wrap">False</property>
+		  <property name="adjustment">1 0 100 1 1 0</property>
+		</widget>
+		<packing>
+		  <property name="padding">0</property>
+		  <property name="expand">True</property>
+		  <property name="fill">True</property>
+		</packing>
+	      </child>
+	    </widget>
+	    <packing>
+	      <property name="padding">0</property>
+	      <property name="expand">False</property>
+	      <property name="fill">False</property>
+	    </packing>
+	  </child>
+	</widget>
+	<packing>
+	  <property name="padding">0</property>
+	  <property name="expand">True</property>
+	  <property name="fill">True</property>
+	</packing>
+      </child>
+    </widget>
+  </child>
+</widget>
+
+</glade-interface>
diff --git a/data/ui/blwhere.glade b/data/ui/blwhere.glade
new file mode 100644
index 0000000..b043413
--- /dev/null
+++ b/data/ui/blwhere.glade
@@ -0,0 +1,378 @@
+<?xml version="1.0" standalone="no"?> <!--*- mode: xml -*-->
+<!DOCTYPE glade-interface SYSTEM "http://glade.gnome.org/glade-2.0.dtd";>
+
+<glade-interface>
+
+<widget class="GtkDialog" id="blwhereDialog">
+  <property name="visible">True</property>
+  <property name="title" translatable="yes">Boot loader device</property>
+  <property name="type">GTK_WINDOW_TOPLEVEL</property>
+  <property name="window_position">GTK_WIN_POS_CENTER_ALWAYS</property>
+  <property name="modal">False</property>
+  <property name="resizable">True</property>
+  <property name="destroy_with_parent">False</property>
+  <property name="decorated">True</property>
+  <property name="skip_taskbar_hint">False</property>
+  <property name="skip_pager_hint">False</property>
+  <property name="type_hint">GDK_WINDOW_TYPE_HINT_DIALOG</property>
+  <property name="gravity">GDK_GRAVITY_NORTH_WEST</property>
+  <property name="focus_on_map">True</property>
+  <property name="urgency_hint">False</property>
+  <property name="has_separator">True</property>
+
+  <child internal-child="vbox">
+    <widget class="GtkVBox" id="dialog-vbox1">
+      <property name="visible">True</property>
+      <property name="homogeneous">False</property>
+      <property name="spacing">6</property>
+
+      <child internal-child="action_area">
+	<widget class="GtkHButtonBox" id="dialog-action_area1">
+	  <property name="visible">True</property>
+	  <property name="layout_style">GTK_BUTTONBOX_END</property>
+
+	  <child>
+	    <widget class="GtkButton" id="cancelbutton1">
+	      <property name="visible">True</property>
+	      <property name="can_default">True</property>
+	      <property name="can_focus">True</property>
+	      <property name="label">gtk-cancel</property>
+	      <property name="use_stock">True</property>
+	      <property name="relief">GTK_RELIEF_NORMAL</property>
+	      <property name="focus_on_click">True</property>
+	      <property name="response_id">-6</property>
+	    </widget>
+	  </child>
+
+	  <child>
+	    <widget class="GtkButton" id="okbutton1">
+	      <property name="visible">True</property>
+	      <property name="can_default">True</property>
+	      <property name="can_focus">True</property>
+	      <property name="label">gtk-ok</property>
+	      <property name="use_stock">True</property>
+	      <property name="relief">GTK_RELIEF_NORMAL</property>
+	      <property name="focus_on_click">True</property>
+	      <property name="response_id">-5</property>
+	    </widget>
+	  </child>
+	</widget>
+	<packing>
+	  <property name="padding">0</property>
+	  <property name="expand">False</property>
+	  <property name="fill">True</property>
+	  <property name="pack_type">GTK_PACK_END</property>
+	</packing>
+      </child>
+
+      <child>
+	<widget class="GtkVBox" id="vbox1">
+	  <property name="visible">True</property>
+	  <property name="homogeneous">False</property>
+	  <property name="spacing">6</property>
+
+	  <child>
+	    <widget class="GtkLabel" id="label1">
+	      <property name="visible">True</property>
+	      <property name="label" translatable="yes">Where would you like to install the boot loader for your system?</property>
+	      <property name="use_underline">False</property>
+	      <property name="use_markup">False</property>
+	      <property name="justify">GTK_JUSTIFY_LEFT</property>
+	      <property name="wrap">True</property>
+	      <property name="selectable">False</property>
+	      <property name="xalign">0.5</property>
+	      <property name="yalign">0.5</property>
+	      <property name="xpad">0</property>
+	      <property name="ypad">0</property>
+	      <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+	      <property name="width_chars">-1</property>
+	      <property name="single_line_mode">False</property>
+	      <property name="angle">0</property>
+	    </widget>
+	    <packing>
+	      <property name="padding">0</property>
+	      <property name="expand">False</property>
+	      <property name="fill">False</property>
+	    </packing>
+	  </child>
+
+	  <child>
+	    <widget class="GtkRadioButton" id="mbrRadio">
+	      <property name="can_focus">True</property>
+	      <property name="label" translatable="yes">MBR</property>
+	      <property name="use_underline">True</property>
+	      <property name="relief">GTK_RELIEF_NORMAL</property>
+	      <property name="focus_on_click">True</property>
+	      <property name="active">False</property>
+	      <property name="inconsistent">False</property>
+	      <property name="draw_indicator">True</property>
+	    </widget>
+	    <packing>
+	      <property name="padding">0</property>
+	      <property name="expand">False</property>
+	      <property name="fill">False</property>
+	    </packing>
+	  </child>
+
+	  <child>
+	    <widget class="GtkRadioButton" id="bootRadio">
+	      <property name="can_focus">True</property>
+	      <property name="label" translatable="yes">/boot</property>
+	      <property name="use_underline">True</property>
+	      <property name="relief">GTK_RELIEF_NORMAL</property>
+	      <property name="focus_on_click">True</property>
+	      <property name="active">False</property>
+	      <property name="inconsistent">False</property>
+	      <property name="draw_indicator">True</property>
+	      <property name="group">mbrRadio</property>
+	    </widget>
+	    <packing>
+	      <property name="padding">0</property>
+	      <property name="expand">False</property>
+	      <property name="fill">False</property>
+	    </packing>
+	  </child>
+
+	  <child>
+	    <widget class="GtkExpander" id="expander1">
+	      <property name="visible">True</property>
+	      <property name="can_focus">True</property>
+	      <property name="expanded">False</property>
+	      <property name="spacing">0</property>
+
+	      <child>
+		<widget class="GtkAlignment" id="alignment1">
+		  <property name="visible">True</property>
+		  <property name="xalign">0.5</property>
+		  <property name="yalign">0.5</property>
+		  <property name="xscale">0.75</property>
+		  <property name="yscale">1</property>
+		  <property name="top_padding">0</property>
+		  <property name="bottom_padding">0</property>
+		  <property name="left_padding">0</property>
+		  <property name="right_padding">0</property>
+
+		  <child>
+		    <widget class="GtkTable" id="table1">
+		      <property name="visible">True</property>
+		      <property name="n_rows">4</property>
+		      <property name="n_columns">2</property>
+		      <property name="homogeneous">False</property>
+		      <property name="row_spacing">6</property>
+		      <property name="column_spacing">18</property>
+
+		      <child>
+			<widget class="GtkLabel" id="bd1Label">
+			  <property name="visible">True</property>
+			  <property name="label" translatable="yes">First BIOS drive:</property>
+			  <property name="use_underline">False</property>
+			  <property name="use_markup">False</property>
+			  <property name="justify">GTK_JUSTIFY_LEFT</property>
+			  <property name="wrap">False</property>
+			  <property name="selectable">False</property>
+			  <property name="xalign">0</property>
+			  <property name="yalign">0.5</property>
+			  <property name="xpad">0</property>
+			  <property name="ypad">0</property>
+			  <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+			  <property name="width_chars">-1</property>
+			  <property name="single_line_mode">False</property>
+			  <property name="angle">0</property>
+			</widget>
+			<packing>
+			  <property name="left_attach">0</property>
+			  <property name="right_attach">1</property>
+			  <property name="top_attach">0</property>
+			  <property name="bottom_attach">1</property>
+			  <property name="x_options">fill</property>
+			  <property name="y_options"></property>
+			</packing>
+		      </child>
+
+		      <child>
+			<widget class="GtkLabel" id="bd2Label">
+			  <property name="label" translatable="yes">Second BIOS drive:</property>
+			  <property name="use_underline">False</property>
+			  <property name="use_markup">False</property>
+			  <property name="justify">GTK_JUSTIFY_LEFT</property>
+			  <property name="wrap">False</property>
+			  <property name="selectable">False</property>
+			  <property name="xalign">0</property>
+			  <property name="yalign">0.5</property>
+			  <property name="xpad">0</property>
+			  <property name="ypad">0</property>
+			  <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+			  <property name="width_chars">-1</property>
+			  <property name="single_line_mode">False</property>
+			  <property name="angle">0</property>
+			</widget>
+			<packing>
+			  <property name="left_attach">0</property>
+			  <property name="right_attach">1</property>
+			  <property name="top_attach">1</property>
+			  <property name="bottom_attach">2</property>
+			  <property name="x_options">fill</property>
+			  <property name="y_options"></property>
+			</packing>
+		      </child>
+
+		      <child>
+			<widget class="GtkLabel" id="bd3Label">
+			  <property name="label" translatable="yes">Third BIOS drive:</property>
+			  <property name="use_underline">False</property>
+			  <property name="use_markup">False</property>
+			  <property name="justify">GTK_JUSTIFY_LEFT</property>
+			  <property name="wrap">False</property>
+			  <property name="selectable">False</property>
+			  <property name="xalign">0</property>
+			  <property name="yalign">0.5</property>
+			  <property name="xpad">0</property>
+			  <property name="ypad">0</property>
+			  <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+			  <property name="width_chars">-1</property>
+			  <property name="single_line_mode">False</property>
+			  <property name="angle">0</property>
+			</widget>
+			<packing>
+			  <property name="left_attach">0</property>
+			  <property name="right_attach">1</property>
+			  <property name="top_attach">2</property>
+			  <property name="bottom_attach">3</property>
+			  <property name="x_options">fill</property>
+			  <property name="y_options"></property>
+			</packing>
+		      </child>
+
+		      <child>
+			<widget class="GtkLabel" id="bd4Label">
+			  <property name="label" translatable="yes">Fourth BIOS drive:</property>
+			  <property name="use_underline">False</property>
+			  <property name="use_markup">False</property>
+			  <property name="justify">GTK_JUSTIFY_LEFT</property>
+			  <property name="wrap">False</property>
+			  <property name="selectable">False</property>
+			  <property name="xalign">0</property>
+			  <property name="yalign">0.5</property>
+			  <property name="xpad">0</property>
+			  <property name="ypad">0</property>
+			  <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+			  <property name="width_chars">-1</property>
+			  <property name="single_line_mode">False</property>
+			  <property name="angle">0</property>
+			</widget>
+			<packing>
+			  <property name="left_attach">0</property>
+			  <property name="right_attach">1</property>
+			  <property name="top_attach">3</property>
+			  <property name="bottom_attach">4</property>
+			  <property name="x_options">fill</property>
+			  <property name="y_options"></property>
+			</packing>
+		      </child>
+
+		      <child>
+			<widget class="GtkComboBox" id="bd2Combo">
+			  <property name="add_tearoffs">False</property>
+			  <property name="focus_on_click">True</property>
+			</widget>
+			<packing>
+			  <property name="left_attach">1</property>
+			  <property name="right_attach">2</property>
+			  <property name="top_attach">1</property>
+			  <property name="bottom_attach">2</property>
+			  <property name="x_options">fill</property>
+			  <property name="y_options">fill</property>
+			</packing>
+		      </child>
+
+		      <child>
+			<widget class="GtkComboBox" id="bd4Combo">
+			  <property name="add_tearoffs">False</property>
+			  <property name="focus_on_click">True</property>
+			</widget>
+			<packing>
+			  <property name="left_attach">1</property>
+			  <property name="right_attach">2</property>
+			  <property name="top_attach">3</property>
+			  <property name="bottom_attach">4</property>
+			  <property name="x_options">fill</property>
+			  <property name="y_options">fill</property>
+			</packing>
+		      </child>
+
+		      <child>
+			<widget class="GtkComboBox" id="bd3Combo">
+			  <property name="add_tearoffs">False</property>
+			  <property name="focus_on_click">True</property>
+			</widget>
+			<packing>
+			  <property name="left_attach">1</property>
+			  <property name="right_attach">2</property>
+			  <property name="top_attach">2</property>
+			  <property name="bottom_attach">3</property>
+			  <property name="x_options">fill</property>
+			  <property name="y_options">fill</property>
+			</packing>
+		      </child>
+
+		      <child>
+			<widget class="GtkComboBox" id="bd1Combo">
+			  <property name="visible">True</property>
+			  <property name="add_tearoffs">False</property>
+			  <property name="focus_on_click">True</property>
+			</widget>
+			<packing>
+			  <property name="left_attach">1</property>
+			  <property name="right_attach">2</property>
+			  <property name="top_attach">0</property>
+			  <property name="bottom_attach">1</property>
+			  <property name="x_options">fill</property>
+			  <property name="y_options">fill</property>
+			</packing>
+		      </child>
+		    </widget>
+		  </child>
+		</widget>
+	      </child>
+
+	      <child>
+		<widget class="GtkLabel" id="label2">
+		  <property name="visible">True</property>
+		  <property name="label" translatable="yes">BIOS Drive Order</property>
+		  <property name="use_underline">False</property>
+		  <property name="use_markup">False</property>
+		  <property name="justify">GTK_JUSTIFY_LEFT</property>
+		  <property name="wrap">False</property>
+		  <property name="selectable">False</property>
+		  <property name="xalign">0.5</property>
+		  <property name="yalign">0.5</property>
+		  <property name="xpad">0</property>
+		  <property name="ypad">0</property>
+		  <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+		  <property name="width_chars">-1</property>
+		  <property name="single_line_mode">False</property>
+		  <property name="angle">0</property>
+		</widget>
+		<packing>
+		  <property name="type">label_item</property>
+		</packing>
+	      </child>
+	    </widget>
+	    <packing>
+	      <property name="padding">0</property>
+	      <property name="expand">True</property>
+	      <property name="fill">True</property>
+	    </packing>
+	  </child>
+	</widget>
+	<packing>
+	  <property name="padding">0</property>
+	  <property name="expand">True</property>
+	  <property name="fill">True</property>
+	</packing>
+      </child>
+    </widget>
+  </child>
+</widget>
+
+</glade-interface>
diff --git a/data/ui/cleardisks.glade b/data/ui/cleardisks.glade
new file mode 100644
index 0000000..f8c9b15
--- /dev/null
+++ b/data/ui/cleardisks.glade
@@ -0,0 +1,300 @@
+<?xml version="1.0" standalone="no"?> <!--*- mode: xml -*-->
+<!DOCTYPE glade-interface SYSTEM "http://glade.gnome.org/glade-2.0.dtd";>
+
+<glade-interface>
+
+<widget class="GtkWindow" id="cleardisksWindow">
+  <property name="border_width">6</property>
+  <property name="width_request">600</property>
+  <property name="title" translatable="yes" context="yes"></property>
+  <property name="type">GTK_WINDOW_TOPLEVEL</property>
+  <property name="window_position">GTK_WIN_POS_NONE</property>
+  <property name="modal">False</property>
+  <property name="resizable">True</property>
+  <property name="destroy_with_parent">False</property>
+  <property name="decorated">True</property>
+  <property name="skip_taskbar_hint">False</property>
+  <property name="skip_pager_hint">False</property>
+  <property name="type_hint">GDK_WINDOW_TYPE_HINT_NORMAL</property>
+  <property name="gravity">GDK_GRAVITY_NORTH_WEST</property>
+  <property name="focus_on_map">True</property>
+  <property name="urgency_hint">False</property>
+
+  <child>
+    <widget class="GtkVBox" id="vbox">
+      <property name="visible">True</property>
+      <property name="homogeneous">False</property>
+      <property name="spacing">12</property>
+
+      <child>
+	<widget class="GtkLabel" id="label1">
+	  <property name="width_request">600</property>
+	  <property name="visible">True</property>
+	  <property name="label" translatable="yes">Below are the storage devices you've selected to be a part of this installation.  Please indicate using the arrows below which devices you'd like to use as data devices (these will not be formatted, only mounted) and which devices you'd like to use as installation target devices (these may be formatted).  Please also indicate which system drive will have the bootloader installed.</property>
+	  <property name="use_underline">False</property>
+	  <property name="use_markup">False</property>
+	  <property name="justify">GTK_JUSTIFY_LEFT</property>
+	  <property name="wrap">True</property>
+	  <property name="selectable">False</property>
+	  <property name="xalign">0</property>
+	  <property name="yalign">0</property>
+	  <property name="xpad">0</property>
+	  <property name="ypad">0</property>
+	  <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+	  <property name="width_chars">-1</property>
+	  <property name="single_line_mode">False</property>
+	  <property name="angle">0</property>
+	</widget>
+	<packing>
+	  <property name="padding">0</property>
+	  <property name="expand">False</property>
+	  <property name="fill">False</property>
+	</packing>
+      </child>
+
+      <child>
+	<widget class="GtkHBox" id="hbox2">
+	  <property name="visible">True</property>
+	  <property name="homogeneous">False</property>
+	  <property name="spacing">6</property>
+
+	  <child>
+	    <widget class="GtkVBox" id="vbox1">
+	      <property name="visible">True</property>
+	      <property name="homogeneous">False</property>
+	      <property name="spacing">0</property>
+
+	      <child>
+		<widget class="GtkLabel" id="label4">
+		  <property name="visible">True</property>
+		  <property name="label" translatable="yes">&lt;b&gt;Data Storage Devices&lt;/b&gt; (to be mounted only)</property>
+		  <property name="use_underline">False</property>
+		  <property name="use_markup">True</property>
+		  <property name="justify">GTK_JUSTIFY_LEFT</property>
+		  <property name="wrap">False</property>
+		  <property name="selectable">False</property>
+		  <property name="xalign">0</property>
+		  <property name="yalign">0.5</property>
+		  <property name="xpad">0</property>
+		  <property name="ypad">0</property>
+		  <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+		  <property name="width_chars">-1</property>
+		  <property name="single_line_mode">False</property>
+		  <property name="angle">0</property>
+		</widget>
+		<packing>
+		  <property name="padding">0</property>
+		  <property name="expand">False</property>
+		  <property name="fill">False</property>
+		</packing>
+	      </child>
+
+	      <child>
+		<widget class="GtkScrolledWindow" id="leftScroll">
+		  <property name="visible">True</property>
+		  <property name="can_focus">True</property>
+		  <property name="hscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
+		  <property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
+		  <property name="shadow_type">GTK_SHADOW_ETCHED_IN</property>
+		  <property name="window_placement">GTK_CORNER_TOP_LEFT</property>
+
+		  <child>
+		    <placeholder/>
+		  </child>
+		</widget>
+		<packing>
+		  <property name="padding">0</property>
+		  <property name="expand">True</property>
+		  <property name="fill">True</property>
+		</packing>
+	      </child>
+	    </widget>
+	    <packing>
+	      <property name="padding">0</property>
+	      <property name="expand">True</property>
+	      <property name="fill">True</property>
+	    </packing>
+	  </child>
+
+	  <child>
+	    <widget class="GtkVButtonBox" id="vbuttonbox1">
+	      <property name="visible">True</property>
+	      <property name="layout_style">GTK_BUTTONBOX_SPREAD</property>
+	      <property name="spacing">0</property>
+
+	      <child>
+		<widget class="GtkButton" id="addButton">
+		  <property name="visible">True</property>
+		  <property name="can_default">True</property>
+		  <property name="can_focus">True</property>
+		  <property name="relief">GTK_RELIEF_NORMAL</property>
+		  <property name="focus_on_click">True</property>
+
+		  <child>
+		    <widget class="GtkImage" id="image3">
+		      <property name="visible">True</property>
+		      <property name="stock">gtk-go-forward</property>
+		      <property name="icon_size">4</property>
+		      <property name="xalign">0.5</property>
+		      <property name="yalign">0.5</property>
+		      <property name="xpad">0</property>
+		      <property name="ypad">0</property>
+		    </widget>
+		  </child>
+		</widget>
+	      </child>
+
+	      <child>
+		<widget class="GtkButton" id="removeButton">
+		  <property name="visible">True</property>
+		  <property name="can_default">True</property>
+		  <property name="can_focus">True</property>
+		  <property name="relief">GTK_RELIEF_NORMAL</property>
+		  <property name="focus_on_click">True</property>
+
+		  <child>
+		    <widget class="GtkImage" id="image2">
+		      <property name="visible">True</property>
+		      <property name="stock">gtk-go-back</property>
+		      <property name="icon_size">4</property>
+		      <property name="xalign">0.5</property>
+		      <property name="yalign">0.5</property>
+		      <property name="xpad">0</property>
+		      <property name="ypad">0</property>
+		    </widget>
+		  </child>
+		</widget>
+	      </child>
+	    </widget>
+	    <packing>
+	      <property name="padding">0</property>
+	      <property name="expand">False</property>
+	      <property name="fill">False</property>
+	    </packing>
+	  </child>
+
+	  <child>
+	    <widget class="GtkVBox" id="vbox2">
+	      <property name="visible">True</property>
+	      <property name="homogeneous">False</property>
+	      <property name="spacing">0</property>
+
+	      <child>
+		<widget class="GtkLabel" id="label5">
+		  <property name="visible">True</property>
+		  <property name="label" translatable="yes">&lt;b&gt;Install Target Devices&lt;/b&gt;</property>
+		  <property name="use_underline">False</property>
+		  <property name="use_markup">True</property>
+		  <property name="justify">GTK_JUSTIFY_LEFT</property>
+		  <property name="wrap">False</property>
+		  <property name="selectable">False</property>
+		  <property name="xalign">0</property>
+		  <property name="yalign">0.5</property>
+		  <property name="xpad">0</property>
+		  <property name="ypad">0</property>
+		  <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+		  <property name="width_chars">-1</property>
+		  <property name="single_line_mode">False</property>
+		  <property name="angle">0</property>
+		</widget>
+		<packing>
+		  <property name="padding">0</property>
+		  <property name="expand">False</property>
+		  <property name="fill">False</property>
+		</packing>
+	      </child>
+
+	      <child>
+		<widget class="GtkScrolledWindow" id="rightScroll">
+		  <property name="visible">True</property>
+		  <property name="can_focus">True</property>
+		  <property name="hscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
+		  <property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
+		  <property name="shadow_type">GTK_SHADOW_ETCHED_IN</property>
+		  <property name="window_placement">GTK_CORNER_TOP_LEFT</property>
+
+		  <child>
+		    <placeholder/>
+		  </child>
+		</widget>
+		<packing>
+		  <property name="padding">0</property>
+		  <property name="expand">True</property>
+		  <property name="fill">True</property>
+		</packing>
+	      </child>
+	    </widget>
+	    <packing>
+	      <property name="padding">0</property>
+	      <property name="expand">True</property>
+	      <property name="fill">True</property>
+	    </packing>
+	  </child>
+	</widget>
+	<packing>
+	  <property name="padding">0</property>
+	  <property name="expand">True</property>
+	  <property name="fill">True</property>
+	</packing>
+      </child>
+
+      <child>
+	<widget class="GtkHBox" id="installTargetHBox">
+	  <property name="visible">True</property>
+	  <property name="homogeneous">False</property>
+	  <property name="spacing">0</property>
+
+	  <child>
+	    <widget class="GtkImage" id="installTargetImage">
+	      <property name="visible">True</property>
+	      <property name="stock">gtk-dialog-info</property>
+	      <property name="icon_size">4</property>
+	      <property name="xalign">0.5</property>
+	      <property name="yalign">0</property>
+	      <property name="xpad">0</property>
+	      <property name="ypad">0</property>
+	    </widget>
+	    <packing>
+	      <property name="padding">0</property>
+	      <property name="expand">False</property>
+	      <property name="fill">False</property>
+	    </packing>
+	  </child>
+
+	  <child>
+	    <widget class="GtkLabel" id="installTargetTip">
+	      <property name="width_request">600</property>
+	      <property name="visible">True</property>
+	      <property name="label" translatable="yes">&lt;b&gt;Tip:&lt;/b&gt; Install target devices will be reformatted and wiped of any data.  Make sure you have backups.</property>
+	      <property name="use_underline">False</property>
+	      <property name="use_markup">True</property>
+	      <property name="justify">GTK_JUSTIFY_LEFT</property>
+	      <property name="wrap">True</property>
+	      <property name="selectable">False</property>
+	      <property name="xalign">0</property>
+	      <property name="yalign">0</property>
+	      <property name="xpad">0</property>
+	      <property name="ypad">0</property>
+	      <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+	      <property name="width_chars">-1</property>
+	      <property name="single_line_mode">False</property>
+	      <property name="angle">0</property>
+	    </widget>
+	    <packing>
+	      <property name="padding">0</property>
+	      <property name="expand">False</property>
+	      <property name="fill">False</property>
+	    </packing>
+	  </child>
+	</widget>
+	<packing>
+	  <property name="padding">0</property>
+	  <property name="expand">False</property>
+	  <property name="fill">False</property>
+	</packing>
+      </child>
+    </widget>
+  </child>
+</widget>
+
+</glade-interface>
diff --git a/data/ui/create-storage.glade b/data/ui/create-storage.glade
new file mode 100644
index 0000000..98db7d7
--- /dev/null
+++ b/data/ui/create-storage.glade
@@ -0,0 +1,379 @@
+<?xml version="1.0"?>
+<glade-interface>
+  <!-- interface-requires gtk+ 2.10 -->
+  <!-- interface-naming-policy toplevel-contextual -->
+  <widget class="GtkDialog" id="create_storage_dialog">
+    <property name="visible">True</property>
+    <property name="title" translatable="yes">Create Storage</property>
+    <property name="modal">True</property>
+    <property name="window_position">center-always</property>
+    <property name="type_hint">dialog</property>
+    <child internal-child="vbox">
+      <widget class="GtkVBox" id="dialog-vbox1">
+        <property name="visible">True</property>
+        <property name="orientation">vertical</property>
+        <property name="spacing">2</property>
+        <child>
+          <widget class="GtkVBox" id="vbox1">
+            <property name="visible">True</property>
+            <property name="orientation">vertical</property>
+            <child>
+              <widget class="GtkHBox" id="hbox1">
+                <property name="visible">True</property>
+                <child>
+                  <widget class="GtkLabel" id="label1">
+                    <property name="visible">True</property>
+                    <property name="xalign">0</property>
+                    <property name="xpad">2</property>
+                    <property name="label" translatable="yes">Create Partition</property>
+                  </widget>
+                  <packing>
+                    <property name="position">0</property>
+                  </packing>
+                </child>
+                <child>
+                  <placeholder/>
+                </child>
+              </widget>
+              <packing>
+                <property name="position">0</property>
+              </packing>
+            </child>
+            <child>
+              <widget class="GtkVBox" id="vbox2">
+                <property name="visible">True</property>
+                <property name="orientation">vertical</property>
+                <child>
+                  <widget class="GtkRadioButton" id="create_storage_rb_standard_part">
+                    <property name="label" translatable="yes">Standard Partition</property>
+                    <property name="visible">True</property>
+                    <property name="sensitive">False</property>
+                    <property name="can_focus">True</property>
+                    <property name="receives_default">False</property>
+                    <property name="draw_indicator">True</property>
+                  </widget>
+                  <packing>
+                    <property name="position">0</property>
+                  </packing>
+                </child>
+                <child>
+                  <widget class="GtkLabel" id="label4">
+                    <property name="visible">True</property>
+                    <property name="xalign">0</property>
+                    <property name="xpad">20</property>
+                    <property name="label" translatable="yes">&lt;span size="small" color="gray"&gt;General purpose partition creation&lt;/span&gt;</property>
+                    <property name="use_markup">True</property>
+                  </widget>
+                  <packing>
+                    <property name="position">1</property>
+                  </packing>
+                </child>
+              </widget>
+              <packing>
+                <property name="position">1</property>
+              </packing>
+            </child>
+            <child>
+              <widget class="GtkHBox" id="hbox2">
+                <property name="visible">True</property>
+                <child>
+                  <widget class="GtkLabel" id="label2">
+                    <property name="visible">True</property>
+                    <property name="xalign">0</property>
+                    <property name="xpad">2</property>
+                    <property name="label" translatable="yes">Create Software RAID</property>
+                  </widget>
+                  <packing>
+                    <property name="position">0</property>
+                  </packing>
+                </child>
+                <child>
+                  <widget class="GtkLinkButton" id="create_storage_info_raid">
+                    <property name="label">gtk-info</property>
+                    <property name="visible">True</property>
+                    <property name="can_focus">True</property>
+                    <property name="receives_default">True</property>
+                    <property name="has_tooltip">True</property>
+                    <property name="relief">none</property>
+                    <property name="use_stock">True</property>
+                    <property name="xalign">1</property>
+                  </widget>
+                  <packing>
+                    <property name="expand">False</property>
+                    <property name="position">1</property>
+                  </packing>
+                </child>
+              </widget>
+              <packing>
+                <property name="position">2</property>
+              </packing>
+            </child>
+            <child>
+              <widget class="GtkVBox" id="vbox3">
+                <property name="visible">True</property>
+                <property name="orientation">vertical</property>
+                <child>
+                  <widget class="GtkRadioButton" id="create_storage_rb_raid_part">
+                    <property name="label" translatable="yes">RAID Partition</property>
+                    <property name="visible">True</property>
+                    <property name="sensitive">False</property>
+                    <property name="can_focus">True</property>
+                    <property name="receives_default">False</property>
+                    <property name="draw_indicator">True</property>
+                    <property name="group">create_storage_rb_standard_part</property>
+                  </widget>
+                  <packing>
+                    <property name="position">0</property>
+                  </packing>
+                </child>
+                <child>
+                  <widget class="GtkLabel" id="label5">
+                    <property name="visible">True</property>
+                    <property name="xalign">0</property>
+                    <property name="xpad">20</property>
+                    <property name="label" translatable="yes">&lt;span size="small" color="gray"&gt;Create a RAID formatted partition&lt;/span&gt;</property>
+                    <property name="use_markup">True</property>
+                  </widget>
+                  <packing>
+                    <property name="position">1</property>
+                  </packing>
+                </child>
+              </widget>
+              <packing>
+                <property name="position">3</property>
+              </packing>
+            </child>
+            <child>
+              <widget class="GtkVBox" id="vbox4">
+                <property name="visible">True</property>
+                <property name="orientation">vertical</property>
+                <child>
+                  <widget class="GtkRadioButton" id="create_storage_rb_raid_dev">
+                    <property name="label" translatable="yes">RAID Device</property>
+                    <property name="visible">True</property>
+                    <property name="sensitive">False</property>
+                    <property name="can_focus">True</property>
+                    <property name="receives_default">False</property>
+                    <property name="draw_indicator">True</property>
+                    <property name="group">create_storage_rb_standard_part</property>
+                  </widget>
+                  <packing>
+                    <property name="position">0</property>
+                  </packing>
+                </child>
+                <child>
+                  <widget class="GtkLabel" id="label6">
+                    <property name="visible">True</property>
+                    <property name="xalign">0</property>
+                    <property name="xpad">20</property>
+                    <property name="label" translatable="yes">&lt;span size="small" color="gray"&gt;Requires at least 2 free RAID formatted partitions&lt;/span&gt;</property>
+                    <property name="use_markup">True</property>
+                  </widget>
+                  <packing>
+                    <property name="position">1</property>
+                  </packing>
+                </child>
+              </widget>
+              <packing>
+                <property name="position">4</property>
+              </packing>
+            </child>
+            <child>
+              <widget class="GtkHBox" id="hbox3">
+                <property name="visible">True</property>
+                <child>
+                  <widget class="GtkLabel" id="label3">
+                    <property name="visible">True</property>
+                    <property name="xalign">0</property>
+                    <property name="xpad">2</property>
+                    <property name="label" translatable="yes">Create LVM</property>
+                  </widget>
+                  <packing>
+                    <property name="position">0</property>
+                  </packing>
+                </child>
+                <child>
+                  <widget class="GtkLinkButton" id="create_storage_info_lvm">
+                    <property name="label">gtk-info</property>
+                    <property name="visible">True</property>
+                    <property name="can_focus">True</property>
+                    <property name="receives_default">True</property>
+                    <property name="has_tooltip">True</property>
+                    <property name="relief">none</property>
+                    <property name="use_stock">True</property>
+                    <property name="xalign">1</property>
+                  </widget>
+                  <packing>
+                    <property name="expand">False</property>
+                    <property name="position">1</property>
+                  </packing>
+                </child>
+              </widget>
+              <packing>
+                <property name="position">5</property>
+              </packing>
+            </child>
+            <child>
+              <widget class="GtkVBox" id="vbox6">
+                <property name="visible">True</property>
+                <property name="orientation">vertical</property>
+                <child>
+                  <widget class="GtkRadioButton" id="create_storage_rb_lvm_vg">
+                    <property name="label" translatable="yes">LVM Volume Group</property>
+                    <property name="visible">True</property>
+                    <property name="sensitive">False</property>
+                    <property name="can_focus">True</property>
+                    <property name="receives_default">False</property>
+                    <property name="draw_indicator">True</property>
+                    <property name="group">create_storage_rb_standard_part</property>
+                  </widget>
+                  <packing>
+                    <property name="position">0</property>
+                  </packing>
+                </child>
+                <child>
+                  <widget class="GtkLabel" id="label8">
+                    <property name="visible">True</property>
+                    <property name="xalign">0</property>
+                    <property name="xpad">20</property>
+                    <property name="label" translatable="yes">&lt;span size="small" color="gray"&gt;Requires at least 1 free LVM formatted partition&lt;/span&gt;</property>
+                    <property name="use_markup">True</property>
+                  </widget>
+                  <packing>
+                    <property name="position">1</property>
+                  </packing>
+                </child>
+              </widget>
+              <packing>
+                <property name="position">6</property>
+              </packing>
+            </child>
+            <child>
+              <widget class="GtkVBox" id="vbox7">
+                <property name="visible">True</property>
+                <property name="orientation">vertical</property>
+                <child>
+                  <widget class="GtkHBox" id="create_storage_hb_lvm_lv">
+                    <property name="visible">True</property>
+                    <child>
+                      <widget class="GtkRadioButton" id="create_storage_rb_lvm_lv">
+                        <property name="label" translatable="yes">LVM Logical Volume</property>
+                        <property name="visible">True</property>
+                        <property name="sensitive">False</property>
+                        <property name="can_focus">True</property>
+                        <property name="receives_default">False</property>
+                        <property name="draw_indicator">True</property>
+                        <property name="group">create_storage_rb_standard_part</property>
+                      </widget>
+                      <packing>
+                        <property name="position">0</property>
+                      </packing>
+                    </child>
+                    <child>
+                      <placeholder/>
+                    </child>
+                  </widget>
+                  <packing>
+                    <property name="position">0</property>
+                  </packing>
+                </child>
+                <child>
+                  <widget class="GtkLabel" id="label9">
+                    <property name="visible">True</property>
+                    <property name="xalign">0</property>
+                    <property name="xpad">20</property>
+                    <property name="label" translatable="yes">&lt;span size="small" color="gray"&gt;Create a logical volume on selected volume group&lt;/span&gt;</property>
+                    <property name="use_markup">True</property>
+                  </widget>
+                  <packing>
+                    <property name="position">1</property>
+                  </packing>
+                </child>
+              </widget>
+              <packing>
+                <property name="position">7</property>
+              </packing>
+            </child>
+            <child>
+              <widget class="GtkVBox" id="vbox8">
+                <property name="visible">True</property>
+                <property name="orientation">vertical</property>
+                <child>
+                  <widget class="GtkRadioButton" id="create_storage_rb_lvm_part">
+                    <property name="label" translatable="yes">LVM Physical Volume</property>
+                    <property name="visible">True</property>
+                    <property name="sensitive">False</property>
+                    <property name="can_focus">True</property>
+                    <property name="receives_default">False</property>
+                    <property name="draw_indicator">True</property>
+                    <property name="group">create_storage_rb_standard_part</property>
+                  </widget>
+                  <packing>
+                    <property name="position">0</property>
+                  </packing>
+                </child>
+                <child>
+                  <widget class="GtkLabel" id="label10">
+                    <property name="visible">True</property>
+                    <property name="xalign">0</property>
+                    <property name="xpad">20</property>
+                    <property name="label" translatable="yes">&lt;span size="small" color="gray"&gt;Create an LVM formatted partition&lt;/span&gt;</property>
+                    <property name="use_markup">True</property>
+                  </widget>
+                  <packing>
+                    <property name="position">1</property>
+                  </packing>
+                </child>
+              </widget>
+              <packing>
+                <property name="position">8</property>
+              </packing>
+            </child>
+          </widget>
+          <packing>
+            <property name="position">1</property>
+          </packing>
+        </child>
+        <child internal-child="action_area">
+          <widget class="GtkHButtonBox" id="dialog-action_area1">
+            <property name="visible">True</property>
+            <property name="layout_style">end</property>
+            <child>
+              <widget class="GtkButton" id="storage_create_button_cancel">
+                <property name="label">gtk-cancel</property>
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+                <property name="receives_default">True</property>
+                <property name="use_stock">True</property>
+              </widget>
+              <packing>
+                <property name="expand">False</property>
+                <property name="fill">False</property>
+                <property name="position">0</property>
+              </packing>
+            </child>
+            <child>
+              <widget class="GtkButton" id="storage_create_button_create">
+                <property name="label" translatable="yes">Create</property>
+                <property name="response_id">1</property>
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+                <property name="receives_default">True</property>
+              </widget>
+              <packing>
+                <property name="expand">False</property>
+                <property name="fill">False</property>
+                <property name="position">1</property>
+              </packing>
+            </child>
+          </widget>
+          <packing>
+            <property name="expand">False</property>
+            <property name="pack_type">end</property>
+            <property name="position">0</property>
+          </packing>
+        </child>
+      </widget>
+    </child>
+  </widget>
+</glade-interface>
diff --git a/data/ui/detailed-dialog.glade b/data/ui/detailed-dialog.glade
new file mode 100644
index 0000000..7c69656
--- /dev/null
+++ b/data/ui/detailed-dialog.glade
@@ -0,0 +1,171 @@
+<?xml version="1.0" standalone="no"?> <!--*- mode: xml -*-->
+<!DOCTYPE glade-interface SYSTEM "http://glade.gnome.org/glade-2.0.dtd";>
+
+<glade-interface>
+
+<widget class="GtkDialog" id="detailedDialog">
+  <property name="visible">True</property>
+  <property name="title"></property>
+  <property name="type">GTK_WINDOW_TOPLEVEL</property>
+  <property name="window_position">GTK_WIN_POS_CENTER</property>
+  <property name="modal">True</property>
+  <property name="default_width">550</property>
+  <property name="default_height">400</property>
+  <property name="resizable">True</property>
+  <property name="destroy_with_parent">False</property>
+  <property name="decorated">True</property>
+  <property name="skip_taskbar_hint">False</property>
+  <property name="skip_pager_hint">False</property>
+  <property name="type_hint">GDK_WINDOW_TYPE_HINT_DIALOG</property>
+  <property name="gravity">GDK_GRAVITY_NORTH_WEST</property>
+  <property name="focus_on_map">True</property>
+  <property name="urgency_hint">False</property>
+  <property name="has_separator">True</property>
+
+  <child internal-child="vbox">
+    <widget class="GtkVBox" id="detailedDialog-vbox">
+      <property name="visible">True</property>
+      <property name="homogeneous">False</property>
+      <property name="spacing">12</property>
+
+      <child internal-child="action_area">
+	<widget class="GtkHButtonBox" id="buttonBox">
+	  <property name="visible">True</property>
+	  <property name="layout_style">GTK_BUTTONBOX_END</property>
+	</widget>
+	<packing>
+	  <property name="padding">0</property>
+	  <property name="expand">False</property>
+	  <property name="fill">True</property>
+	  <property name="pack_type">GTK_PACK_END</property>
+	</packing>
+      </child>
+
+      <child>
+	<widget class="GtkVBox" id="mainVBox">
+	  <property name="visible">True</property>
+	  <property name="homogeneous">False</property>
+	  <property name="spacing">12</property>
+
+	  <child>
+	    <widget class="GtkHBox" id="hbox1">
+	      <property name="visible">True</property>
+	      <property name="homogeneous">False</property>
+	      <property name="spacing">6</property>
+
+	      <child>
+		<placeholder/>
+	      </child>
+
+	      <child>
+		<widget class="GtkLabel" id="info">
+		  <property name="visible">True</property>
+		  <property name="label" translatable="yes">Info</property>
+		  <property name="use_underline">False</property>
+		  <property name="use_markup">False</property>
+		  <property name="justify">GTK_JUSTIFY_LEFT</property>
+		  <property name="wrap">True</property>
+		  <property name="selectable">False</property>
+		  <property name="xalign">0</property>
+		  <property name="yalign">0.5</property>
+		  <property name="xpad">0</property>
+		  <property name="ypad">0</property>
+		  <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+		  <property name="width_chars">-1</property>
+		  <property name="single_line_mode">False</property>
+		  <property name="angle">0</property>
+		</widget>
+		<packing>
+		  <property name="padding">0</property>
+		  <property name="expand">True</property>
+		  <property name="fill">True</property>
+		</packing>
+	      </child>
+	    </widget>
+	    <packing>
+	      <property name="padding">0</property>
+	      <property name="expand">False</property>
+	      <property name="fill">False</property>
+	    </packing>
+	  </child>
+
+	  <child>
+	    <widget class="GtkExpander" id="detailedExpander">
+	      <property name="visible">True</property>
+	      <property name="can_focus">True</property>
+	      <property name="expanded">False</property>
+	      <property name="spacing">0</property>
+
+	      <child>
+		<widget class="GtkScrolledWindow" id="scrolledwindow2">
+		  <property name="visible">True</property>
+		  <property name="can_focus">True</property>
+		  <property name="hscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
+		  <property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
+		  <property name="shadow_type">GTK_SHADOW_IN</property>
+		  <property name="window_placement">GTK_CORNER_TOP_LEFT</property>
+
+		  <child>
+		    <widget class="GtkTextView" id="detailedView">
+		      <property name="visible">True</property>
+		      <property name="can_focus">True</property>
+		      <property name="editable">False</property>
+		      <property name="overwrite">False</property>
+		      <property name="accepts_tab">True</property>
+		      <property name="justification">GTK_JUSTIFY_LEFT</property>
+		      <property name="wrap_mode">GTK_WRAP_NONE</property>
+		      <property name="cursor_visible">False</property>
+		      <property name="pixels_above_lines">0</property>
+		      <property name="pixels_below_lines">0</property>
+		      <property name="pixels_inside_wrap">0</property>
+		      <property name="left_margin">0</property>
+		      <property name="right_margin">0</property>
+		      <property name="indent">0</property>
+		      <property name="text" translatable="yes"></property>
+		    </widget>
+		  </child>
+		</widget>
+	      </child>
+
+	      <child>
+		<widget class="GtkLabel" id="label1">
+		  <property name="visible">True</property>
+		  <property name="label" translatable="yes">_Details</property>
+		  <property name="use_underline">True</property>
+		  <property name="use_markup">False</property>
+		  <property name="justify">GTK_JUSTIFY_LEFT</property>
+		  <property name="wrap">False</property>
+		  <property name="selectable">False</property>
+		  <property name="xalign">0.5</property>
+		  <property name="yalign">0.5</property>
+		  <property name="xpad">0</property>
+		  <property name="ypad">0</property>
+		  <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+		  <property name="width_chars">-1</property>
+		  <property name="single_line_mode">False</property>
+		  <property name="angle">0</property>
+		</widget>
+		<packing>
+		  <property name="type">label_item</property>
+		</packing>
+	      </child>
+	    </widget>
+	    <packing>
+	      <property name="padding">0</property>
+	      <property name="expand">True</property>
+	      <property name="fill">True</property>
+	      <property name="pack_type">GTK_PACK_END</property>
+	    </packing>
+	  </child>
+	</widget>
+	<packing>
+	  <property name="padding">0</property>
+	  <property name="expand">True</property>
+	  <property name="fill">True</property>
+	</packing>
+      </child>
+    </widget>
+  </child>
+</widget>
+
+</glade-interface>
diff --git a/data/ui/fcoe-config.glade b/data/ui/fcoe-config.glade
new file mode 100644
index 0000000..57c72ab
--- /dev/null
+++ b/data/ui/fcoe-config.glade
@@ -0,0 +1,130 @@
+<?xml version="1.0"?>
+<glade-interface>
+  <!-- interface-requires gtk+ 2.16 -->
+  <!-- interface-naming-policy toplevel-contextual -->
+  <widget class="GtkDialog" id="fcoeDialog">
+    <property name="title" translatable="yes">Configure FCoE Parameters</property>
+    <property name="window_position">center</property>
+    <property name="type_hint">dialog</property>
+    <child internal-child="vbox">
+      <widget class="GtkVBox" id="dialog-vbox1">
+        <property name="visible">True</property>
+        <property name="orientation">vertical</property>
+        <child>
+          <widget class="GtkVBox" id="vbox1">
+            <property name="visible">True</property>
+            <property name="border_width">12</property>
+            <property name="orientation">vertical</property>
+            <property name="spacing">12</property>
+            <child>
+              <widget class="GtkLabel" id="label3">
+                <property name="visible">True</property>
+                <property name="label" translatable="yes">Please select the network interface which is connected to
+your FCoE switch.</property>
+                <property name="wrap">True</property>
+              </widget>
+              <packing>
+                <property name="expand">False</property>
+                <property name="fill">False</property>
+                <property name="position">0</property>
+              </packing>
+            </child>
+            <child>
+              <widget class="GtkHBox" id="hbox2">
+                <property name="visible">True</property>
+                <child>
+                  <widget class="GtkLabel" id="label1">
+                    <property name="visible">True</property>
+                    <property name="label" translatable="yes">NIC:</property>
+                  </widget>
+                  <packing>
+                    <property name="expand">False</property>
+                    <property name="position">0</property>
+                  </packing>
+                </child>
+                <child>
+                  <widget class="GtkComboBox" id="fcoeNicCombo">
+                    <property name="visible">True</property>
+                  </widget>
+                  <packing>
+                    <property name="expand">False</property>
+                    <property name="position">1</property>
+                  </packing>
+                </child>
+              </widget>
+              <packing>
+                <property name="expand">False</property>
+                <property name="position">1</property>
+              </packing>
+            </child>
+            <child>
+              <widget class="GtkCheckButton" id="dcbCheckbutton">
+                <property name="label" translatable="yes">Use DCB</property>
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+                <property name="receives_default">False</property>
+                <property name="active">True</property>
+                <property name="draw_indicator">True</property>
+              </widget>
+              <packing>
+                <property name="expand">False</property>
+                <property name="position">2</property>
+              </packing>
+            </child>
+          </widget>
+          <packing>
+            <property name="position">2</property>
+          </packing>
+        </child>
+        <child internal-child="action_area">
+          <widget class="GtkHButtonBox" id="dialog-action_area1">
+            <property name="visible">True</property>
+            <property name="layout_style">end</property>
+            <child>
+              <widget class="GtkButton" id="button1">
+                <property name="label">gtk-cancel</property>
+                <property name="response_id">-6</property>
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+                <property name="can_default">True</property>
+                <property name="receives_default">False</property>
+                <property name="use_stock">True</property>
+              </widget>
+              <packing>
+                <property name="expand">False</property>
+                <property name="fill">False</property>
+                <property name="position">0</property>
+              </packing>
+            </child>
+            <child>
+              <widget class="GtkButton" id="button2">
+                <property name="response_id">-10</property>
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+                <property name="can_default">True</property>
+                <property name="receives_default">False</property>
+                <child>
+                  <widget class="GtkLabel" id="label6">
+                    <property name="visible">True</property>
+                    <property name="label" translatable="yes">_Add FCoE Disk(s)</property>
+                    <property name="use_underline">True</property>
+                  </widget>
+                </child>
+              </widget>
+              <packing>
+                <property name="expand">False</property>
+                <property name="fill">False</property>
+                <property name="position">1</property>
+              </packing>
+            </child>
+          </widget>
+          <packing>
+            <property name="expand">False</property>
+            <property name="pack_type">end</property>
+            <property name="position">0</property>
+          </packing>
+        </child>
+      </widget>
+    </child>
+  </widget>
+</glade-interface>
diff --git a/data/ui/filter.glade b/data/ui/filter.glade
new file mode 100644
index 0000000..c8c2ba8
--- /dev/null
+++ b/data/ui/filter.glade
@@ -0,0 +1,1387 @@
+<?xml version="1.0" standalone="no"?> <!--*- mode: xml -*-->
+<!DOCTYPE glade-interface SYSTEM "http://glade.gnome.org/glade-2.0.dtd";>
+
+<glade-interface>
+
+<widget class="GtkWindow" id="advancedFilterWindow">
+  <property name="border_width">6</property>
+  <property name="title" translatable="yes" context="yes"></property>
+  <property name="type">GTK_WINDOW_TOPLEVEL</property>
+  <property name="window_position">GTK_WIN_POS_NONE</property>
+  <property name="modal">False</property>
+  <property name="resizable">True</property>
+  <property name="destroy_with_parent">False</property>
+  <property name="decorated">True</property>
+  <property name="skip_taskbar_hint">False</property>
+  <property name="skip_pager_hint">False</property>
+  <property name="type_hint">GDK_WINDOW_TYPE_HINT_NORMAL</property>
+  <property name="gravity">GDK_GRAVITY_NORTH_WEST</property>
+  <property name="focus_on_map">True</property>
+  <property name="urgency_hint">False</property>
+
+  <child>
+    <widget class="GtkVBox" id="vbox">
+      <property name="visible">True</property>
+      <property name="homogeneous">False</property>
+      <property name="spacing">6</property>
+
+      <child>
+	<widget class="GtkLabel" id="label1">
+	  <property name="width_request">600</property>
+	  <property name="visible">True</property>
+	  <property name="label" translatable="yes">Please select the drives you'd like to install the operating system on, as well as any drives you'd like to automatically mount on your system:</property>
+	  <property name="use_underline">False</property>
+	  <property name="use_markup">False</property>
+	  <property name="justify">GTK_JUSTIFY_LEFT</property>
+	  <property name="wrap">True</property>
+	  <property name="selectable">False</property>
+	  <property name="xalign">0</property>
+	  <property name="yalign">0</property>
+	  <property name="xpad">0</property>
+	  <property name="ypad">0</property>
+	  <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+	  <property name="width_chars">-1</property>
+	  <property name="single_line_mode">False</property>
+	  <property name="angle">0</property>
+	</widget>
+	<packing>
+	  <property name="padding">0</property>
+	  <property name="expand">False</property>
+	  <property name="fill">False</property>
+	</packing>
+      </child>
+
+      <child>
+	<widget class="GtkNotebook" id="notebook">
+	  <property name="visible">True</property>
+	  <property name="can_focus">True</property>
+	  <property name="show_tabs">True</property>
+	  <property name="show_border">True</property>
+	  <property name="tab_pos">GTK_POS_TOP</property>
+	  <property name="scrollable">False</property>
+	  <property name="enable_popup">False</property>
+
+	  <child>
+	    <widget class="GtkScrolledWindow" id="basicScroll">
+	      <property name="visible">True</property>
+	      <property name="can_focus">True</property>
+	      <property name="hscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
+	      <property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
+	      <property name="shadow_type">GTK_SHADOW_ETCHED_IN</property>
+	      <property name="window_placement">GTK_CORNER_TOP_LEFT</property>
+
+	      <child>
+		<placeholder/>
+	      </child>
+	    </widget>
+	    <packing>
+	      <property name="tab_expand">False</property>
+	      <property name="tab_fill">True</property>
+	    </packing>
+	  </child>
+
+	  <child>
+	    <widget class="GtkLabel" id="label4">
+	      <property name="visible">True</property>
+	      <property name="label" translatable="yes">Basic Devices</property>
+	      <property name="use_underline">False</property>
+	      <property name="use_markup">False</property>
+	      <property name="justify">GTK_JUSTIFY_LEFT</property>
+	      <property name="wrap">False</property>
+	      <property name="selectable">False</property>
+	      <property name="xalign">0.5</property>
+	      <property name="yalign">0.5</property>
+	      <property name="xpad">0</property>
+	      <property name="ypad">0</property>
+	      <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+	      <property name="width_chars">-1</property>
+	      <property name="single_line_mode">False</property>
+	      <property name="angle">0</property>
+	    </widget>
+	    <packing>
+	      <property name="type">tab</property>
+	    </packing>
+	  </child>
+
+	  <child>
+	    <widget class="GtkScrolledWindow" id="raidScroll">
+	      <property name="visible">True</property>
+	      <property name="can_focus">True</property>
+	      <property name="hscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
+	      <property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
+	      <property name="shadow_type">GTK_SHADOW_ETCHED_IN</property>
+	      <property name="window_placement">GTK_CORNER_TOP_LEFT</property>
+
+	      <child>
+		<placeholder/>
+	      </child>
+	    </widget>
+	    <packing>
+	      <property name="tab_expand">False</property>
+	      <property name="tab_fill">True</property>
+	    </packing>
+	  </child>
+
+	  <child>
+	    <widget class="GtkLabel" id="label5">
+	      <property name="visible">True</property>
+	      <property name="label" translatable="yes">Firmware RAID</property>
+	      <property name="use_underline">False</property>
+	      <property name="use_markup">False</property>
+	      <property name="justify">GTK_JUSTIFY_LEFT</property>
+	      <property name="wrap">False</property>
+	      <property name="selectable">False</property>
+	      <property name="xalign">0.5</property>
+	      <property name="yalign">0.5</property>
+	      <property name="xpad">0</property>
+	      <property name="ypad">0</property>
+	      <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+	      <property name="width_chars">-1</property>
+	      <property name="single_line_mode">False</property>
+	      <property name="angle">0</property>
+	    </widget>
+	    <packing>
+	      <property name="type">tab</property>
+	    </packing>
+	  </child>
+
+	  <child>
+	    <widget class="GtkVBox" id="mpathVBox">
+	      <property name="visible">True</property>
+	      <property name="homogeneous">False</property>
+	      <property name="spacing">6</property>
+
+	      <child>
+		<widget class="GtkHBox" id="mpathFilterHBox">
+		  <property name="visible">True</property>
+		  <property name="homogeneous">False</property>
+		  <property name="spacing">6</property>
+
+		  <child>
+		    <widget class="GtkLabel" id="label11">
+		      <property name="visible">True</property>
+		      <property name="label" translatable="yes">Filter By:</property>
+		      <property name="use_underline">False</property>
+		      <property name="use_markup">False</property>
+		      <property name="justify">GTK_JUSTIFY_LEFT</property>
+		      <property name="wrap">False</property>
+		      <property name="selectable">False</property>
+		      <property name="xalign">0.5</property>
+		      <property name="yalign">0.5</property>
+		      <property name="xpad">0</property>
+		      <property name="ypad">0</property>
+		      <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+		      <property name="width_chars">-1</property>
+		      <property name="single_line_mode">False</property>
+		      <property name="angle">0</property>
+		    </widget>
+		    <packing>
+		      <property name="padding">0</property>
+		      <property name="expand">False</property>
+		      <property name="fill">False</property>
+		    </packing>
+		  </child>
+
+		  <child>
+		    <widget class="GtkComboBoxEntry" id="mpathFilterBy">
+		      <property name="visible">True</property>
+		      <property name="items" translatable="yes">Interconnect
+Vendor
+Identifier</property>
+		      <property name="add_tearoffs">False</property>
+		      <property name="has_frame">True</property>
+		      <property name="focus_on_click">True</property>
+		    </widget>
+		    <packing>
+		      <property name="padding">0</property>
+		      <property name="expand">False</property>
+		      <property name="fill">False</property>
+		    </packing>
+		  </child>
+
+		  <child>
+		    <widget class="GtkNotebook" id="mpathNotebook">
+		      <property name="visible">True</property>
+		      <property name="show_tabs">False</property>
+		      <property name="show_border">False</property>
+		      <property name="tab_pos">GTK_POS_TOP</property>
+		      <property name="scrollable">False</property>
+		      <property name="enable_popup">False</property>
+
+		      <child>
+			<widget class="GtkHBox" id="hbox11">
+			  <property name="visible">True</property>
+			  <property name="homogeneous">False</property>
+			  <property name="spacing">6</property>
+
+			  <child>
+			    <widget class="GtkLabel" id="label28">
+			      <property name="visible">True</property>
+			      <property name="label" translatable="yes">Show Only Devices Using:</property>
+			      <property name="use_underline">False</property>
+			      <property name="use_markup">False</property>
+			      <property name="justify">GTK_JUSTIFY_LEFT</property>
+			      <property name="wrap">False</property>
+			      <property name="selectable">False</property>
+			      <property name="xalign">0.5</property>
+			      <property name="yalign">0.5</property>
+			      <property name="xpad">0</property>
+			      <property name="ypad">0</property>
+			      <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+			      <property name="width_chars">-1</property>
+			      <property name="single_line_mode">False</property>
+			      <property name="angle">0</property>
+			    </widget>
+			    <packing>
+			      <property name="padding">0</property>
+			      <property name="expand">False</property>
+			      <property name="fill">False</property>
+			    </packing>
+			  </child>
+
+			  <child>
+			    <widget class="GtkComboBoxEntry" id="mpathInterconnectEntry">
+			      <property name="visible">True</property>
+			      <property name="add_tearoffs">False</property>
+			      <property name="has_frame">True</property>
+			      <property name="focus_on_click">True</property>
+			    </widget>
+			    <packing>
+			      <property name="padding">0</property>
+			      <property name="expand">True</property>
+			      <property name="fill">True</property>
+			    </packing>
+			  </child>
+			</widget>
+			<packing>
+			  <property name="tab_expand">False</property>
+			  <property name="tab_fill">True</property>
+			</packing>
+		      </child>
+
+		      <child>
+			<widget class="GtkLabel" id="label29">
+			  <property name="visible">True</property>
+			  <property name="label" translatable="yes">label22</property>
+			  <property name="use_underline">False</property>
+			  <property name="use_markup">False</property>
+			  <property name="justify">GTK_JUSTIFY_LEFT</property>
+			  <property name="wrap">False</property>
+			  <property name="selectable">False</property>
+			  <property name="xalign">0.5</property>
+			  <property name="yalign">0.5</property>
+			  <property name="xpad">0</property>
+			  <property name="ypad">0</property>
+			  <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+			  <property name="width_chars">-1</property>
+			  <property name="single_line_mode">False</property>
+			  <property name="angle">0</property>
+			</widget>
+			<packing>
+			  <property name="type">tab</property>
+			</packing>
+		      </child>
+
+		      <child>
+			<widget class="GtkHBox" id="hbox12">
+			  <property name="visible">True</property>
+			  <property name="homogeneous">False</property>
+			  <property name="spacing">6</property>
+
+			  <child>
+			    <widget class="GtkLabel" id="label30">
+			      <property name="visible">True</property>
+			      <property name="label" translatable="yes">Show Only Devices From:</property>
+			      <property name="use_underline">False</property>
+			      <property name="use_markup">False</property>
+			      <property name="justify">GTK_JUSTIFY_LEFT</property>
+			      <property name="wrap">False</property>
+			      <property name="selectable">False</property>
+			      <property name="xalign">0.5</property>
+			      <property name="yalign">0.5</property>
+			      <property name="xpad">0</property>
+			      <property name="ypad">0</property>
+			      <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+			      <property name="width_chars">-1</property>
+			      <property name="single_line_mode">False</property>
+			      <property name="angle">0</property>
+			    </widget>
+			    <packing>
+			      <property name="padding">0</property>
+			      <property name="expand">False</property>
+			      <property name="fill">False</property>
+			    </packing>
+			  </child>
+
+			  <child>
+			    <widget class="GtkComboBoxEntry" id="mpathVendorEntry">
+			      <property name="visible">True</property>
+			      <property name="add_tearoffs">False</property>
+			      <property name="has_frame">True</property>
+			      <property name="focus_on_click">True</property>
+			    </widget>
+			    <packing>
+			      <property name="padding">0</property>
+			      <property name="expand">True</property>
+			      <property name="fill">True</property>
+			    </packing>
+			  </child>
+			</widget>
+			<packing>
+			  <property name="tab_expand">False</property>
+			  <property name="tab_fill">True</property>
+			</packing>
+		      </child>
+
+		      <child>
+			<widget class="GtkLabel" id="label31">
+			  <property name="visible">True</property>
+			  <property name="label" translatable="yes">label23</property>
+			  <property name="use_underline">False</property>
+			  <property name="use_markup">False</property>
+			  <property name="justify">GTK_JUSTIFY_LEFT</property>
+			  <property name="wrap">False</property>
+			  <property name="selectable">False</property>
+			  <property name="xalign">0.5</property>
+			  <property name="yalign">0.5</property>
+			  <property name="xpad">0</property>
+			  <property name="ypad">0</property>
+			  <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+			  <property name="width_chars">-1</property>
+			  <property name="single_line_mode">False</property>
+			  <property name="angle">0</property>
+			</widget>
+			<packing>
+			  <property name="type">tab</property>
+			</packing>
+		      </child>
+
+		      <child>
+			<widget class="GtkHBox" id="hbox13">
+			  <property name="visible">True</property>
+			  <property name="homogeneous">False</property>
+			  <property name="spacing">6</property>
+
+			  <child>
+			    <widget class="GtkLabel" id="label32">
+			      <property name="visible">True</property>
+			      <property name="label" translatable="yes">Show Identifiers that Include:</property>
+			      <property name="use_underline">False</property>
+			      <property name="use_markup">False</property>
+			      <property name="justify">GTK_JUSTIFY_LEFT</property>
+			      <property name="wrap">False</property>
+			      <property name="selectable">False</property>
+			      <property name="xalign">0.5</property>
+			      <property name="yalign">0.5</property>
+			      <property name="xpad">0</property>
+			      <property name="ypad">0</property>
+			      <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+			      <property name="width_chars">-1</property>
+			      <property name="single_line_mode">False</property>
+			      <property name="angle">0</property>
+			    </widget>
+			    <packing>
+			      <property name="padding">0</property>
+			      <property name="expand">False</property>
+			      <property name="fill">False</property>
+			    </packing>
+			  </child>
+
+			  <child>
+			    <widget class="GtkEntry" id="mpathIDEntry">
+			      <property name="visible">True</property>
+			      <property name="can_focus">True</property>
+			      <property name="editable">True</property>
+			      <property name="visibility">True</property>
+			      <property name="max_length">0</property>
+			      <property name="text" translatable="yes"></property>
+			      <property name="has_frame">True</property>
+			      <property name="invisible_char">â??</property>
+			      <property name="activates_default">False</property>
+			    </widget>
+			    <packing>
+			      <property name="padding">0</property>
+			      <property name="expand">True</property>
+			      <property name="fill">True</property>
+			    </packing>
+			  </child>
+			</widget>
+			<packing>
+			  <property name="tab_expand">False</property>
+			  <property name="tab_fill">True</property>
+			</packing>
+		      </child>
+
+		      <child>
+			<widget class="GtkLabel" id="label33">
+			  <property name="visible">True</property>
+			  <property name="label" translatable="yes">label24</property>
+			  <property name="use_underline">False</property>
+			  <property name="use_markup">False</property>
+			  <property name="justify">GTK_JUSTIFY_LEFT</property>
+			  <property name="wrap">False</property>
+			  <property name="selectable">False</property>
+			  <property name="xalign">0.5</property>
+			  <property name="yalign">0.5</property>
+			  <property name="xpad">0</property>
+			  <property name="ypad">0</property>
+			  <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+			  <property name="width_chars">-1</property>
+			  <property name="single_line_mode">False</property>
+			  <property name="angle">0</property>
+			</widget>
+			<packing>
+			  <property name="type">tab</property>
+			</packing>
+		      </child>
+		    </widget>
+		    <packing>
+		      <property name="padding">0</property>
+		      <property name="expand">True</property>
+		      <property name="fill">True</property>
+		    </packing>
+		  </child>
+		</widget>
+		<packing>
+		  <property name="padding">0</property>
+		  <property name="expand">False</property>
+		  <property name="fill">True</property>
+		</packing>
+	      </child>
+
+	      <child>
+		<widget class="GtkScrolledWindow" id="mpathScroll">
+		  <property name="visible">True</property>
+		  <property name="can_focus">True</property>
+		  <property name="hscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
+		  <property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
+		  <property name="shadow_type">GTK_SHADOW_ETCHED_IN</property>
+		  <property name="window_placement">GTK_CORNER_TOP_LEFT</property>
+
+		  <child>
+		    <placeholder/>
+		  </child>
+		</widget>
+		<packing>
+		  <property name="padding">0</property>
+		  <property name="expand">True</property>
+		  <property name="fill">True</property>
+		</packing>
+	      </child>
+	    </widget>
+	    <packing>
+	      <property name="tab_expand">False</property>
+	      <property name="tab_fill">True</property>
+	    </packing>
+	  </child>
+
+	  <child>
+	    <widget class="GtkLabel" id="label6">
+	      <property name="visible">True</property>
+	      <property name="label" translatable="yes">Multipath Devices</property>
+	      <property name="use_underline">False</property>
+	      <property name="use_markup">False</property>
+	      <property name="justify">GTK_JUSTIFY_LEFT</property>
+	      <property name="wrap">False</property>
+	      <property name="selectable">False</property>
+	      <property name="xalign">0.5</property>
+	      <property name="yalign">0.5</property>
+	      <property name="xpad">0</property>
+	      <property name="ypad">0</property>
+	      <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+	      <property name="width_chars">-1</property>
+	      <property name="single_line_mode">False</property>
+	      <property name="angle">0</property>
+	    </widget>
+	    <packing>
+	      <property name="type">tab</property>
+	    </packing>
+	  </child>
+
+	  <child>
+	    <widget class="GtkVBox" id="otherVBox">
+	      <property name="visible">True</property>
+	      <property name="homogeneous">False</property>
+	      <property name="spacing">6</property>
+
+	      <child>
+		<widget class="GtkHBox" id="otherFilterHBox">
+		  <property name="visible">True</property>
+		  <property name="homogeneous">False</property>
+		  <property name="spacing">6</property>
+
+		  <child>
+		    <widget class="GtkLabel" id="label35">
+		      <property name="visible">True</property>
+		      <property name="label" translatable="yes">Filter By:</property>
+		      <property name="use_underline">False</property>
+		      <property name="use_markup">False</property>
+		      <property name="justify">GTK_JUSTIFY_LEFT</property>
+		      <property name="wrap">False</property>
+		      <property name="selectable">False</property>
+		      <property name="xalign">0.5</property>
+		      <property name="yalign">0.5</property>
+		      <property name="xpad">0</property>
+		      <property name="ypad">0</property>
+		      <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+		      <property name="width_chars">-1</property>
+		      <property name="single_line_mode">False</property>
+		      <property name="angle">0</property>
+		    </widget>
+		    <packing>
+		      <property name="padding">0</property>
+		      <property name="expand">False</property>
+		      <property name="fill">False</property>
+		    </packing>
+		  </child>
+
+		  <child>
+		    <widget class="GtkComboBoxEntry" id="otherFilterBy">
+		      <property name="visible">True</property>
+		      <property name="items" translatable="yes">Interconnect
+Vendor
+Identifier</property>
+		      <property name="add_tearoffs">False</property>
+		      <property name="has_frame">True</property>
+		      <property name="focus_on_click">True</property>
+		    </widget>
+		    <packing>
+		      <property name="padding">0</property>
+		      <property name="expand">False</property>
+		      <property name="fill">False</property>
+		    </packing>
+		  </child>
+
+		  <child>
+		    <widget class="GtkNotebook" id="otherNotebook">
+		      <property name="visible">True</property>
+		      <property name="show_tabs">False</property>
+		      <property name="show_border">False</property>
+		      <property name="tab_pos">GTK_POS_TOP</property>
+		      <property name="scrollable">False</property>
+		      <property name="enable_popup">False</property>
+
+		      <child>
+			<widget class="GtkHBox" id="hbox15">
+			  <property name="visible">True</property>
+			  <property name="homogeneous">False</property>
+			  <property name="spacing">6</property>
+
+			  <child>
+			    <widget class="GtkLabel" id="label36">
+			      <property name="visible">True</property>
+			      <property name="label" translatable="yes">Show Only Devices Using:</property>
+			      <property name="use_underline">False</property>
+			      <property name="use_markup">False</property>
+			      <property name="justify">GTK_JUSTIFY_LEFT</property>
+			      <property name="wrap">False</property>
+			      <property name="selectable">False</property>
+			      <property name="xalign">0.5</property>
+			      <property name="yalign">0.5</property>
+			      <property name="xpad">0</property>
+			      <property name="ypad">0</property>
+			      <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+			      <property name="width_chars">-1</property>
+			      <property name="single_line_mode">False</property>
+			      <property name="angle">0</property>
+			    </widget>
+			    <packing>
+			      <property name="padding">0</property>
+			      <property name="expand">False</property>
+			      <property name="fill">False</property>
+			    </packing>
+			  </child>
+
+			  <child>
+			    <widget class="GtkComboBoxEntry" id="otherInterconnectEntry">
+			      <property name="visible">True</property>
+			      <property name="add_tearoffs">False</property>
+			      <property name="has_frame">True</property>
+			      <property name="focus_on_click">True</property>
+			    </widget>
+			    <packing>
+			      <property name="padding">0</property>
+			      <property name="expand">True</property>
+			      <property name="fill">True</property>
+			    </packing>
+			  </child>
+			</widget>
+			<packing>
+			  <property name="tab_expand">False</property>
+			  <property name="tab_fill">True</property>
+			</packing>
+		      </child>
+
+		      <child>
+			<widget class="GtkLabel" id="label37">
+			  <property name="visible">True</property>
+			  <property name="label" translatable="yes">label22</property>
+			  <property name="use_underline">False</property>
+			  <property name="use_markup">False</property>
+			  <property name="justify">GTK_JUSTIFY_LEFT</property>
+			  <property name="wrap">False</property>
+			  <property name="selectable">False</property>
+			  <property name="xalign">0.5</property>
+			  <property name="yalign">0.5</property>
+			  <property name="xpad">0</property>
+			  <property name="ypad">0</property>
+			  <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+			  <property name="width_chars">-1</property>
+			  <property name="single_line_mode">False</property>
+			  <property name="angle">0</property>
+			</widget>
+			<packing>
+			  <property name="type">tab</property>
+			</packing>
+		      </child>
+
+		      <child>
+			<widget class="GtkHBox" id="hbox16">
+			  <property name="visible">True</property>
+			  <property name="homogeneous">False</property>
+			  <property name="spacing">6</property>
+
+			  <child>
+			    <widget class="GtkLabel" id="label38">
+			      <property name="visible">True</property>
+			      <property name="label" translatable="yes">Show Only Devices From:</property>
+			      <property name="use_underline">False</property>
+			      <property name="use_markup">False</property>
+			      <property name="justify">GTK_JUSTIFY_LEFT</property>
+			      <property name="wrap">False</property>
+			      <property name="selectable">False</property>
+			      <property name="xalign">0.5</property>
+			      <property name="yalign">0.5</property>
+			      <property name="xpad">0</property>
+			      <property name="ypad">0</property>
+			      <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+			      <property name="width_chars">-1</property>
+			      <property name="single_line_mode">False</property>
+			      <property name="angle">0</property>
+			    </widget>
+			    <packing>
+			      <property name="padding">0</property>
+			      <property name="expand">False</property>
+			      <property name="fill">False</property>
+			    </packing>
+			  </child>
+
+			  <child>
+			    <widget class="GtkComboBoxEntry" id="otherVendorEntry">
+			      <property name="visible">True</property>
+			      <property name="add_tearoffs">False</property>
+			      <property name="has_frame">True</property>
+			      <property name="focus_on_click">True</property>
+			    </widget>
+			    <packing>
+			      <property name="padding">0</property>
+			      <property name="expand">True</property>
+			      <property name="fill">True</property>
+			    </packing>
+			  </child>
+			</widget>
+			<packing>
+			  <property name="tab_expand">False</property>
+			  <property name="tab_fill">True</property>
+			</packing>
+		      </child>
+
+		      <child>
+			<widget class="GtkLabel" id="label39">
+			  <property name="visible">True</property>
+			  <property name="label" translatable="yes">label23</property>
+			  <property name="use_underline">False</property>
+			  <property name="use_markup">False</property>
+			  <property name="justify">GTK_JUSTIFY_LEFT</property>
+			  <property name="wrap">False</property>
+			  <property name="selectable">False</property>
+			  <property name="xalign">0.5</property>
+			  <property name="yalign">0.5</property>
+			  <property name="xpad">0</property>
+			  <property name="ypad">0</property>
+			  <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+			  <property name="width_chars">-1</property>
+			  <property name="single_line_mode">False</property>
+			  <property name="angle">0</property>
+			</widget>
+			<packing>
+			  <property name="type">tab</property>
+			</packing>
+		      </child>
+
+		      <child>
+			<widget class="GtkHBox" id="hbox17">
+			  <property name="visible">True</property>
+			  <property name="homogeneous">False</property>
+			  <property name="spacing">6</property>
+
+			  <child>
+			    <widget class="GtkLabel" id="label40">
+			      <property name="visible">True</property>
+			      <property name="label" translatable="yes">Show Identifiers that Include:</property>
+			      <property name="use_underline">False</property>
+			      <property name="use_markup">False</property>
+			      <property name="justify">GTK_JUSTIFY_LEFT</property>
+			      <property name="wrap">False</property>
+			      <property name="selectable">False</property>
+			      <property name="xalign">0.5</property>
+			      <property name="yalign">0.5</property>
+			      <property name="xpad">0</property>
+			      <property name="ypad">0</property>
+			      <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+			      <property name="width_chars">-1</property>
+			      <property name="single_line_mode">False</property>
+			      <property name="angle">0</property>
+			    </widget>
+			    <packing>
+			      <property name="padding">0</property>
+			      <property name="expand">False</property>
+			      <property name="fill">False</property>
+			    </packing>
+			  </child>
+
+			  <child>
+			    <widget class="GtkEntry" id="otherIDEntry">
+			      <property name="visible">True</property>
+			      <property name="can_focus">True</property>
+			      <property name="editable">True</property>
+			      <property name="visibility">True</property>
+			      <property name="max_length">0</property>
+			      <property name="text" translatable="yes"></property>
+			      <property name="has_frame">True</property>
+			      <property name="invisible_char">â??</property>
+			      <property name="activates_default">False</property>
+			    </widget>
+			    <packing>
+			      <property name="padding">0</property>
+			      <property name="expand">True</property>
+			      <property name="fill">True</property>
+			    </packing>
+			  </child>
+			</widget>
+			<packing>
+			  <property name="tab_expand">False</property>
+			  <property name="tab_fill">True</property>
+			</packing>
+		      </child>
+
+		      <child>
+			<widget class="GtkLabel" id="label41">
+			  <property name="visible">True</property>
+			  <property name="label" translatable="yes">label24</property>
+			  <property name="use_underline">False</property>
+			  <property name="use_markup">False</property>
+			  <property name="justify">GTK_JUSTIFY_LEFT</property>
+			  <property name="wrap">False</property>
+			  <property name="selectable">False</property>
+			  <property name="xalign">0.5</property>
+			  <property name="yalign">0.5</property>
+			  <property name="xpad">0</property>
+			  <property name="ypad">0</property>
+			  <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+			  <property name="width_chars">-1</property>
+			  <property name="single_line_mode">False</property>
+			  <property name="angle">0</property>
+			</widget>
+			<packing>
+			  <property name="type">tab</property>
+			</packing>
+		      </child>
+		    </widget>
+		    <packing>
+		      <property name="padding">0</property>
+		      <property name="expand">True</property>
+		      <property name="fill">True</property>
+		    </packing>
+		  </child>
+		</widget>
+		<packing>
+		  <property name="padding">0</property>
+		  <property name="expand">False</property>
+		  <property name="fill">True</property>
+		</packing>
+	      </child>
+
+	      <child>
+		<widget class="GtkScrolledWindow" id="otherScroll">
+		  <property name="visible">True</property>
+		  <property name="can_focus">True</property>
+		  <property name="hscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
+		  <property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
+		  <property name="shadow_type">GTK_SHADOW_ETCHED_IN</property>
+		  <property name="window_placement">GTK_CORNER_TOP_LEFT</property>
+
+		  <child>
+		    <placeholder/>
+		  </child>
+		</widget>
+		<packing>
+		  <property name="padding">0</property>
+		  <property name="expand">True</property>
+		  <property name="fill">True</property>
+		</packing>
+	      </child>
+	    </widget>
+	    <packing>
+	      <property name="tab_expand">False</property>
+	      <property name="tab_fill">True</property>
+	    </packing>
+	  </child>
+
+	  <child>
+	    <widget class="GtkLabel" id="label34">
+	      <property name="visible">True</property>
+	      <property name="label" translatable="yes">Other SAN Devices</property>
+	      <property name="use_underline">False</property>
+	      <property name="use_markup">False</property>
+	      <property name="justify">GTK_JUSTIFY_LEFT</property>
+	      <property name="wrap">False</property>
+	      <property name="selectable">False</property>
+	      <property name="xalign">0.5</property>
+	      <property name="yalign">0.5</property>
+	      <property name="xpad">0</property>
+	      <property name="ypad">0</property>
+	      <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+	      <property name="width_chars">-1</property>
+	      <property name="single_line_mode">False</property>
+	      <property name="angle">0</property>
+	    </widget>
+	    <packing>
+	      <property name="type">tab</property>
+	    </packing>
+	  </child>
+
+	  <child>
+	    <widget class="GtkVBox" id="searchVBox">
+	      <property name="visible">True</property>
+	      <property name="homogeneous">False</property>
+	      <property name="spacing">0</property>
+
+	      <child>
+		<widget class="GtkHBox" id="searchFilterHBox">
+		  <property name="visible">True</property>
+		  <property name="homogeneous">False</property>
+		  <property name="spacing">6</property>
+
+		  <child>
+		    <widget class="GtkLabel" id="label15">
+		      <property name="visible">True</property>
+		      <property name="label" translatable="yes">Search By:</property>
+		      <property name="use_underline">False</property>
+		      <property name="use_markup">False</property>
+		      <property name="justify">GTK_JUSTIFY_LEFT</property>
+		      <property name="wrap">False</property>
+		      <property name="selectable">False</property>
+		      <property name="xalign">0.5</property>
+		      <property name="yalign">0.5</property>
+		      <property name="xpad">0</property>
+		      <property name="ypad">0</property>
+		      <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+		      <property name="width_chars">-1</property>
+		      <property name="single_line_mode">False</property>
+		      <property name="angle">0</property>
+		    </widget>
+		    <packing>
+		      <property name="padding">0</property>
+		      <property name="expand">False</property>
+		      <property name="fill">False</property>
+		    </packing>
+		  </child>
+
+		  <child>
+		    <widget class="GtkComboBoxEntry" id="searchFilterBy">
+		      <property name="visible">True</property>
+		      <property name="items" translatable="yes">Port / Target / LUN
+Target Identifier</property>
+		      <property name="add_tearoffs">False</property>
+		      <property name="has_frame">True</property>
+		      <property name="focus_on_click">True</property>
+		    </widget>
+		    <packing>
+		      <property name="padding">0</property>
+		      <property name="expand">False</property>
+		      <property name="fill">False</property>
+		    </packing>
+		  </child>
+
+		  <child>
+		    <widget class="GtkNotebook" id="searchNotebook">
+		      <property name="visible">True</property>
+		      <property name="show_tabs">False</property>
+		      <property name="show_border">False</property>
+		      <property name="tab_pos">GTK_POS_TOP</property>
+		      <property name="scrollable">False</property>
+		      <property name="enable_popup">False</property>
+
+		      <child>
+			<widget class="GtkHBox" id="hbox6">
+			  <property name="visible">True</property>
+			  <property name="homogeneous">False</property>
+			  <property name="spacing">6</property>
+
+			  <child>
+			    <widget class="GtkLabel" id="label18">
+			      <property name="visible">True</property>
+			      <property name="label" translatable="yes">Port:</property>
+			      <property name="use_underline">False</property>
+			      <property name="use_markup">False</property>
+			      <property name="justify">GTK_JUSTIFY_LEFT</property>
+			      <property name="wrap">False</property>
+			      <property name="selectable">False</property>
+			      <property name="xalign">0.5</property>
+			      <property name="yalign">0.5</property>
+			      <property name="xpad">0</property>
+			      <property name="ypad">0</property>
+			      <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+			      <property name="width_chars">-1</property>
+			      <property name="single_line_mode">False</property>
+			      <property name="angle">0</property>
+			    </widget>
+			    <packing>
+			      <property name="padding">0</property>
+			      <property name="expand">False</property>
+			      <property name="fill">False</property>
+			    </packing>
+			  </child>
+
+			  <child>
+			    <widget class="GtkEntry" id="searchPortEntry">
+			      <property name="width_request">50</property>
+			      <property name="visible">True</property>
+			      <property name="can_focus">True</property>
+			      <property name="editable">True</property>
+			      <property name="visibility">True</property>
+			      <property name="max_length">0</property>
+			      <property name="text" translatable="yes"></property>
+			      <property name="has_frame">True</property>
+			      <property name="invisible_char">â??</property>
+			      <property name="activates_default">False</property>
+			    </widget>
+			    <packing>
+			      <property name="padding">0</property>
+			      <property name="expand">False</property>
+			      <property name="fill">False</property>
+			    </packing>
+			  </child>
+
+			  <child>
+			    <widget class="GtkLabel" id="label19">
+			      <property name="visible">True</property>
+			      <property name="label" translatable="yes">Target:</property>
+			      <property name="use_underline">False</property>
+			      <property name="use_markup">False</property>
+			      <property name="justify">GTK_JUSTIFY_LEFT</property>
+			      <property name="wrap">False</property>
+			      <property name="selectable">False</property>
+			      <property name="xalign">0.5</property>
+			      <property name="yalign">0.5</property>
+			      <property name="xpad">0</property>
+			      <property name="ypad">0</property>
+			      <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+			      <property name="width_chars">-1</property>
+			      <property name="single_line_mode">False</property>
+			      <property name="angle">0</property>
+			    </widget>
+			    <packing>
+			      <property name="padding">0</property>
+			      <property name="expand">False</property>
+			      <property name="fill">False</property>
+			    </packing>
+			  </child>
+
+			  <child>
+			    <widget class="GtkEntry" id="searchTargetEntry">
+			      <property name="width_request">50</property>
+			      <property name="visible">True</property>
+			      <property name="can_focus">True</property>
+			      <property name="editable">True</property>
+			      <property name="visibility">True</property>
+			      <property name="max_length">0</property>
+			      <property name="text" translatable="yes"></property>
+			      <property name="has_frame">True</property>
+			      <property name="invisible_char">â??</property>
+			      <property name="activates_default">False</property>
+			    </widget>
+			    <packing>
+			      <property name="padding">0</property>
+			      <property name="expand">False</property>
+			      <property name="fill">False</property>
+			    </packing>
+			  </child>
+
+			  <child>
+			    <widget class="GtkLabel" id="label20">
+			      <property name="visible">True</property>
+			      <property name="label" translatable="yes">LUN:</property>
+			      <property name="use_underline">False</property>
+			      <property name="use_markup">False</property>
+			      <property name="justify">GTK_JUSTIFY_LEFT</property>
+			      <property name="wrap">False</property>
+			      <property name="selectable">False</property>
+			      <property name="xalign">0.5</property>
+			      <property name="yalign">0.5</property>
+			      <property name="xpad">0</property>
+			      <property name="ypad">0</property>
+			      <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+			      <property name="width_chars">-1</property>
+			      <property name="single_line_mode">False</property>
+			      <property name="angle">0</property>
+			    </widget>
+			    <packing>
+			      <property name="padding">0</property>
+			      <property name="expand">False</property>
+			      <property name="fill">False</property>
+			    </packing>
+			  </child>
+
+			  <child>
+			    <widget class="GtkEntry" id="searchLUNEntry">
+			      <property name="width_request">50</property>
+			      <property name="visible">True</property>
+			      <property name="can_focus">True</property>
+			      <property name="editable">True</property>
+			      <property name="visibility">True</property>
+			      <property name="max_length">0</property>
+			      <property name="text" translatable="yes"></property>
+			      <property name="has_frame">True</property>
+			      <property name="invisible_char">â??</property>
+			      <property name="activates_default">False</property>
+			    </widget>
+			    <packing>
+			      <property name="padding">0</property>
+			      <property name="expand">False</property>
+			      <property name="fill">False</property>
+			    </packing>
+			  </child>
+			</widget>
+			<packing>
+			  <property name="tab_expand">False</property>
+			  <property name="tab_fill">True</property>
+			</packing>
+		      </child>
+
+		      <child>
+			<widget class="GtkLabel" id="label16">
+			  <property name="visible">True</property>
+			  <property name="label" translatable="yes">label16</property>
+			  <property name="use_underline">False</property>
+			  <property name="use_markup">False</property>
+			  <property name="justify">GTK_JUSTIFY_LEFT</property>
+			  <property name="wrap">False</property>
+			  <property name="selectable">False</property>
+			  <property name="xalign">0.5</property>
+			  <property name="yalign">0.5</property>
+			  <property name="xpad">0</property>
+			  <property name="ypad">0</property>
+			  <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+			  <property name="width_chars">-1</property>
+			  <property name="single_line_mode">False</property>
+			  <property name="angle">0</property>
+			</widget>
+			<packing>
+			  <property name="type">tab</property>
+			</packing>
+		      </child>
+
+		      <child>
+			<widget class="GtkHBox" id="hbox7">
+			  <property name="visible">True</property>
+			  <property name="homogeneous">False</property>
+			  <property name="spacing">6</property>
+
+			  <child>
+			    <widget class="GtkLabel" id="label21">
+			      <property name="visible">True</property>
+			      <property name="label" translatable="yes">Identifier:</property>
+			      <property name="use_underline">False</property>
+			      <property name="use_markup">False</property>
+			      <property name="justify">GTK_JUSTIFY_LEFT</property>
+			      <property name="wrap">False</property>
+			      <property name="selectable">False</property>
+			      <property name="xalign">0.5</property>
+			      <property name="yalign">0.5</property>
+			      <property name="xpad">0</property>
+			      <property name="ypad">0</property>
+			      <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+			      <property name="width_chars">-1</property>
+			      <property name="single_line_mode">False</property>
+			      <property name="angle">0</property>
+			    </widget>
+			    <packing>
+			      <property name="padding">0</property>
+			      <property name="expand">False</property>
+			      <property name="fill">False</property>
+			    </packing>
+			  </child>
+
+			  <child>
+			    <widget class="GtkEntry" id="searchIDEntry">
+			      <property name="visible">True</property>
+			      <property name="can_focus">True</property>
+			      <property name="editable">True</property>
+			      <property name="visibility">True</property>
+			      <property name="max_length">0</property>
+			      <property name="text" translatable="yes"></property>
+			      <property name="has_frame">True</property>
+			      <property name="invisible_char">â??</property>
+			      <property name="activates_default">False</property>
+			    </widget>
+			    <packing>
+			      <property name="padding">0</property>
+			      <property name="expand">True</property>
+			      <property name="fill">True</property>
+			    </packing>
+			  </child>
+			</widget>
+			<packing>
+			  <property name="tab_expand">False</property>
+			  <property name="tab_fill">True</property>
+			</packing>
+		      </child>
+
+		      <child>
+			<widget class="GtkLabel" id="label17">
+			  <property name="visible">True</property>
+			  <property name="label" translatable="yes">label17</property>
+			  <property name="use_underline">False</property>
+			  <property name="use_markup">False</property>
+			  <property name="justify">GTK_JUSTIFY_LEFT</property>
+			  <property name="wrap">False</property>
+			  <property name="selectable">False</property>
+			  <property name="xalign">0.5</property>
+			  <property name="yalign">0.5</property>
+			  <property name="xpad">0</property>
+			  <property name="ypad">0</property>
+			  <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+			  <property name="width_chars">-1</property>
+			  <property name="single_line_mode">False</property>
+			  <property name="angle">0</property>
+			</widget>
+			<packing>
+			  <property name="type">tab</property>
+			</packing>
+		      </child>
+		    </widget>
+		    <packing>
+		      <property name="padding">0</property>
+		      <property name="expand">True</property>
+		      <property name="fill">True</property>
+		    </packing>
+		  </child>
+		</widget>
+		<packing>
+		  <property name="padding">0</property>
+		  <property name="expand">False</property>
+		  <property name="fill">True</property>
+		</packing>
+	      </child>
+
+	      <child>
+		<widget class="GtkLabel" id="label10">
+		  <property name="visible">True</property>
+		  <property name="label" translatable="yes">Search Results:</property>
+		  <property name="use_underline">False</property>
+		  <property name="use_markup">False</property>
+		  <property name="justify">GTK_JUSTIFY_LEFT</property>
+		  <property name="wrap">False</property>
+		  <property name="selectable">False</property>
+		  <property name="xalign">0</property>
+		  <property name="yalign">0</property>
+		  <property name="xpad">0</property>
+		  <property name="ypad">0</property>
+		  <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+		  <property name="width_chars">-1</property>
+		  <property name="single_line_mode">False</property>
+		  <property name="angle">0</property>
+		</widget>
+		<packing>
+		  <property name="padding">0</property>
+		  <property name="expand">False</property>
+		  <property name="fill">False</property>
+		</packing>
+	      </child>
+
+	      <child>
+		<widget class="GtkScrolledWindow" id="searchScroll">
+		  <property name="visible">True</property>
+		  <property name="can_focus">True</property>
+		  <property name="hscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
+		  <property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
+		  <property name="shadow_type">GTK_SHADOW_ETCHED_IN</property>
+		  <property name="window_placement">GTK_CORNER_TOP_LEFT</property>
+
+		  <child>
+		    <placeholder/>
+		  </child>
+		</widget>
+		<packing>
+		  <property name="padding">0</property>
+		  <property name="expand">True</property>
+		  <property name="fill">True</property>
+		</packing>
+	      </child>
+	    </widget>
+	    <packing>
+	      <property name="tab_expand">False</property>
+	      <property name="tab_fill">True</property>
+	    </packing>
+	  </child>
+
+	  <child>
+	    <widget class="GtkLabel" id="label8">
+	      <property name="visible">True</property>
+	      <property name="label" translatable="yes">Search</property>
+	      <property name="use_underline">False</property>
+	      <property name="use_markup">False</property>
+	      <property name="justify">GTK_JUSTIFY_LEFT</property>
+	      <property name="wrap">False</property>
+	      <property name="selectable">False</property>
+	      <property name="xalign">0.5</property>
+	      <property name="yalign">0.5</property>
+	      <property name="xpad">0</property>
+	      <property name="ypad">0</property>
+	      <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+	      <property name="width_chars">-1</property>
+	      <property name="single_line_mode">False</property>
+	      <property name="angle">0</property>
+	    </widget>
+	    <packing>
+	      <property name="type">tab</property>
+	    </packing>
+	  </child>
+	</widget>
+	<packing>
+	  <property name="padding">0</property>
+	  <property name="expand">True</property>
+	  <property name="fill">True</property>
+	</packing>
+      </child>
+
+      <child>
+	<widget class="GtkHButtonBox" id="buttonBox">
+	  <property name="visible">True</property>
+	  <property name="layout_style">GTK_BUTTONBOX_END</property>
+	  <property name="spacing">0</property>
+
+	  <child>
+	    <widget class="GtkButton" id="addAdvancedButton">
+	      <property name="visible">True</property>
+	      <property name="can_default">True</property>
+	      <property name="can_focus">True</property>
+	      <property name="relief">GTK_RELIEF_NORMAL</property>
+	      <property name="focus_on_click">True</property>
+
+	      <child>
+		<widget class="GtkLabel" id="label9">
+		  <property name="visible">True</property>
+		  <property name="label" translatable="yes">Add Advanced Target</property>
+		  <property name="use_underline">True</property>
+		  <property name="use_markup">False</property>
+		  <property name="justify">GTK_JUSTIFY_LEFT</property>
+		  <property name="wrap">False</property>
+		  <property name="selectable">False</property>
+		  <property name="xalign">0.5</property>
+		  <property name="yalign">0.5</property>
+		  <property name="xpad">0</property>
+		  <property name="ypad">0</property>
+		  <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+		  <property name="width_chars">-1</property>
+		  <property name="single_line_mode">False</property>
+		  <property name="angle">0</property>
+		</widget>
+	      </child>
+	    </widget>
+	  </child>
+	</widget>
+	<packing>
+	  <property name="padding">0</property>
+	  <property name="expand">False</property>
+	  <property name="fill">False</property>
+	</packing>
+      </child>
+
+      <child>
+	<widget class="GtkLabel" id="sizeLabel">
+	  <property name="visible">True</property>
+	  <property name="label" translatable="yes">Selected devices: %s (%s) out of %s (%s).</property>
+	  <property name="use_underline">False</property>
+	  <property name="use_markup">True</property>
+	  <property name="justify">GTK_JUSTIFY_LEFT</property>
+	  <property name="wrap">False</property>
+	  <property name="selectable">False</property>
+	  <property name="xalign">0</property>
+	  <property name="yalign">0</property>
+	  <property name="xpad">0</property>
+	  <property name="ypad">0</property>
+	  <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+	  <property name="width_chars">-1</property>
+	  <property name="single_line_mode">False</property>
+	  <property name="angle">0</property>
+	</widget>
+	<packing>
+	  <property name="padding">0</property>
+	  <property name="expand">False</property>
+	  <property name="fill">False</property>
+	</packing>
+      </child>
+
+      <child>
+	<widget class="GtkHBox" id="hbox1">
+	  <property name="visible">True</property>
+	  <property name="homogeneous">False</property>
+	  <property name="spacing">0</property>
+
+	  <child>
+	    <widget class="GtkImage" id="image1">
+	      <property name="visible">True</property>
+	      <property name="stock">gtk-dialog-info</property>
+	      <property name="icon_size">4</property>
+	      <property name="xalign">0.5</property>
+	      <property name="yalign">0</property>
+	      <property name="xpad">0</property>
+	      <property name="ypad">0</property>
+	    </widget>
+	    <packing>
+	      <property name="padding">0</property>
+	      <property name="expand">False</property>
+	      <property name="fill">False</property>
+	    </packing>
+	  </child>
+
+	  <child>
+	    <widget class="GtkLabel" id="label3">
+	      <property name="width_request">600</property>
+	      <property name="visible">True</property>
+	      <property name="label" translatable="yes">&lt;b&gt;Tip:&lt;/b&gt; Selected drives will not be formatted unless you choose to do so later during installation.  Also, note that post-installation you may mount drives you did not select here by modifying your /etc/fstab file.</property>
+	      <property name="use_underline">False</property>
+	      <property name="use_markup">True</property>
+	      <property name="justify">GTK_JUSTIFY_LEFT</property>
+	      <property name="wrap">True</property>
+	      <property name="selectable">False</property>
+	      <property name="xalign">0</property>
+	      <property name="yalign">0</property>
+	      <property name="xpad">0</property>
+	      <property name="ypad">0</property>
+	      <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+	      <property name="width_chars">-1</property>
+	      <property name="single_line_mode">False</property>
+	      <property name="angle">0</property>
+	    </widget>
+	    <packing>
+	      <property name="padding">0</property>
+	      <property name="expand">False</property>
+	      <property name="fill">False</property>
+	    </packing>
+	  </child>
+	</widget>
+	<packing>
+	  <property name="padding">0</property>
+	  <property name="expand">False</property>
+	  <property name="fill">False</property>
+	</packing>
+      </child>
+    </widget>
+  </child>
+</widget>
+
+</glade-interface>
diff --git a/data/ui/iscsi-config.glade b/data/ui/iscsi-config.glade
new file mode 100644
index 0000000..0757a2e
--- /dev/null
+++ b/data/ui/iscsi-config.glade
@@ -0,0 +1,456 @@
+<?xml version="1.0" standalone="no"?> <!--*- mode: xml -*-->
+<!DOCTYPE glade-interface SYSTEM "http://glade.gnome.org/glade-2.0.dtd";>
+
+<glade-interface>
+
+<widget class="GtkDialog" id="iscsiDialog">
+  <property name="title" translatable="yes">Configure iSCSI Parameters</property>
+  <property name="type">GTK_WINDOW_TOPLEVEL</property>
+  <property name="window_position">GTK_WIN_POS_CENTER</property>
+  <property name="modal">False</property>
+  <property name="resizable">True</property>
+  <property name="destroy_with_parent">False</property>
+  <property name="decorated">True</property>
+  <property name="skip_taskbar_hint">False</property>
+  <property name="skip_pager_hint">False</property>
+  <property name="type_hint">GDK_WINDOW_TYPE_HINT_DIALOG</property>
+  <property name="gravity">GDK_GRAVITY_NORTH_WEST</property>
+  <property name="focus_on_map">True</property>
+  <property name="urgency_hint">False</property>
+  <property name="has_separator">True</property>
+
+  <child internal-child="vbox">
+    <widget class="GtkVBox" id="dialog-vbox1">
+      <property name="visible">True</property>
+      <property name="homogeneous">False</property>
+      <property name="spacing">0</property>
+
+      <child internal-child="action_area">
+	<widget class="GtkHButtonBox" id="dialog-action_area1">
+	  <property name="visible">True</property>
+	  <property name="layout_style">GTK_BUTTONBOX_END</property>
+
+	  <child>
+	    <widget class="GtkButton" id="button1">
+	      <property name="visible">True</property>
+	      <property name="can_default">True</property>
+	      <property name="can_focus">True</property>
+	      <property name="label">gtk-cancel</property>
+	      <property name="use_stock">True</property>
+	      <property name="relief">GTK_RELIEF_NORMAL</property>
+	      <property name="focus_on_click">True</property>
+	      <property name="response_id">-6</property>
+	    </widget>
+	  </child>
+
+	  <child>
+	    <widget class="GtkButton" id="button2">
+	      <property name="visible">True</property>
+	      <property name="can_default">True</property>
+	      <property name="can_focus">True</property>
+	      <property name="relief">GTK_RELIEF_NORMAL</property>
+	      <property name="focus_on_click">True</property>
+	      <property name="response_id">-10</property>
+
+	      <child>
+		<widget class="GtkLabel" id="label6">
+		  <property name="visible">True</property>
+		  <property name="label" translatable="yes">_Add target</property>
+		  <property name="use_underline">True</property>
+		  <property name="use_markup">False</property>
+		  <property name="justify">GTK_JUSTIFY_LEFT</property>
+		  <property name="wrap">False</property>
+		  <property name="selectable">False</property>
+		  <property name="xalign">0.5</property>
+		  <property name="yalign">0.5</property>
+		  <property name="xpad">0</property>
+		  <property name="ypad">0</property>
+		  <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+		  <property name="width_chars">-1</property>
+		  <property name="single_line_mode">False</property>
+		  <property name="angle">0</property>
+		</widget>
+	      </child>
+	    </widget>
+	  </child>
+	</widget>
+	<packing>
+	  <property name="padding">0</property>
+	  <property name="expand">False</property>
+	  <property name="fill">True</property>
+	  <property name="pack_type">GTK_PACK_END</property>
+	</packing>
+      </child>
+
+      <child>
+	<widget class="GtkVBox" id="vbox1">
+	  <property name="border_width">12</property>
+	  <property name="visible">True</property>
+	  <property name="homogeneous">False</property>
+	  <property name="spacing">12</property>
+
+	  <child>
+	    <widget class="GtkLabel" id="label3">
+	      <property name="visible">True</property>
+	      <property name="label" translatable="yes">To use iSCSI disks, you must provide the address of your iSCSI target and the iSCSI initiator name you've configured for your host.</property>
+	      <property name="use_underline">False</property>
+	      <property name="use_markup">False</property>
+	      <property name="justify">GTK_JUSTIFY_LEFT</property>
+	      <property name="wrap">True</property>
+	      <property name="selectable">False</property>
+	      <property name="xalign">0.5</property>
+	      <property name="yalign">0.5</property>
+	      <property name="xpad">0</property>
+	      <property name="ypad">0</property>
+	      <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+	      <property name="width_chars">-1</property>
+	      <property name="single_line_mode">False</property>
+	      <property name="angle">0</property>
+	    </widget>
+	    <packing>
+	      <property name="padding">0</property>
+	      <property name="expand">False</property>
+	      <property name="fill">False</property>
+	    </packing>
+	  </child>
+
+	  <child>
+	    <widget class="GtkTable" id="iscsiTable">
+	      <property name="border_width">12</property>
+	      <property name="visible">True</property>
+	      <property name="n_rows">6</property>
+	      <property name="n_columns">2</property>
+	      <property name="homogeneous">False</property>
+	      <property name="row_spacing">6</property>
+	      <property name="column_spacing">6</property>
+
+	      <child>
+		<widget class="GtkLabel" id="labeliscsiAddr">
+		  <property name="visible">True</property>
+		  <property name="label" translatable="yes">&lt;b&gt;_Target IP Address:&lt;/b&gt;</property>
+		  <property name="use_underline">True</property>
+		  <property name="use_markup">True</property>
+		  <property name="justify">GTK_JUSTIFY_LEFT</property>
+		  <property name="wrap">False</property>
+		  <property name="selectable">False</property>
+		  <property name="xalign">0</property>
+		  <property name="yalign">0.5</property>
+		  <property name="xpad">0</property>
+		  <property name="ypad">0</property>
+		  <property name="mnemonic_widget">iscsiAddrEntry</property>
+		  <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+		  <property name="width_chars">-1</property>
+		  <property name="single_line_mode">False</property>
+		  <property name="angle">0</property>
+		</widget>
+		<packing>
+		  <property name="left_attach">0</property>
+		  <property name="right_attach">1</property>
+		  <property name="top_attach">0</property>
+		  <property name="bottom_attach">1</property>
+		  <property name="x_options">fill</property>
+		  <property name="y_options"></property>
+		</packing>
+	      </child>
+
+	      <child>
+		<widget class="GtkEntry" id="iscsiAddrEntry">
+		  <property name="visible">True</property>
+		  <property name="can_focus">True</property>
+		  <property name="editable">True</property>
+		  <property name="visibility">True</property>
+		  <property name="max_length">0</property>
+		  <property name="text" translatable="yes"></property>
+		  <property name="has_frame">True</property>
+		  <property name="invisible_char">â?¢</property>
+		  <property name="activates_default">False</property>
+		  <property name="width_chars">45</property>
+		</widget>
+		<packing>
+		  <property name="left_attach">1</property>
+		  <property name="right_attach">2</property>
+		  <property name="top_attach">0</property>
+		  <property name="bottom_attach">1</property>
+		  <property name="x_options">fill</property>
+		  <property name="y_options"></property>
+		</packing>
+	      </child>
+
+	      <child>
+		<widget class="GtkLabel" id="labeliscsiInititiator">
+		  <property name="visible">True</property>
+		  <property name="label" translatable="yes">&lt;b&gt;iSCSI Initiator _Name:&lt;/b&gt;</property>
+		  <property name="use_underline">True</property>
+		  <property name="use_markup">True</property>
+		  <property name="justify">GTK_JUSTIFY_LEFT</property>
+		  <property name="wrap">False</property>
+		  <property name="selectable">False</property>
+		  <property name="xalign">0</property>
+		  <property name="yalign">0.5</property>
+		  <property name="xpad">0</property>
+		  <property name="ypad">0</property>
+		  <property name="mnemonic_widget">iscsiInitiatorEntry</property>
+		  <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+		  <property name="width_chars">-1</property>
+		  <property name="single_line_mode">False</property>
+		  <property name="angle">0</property>
+		</widget>
+		<packing>
+		  <property name="left_attach">0</property>
+		  <property name="right_attach">1</property>
+		  <property name="top_attach">1</property>
+		  <property name="bottom_attach">2</property>
+		  <property name="x_options">fill</property>
+		  <property name="y_options"></property>
+		</packing>
+	      </child>
+
+	      <child>
+		<widget class="GtkEntry" id="iscsiInitiatorEntry">
+		  <property name="visible">True</property>
+		  <property name="can_focus">True</property>
+		  <property name="editable">True</property>
+		  <property name="visibility">True</property>
+		  <property name="max_length">0</property>
+		  <property name="text" translatable="yes"></property>
+		  <property name="has_frame">True</property>
+		  <property name="invisible_char">â?¢</property>
+		  <property name="activates_default">False</property>
+		  <property name="width_chars">45</property>
+		</widget>
+		<packing>
+		  <property name="left_attach">1</property>
+		  <property name="right_attach">2</property>
+		  <property name="top_attach">1</property>
+		  <property name="bottom_attach">2</property>
+		  <property name="x_options">fill</property>
+		  <property name="y_options"></property>
+		</packing>
+	      </child>
+
+	      <child>
+		<widget class="GtkLabel" id="userLabel">
+		  <property name="visible">True</property>
+		  <property name="label" translatable="yes">&lt;b&gt;CHAP _Username:&lt;/b&gt;</property>
+		  <property name="use_underline">True</property>
+		  <property name="use_markup">True</property>
+		  <property name="justify">GTK_JUSTIFY_LEFT</property>
+		  <property name="wrap">False</property>
+		  <property name="selectable">False</property>
+		  <property name="xalign">0</property>
+		  <property name="yalign">0.5</property>
+		  <property name="xpad">0</property>
+		  <property name="ypad">0</property>
+		  <property name="mnemonic_widget">userEntry</property>
+		  <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+		  <property name="width_chars">-1</property>
+		  <property name="single_line_mode">False</property>
+		  <property name="angle">0</property>
+		</widget>
+		<packing>
+		  <property name="left_attach">0</property>
+		  <property name="right_attach">1</property>
+		  <property name="top_attach">2</property>
+		  <property name="bottom_attach">3</property>
+		  <property name="x_options">fill</property>
+		  <property name="y_options"></property>
+		</packing>
+	      </child>
+
+	      <child>
+		<widget class="GtkEntry" id="userEntry">
+		  <property name="visible">True</property>
+		  <property name="can_focus">True</property>
+		  <property name="editable">True</property>
+		  <property name="visibility">True</property>
+		  <property name="max_length">0</property>
+		  <property name="text" translatable="yes"></property>
+		  <property name="has_frame">True</property>
+		  <property name="invisible_char">â?¢</property>
+		  <property name="activates_default">False</property>
+		  <property name="width_chars">45</property>
+		</widget>
+		<packing>
+		  <property name="left_attach">1</property>
+		  <property name="right_attach">2</property>
+		  <property name="top_attach">2</property>
+		  <property name="bottom_attach">3</property>
+		  <property name="x_options">fill</property>
+		  <property name="y_options"></property>
+		</packing>
+	      </child>
+
+	      <child>
+		<widget class="GtkLabel" id="passLabel">
+		  <property name="visible">True</property>
+		  <property name="label" translatable="yes">&lt;b&gt;CHAP _Password:&lt;/b&gt;</property>
+		  <property name="use_underline">True</property>
+		  <property name="use_markup">True</property>
+		  <property name="justify">GTK_JUSTIFY_LEFT</property>
+		  <property name="wrap">False</property>
+		  <property name="selectable">False</property>
+		  <property name="xalign">0</property>
+		  <property name="yalign">0.5</property>
+		  <property name="xpad">0</property>
+		  <property name="ypad">0</property>
+		  <property name="mnemonic_widget">passEntry</property>
+		  <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+		  <property name="width_chars">-1</property>
+		  <property name="single_line_mode">False</property>
+		  <property name="angle">0</property>
+		</widget>
+		<packing>
+		  <property name="left_attach">0</property>
+		  <property name="right_attach">1</property>
+		  <property name="top_attach">3</property>
+		  <property name="bottom_attach">4</property>
+		  <property name="x_options">fill</property>
+		  <property name="y_options"></property>
+		</packing>
+	      </child>
+
+	      <child>
+		<widget class="GtkEntry" id="passEntry">
+		  <property name="visible">True</property>
+		  <property name="can_focus">True</property>
+		  <property name="editable">True</property>
+		  <property name="visibility">False</property>
+		  <property name="max_length">0</property>
+		  <property name="text" translatable="yes"></property>
+		  <property name="has_frame">True</property>
+		  <property name="invisible_char">â?¢</property>
+		  <property name="activates_default">False</property>
+		  <property name="width_chars">45</property>
+		</widget>
+		<packing>
+		  <property name="left_attach">1</property>
+		  <property name="right_attach">2</property>
+		  <property name="top_attach">3</property>
+		  <property name="bottom_attach">4</property>
+		  <property name="x_options">fill</property>
+		  <property name="y_options"></property>
+		</packing>
+	      </child>
+
+	      <child>
+		<widget class="GtkLabel" id="userinLabel">
+		  <property name="visible">True</property>
+		  <property name="label" translatable="yes">&lt;b&gt;Reverse CHAP U_sername:&lt;/b&gt;</property>
+		  <property name="use_underline">True</property>
+		  <property name="use_markup">True</property>
+		  <property name="justify">GTK_JUSTIFY_LEFT</property>
+		  <property name="wrap">False</property>
+		  <property name="selectable">False</property>
+		  <property name="xalign">0</property>
+		  <property name="yalign">0.5</property>
+		  <property name="xpad">0</property>
+		  <property name="ypad">0</property>
+		  <property name="mnemonic_widget">userinEntry</property>
+		  <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+		  <property name="width_chars">-1</property>
+		  <property name="single_line_mode">False</property>
+		  <property name="angle">0</property>
+		</widget>
+		<packing>
+		  <property name="left_attach">0</property>
+		  <property name="right_attach">1</property>
+		  <property name="top_attach">4</property>
+		  <property name="bottom_attach">5</property>
+		  <property name="x_options">fill</property>
+		  <property name="y_options"></property>
+		</packing>
+	      </child>
+
+	      <child>
+		<widget class="GtkEntry" id="userinEntry">
+		  <property name="visible">True</property>
+		  <property name="can_focus">True</property>
+		  <property name="editable">True</property>
+		  <property name="visibility">True</property>
+		  <property name="max_length">0</property>
+		  <property name="text" translatable="yes"></property>
+		  <property name="has_frame">True</property>
+		  <property name="invisible_char">â?¢</property>
+		  <property name="activates_default">False</property>
+		  <property name="width_chars">45</property>
+		</widget>
+		<packing>
+		  <property name="left_attach">1</property>
+		  <property name="right_attach">2</property>
+		  <property name="top_attach">4</property>
+		  <property name="bottom_attach">5</property>
+		  <property name="x_options">fill</property>
+		  <property name="y_options"></property>
+		</packing>
+	      </child>
+
+	      <child>
+		<widget class="GtkLabel" id="passinLabel">
+		  <property name="visible">True</property>
+		  <property name="label" translatable="yes">&lt;b&gt;Reverse CHAP P_assword:&lt;/b&gt;</property>
+		  <property name="use_underline">True</property>
+		  <property name="use_markup">True</property>
+		  <property name="justify">GTK_JUSTIFY_LEFT</property>
+		  <property name="wrap">False</property>
+		  <property name="selectable">False</property>
+		  <property name="xalign">0</property>
+		  <property name="yalign">0.5</property>
+		  <property name="xpad">0</property>
+		  <property name="ypad">0</property>
+		  <property name="mnemonic_widget">passinEntry</property>
+		  <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+		  <property name="width_chars">-1</property>
+		  <property name="single_line_mode">False</property>
+		  <property name="angle">0</property>
+		</widget>
+		<packing>
+		  <property name="left_attach">0</property>
+		  <property name="right_attach">1</property>
+		  <property name="top_attach">5</property>
+		  <property name="bottom_attach">6</property>
+		  <property name="x_options">fill</property>
+		  <property name="y_options"></property>
+		</packing>
+	      </child>
+
+	      <child>
+		<widget class="GtkEntry" id="passinEntry">
+		  <property name="visible">True</property>
+		  <property name="can_focus">True</property>
+		  <property name="editable">True</property>
+		  <property name="visibility">False</property>
+		  <property name="max_length">0</property>
+		  <property name="text" translatable="yes"></property>
+		  <property name="has_frame">True</property>
+		  <property name="invisible_char">â?¢</property>
+		  <property name="activates_default">False</property>
+		  <property name="width_chars">45</property>
+		</widget>
+		<packing>
+		  <property name="left_attach">1</property>
+		  <property name="right_attach">2</property>
+		  <property name="top_attach">5</property>
+		  <property name="bottom_attach">6</property>
+		  <property name="x_options">fill</property>
+		  <property name="y_options"></property>
+		</packing>
+	      </child>
+	    </widget>
+	    <packing>
+	      <property name="padding">0</property>
+	      <property name="expand">True</property>
+	      <property name="fill">True</property>
+	    </packing>
+	  </child>
+	</widget>
+	<packing>
+	  <property name="padding">0</property>
+	  <property name="expand">True</property>
+	  <property name="fill">True</property>
+	</packing>
+      </child>
+    </widget>
+  </child>
+</widget>
+
+</glade-interface>
diff --git a/data/ui/lukspassphrase.glade b/data/ui/lukspassphrase.glade
new file mode 100644
index 0000000..b688e8a
--- /dev/null
+++ b/data/ui/lukspassphrase.glade
@@ -0,0 +1,446 @@
+<?xml version="1.0" standalone="no"?> <!--*- mode: xml -*-->
+<!DOCTYPE glade-interface SYSTEM "http://glade.gnome.org/glade-2.0.dtd";>
+
+<glade-interface>
+
+<widget class="GtkDialog" id="luksPassphraseDialog">
+  <property name="visible">True</property>
+  <property name="title" translatable="yes">Enter passphrase for encrypted partition</property>
+  <property name="type">GTK_WINDOW_TOPLEVEL</property>
+  <property name="window_position">GTK_WIN_POS_CENTER</property>
+  <property name="modal">False</property>
+  <property name="resizable">True</property>
+  <property name="destroy_with_parent">False</property>
+  <property name="decorated">True</property>
+  <property name="skip_taskbar_hint">False</property>
+  <property name="skip_pager_hint">False</property>
+  <property name="type_hint">GDK_WINDOW_TYPE_HINT_DIALOG</property>
+  <property name="gravity">GDK_GRAVITY_NORTH_WEST</property>
+  <property name="focus_on_map">True</property>
+  <property name="urgency_hint">False</property>
+  <property name="has_separator">True</property>
+
+  <child internal-child="vbox">
+    <widget class="GtkVBox" id="dialog-vbox1">
+      <property name="visible">True</property>
+      <property name="homogeneous">False</property>
+      <property name="spacing">0</property>
+
+      <child internal-child="action_area">
+	<widget class="GtkHButtonBox" id="dialog-action_area1">
+	  <property name="visible">True</property>
+	  <property name="layout_style">GTK_BUTTONBOX_END</property>
+
+	  <child>
+	    <widget class="GtkButton" id="cancelbutton1">
+	      <property name="visible">True</property>
+	      <property name="can_default">True</property>
+	      <property name="can_focus">True</property>
+	      <property name="label">gtk-cancel</property>
+	      <property name="use_stock">True</property>
+	      <property name="relief">GTK_RELIEF_NORMAL</property>
+	      <property name="focus_on_click">True</property>
+	      <property name="response_id">-6</property>
+	    </widget>
+	  </child>
+
+	  <child>
+	    <widget class="GtkButton" id="okbutton1">
+	      <property name="visible">True</property>
+	      <property name="can_default">True</property>
+	      <property name="can_focus">True</property>
+	      <property name="label">gtk-ok</property>
+	      <property name="use_stock">True</property>
+	      <property name="relief">GTK_RELIEF_NORMAL</property>
+	      <property name="focus_on_click">True</property>
+	      <property name="response_id">-5</property>
+	    </widget>
+	  </child>
+	</widget>
+	<packing>
+	  <property name="padding">0</property>
+	  <property name="expand">False</property>
+	  <property name="fill">True</property>
+	  <property name="pack_type">GTK_PACK_END</property>
+	</packing>
+      </child>
+
+      <child>
+	<widget class="GtkVBox" id="vbox1">
+	  <property name="visible">True</property>
+	  <property name="homogeneous">False</property>
+	  <property name="spacing">0</property>
+
+	  <child>
+	    <widget class="GtkHBox" id="hbox2">
+	      <property name="visible">True</property>
+	      <property name="homogeneous">False</property>
+	      <property name="spacing">0</property>
+
+	      <child>
+		<widget class="GtkImage" id="image2">
+		  <property name="visible">True</property>
+		  <property name="icon_size">6</property>
+		  <property name="icon_name">gtk-dialog-authentication</property>
+		  <property name="xalign">0.5</property>
+		  <property name="yalign">0.5</property>
+		  <property name="xpad">0</property>
+		  <property name="ypad">0</property>
+		</widget>
+		<packing>
+		  <property name="padding">0</property>
+		  <property name="expand">True</property>
+		  <property name="fill">True</property>
+		</packing>
+	      </child>
+
+	      <child>
+		<widget class="GtkLabel" id="mainLabel">
+		  <property name="visible">True</property>
+		  <property name="label" translatable="yes">Choose a passphrase for this encrypted partition. You will be prompted for the passphrase during system boot.</property>
+		  <property name="use_underline">False</property>
+		  <property name="use_markup">False</property>
+		  <property name="justify">GTK_JUSTIFY_LEFT</property>
+		  <property name="wrap">True</property>
+		  <property name="selectable">False</property>
+		  <property name="xalign">0</property>
+		  <property name="yalign">0.5</property>
+		  <property name="xpad">5</property>
+		  <property name="ypad">15</property>
+		  <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+		  <property name="width_chars">-1</property>
+		  <property name="single_line_mode">False</property>
+		  <property name="angle">0</property>
+		</widget>
+		<packing>
+		  <property name="padding">0</property>
+		  <property name="expand">True</property>
+		  <property name="fill">True</property>
+		</packing>
+	      </child>
+	    </widget>
+	    <packing>
+	      <property name="padding">0</property>
+	      <property name="expand">False</property>
+	      <property name="fill">False</property>
+	    </packing>
+	  </child>
+
+	  <child>
+	    <widget class="GtkTable" id="entryTable">
+	      <property name="visible">True</property>
+	      <property name="n_rows">2</property>
+	      <property name="n_columns">2</property>
+	      <property name="homogeneous">False</property>
+	      <property name="row_spacing">10</property>
+	      <property name="column_spacing">5</property>
+
+	      <child>
+		<widget class="GtkLabel" id="passphraseEntryLabel">
+		  <property name="visible">True</property>
+		  <property name="label" translatable="yes">Enter passphrase:</property>
+		  <property name="use_underline">False</property>
+		  <property name="use_markup">False</property>
+		  <property name="justify">GTK_JUSTIFY_RIGHT</property>
+		  <property name="wrap">False</property>
+		  <property name="selectable">False</property>
+		  <property name="xalign">0</property>
+		  <property name="yalign">0.5</property>
+		  <property name="xpad">5</property>
+		  <property name="ypad">0</property>
+		  <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+		  <property name="width_chars">-1</property>
+		  <property name="single_line_mode">False</property>
+		  <property name="angle">0</property>
+		</widget>
+		<packing>
+		  <property name="left_attach">0</property>
+		  <property name="right_attach">1</property>
+		  <property name="top_attach">0</property>
+		  <property name="bottom_attach">1</property>
+		  <property name="x_options">fill</property>
+		  <property name="y_options"></property>
+		</packing>
+	      </child>
+
+	      <child>
+		<widget class="GtkLabel" id="confirmEntryLabel">
+		  <property name="visible">True</property>
+		  <property name="label" translatable="yes">Confirm passphrase:</property>
+		  <property name="use_underline">False</property>
+		  <property name="use_markup">False</property>
+		  <property name="justify">GTK_JUSTIFY_RIGHT</property>
+		  <property name="wrap">False</property>
+		  <property name="selectable">False</property>
+		  <property name="xalign">0</property>
+		  <property name="yalign">0.5</property>
+		  <property name="xpad">5</property>
+		  <property name="ypad">0</property>
+		  <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+		  <property name="width_chars">-1</property>
+		  <property name="single_line_mode">False</property>
+		  <property name="angle">0</property>
+		</widget>
+		<packing>
+		  <property name="left_attach">0</property>
+		  <property name="right_attach">1</property>
+		  <property name="top_attach">1</property>
+		  <property name="bottom_attach">2</property>
+		  <property name="x_options">fill</property>
+		  <property name="y_options"></property>
+		</packing>
+	      </child>
+
+	      <child>
+		<widget class="GtkEntry" id="passphraseEntry">
+		  <property name="visible">True</property>
+		  <property name="can_focus">True</property>
+		  <property name="editable">True</property>
+		  <property name="visibility">False</property>
+		  <property name="max_length">500</property>
+		  <property name="text" translatable="yes"></property>
+		  <property name="has_frame">True</property>
+		  <property name="invisible_char">â?¢</property>
+		  <property name="activates_default">False</property>
+		</widget>
+		<packing>
+		  <property name="left_attach">1</property>
+		  <property name="right_attach">2</property>
+		  <property name="top_attach">0</property>
+		  <property name="bottom_attach">1</property>
+		  <property name="y_options"></property>
+		</packing>
+	      </child>
+
+	      <child>
+		<widget class="GtkEntry" id="confirmEntry">
+		  <property name="visible">True</property>
+		  <property name="can_focus">True</property>
+		  <property name="editable">True</property>
+		  <property name="visibility">False</property>
+		  <property name="max_length">500</property>
+		  <property name="text" translatable="yes"></property>
+		  <property name="has_frame">True</property>
+		  <property name="invisible_char">â?¢</property>
+		  <property name="activates_default">False</property>
+		</widget>
+		<packing>
+		  <property name="left_attach">1</property>
+		  <property name="right_attach">2</property>
+		  <property name="top_attach">1</property>
+		  <property name="bottom_attach">2</property>
+		  <property name="y_options"></property>
+		</packing>
+	      </child>
+	    </widget>
+	    <packing>
+	      <property name="padding">0</property>
+	      <property name="expand">True</property>
+	      <property name="fill">True</property>
+	    </packing>
+	  </child>
+
+	  <child>
+	    <widget class="GtkCheckButton" id="globalcheckbutton">
+	      <property name="border_width">5</property>
+	      <property name="visible">True</property>
+	      <property name="can_focus">True</property>
+	      <property name="label" translatable="yes">Also add this passphrase to all existing encrypted devices to streamline the boot process</property>
+	      <property name="use_underline">True</property>
+	      <property name="relief">GTK_RELIEF_NORMAL</property>
+	      <property name="focus_on_click">True</property>
+	      <property name="active">False</property>
+	      <property name="inconsistent">False</property>
+	      <property name="draw_indicator">True</property>
+	    </widget>
+	    <packing>
+	      <property name="padding">0</property>
+	      <property name="expand">False</property>
+	      <property name="fill">False</property>
+	    </packing>
+	  </child>
+	</widget>
+	<packing>
+	  <property name="padding">0</property>
+	  <property name="expand">True</property>
+	  <property name="fill">True</property>
+	</packing>
+      </child>
+    </widget>
+  </child>
+</widget>
+
+<widget class="GtkDialog" id="passphraseEntryDialog">
+  <property name="visible">True</property>
+  <property name="title" translatable="yes">Passphrase</property>
+  <property name="type">GTK_WINDOW_TOPLEVEL</property>
+  <property name="window_position">GTK_WIN_POS_CENTER_ALWAYS</property>
+  <property name="modal">True</property>
+  <property name="resizable">True</property>
+  <property name="destroy_with_parent">False</property>
+  <property name="icon_name">gtk-dialog-authentication</property>
+  <property name="decorated">True</property>
+  <property name="skip_taskbar_hint">False</property>
+  <property name="skip_pager_hint">False</property>
+  <property name="type_hint">GDK_WINDOW_TYPE_HINT_DIALOG</property>
+  <property name="gravity">GDK_GRAVITY_NORTH_WEST</property>
+  <property name="focus_on_map">True</property>
+  <property name="urgency_hint">False</property>
+  <property name="has_separator">True</property>
+
+  <child internal-child="vbox">
+    <widget class="GtkVBox" id="dialog2-vbox1">
+      <property name="visible">True</property>
+      <property name="homogeneous">False</property>
+      <property name="spacing">0</property>
+
+      <child internal-child="action_area">
+	<widget class="GtkHButtonBox" id="dialog2-action_area1">
+	  <property name="visible">True</property>
+	  <property name="layout_style">GTK_BUTTONBOX_END</property>
+
+	  <child>
+	    <widget class="GtkButton" id="cancelbutton2">
+	      <property name="visible">True</property>
+	      <property name="can_default">True</property>
+	      <property name="can_focus">True</property>
+	      <property name="label">gtk-cancel</property>
+	      <property name="use_stock">True</property>
+	      <property name="relief">GTK_RELIEF_NORMAL</property>
+	      <property name="focus_on_click">True</property>
+	      <property name="response_id">-6</property>
+	    </widget>
+	  </child>
+
+	  <child>
+	    <widget class="GtkButton" id="okbutton2">
+	      <property name="visible">True</property>
+	      <property name="can_default">True</property>
+	      <property name="can_focus">True</property>
+	      <property name="label">gtk-ok</property>
+	      <property name="use_stock">True</property>
+	      <property name="relief">GTK_RELIEF_NORMAL</property>
+	      <property name="focus_on_click">True</property>
+	      <property name="response_id">-5</property>
+	    </widget>
+	  </child>
+	</widget>
+	<packing>
+	  <property name="padding">0</property>
+	  <property name="expand">False</property>
+	  <property name="fill">True</property>
+	  <property name="pack_type">GTK_PACK_END</property>
+	</packing>
+      </child>
+
+      <child>
+	<widget class="GtkVBox" id="vbox2">
+	  <property name="visible">True</property>
+	  <property name="homogeneous">False</property>
+	  <property name="spacing">0</property>
+
+	  <child>
+	    <widget class="GtkHBox" id="hbox1">
+	      <property name="visible">True</property>
+	      <property name="homogeneous">False</property>
+	      <property name="spacing">12</property>
+
+	      <child>
+		<widget class="GtkImage" id="image1">
+		  <property name="visible">True</property>
+		  <property name="icon_size">6</property>
+		  <property name="icon_name">gtk-dialog-authentication</property>
+		  <property name="xalign">0.5</property>
+		  <property name="yalign">0.5</property>
+		  <property name="xpad">0</property>
+		  <property name="ypad">0</property>
+		</widget>
+		<packing>
+		  <property name="padding">0</property>
+		  <property name="expand">False</property>
+		  <property name="fill">True</property>
+		</packing>
+	      </child>
+
+	      <child>
+		<widget class="GtkLabel" id="passphraseLabel">
+		  <property name="visible">True</property>
+		  <property name="label" translatable="yes">label1</property>
+		  <property name="use_underline">False</property>
+		  <property name="use_markup">False</property>
+		  <property name="justify">GTK_JUSTIFY_LEFT</property>
+		  <property name="wrap">True</property>
+		  <property name="selectable">False</property>
+		  <property name="xalign">0.5</property>
+		  <property name="yalign">0.5</property>
+		  <property name="xpad">0</property>
+		  <property name="ypad">0</property>
+		  <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+		  <property name="width_chars">-1</property>
+		  <property name="single_line_mode">False</property>
+		  <property name="angle">0</property>
+		</widget>
+		<packing>
+		  <property name="padding">0</property>
+		  <property name="expand">True</property>
+		  <property name="fill">True</property>
+		</packing>
+	      </child>
+	    </widget>
+	    <packing>
+	      <property name="padding">0</property>
+	      <property name="expand">False</property>
+	      <property name="fill">False</property>
+	    </packing>
+	  </child>
+
+	  <child>
+	    <widget class="GtkEntry" id="passphraseEntry2">
+	      <property name="visible">True</property>
+	      <property name="can_focus">True</property>
+	      <property name="has_focus">True</property>
+	      <property name="editable">True</property>
+	      <property name="visibility">False</property>
+	      <property name="max_length">500</property>
+	      <property name="text" translatable="yes"></property>
+	      <property name="has_frame">True</property>
+	      <property name="invisible_char">â?¢</property>
+	      <property name="activates_default">False</property>
+	    </widget>
+	    <packing>
+	      <property name="padding">0</property>
+	      <property name="expand">False</property>
+	      <property name="fill">False</property>
+	    </packing>
+	  </child>
+
+	  <child>
+	    <widget class="GtkCheckButton" id="globalcheckbutton">
+	      <property name="visible">True</property>
+	      <property name="can_focus">True</property>
+	      <property name="label" translatable="yes">This is a global passphrase</property>
+	      <property name="use_underline">True</property>
+	      <property name="relief">GTK_RELIEF_NORMAL</property>
+	      <property name="focus_on_click">True</property>
+	      <property name="active">False</property>
+	      <property name="inconsistent">False</property>
+	      <property name="draw_indicator">True</property>
+	    </widget>
+	    <packing>
+	      <property name="padding">0</property>
+	      <property name="expand">False</property>
+	      <property name="fill">False</property>
+	    </packing>
+	  </child>
+	</widget>
+	<packing>
+	  <property name="padding">0</property>
+	  <property name="expand">True</property>
+	  <property name="fill">True</property>
+	</packing>
+      </child>
+    </widget>
+  </child>
+</widget>
+
+</glade-interface>
diff --git a/data/ui/netconfig.glade b/data/ui/netconfig.glade
new file mode 100644
index 0000000..cb8991f
--- /dev/null
+++ b/data/ui/netconfig.glade
@@ -0,0 +1,538 @@
+<?xml version="1.0" standalone="no"?> <!--*- mode: xml -*-->
+<!DOCTYPE glade-interface SYSTEM "http://glade.gnome.org/glade-2.0.dtd";>
+
+<glade-interface>
+
+<widget class="GtkDialog" id="NetworkConfigWindow">
+  <property name="visible">True</property>
+  <property name="title" translatable="yes">Enable network interface</property>
+  <property name="type">GTK_WINDOW_TOPLEVEL</property>
+  <property name="window_position">GTK_WIN_POS_CENTER_ALWAYS</property>
+  <property name="modal">False</property>
+  <property name="resizable">True</property>
+  <property name="destroy_with_parent">False</property>
+  <property name="decorated">True</property>
+  <property name="skip_taskbar_hint">False</property>
+  <property name="skip_pager_hint">False</property>
+  <property name="type_hint">GDK_WINDOW_TYPE_HINT_DIALOG</property>
+  <property name="gravity">GDK_GRAVITY_NORTH_WEST</property>
+  <property name="focus_on_map">True</property>
+  <property name="urgency_hint">False</property>
+  <property name="has_separator">True</property>
+
+  <child internal-child="vbox">
+    <widget class="GtkVBox" id="dialog-vbox1">
+      <property name="visible">True</property>
+      <property name="homogeneous">False</property>
+      <property name="spacing">0</property>
+
+      <child internal-child="action_area">
+	<widget class="GtkHButtonBox" id="dialog-action_area1">
+	  <property name="visible">True</property>
+	  <property name="layout_style">GTK_BUTTONBOX_END</property>
+
+	  <child>
+	    <widget class="GtkButton" id="cancelButton">
+	      <property name="visible">True</property>
+	      <property name="can_default">True</property>
+	      <property name="can_focus">True</property>
+	      <property name="label">gtk-cancel</property>
+	      <property name="use_stock">True</property>
+	      <property name="relief">GTK_RELIEF_NORMAL</property>
+	      <property name="focus_on_click">True</property>
+	      <property name="response_id">-6</property>
+	    </widget>
+	  </child>
+
+	  <child>
+	    <widget class="GtkButton" id="okButton">
+	      <property name="visible">True</property>
+	      <property name="can_default">True</property>
+	      <property name="can_focus">True</property>
+	      <property name="label">gtk-ok</property>
+	      <property name="use_stock">True</property>
+	      <property name="relief">GTK_RELIEF_NORMAL</property>
+	      <property name="focus_on_click">True</property>
+	      <property name="response_id">-5</property>
+	    </widget>
+	  </child>
+	</widget>
+	<packing>
+	  <property name="padding">0</property>
+	  <property name="expand">False</property>
+	  <property name="fill">True</property>
+	  <property name="pack_type">GTK_PACK_END</property>
+	</packing>
+      </child>
+
+      <child>
+	<widget class="GtkVBox" id="vbox1">
+	  <property name="border_width">18</property>
+	  <property name="visible">True</property>
+	  <property name="homogeneous">False</property>
+	  <property name="spacing">12</property>
+
+	  <child>
+	    <widget class="GtkLabel" id="label1">
+	      <property name="visible">True</property>
+	      <property name="label" translatable="yes" context="yes">This requires that you have an active network connection during the installation process.  Please configure a network interface.</property>
+	      <property name="use_underline">False</property>
+	      <property name="use_markup">False</property>
+	      <property name="justify">GTK_JUSTIFY_LEFT</property>
+	      <property name="wrap">True</property>
+	      <property name="selectable">False</property>
+	      <property name="xalign">0</property>
+	      <property name="yalign">0</property>
+	      <property name="xpad">0</property>
+	      <property name="ypad">0</property>
+	      <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+	      <property name="width_chars">-1</property>
+	      <property name="single_line_mode">False</property>
+	      <property name="angle">0</property>
+	    </widget>
+	    <packing>
+	      <property name="padding">0</property>
+	      <property name="expand">False</property>
+	      <property name="fill">False</property>
+	    </packing>
+	  </child>
+
+	  <child>
+	    <widget class="GtkHBox" id="interfaceBox">
+	      <property name="visible">True</property>
+	      <property name="homogeneous">False</property>
+	      <property name="spacing">6</property>
+
+	      <child>
+		<widget class="GtkLabel" id="interfaceLabel">
+		  <property name="visible">True</property>
+		  <property name="label" translatable="yes" context="yes">&lt;b&gt;_Interface:&lt;/b&gt;</property>
+		  <property name="use_underline">True</property>
+		  <property name="use_markup">True</property>
+		  <property name="justify">GTK_JUSTIFY_LEFT</property>
+		  <property name="wrap">False</property>
+		  <property name="selectable">False</property>
+		  <property name="xalign">0</property>
+		  <property name="yalign">0.5</property>
+		  <property name="xpad">0</property>
+		  <property name="ypad">0</property>
+		  <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+		  <property name="width_chars">-1</property>
+		  <property name="single_line_mode">False</property>
+		  <property name="angle">0</property>
+		</widget>
+		<packing>
+		  <property name="padding">0</property>
+		  <property name="expand">False</property>
+		  <property name="fill">False</property>
+		</packing>
+	      </child>
+
+	      <child>
+		<widget class="GtkComboBox" id="interfaceCombo">
+		  <property name="visible">True</property>
+		  <property name="add_tearoffs">False</property>
+		  <property name="focus_on_click">True</property>
+		  <signal name="changed" handler="on_interfaceCombo_changed"/>
+		</widget>
+		<packing>
+		  <property name="padding">0</property>
+		  <property name="expand">True</property>
+		  <property name="fill">True</property>
+		</packing>
+	      </child>
+	    </widget>
+	    <packing>
+	      <property name="padding">0</property>
+	      <property name="expand">True</property>
+	      <property name="fill">True</property>
+	    </packing>
+	  </child>
+
+	  <child>
+	    <widget class="GtkCheckButton" id="dhcpCheckbutton">
+	      <property name="visible">True</property>
+	      <property name="label" translatable="yes" context="yes">Use _dynamic IP configuration (DHCP)</property>
+	      <property name="use_underline">True</property>
+	      <property name="relief">GTK_RELIEF_NORMAL</property>
+	      <property name="focus_on_click">True</property>
+	      <property name="active">False</property>
+	      <property name="inconsistent">False</property>
+	      <property name="draw_indicator">True</property>
+	      <signal name="toggled" handler="on_dhcpCheckbutton_toggled"/>
+	    </widget>
+	    <packing>
+	      <property name="padding">0</property>
+	      <property name="expand">True</property>
+	      <property name="fill">True</property>
+	    </packing>
+	  </child>
+
+	  <child>
+	    <widget class="GtkCheckButton" id="ipv4Checkbutton">
+	      <property name="visible">True</property>
+	      <property name="label" translatable="yes" context="yes">Enable IPv_4 support</property>
+	      <property name="use_underline">True</property>
+	      <property name="relief">GTK_RELIEF_NORMAL</property>
+	      <property name="focus_on_click">True</property>
+	      <property name="active">False</property>
+	      <property name="inconsistent">False</property>
+	      <property name="draw_indicator">True</property>
+	      <signal name="toggled" handler="on_ipv4Checkbutton_toggled"/>
+	    </widget>
+	    <packing>
+	      <property name="padding">0</property>
+	      <property name="expand">True</property>
+	      <property name="fill">True</property>
+	    </packing>
+	  </child>
+
+	  <child>
+	    <widget class="GtkCheckButton" id="ipv6Checkbutton">
+	      <property name="label" translatable="yes" context="yes">Enable IPv_6 support</property>
+	      <property name="use_underline">True</property>
+	      <property name="relief">GTK_RELIEF_NORMAL</property>
+	      <property name="focus_on_click">True</property>
+	      <property name="active">False</property>
+	      <property name="inconsistent">False</property>
+	      <property name="draw_indicator">True</property>
+	      <signal name="toggled" handler="on_ipv6Checkbutton_toggled"/>
+	    </widget>
+	    <packing>
+	      <property name="padding">0</property>
+	      <property name="expand">True</property>
+	      <property name="fill">True</property>
+	    </packing>
+	  </child>
+
+	  <child>
+	    <widget class="GtkHBox" id="ipv4Box">
+	      <property name="visible">True</property>
+	      <property name="homogeneous">False</property>
+	      <property name="spacing">6</property>
+
+	      <child>
+		<widget class="GtkLabel" id="ipv4Label">
+		  <property name="visible">True</property>
+		  <property name="label" translatable="yes" context="yes">&lt;b&gt;IPv4 Address:&lt;/b&gt;</property>
+		  <property name="use_underline">False</property>
+		  <property name="use_markup">True</property>
+		  <property name="justify">GTK_JUSTIFY_LEFT</property>
+		  <property name="wrap">False</property>
+		  <property name="selectable">False</property>
+		  <property name="xalign">0</property>
+		  <property name="yalign">0.5</property>
+		  <property name="xpad">0</property>
+		  <property name="ypad">0</property>
+		  <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+		  <property name="width_chars">-1</property>
+		  <property name="single_line_mode">False</property>
+		  <property name="angle">0</property>
+		</widget>
+		<packing>
+		  <property name="padding">0</property>
+		  <property name="expand">False</property>
+		  <property name="fill">False</property>
+		</packing>
+	      </child>
+
+	      <child>
+		<widget class="GtkEntry" id="ipv4Address">
+		  <property name="visible">True</property>
+		  <property name="editable">True</property>
+		  <property name="visibility">True</property>
+		  <property name="max_length">0</property>
+		  <property name="text" translatable="yes"></property>
+		  <property name="has_frame">True</property>
+		  <property name="invisible_char">â?¢</property>
+		  <property name="activates_default">False</property>
+		  <property name="width_chars">16</property>
+		</widget>
+		<packing>
+		  <property name="padding">0</property>
+		  <property name="expand">False</property>
+		  <property name="fill">True</property>
+		</packing>
+	      </child>
+
+	      <child>
+		<widget class="GtkLabel" id="label10">
+		  <property name="visible">True</property>
+		  <property name="label" translatable="yes" context="yes">/</property>
+		  <property name="use_underline">False</property>
+		  <property name="use_markup">False</property>
+		  <property name="justify">GTK_JUSTIFY_LEFT</property>
+		  <property name="wrap">False</property>
+		  <property name="selectable">False</property>
+		  <property name="xalign">0.5</property>
+		  <property name="yalign">0.5</property>
+		  <property name="xpad">0</property>
+		  <property name="ypad">0</property>
+		  <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+		  <property name="width_chars">-1</property>
+		  <property name="single_line_mode">False</property>
+		  <property name="angle">0</property>
+		</widget>
+		<packing>
+		  <property name="padding">0</property>
+		  <property name="expand">False</property>
+		  <property name="fill">False</property>
+		</packing>
+	      </child>
+
+	      <child>
+		<widget class="GtkEntry" id="ipv4Netmask">
+		  <property name="visible">True</property>
+		  <property name="editable">True</property>
+		  <property name="visibility">True</property>
+		  <property name="max_length">0</property>
+		  <property name="text" translatable="yes"></property>
+		  <property name="has_frame">True</property>
+		  <property name="invisible_char">â?¢</property>
+		  <property name="activates_default">False</property>
+		  <property name="width_chars">16</property>
+		</widget>
+		<packing>
+		  <property name="padding">0</property>
+		  <property name="expand">False</property>
+		  <property name="fill">True</property>
+		</packing>
+	      </child>
+	    </widget>
+	    <packing>
+	      <property name="padding">0</property>
+	      <property name="expand">True</property>
+	      <property name="fill">True</property>
+	    </packing>
+	  </child>
+
+	  <child>
+	    <widget class="GtkHBox" id="ipv6Box">
+	      <property name="sensitive">False</property>
+	      <property name="homogeneous">False</property>
+	      <property name="spacing">6</property>
+
+	      <child>
+		<widget class="GtkLabel" id="ipv6Label">
+		  <property name="visible">True</property>
+		  <property name="label" translatable="yes" context="yes">&lt;b&gt;IPv6 Address:&lt;/b&gt;</property>
+		  <property name="use_underline">False</property>
+		  <property name="use_markup">True</property>
+		  <property name="justify">GTK_JUSTIFY_LEFT</property>
+		  <property name="wrap">False</property>
+		  <property name="selectable">False</property>
+		  <property name="xalign">0</property>
+		  <property name="yalign">0.5</property>
+		  <property name="xpad">0</property>
+		  <property name="ypad">0</property>
+		  <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+		  <property name="width_chars">-1</property>
+		  <property name="single_line_mode">False</property>
+		  <property name="angle">0</property>
+		</widget>
+		<packing>
+		  <property name="padding">0</property>
+		  <property name="expand">False</property>
+		  <property name="fill">True</property>
+		</packing>
+	      </child>
+
+	      <child>
+		<widget class="GtkEntry" id="ipv6Address">
+		  <property name="visible">True</property>
+		  <property name="editable">True</property>
+		  <property name="visibility">True</property>
+		  <property name="max_length">0</property>
+		  <property name="text" translatable="yes"></property>
+		  <property name="has_frame">True</property>
+		  <property name="invisible_char">â?¢</property>
+		  <property name="activates_default">False</property>
+		  <property name="width_chars">41</property>
+		</widget>
+		<packing>
+		  <property name="padding">0</property>
+		  <property name="expand">False</property>
+		  <property name="fill">True</property>
+		</packing>
+	      </child>
+
+	      <child>
+		<widget class="GtkLabel" id="label11">
+		  <property name="visible">True</property>
+		  <property name="label" translatable="yes" context="yes">/</property>
+		  <property name="use_underline">False</property>
+		  <property name="use_markup">False</property>
+		  <property name="justify">GTK_JUSTIFY_LEFT</property>
+		  <property name="wrap">False</property>
+		  <property name="selectable">False</property>
+		  <property name="xalign">0.5</property>
+		  <property name="yalign">0.5</property>
+		  <property name="xpad">0</property>
+		  <property name="ypad">0</property>
+		  <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+		  <property name="width_chars">-1</property>
+		  <property name="single_line_mode">False</property>
+		  <property name="angle">0</property>
+		</widget>
+		<packing>
+		  <property name="padding">0</property>
+		  <property name="expand">False</property>
+		  <property name="fill">False</property>
+		</packing>
+	      </child>
+
+	      <child>
+		<widget class="GtkEntry" id="ipv6Netmask">
+		  <property name="visible">True</property>
+		  <property name="editable">True</property>
+		  <property name="visibility">True</property>
+		  <property name="max_length">0</property>
+		  <property name="text" translatable="yes"></property>
+		  <property name="has_frame">True</property>
+		  <property name="invisible_char">â?¢</property>
+		  <property name="activates_default">False</property>
+		  <property name="width_chars">4</property>
+		</widget>
+		<packing>
+		  <property name="padding">0</property>
+		  <property name="expand">False</property>
+		  <property name="fill">True</property>
+		</packing>
+	      </child>
+	    </widget>
+	    <packing>
+	      <property name="padding">0</property>
+	      <property name="expand">True</property>
+	      <property name="fill">True</property>
+	    </packing>
+	  </child>
+
+	  <child>
+	    <widget class="GtkHBox" id="gatewayBox">
+	      <property name="visible">True</property>
+	      <property name="homogeneous">False</property>
+	      <property name="spacing">6</property>
+
+	      <child>
+		<widget class="GtkLabel" id="gatewayLabel">
+		  <property name="visible">True</property>
+		  <property name="label" translatable="yes" context="yes">&lt;b&gt;Gateway:&lt;/b&gt;</property>
+		  <property name="use_underline">False</property>
+		  <property name="use_markup">True</property>
+		  <property name="justify">GTK_JUSTIFY_LEFT</property>
+		  <property name="wrap">False</property>
+		  <property name="selectable">False</property>
+		  <property name="xalign">0</property>
+		  <property name="yalign">0.5</property>
+		  <property name="xpad">0</property>
+		  <property name="ypad">0</property>
+		  <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+		  <property name="width_chars">-1</property>
+		  <property name="single_line_mode">False</property>
+		  <property name="angle">0</property>
+		</widget>
+		<packing>
+		  <property name="padding">0</property>
+		  <property name="expand">False</property>
+		  <property name="fill">True</property>
+		</packing>
+	      </child>
+
+	      <child>
+		<widget class="GtkEntry" id="gatewayEntry">
+		  <property name="visible">True</property>
+		  <property name="editable">True</property>
+		  <property name="visibility">True</property>
+		  <property name="max_length">0</property>
+		  <property name="text" translatable="yes"></property>
+		  <property name="has_frame">True</property>
+		  <property name="invisible_char">â?¢</property>
+		  <property name="activates_default">False</property>
+		  <property name="width_chars">41</property>
+		</widget>
+		<packing>
+		  <property name="padding">0</property>
+		  <property name="expand">False</property>
+		  <property name="fill">True</property>
+		</packing>
+	      </child>
+	    </widget>
+	    <packing>
+	      <property name="padding">0</property>
+	      <property name="expand">True</property>
+	      <property name="fill">True</property>
+	    </packing>
+	  </child>
+
+	  <child>
+	    <widget class="GtkHBox" id="nameserverBox">
+	      <property name="visible">True</property>
+	      <property name="homogeneous">False</property>
+	      <property name="spacing">6</property>
+
+	      <child>
+		<widget class="GtkLabel" id="nameserverLabel">
+		  <property name="visible">True</property>
+		  <property name="label" translatable="yes" context="yes">&lt;b&gt;Nameserver:&lt;/b&gt;</property>
+		  <property name="use_underline">False</property>
+		  <property name="use_markup">True</property>
+		  <property name="justify">GTK_JUSTIFY_LEFT</property>
+		  <property name="wrap">False</property>
+		  <property name="selectable">False</property>
+		  <property name="xalign">0</property>
+		  <property name="yalign">0.5</property>
+		  <property name="xpad">0</property>
+		  <property name="ypad">0</property>
+		  <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+		  <property name="width_chars">-1</property>
+		  <property name="single_line_mode">False</property>
+		  <property name="angle">0</property>
+		</widget>
+		<packing>
+		  <property name="padding">0</property>
+		  <property name="expand">False</property>
+		  <property name="fill">True</property>
+		</packing>
+	      </child>
+
+	      <child>
+		<widget class="GtkEntry" id="nameserverEntry">
+		  <property name="visible">True</property>
+		  <property name="editable">True</property>
+		  <property name="visibility">True</property>
+		  <property name="max_length">0</property>
+		  <property name="text" translatable="yes"></property>
+		  <property name="has_frame">True</property>
+		  <property name="invisible_char">â?¢</property>
+		  <property name="activates_default">False</property>
+		  <property name="width_chars">41</property>
+		</widget>
+		<packing>
+		  <property name="padding">0</property>
+		  <property name="expand">False</property>
+		  <property name="fill">True</property>
+		</packing>
+	      </child>
+	    </widget>
+	    <packing>
+	      <property name="padding">0</property>
+	      <property name="expand">True</property>
+	      <property name="fill">True</property>
+	    </packing>
+	  </child>
+
+	  <child>
+	    <placeholder/>
+	  </child>
+	</widget>
+	<packing>
+	  <property name="padding">0</property>
+	  <property name="expand">True</property>
+	  <property name="fill">True</property>
+	</packing>
+      </child>
+    </widget>
+  </child>
+</widget>
+
+</glade-interface>
diff --git a/data/ui/network.glade b/data/ui/network.glade
new file mode 100644
index 0000000..1f17e2f
--- /dev/null
+++ b/data/ui/network.glade
@@ -0,0 +1,259 @@
+<?xml version="1.0" standalone="no"?> <!--*- mode: xml -*-->
+<!DOCTYPE glade-interface SYSTEM "http://glade.gnome.org/glade-2.0.dtd";>
+
+<glade-interface>
+
+<widget class="GtkWindow" id="network_window">
+  <property name="border_width">18</property>
+  <property name="title" translatable="yes" context="yes"></property>
+  <property name="type">GTK_WINDOW_TOPLEVEL</property>
+  <property name="window_position">GTK_WIN_POS_NONE</property>
+  <property name="modal">False</property>
+  <property name="resizable">True</property>
+  <property name="destroy_with_parent">False</property>
+  <property name="decorated">True</property>
+  <property name="skip_taskbar_hint">False</property>
+  <property name="skip_pager_hint">False</property>
+  <property name="type_hint">GDK_WINDOW_TYPE_HINT_NORMAL</property>
+  <property name="gravity">GDK_GRAVITY_NORTH_WEST</property>
+  <property name="focus_on_map">True</property>
+  <property name="urgency_hint">False</property>
+
+  <child>
+    <widget class="GtkAlignment" id="network_align">
+      <property name="width_request">400</property>
+      <property name="visible">True</property>
+      <property name="xalign">0</property>
+      <property name="yalign">0</property>
+      <property name="xscale">1</property>
+      <property name="yscale">1</property>
+      <property name="top_padding">0</property>
+      <property name="bottom_padding">0</property>
+      <property name="left_padding">0</property>
+      <property name="right_padding">0</property>
+
+      <child>
+	<widget class="GtkVBox" id="account_box">
+	  <property name="border_width">5</property>
+	  <property name="visible">True</property>
+	  <property name="homogeneous">False</property>
+	  <property name="spacing">10</property>
+
+	  <child>
+	    <widget class="GtkAlignment" id="alignment2">
+	      <property name="visible">True</property>
+	      <property name="xalign">0</property>
+	      <property name="yalign">0</property>
+	      <property name="xscale">1</property>
+	      <property name="yscale">1</property>
+	      <property name="top_padding">0</property>
+	      <property name="bottom_padding">0</property>
+	      <property name="left_padding">0</property>
+	      <property name="right_padding">0</property>
+
+	      <child>
+		<widget class="GtkHBox" id="desc_box">
+		  <property name="visible">True</property>
+		  <property name="homogeneous">False</property>
+		  <property name="spacing">0</property>
+
+		  <child>
+		    <widget class="GtkImage" id="icon">
+		      <property name="visible">True</property>
+		      <property name="xalign">0.5</property>
+		      <property name="yalign">0.5</property>
+		      <property name="xpad">10</property>
+		      <property name="ypad">0</property>
+		    </widget>
+		    <packing>
+		      <property name="padding">0</property>
+		      <property name="expand">False</property>
+		      <property name="fill">False</property>
+		    </packing>
+		  </child>
+
+		  <child>
+		    <widget class="GtkLabel" id="desc">
+		      <property name="visible">True</property>
+		      <property name="label" translatable="yes">Please name this computer.  The hostname identifies the computer on a network.</property>
+		      <property name="use_underline">False</property>
+		      <property name="use_markup">False</property>
+		      <property name="justify">GTK_JUSTIFY_LEFT</property>
+		      <property name="wrap">True</property>
+		      <property name="selectable">False</property>
+		      <property name="xalign">0</property>
+		      <property name="yalign">0.5</property>
+		      <property name="xpad">0</property>
+		      <property name="ypad">0</property>
+		      <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+		      <property name="width_chars">-1</property>
+		      <property name="single_line_mode">False</property>
+		      <property name="angle">0</property>
+		    </widget>
+		    <packing>
+		      <property name="padding">0</property>
+		      <property name="expand">False</property>
+		      <property name="fill">False</property>
+		    </packing>
+		  </child>
+		</widget>
+	      </child>
+	    </widget>
+	    <packing>
+	      <property name="padding">0</property>
+	      <property name="expand">False</property>
+	      <property name="fill">False</property>
+	    </packing>
+	  </child>
+
+	  <child>
+	    <widget class="GtkAlignment" id="alignment4">
+	      <property name="visible">True</property>
+	      <property name="xalign">0.5</property>
+	      <property name="yalign">0.5</property>
+	      <property name="xscale">1</property>
+	      <property name="yscale">1</property>
+	      <property name="top_padding">0</property>
+	      <property name="bottom_padding">0</property>
+	      <property name="left_padding">0</property>
+	      <property name="right_padding">0</property>
+
+	      <child>
+		<widget class="GtkTable" id="table1">
+		  <property name="width_request">365</property>
+		  <property name="visible">True</property>
+		  <property name="n_rows">1</property>
+		  <property name="n_columns">2</property>
+		  <property name="homogeneous">False</property>
+		  <property name="row_spacing">5</property>
+		  <property name="column_spacing">5</property>
+
+		  <child>
+		    <widget class="GtkLabel" id="hostnameLabel">
+		      <property name="visible">True</property>
+		      <property name="label" translatable="yes">Hostname:</property>
+		      <property name="use_underline">False</property>
+		      <property name="use_markup">True</property>
+		      <property name="justify">GTK_JUSTIFY_LEFT</property>
+		      <property name="wrap">False</property>
+		      <property name="selectable">False</property>
+		      <property name="xalign">0</property>
+		      <property name="yalign">0.5</property>
+		      <property name="xpad">0</property>
+		      <property name="ypad">0</property>
+		      <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+		      <property name="width_chars">-1</property>
+		      <property name="single_line_mode">False</property>
+		      <property name="angle">0</property>
+		    </widget>
+		    <packing>
+		      <property name="left_attach">0</property>
+		      <property name="right_attach">1</property>
+		      <property name="top_attach">0</property>
+		      <property name="bottom_attach">1</property>
+		      <property name="x_options">fill</property>
+		      <property name="y_options"></property>
+		    </packing>
+		  </child>
+
+		  <child>
+		    <widget class="GtkEntry" id="hostnameEntry">
+		      <property name="width_request">256</property>
+		      <property name="visible">True</property>
+		      <property name="can_focus">True</property>
+		      <property name="has_focus">True</property>
+		      <property name="editable">True</property>
+		      <property name="visibility">True</property>
+		      <property name="max_length">255</property>
+		      <property name="text" translatable="yes"></property>
+		      <property name="has_frame">True</property>
+		      <property name="invisible_char">â?¢</property>
+		      <property name="activates_default">True</property>
+		    </widget>
+		    <packing>
+		      <property name="left_attach">1</property>
+		      <property name="right_attach">2</property>
+		      <property name="top_attach">0</property>
+		      <property name="bottom_attach">1</property>
+		      <property name="x_options">fill</property>
+		      <property name="y_options"></property>
+		    </packing>
+		  </child>
+		</widget>
+	      </child>
+	    </widget>
+	    <packing>
+	      <property name="padding">0</property>
+	      <property name="expand">False</property>
+	      <property name="fill">False</property>
+	    </packing>
+	  </child>
+
+	  <child>
+	    <widget class="GtkAlignment" id="alignment5">
+	      <property name="visible">True</property>
+	      <property name="xalign">0.5</property>
+	      <property name="yalign">0.5</property>
+	      <property name="xscale">1</property>
+	      <property name="yscale">1</property>
+	      <property name="top_padding">0</property>
+	      <property name="bottom_padding">0</property>
+	      <property name="left_padding">0</property>
+	      <property name="right_padding">209</property>
+
+	      <child>
+		<placeholder/>
+	      </child>
+	    </widget>
+	    <packing>
+	      <property name="padding">0</property>
+	      <property name="expand">True</property>
+	      <property name="fill">True</property>
+	    </packing>
+	  </child>
+
+	  <child>
+	    <widget class="GtkAlignment" id="alignment6">
+	      <property name="visible">True</property>
+	      <property name="xalign">0.5</property>
+	      <property name="yalign">0.5</property>
+	      <property name="xscale">1</property>
+	      <property name="yscale">1</property>
+	      <property name="top_padding">0</property>
+	      <property name="bottom_padding">0</property>
+	      <property name="left_padding">0</property>
+	      <property name="right_padding">0</property>
+
+	      <child>
+		<widget class="GtkHButtonBox" id="hbuttonbox2">
+		  <property name="visible">True</property>
+		  <property name="layout_style">GTK_BUTTONBOX_START</property>
+		  <property name="spacing">0</property>
+
+		  <child>
+		    <widget class="GtkButton" id="netconfButton">
+		      <property name="visible">True</property>
+		      <property name="can_default">True</property>
+		      <property name="can_focus">True</property>
+		      <property name="label" translatable="yes">Configure Network</property>
+		      <property name="use_underline">True</property>
+		      <property name="relief">GTK_RELIEF_NORMAL</property>
+		      <property name="focus_on_click">True</property>
+		    </widget>
+		  </child>
+		</widget>
+	      </child>
+	    </widget>
+	    <packing>
+	      <property name="padding">0</property>
+	      <property name="expand">False</property>
+	      <property name="fill">False</property>
+	    </packing>
+	  </child>
+	</widget>
+      </child>
+    </widget>
+  </child>
+</widget>
+
+</glade-interface>
diff --git a/data/ui/tasksel.glade b/data/ui/tasksel.glade
new file mode 100644
index 0000000..3c280aa
--- /dev/null
+++ b/data/ui/tasksel.glade
@@ -0,0 +1,335 @@
+<?xml version="1.0" standalone="no"?> <!--*- mode: xml -*-->
+<!DOCTYPE glade-interface SYSTEM "http://glade.gnome.org/glade-2.0.dtd";>
+
+<glade-interface>
+
+<widget class="GtkWindow" id="window1">
+  <property name="visible">True</property>
+  <property name="title" translatable="yes" context="yes"></property>
+  <property name="type">GTK_WINDOW_TOPLEVEL</property>
+  <property name="window_position">GTK_WIN_POS_NONE</property>
+  <property name="modal">False</property>
+  <property name="default_width">440</property>
+  <property name="default_height">250</property>
+  <property name="resizable">True</property>
+  <property name="destroy_with_parent">False</property>
+  <property name="decorated">True</property>
+  <property name="skip_taskbar_hint">False</property>
+  <property name="skip_pager_hint">False</property>
+  <property name="type_hint">GDK_WINDOW_TYPE_HINT_NORMAL</property>
+  <property name="gravity">GDK_GRAVITY_NORTH_WEST</property>
+  <property name="focus_on_map">True</property>
+  <property name="urgency_hint">False</property>
+
+  <child>
+    <widget class="GtkVBox" id="taskBox">
+      <property name="border_width">12</property>
+      <property name="visible">True</property>
+      <property name="homogeneous">False</property>
+      <property name="spacing">18</property>
+
+      <child>
+	<widget class="GtkLabel" id="mainLabel">
+	  <property name="width_request">600</property>
+	  <property name="visible">True</property>
+	  <property name="label" translatable="yes" context="yes">The default installation of %s includes a set of software applicable for general internet usage.  What additional tasks would you like your system to support?</property>
+	  <property name="use_underline">False</property>
+	  <property name="use_markup">False</property>
+	  <property name="justify">GTK_JUSTIFY_LEFT</property>
+	  <property name="wrap">True</property>
+	  <property name="selectable">False</property>
+	  <property name="xalign">0</property>
+	  <property name="yalign">0</property>
+	  <property name="xpad">0</property>
+	  <property name="ypad">0</property>
+	  <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+	  <property name="width_chars">-1</property>
+	  <property name="single_line_mode">False</property>
+	  <property name="angle">0</property>
+	</widget>
+	<packing>
+	  <property name="padding">0</property>
+	  <property name="expand">False</property>
+	  <property name="fill">False</property>
+	</packing>
+      </child>
+
+      <child>
+	<widget class="GtkVBox" id="cbVBox">
+	  <property name="visible">True</property>
+	  <property name="homogeneous">False</property>
+	  <property name="spacing">6</property>
+
+	  <child>
+	    <widget class="GtkScrolledWindow" id="taskSW">
+	      <property name="visible">True</property>
+	      <property name="can_focus">True</property>
+	      <property name="hscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
+	      <property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
+	      <property name="shadow_type">GTK_SHADOW_IN</property>
+	      <property name="window_placement">GTK_CORNER_TOP_LEFT</property>
+
+	      <child>
+		<widget class="GtkTreeView" id="taskList">
+		  <property name="visible">True</property>
+		  <property name="can_focus">True</property>
+		  <property name="headers_visible">False</property>
+		  <property name="rules_hint">False</property>
+		  <property name="reorderable">False</property>
+		  <property name="enable_search">False</property>
+		  <property name="fixed_height_mode">False</property>
+		  <property name="hover_selection">False</property>
+		  <property name="hover_expand">False</property>
+		</widget>
+	      </child>
+	    </widget>
+	    <packing>
+	      <property name="padding">0</property>
+	      <property name="expand">True</property>
+	      <property name="fill">True</property>
+	    </packing>
+	  </child>
+	</widget>
+	<packing>
+	  <property name="padding">0</property>
+	  <property name="expand">True</property>
+	  <property name="fill">True</property>
+	</packing>
+      </child>
+
+      <child>
+	<widget class="GtkVBox" id="customizeBox">
+	  <property name="visible">True</property>
+	  <property name="homogeneous">False</property>
+	  <property name="spacing">6</property>
+
+	  <child>
+	    <widget class="GtkLabel" id="label2">
+	      <property name="width_request">600</property>
+	      <property name="visible">True</property>
+	      <property name="label" translatable="yes" context="yes">You can further customize the software selection now, or after install via the software management application.</property>
+	      <property name="use_underline">False</property>
+	      <property name="use_markup">False</property>
+	      <property name="justify">GTK_JUSTIFY_LEFT</property>
+	      <property name="wrap">True</property>
+	      <property name="selectable">False</property>
+	      <property name="xalign">0</property>
+	      <property name="yalign">0.5</property>
+	      <property name="xpad">0</property>
+	      <property name="ypad">0</property>
+	      <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+	      <property name="width_chars">-1</property>
+	      <property name="single_line_mode">False</property>
+	      <property name="angle">0</property>
+	    </widget>
+	    <packing>
+	      <property name="padding">0</property>
+	      <property name="expand">True</property>
+	      <property name="fill">True</property>
+	    </packing>
+	  </child>
+
+	  <child>
+	    <widget class="GtkHBox" id="hbox1">
+	      <property name="visible">True</property>
+	      <property name="homogeneous">False</property>
+	      <property name="spacing">24</property>
+
+	      <child>
+		<widget class="GtkRadioButton" id="laterRadio">
+		  <property name="visible">True</property>
+		  <property name="label" translatable="yes" context="yes">Customize _later</property>
+		  <property name="use_underline">True</property>
+		  <property name="relief">GTK_RELIEF_NORMAL</property>
+		  <property name="focus_on_click">True</property>
+		  <property name="active">False</property>
+		  <property name="inconsistent">False</property>
+		  <property name="draw_indicator">True</property>
+		</widget>
+		<packing>
+		  <property name="padding">0</property>
+		  <property name="expand">False</property>
+		  <property name="fill">False</property>
+		</packing>
+	      </child>
+
+	      <child>
+		<widget class="GtkRadioButton" id="customRadio">
+		  <property name="visible">True</property>
+		  <property name="label" translatable="yes" context="yes">_Customize now</property>
+		  <property name="use_underline">True</property>
+		  <property name="relief">GTK_RELIEF_NORMAL</property>
+		  <property name="focus_on_click">True</property>
+		  <property name="active">False</property>
+		  <property name="inconsistent">False</property>
+		  <property name="draw_indicator">True</property>
+		  <property name="group">laterRadio</property>
+		</widget>
+		<packing>
+		  <property name="padding">0</property>
+		  <property name="expand">False</property>
+		  <property name="fill">False</property>
+		</packing>
+	      </child>
+	    </widget>
+	    <packing>
+	      <property name="padding">0</property>
+	      <property name="expand">True</property>
+	      <property name="fill">True</property>
+	    </packing>
+	  </child>
+	</widget>
+	<packing>
+	  <property name="padding">0</property>
+	  <property name="expand">False</property>
+	  <property name="fill">False</property>
+	  <property name="pack_type">GTK_PACK_END</property>
+	</packing>
+      </child>
+
+      <child>
+	<widget class="GtkVBox" id="addRepoBox">
+	  <property name="visible">True</property>
+	  <property name="homogeneous">False</property>
+	  <property name="spacing">6</property>
+
+	  <child>
+	    <widget class="GtkLabel" id="label4">
+	      <property name="width_request">600</property>
+	      <property name="visible">True</property>
+	      <property name="label" translatable="yes">Please select any additional repositories that you want to use for software installation.</property>
+	      <property name="use_underline">False</property>
+	      <property name="use_markup">False</property>
+	      <property name="justify">GTK_JUSTIFY_LEFT</property>
+	      <property name="wrap">True</property>
+	      <property name="selectable">False</property>
+	      <property name="xalign">0</property>
+	      <property name="yalign">0.5</property>
+	      <property name="xpad">0</property>
+	      <property name="ypad">0</property>
+	      <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+	      <property name="width_chars">-1</property>
+	      <property name="single_line_mode">False</property>
+	      <property name="angle">0</property>
+	    </widget>
+	    <packing>
+	      <property name="padding">0</property>
+	      <property name="expand">True</property>
+	      <property name="fill">True</property>
+	    </packing>
+	  </child>
+
+	  <child>
+	    <widget class="GtkScrolledWindow" id="repoSW">
+	      <property name="visible">True</property>
+	      <property name="can_focus">True</property>
+	      <property name="hscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
+	      <property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
+	      <property name="shadow_type">GTK_SHADOW_IN</property>
+	      <property name="window_placement">GTK_CORNER_TOP_LEFT</property>
+
+	      <child>
+		<widget class="GtkTreeView" id="repoList">
+		  <property name="visible">True</property>
+		  <property name="can_focus">True</property>
+		  <property name="headers_visible">False</property>
+		  <property name="rules_hint">False</property>
+		  <property name="reorderable">False</property>
+		  <property name="enable_search">False</property>
+		  <property name="fixed_height_mode">False</property>
+		  <property name="hover_selection">False</property>
+		  <property name="hover_expand">False</property>
+		</widget>
+	      </child>
+	    </widget>
+	    <packing>
+	      <property name="padding">0</property>
+	      <property name="expand">False</property>
+	      <property name="fill">False</property>
+	    </packing>
+	  </child>
+
+	  <child>
+	    <widget class="GtkHButtonBox" id="hbuttonbox1">
+	      <property name="visible">True</property>
+	      <property name="layout_style">GTK_BUTTONBOX_START</property>
+	      <property name="spacing">5</property>
+
+	      <child>
+		<widget class="GtkButton" id="addRepoButton">
+		  <property name="visible">True</property>
+		  <property name="can_default">True</property>
+		  <property name="can_focus">True</property>
+		  <property name="relief">GTK_RELIEF_NORMAL</property>
+		  <property name="focus_on_click">True</property>
+
+		  <child>
+		    <widget class="GtkLabel" id="label5">
+		      <property name="visible">True</property>
+		      <property name="label" translatable="yes">_Add additional software repositories</property>
+		      <property name="use_underline">True</property>
+		      <property name="use_markup">False</property>
+		      <property name="justify">GTK_JUSTIFY_LEFT</property>
+		      <property name="wrap">False</property>
+		      <property name="selectable">False</property>
+		      <property name="xalign">0.5</property>
+		      <property name="yalign">0.5</property>
+		      <property name="xpad">0</property>
+		      <property name="ypad">0</property>
+		      <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+		      <property name="width_chars">-1</property>
+		      <property name="single_line_mode">False</property>
+		      <property name="angle">0</property>
+		    </widget>
+		  </child>
+		</widget>
+	      </child>
+
+	      <child>
+		<widget class="GtkButton" id="editRepoButton">
+		  <property name="visible">True</property>
+		  <property name="can_default">True</property>
+		  <property name="can_focus">True</property>
+		  <property name="relief">GTK_RELIEF_NORMAL</property>
+		  <property name="focus_on_click">True</property>
+
+		  <child>
+		    <widget class="GtkLabel" id="label6">
+		      <property name="visible">True</property>
+		      <property name="label" translatable="yes">_Modify repository</property>
+		      <property name="use_underline">True</property>
+		      <property name="use_markup">False</property>
+		      <property name="justify">GTK_JUSTIFY_LEFT</property>
+		      <property name="wrap">False</property>
+		      <property name="selectable">False</property>
+		      <property name="xalign">0.5</property>
+		      <property name="yalign">0.5</property>
+		      <property name="xpad">0</property>
+		      <property name="ypad">0</property>
+		      <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+		      <property name="width_chars">-1</property>
+		      <property name="single_line_mode">False</property>
+		      <property name="angle">0</property>
+		    </widget>
+		  </child>
+		</widget>
+	      </child>
+	    </widget>
+	    <packing>
+	      <property name="padding">0</property>
+	      <property name="expand">False</property>
+	      <property name="fill">False</property>
+	    </packing>
+	  </child>
+	</widget>
+	<packing>
+	  <property name="padding">0</property>
+	  <property name="expand">False</property>
+	  <property name="fill">False</property>
+	</packing>
+      </child>
+    </widget>
+  </child>
+</widget>
+
+</glade-interface>
diff --git a/data/ui/zfcp-config.glade b/data/ui/zfcp-config.glade
new file mode 100644
index 0000000..8a09673
--- /dev/null
+++ b/data/ui/zfcp-config.glade
@@ -0,0 +1,276 @@
+<?xml version="1.0" standalone="no"?> <!--*- mode: xml -*-->
+<!DOCTYPE glade-interface SYSTEM "http://glade.gnome.org/glade-2.0.dtd";>
+
+<glade-interface>
+
+<widget class="GtkDialog" id="zfcpDialog">
+  <property name="title" translatable="yes">Add FCP device</property>
+  <property name="type">GTK_WINDOW_TOPLEVEL</property>
+  <property name="window_position">GTK_WIN_POS_CENTER</property>
+  <property name="modal">False</property>
+  <property name="resizable">True</property>
+  <property name="destroy_with_parent">False</property>
+  <property name="decorated">True</property>
+  <property name="skip_taskbar_hint">False</property>
+  <property name="skip_pager_hint">False</property>
+  <property name="type_hint">GDK_WINDOW_TYPE_HINT_DIALOG</property>
+  <property name="gravity">GDK_GRAVITY_NORTH_WEST</property>
+  <property name="focus_on_map">True</property>
+  <property name="urgency_hint">False</property>
+  <property name="has_separator">True</property>
+
+  <child internal-child="vbox">
+    <widget class="GtkVBox" id="dialog-vbox1">
+      <property name="visible">True</property>
+      <property name="homogeneous">False</property>
+      <property name="spacing">0</property>
+
+      <child internal-child="action_area">
+	<widget class="GtkHButtonBox" id="dialog-action_area1">
+	  <property name="visible">True</property>
+	  <property name="layout_style">GTK_BUTTONBOX_END</property>
+
+	  <child>
+	    <widget class="GtkButton" id="button1">
+	      <property name="visible">True</property>
+	      <property name="can_default">True</property>
+	      <property name="can_focus">True</property>
+	      <property name="label">gtk-cancel</property>
+	      <property name="use_stock">True</property>
+	      <property name="relief">GTK_RELIEF_NORMAL</property>
+	      <property name="focus_on_click">True</property>
+	      <property name="response_id">-6</property>
+	    </widget>
+	  </child>
+
+	  <child>
+	    <widget class="GtkButton" id="button2">
+	      <property name="visible">True</property>
+	      <property name="can_default">True</property>
+	      <property name="can_focus">True</property>
+	      <property name="label">gtk-add</property>
+	      <property name="use_stock">True</property>
+	      <property name="relief">GTK_RELIEF_NORMAL</property>
+	      <property name="focus_on_click">True</property>
+	      <property name="response_id">-10</property>
+	    </widget>
+	  </child>
+	</widget>
+	<packing>
+	  <property name="padding">0</property>
+	  <property name="expand">False</property>
+	  <property name="fill">True</property>
+	  <property name="pack_type">GTK_PACK_END</property>
+	</packing>
+      </child>
+
+      <child>
+	<widget class="GtkVBox" id="vbox1">
+	  <property name="border_width">12</property>
+	  <property name="visible">True</property>
+	  <property name="homogeneous">False</property>
+	  <property name="spacing">12</property>
+
+	  <child>
+	    <widget class="GtkLabel" id="label8">
+	      <property name="visible">True</property>
+	      <property name="label" translatable="yes">zSeries machines can access industry-standard SCSI devices via Fibre Channel (FCP). You need to provide a 16 bit device number, a 64 bit World Wide Port Name (WWPN), and a 64 bit FCP LUN for each device.</property>
+	      <property name="use_underline">False</property>
+	      <property name="use_markup">False</property>
+	      <property name="justify">GTK_JUSTIFY_LEFT</property>
+	      <property name="wrap">True</property>
+	      <property name="selectable">False</property>
+	      <property name="xalign">0.5</property>
+	      <property name="yalign">0.5</property>
+	      <property name="xpad">0</property>
+	      <property name="ypad">0</property>
+	      <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+	      <property name="width_chars">-1</property>
+	      <property name="single_line_mode">False</property>
+	      <property name="angle">0</property>
+	    </widget>
+	    <packing>
+	      <property name="padding">0</property>
+	      <property name="expand">False</property>
+	      <property name="fill">False</property>
+	    </packing>
+	  </child>
+
+	  <child>
+	    <widget class="GtkTable" id="zfcpTable">
+	      <property name="border_width">12</property>
+	      <property name="visible">True</property>
+	      <property name="n_rows">3</property>
+	      <property name="n_columns">2</property>
+	      <property name="homogeneous">False</property>
+	      <property name="row_spacing">6</property>
+	      <property name="column_spacing">6</property>
+
+	      <child>
+		<widget class="GtkLabel" id="devnumLabel">
+		  <property name="visible">True</property>
+		  <property name="label" translatable="yes">&lt;b&gt;Device number:&lt;/b&gt;</property>
+		  <property name="use_underline">True</property>
+		  <property name="use_markup">True</property>
+		  <property name="justify">GTK_JUSTIFY_LEFT</property>
+		  <property name="wrap">False</property>
+		  <property name="selectable">False</property>
+		  <property name="xalign">0</property>
+		  <property name="yalign">0.5</property>
+		  <property name="xpad">0</property>
+		  <property name="ypad">0</property>
+		  <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+		  <property name="width_chars">-1</property>
+		  <property name="single_line_mode">False</property>
+		  <property name="angle">0</property>
+		</widget>
+		<packing>
+		  <property name="left_attach">0</property>
+		  <property name="right_attach">1</property>
+		  <property name="top_attach">0</property>
+		  <property name="bottom_attach">1</property>
+		  <property name="x_options">fill</property>
+		  <property name="y_options"></property>
+		</packing>
+	      </child>
+
+	      <child>
+		<widget class="GtkEntry" id="devnumEntry">
+		  <property name="visible">True</property>
+		  <property name="can_focus">True</property>
+		  <property name="editable">True</property>
+		  <property name="visibility">True</property>
+		  <property name="max_length">0</property>
+		  <property name="text" translatable="yes"></property>
+		  <property name="has_frame">True</property>
+		  <property name="invisible_char">â?¢</property>
+		  <property name="activates_default">False</property>
+		</widget>
+		<packing>
+		  <property name="left_attach">1</property>
+		  <property name="right_attach">2</property>
+		  <property name="top_attach">0</property>
+		  <property name="bottom_attach">1</property>
+		  <property name="x_options"></property>
+		  <property name="y_options"></property>
+		</packing>
+	      </child>
+
+	      <child>
+		<widget class="GtkLabel" id="wwwpnLabel">
+		  <property name="visible">True</property>
+		  <property name="label" translatable="yes">&lt;b&gt;WWPN:&lt;/b&gt;</property>
+		  <property name="use_underline">True</property>
+		  <property name="use_markup">True</property>
+		  <property name="justify">GTK_JUSTIFY_LEFT</property>
+		  <property name="wrap">False</property>
+		  <property name="selectable">False</property>
+		  <property name="xalign">0</property>
+		  <property name="yalign">0.5</property>
+		  <property name="xpad">0</property>
+		  <property name="ypad">0</property>
+		  <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+		  <property name="width_chars">-1</property>
+		  <property name="single_line_mode">False</property>
+		  <property name="angle">0</property>
+		</widget>
+		<packing>
+		  <property name="left_attach">0</property>
+		  <property name="right_attach">1</property>
+		  <property name="top_attach">1</property>
+		  <property name="bottom_attach">2</property>
+		  <property name="x_options">fill</property>
+		  <property name="y_options"></property>
+		</packing>
+	      </child>
+
+	      <child>
+		<widget class="GtkEntry" id="wwpnEntry">
+		  <property name="visible">True</property>
+		  <property name="can_focus">True</property>
+		  <property name="editable">True</property>
+		  <property name="visibility">True</property>
+		  <property name="max_length">0</property>
+		  <property name="text" translatable="yes"></property>
+		  <property name="has_frame">True</property>
+		  <property name="invisible_char">*</property>
+		  <property name="activates_default">False</property>
+		</widget>
+		<packing>
+		  <property name="left_attach">1</property>
+		  <property name="right_attach">2</property>
+		  <property name="top_attach">1</property>
+		  <property name="bottom_attach">2</property>
+		  <property name="x_options"></property>
+		  <property name="y_options"></property>
+		</packing>
+	      </child>
+
+	      <child>
+		<widget class="GtkLabel" id="fcplunLabel">
+		  <property name="visible">True</property>
+		  <property name="label" translatable="yes">&lt;b&gt;FCP LUN:&lt;/b&gt;</property>
+		  <property name="use_underline">True</property>
+		  <property name="use_markup">True</property>
+		  <property name="justify">GTK_JUSTIFY_LEFT</property>
+		  <property name="wrap">False</property>
+		  <property name="selectable">False</property>
+		  <property name="xalign">0</property>
+		  <property name="yalign">0.5</property>
+		  <property name="xpad">0</property>
+		  <property name="ypad">0</property>
+		  <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+		  <property name="width_chars">-1</property>
+		  <property name="single_line_mode">False</property>
+		  <property name="angle">0</property>
+		</widget>
+		<packing>
+		  <property name="left_attach">0</property>
+		  <property name="right_attach">1</property>
+		  <property name="top_attach">2</property>
+		  <property name="bottom_attach">3</property>
+		  <property name="x_options">fill</property>
+		  <property name="y_options"></property>
+		</packing>
+	      </child>
+
+	      <child>
+		<widget class="GtkEntry" id="fcplunEntry">
+		  <property name="visible">True</property>
+		  <property name="can_focus">True</property>
+		  <property name="editable">True</property>
+		  <property name="visibility">True</property>
+		  <property name="max_length">0</property>
+		  <property name="text" translatable="yes"></property>
+		  <property name="has_frame">True</property>
+		  <property name="invisible_char">*</property>
+		  <property name="activates_default">False</property>
+		</widget>
+		<packing>
+		  <property name="left_attach">1</property>
+		  <property name="right_attach">2</property>
+		  <property name="top_attach">2</property>
+		  <property name="bottom_attach">3</property>
+		  <property name="x_options"></property>
+		  <property name="y_options"></property>
+		</packing>
+	      </child>
+	    </widget>
+	    <packing>
+	      <property name="padding">0</property>
+	      <property name="expand">True</property>
+	      <property name="fill">True</property>
+	    </packing>
+	  </child>
+	</widget>
+	<packing>
+	  <property name="padding">0</property>
+	  <property name="expand">True</property>
+	  <property name="fill">True</property>
+	</packing>
+      </child>
+    </widget>
+  </child>
+</widget>
+
+</glade-interface>
diff --git a/desktop.py b/desktop.py
deleted file mode 100644
index 49b7bbe..0000000
--- a/desktop.py
+++ /dev/null
@@ -1,71 +0,0 @@
-#
-# desktop.py - install data for default desktop and run level
-#
-# Copyright (C) 2001, 2002  Red Hat, Inc.  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 as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# 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, see <http://www.gnu.org/licenses/>.
-#
-# Author(s): Matt Wilson <msw@xxxxxxxxxx>
-#
-
-import string
-from simpleconfig import SimpleConfigFile
-
-import logging
-log = logging.getLogger("anaconda")
-
-class Desktop (SimpleConfigFile):
-#
-# This class represents the default desktop to run and the default runlevel
-# to start in
-#
-    def setDefaultRunLevel(self, runlevel):
-        if str(runlevel) != "3" and str(runlevel) != "5":
-            raise RuntimeError, "Desktop::setDefaultRunLevel() - Must specify runlevel as 3 or 5!"
-        self.runlevel = runlevel
-
-    def getDefaultRunLevel(self):
-        return self.runlevel
-
-    def setDefaultDesktop(self, desktop):
-        self.info["DESKTOP"] = desktop
-
-    def getDefaultDesktop(self):
-        return self.get("DESKTOP")
-
-    def __init__ (self):
-        SimpleConfigFile.__init__ (self)
-        self.runlevel = 3
-
-    def write (self, instPath):
-        try:
-            inittab = open (instPath + '/etc/inittab', 'r')
-        except IOError:
-            log.warning ("there is no inittab, bad things will happen!")
-            return
-        lines = inittab.readlines ()
-        inittab.close ()
-        inittab = open (instPath + '/etc/inittab', 'w')        
-        for line in lines:
-            if len (line) > 3 and line[:3] == "id:":
-                fields = string.split (line, ':')
-                fields[1] = str (self.runlevel)
-                line = string.join (fields, ':')
-            inittab.write (line)
-        inittab.close ()
-
-        if self.getDefaultDesktop():
-            f = open(instPath + "/etc/sysconfig/desktop", "w")
-            f.write(str (self))
-            f.close()
diff --git a/dispatch.py b/dispatch.py
deleted file mode 100644
index 2f3d787..0000000
--- a/dispatch.py
+++ /dev/null
@@ -1,254 +0,0 @@
-#
-# dispatch.py: install/upgrade master flow control
-#
-# Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006  Red Hat, Inc.
-# 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 as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# 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, see <http://www.gnu.org/licenses/>.
-#
-# Author(s): Erik Troan <ewt@xxxxxxxxxx>
-#
-
-import string
-from types import *
-from constants import *
-from packages import writeKSConfiguration, turnOnFilesystems
-from packages import doPostAction
-from packages import copyAnacondaLogs
-from packages import firstbootConfiguration
-from packages import betaNagScreen
-from packages import setupTimezone
-from packages import setFileCons
-from storage import storageInitialize
-from storage import storageComplete
-from storage.partitioning import doAutoPartition
-from bootloader import writeBootloader, bootloaderSetupChoices
-from flags import flags
-from upgrade import upgradeMountFilesystems
-from upgrade import restoreTime
-from upgrade import upgradeSwapSuggestion, upgradeMigrateFind
-from upgrade import findRootParts, queryUpgradeContinue
-from installmethod import doMethodComplete
-from kickstart import runPostScripts
-
-from backend import doPostSelection, doBackendSetup, doBasePackageSelect
-from backend import doPreInstall, doPostInstall, doInstall
-from backend import writeConfiguration
-
-from packages import doReIPL
-
-import logging
-log = logging.getLogger("anaconda")
-
-# These are all of the install steps, in order. Note that upgrade and
-# install steps are the same thing! Upgrades skip install steps, while
-# installs skip upgrade steps.
-
-#
-# items are one of
-#
-#       ( name )
-#       ( name, Function )
-#
-# in the second case, the function is called directly from the dispatcher
-
-# All install steps take the anaconda object as their sole argument.  This
-# gets passed in when we call the function.
-installSteps = [
-    ("welcome", ),
-    ("language", ),
-    ("keyboard", ),
-    ("betanag", betaNagScreen, ),
-    ("filtertype", ),
-    ("filter", ),
-    ("storageinit", storageInitialize, ),
-    ("findrootparts", findRootParts, ),
-    ("findinstall", ),
-    ("network", ),
-    ("timezone", ),
-    ("accounts", ),
-    ("setuptime", setupTimezone, ),
-    ("parttype", ),
-    ("cleardiskssel", ),
-    ("autopartitionexecute", doAutoPartition, ),
-    ("partition", ),
-    ("upgrademount", upgradeMountFilesystems, ),
-    ("restoretime", restoreTime, ),
-    ("upgradecontinue", queryUpgradeContinue, ),
-    ("upgradeswapsuggestion", upgradeSwapSuggestion, ),
-    ("addswap", ),
-    ("upgrademigfind", upgradeMigrateFind, ),
-    ("upgrademigratefs", ),
-    ("storagedone", storageComplete, ),
-    ("enablefilesystems", turnOnFilesystems, ),
-    ("upgbootloader", ),
-    ("bootloadersetup", bootloaderSetupChoices, ),
-    ("bootloader", ),
-    ("reposetup", doBackendSetup, ),
-    ("tasksel", ),
-    ("basepkgsel", doBasePackageSelect, ),
-    ("group-selection", ),
-    ("postselection", doPostSelection, ),
-    ("reipl", doReIPL, ),
-    ("install", ),
-    ("preinstallconfig", doPreInstall, ),
-    ("installpackages", doInstall, ),
-    ("postinstallconfig", doPostInstall, ),
-    ("writeconfig", writeConfiguration, ),
-    ("firstboot", firstbootConfiguration, ),
-    ("instbootloader", writeBootloader, ),
-    ("writeksconfig", writeKSConfiguration, ),
-    ("setfilecon", setFileCons, ),
-    ("copylogs", copyAnacondaLogs, ),
-    ("methodcomplete", doMethodComplete, ),
-    ("postscripts", runPostScripts, ),
-    ("dopostaction", doPostAction, ),
-    ("complete", ),
-    ]
-
-class Dispatcher(object):
-
-    def gotoPrev(self):
-        self._setDir(DISPATCH_BACK)
-        self.moveStep()
-
-    def gotoNext(self):
-        self._setDir(DISPATCH_FORWARD)
-        self.moveStep()
-
-    def canGoBack(self):
-        # begin with the step before this one.  If all steps are skipped,
-        # we can not go backwards from this screen
-        i = self.step - 1
-        while i >= self.firstStep:
-            if not self.stepIsDirect(i) and not self.skipSteps.has_key(installSteps[i][0]):
-                return True
-            i = i - 1
-        return False
-
-    def setStepList(self, *steps):
-        # only remove non-permanently skipped steps from our skip list
-        for step, state in self.skipSteps.items():
-            if state == 1:
-                del self.skipSteps[step]
-
-        stepExists = {}
-        for step in installSteps:
-            name = step[0]
-            if not name in steps:
-                self.skipSteps[name] = 1
-
-            stepExists[name] = 1
-
-        for name in steps:
-            if not stepExists.has_key(name):
-                #XXX: hack for yum support
-                #raise KeyError, ("step %s does not exist" % name)
-                log.warning("step %s does not exist", name)
-
-    def stepInSkipList(self, step):
-        if type(step) == type(1):
-            step = installSteps[step][0]
-        return self.skipSteps.has_key(step)
-
-    def skipStep(self, stepToSkip, skip = 1, permanent = 0):
-        for step in installSteps:
-            name = step[0]
-            if name == stepToSkip:
-                if skip:
-                    if permanent:
-                        self.skipSteps[name] = 2
-                    elif not self.skipSteps.has_key(name):
-                        self.skipSteps[name] = 1
-                elif self.skipSteps.has_key(name):
-                    # if marked as permanent then dont change
-                    if self.skipSteps[name] != 2:
-                        del self.skipSteps[name]
-                return
-
-        #raise KeyError, ("unknown step %s" % stepToSkip)
-        log.warning("step %s does not exist", name)
-
-    def stepIsDirect(self, step):
-        """Takes a step number"""
-        if len(installSteps[step]) == 2:
-            return True
-        else:
-            return False
-
-    def moveStep(self):
-        if self.step == None:
-            self.step = self.firstStep
-        else:
-            log.info("leaving (%d) step %s" %(self._getDir(), installSteps[self.step][0]))
-            self.step = self.step + self._getDir()
-
-        if self.step >= len(installSteps):
-            return None
-
-        while self.step >= self.firstStep and self.step < len(installSteps) \
-            and (self.stepInSkipList(self.step) or self.stepIsDirect(self.step)):
-
-            if self.stepIsDirect(self.step) and not self.stepInSkipList(self.step):
-                (stepName, stepFunc) = installSteps[self.step]
-                log.info("moving (%d) to step %s" %(self._getDir(), stepName))
-                log.debug("%s is a direct step" %(stepName,))
-                rc = stepFunc(self.anaconda)
-                if rc in [DISPATCH_BACK, DISPATCH_FORWARD]:
-                    self._setDir(rc)
-                log.info("leaving (%d) step %s" %(self._getDir(), stepName))
-                # if anything else, leave self.dir alone
-
-            self.step = self.step + self._getDir()
-            if self.step == len(installSteps):
-                return None
-
-        if (self.step < 0):
-            # pick the first step not in the skip list
-            self.step = 0
-            while self.skipSteps.has_key(installSteps[self.step][0]):
-                self.step = self.step + 1
-        elif self.step >= len(installSteps):
-            self.step = len(installSteps) - 1
-            while self.skipSteps.has_key(installSteps[self.step][0]):
-                self.step = self.step - 1
-        log.info("moving (%d) to step %s" %(self._getDir(), installSteps[self.step][0]))
-
-    def currentStep(self):
-        if self.step == None:
-            self.gotoNext()
-        elif self.step >= len(installSteps):
-            return (None, None)
-
-        stepInfo = installSteps[self.step]
-        step = stepInfo[0]
-
-        return (step, self.anaconda)
-
-    def __init__(self, anaconda):
-        self.anaconda = anaconda
-        self.anaconda.dir = DISPATCH_FORWARD
-        self.step = None
-        self.skipSteps = {}
-
-        self.firstStep = 0
-
-    def _getDir(self):
-        return self.anaconda.dir
-
-    def _setDir(self, dir):
-        self.anaconda.dir = dir
-
-    dir = property(_getDir,_setDir)
-
diff --git a/errors.py b/errors.py
deleted file mode 100644
index 9733733..0000000
--- a/errors.py
+++ /dev/null
@@ -1,159 +0,0 @@
-#
-# errors.py: exception classes used throughout anaconda
-#
-# Copyright (C) 2002, 2007, 2008  Red Hat, Inc.  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 as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# 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, see <http://www.gnu.org/licenses/>.
-#
-# Author(s): Peter Jones <pjones@xxxxxxxxxx>
-#            Chris Lumens <clumens@xxxxxxxxxx>
-#            Matt Wilson <msw@xxxxxxxxxx>
-#            Jeremy Katz <katzj@xxxxxxxxxx>
-#            Mike Fulbright <msf@xxxxxxxxxx>
-#
-
-import string
-import os
-from constants import lvmErrorOutput
-
-# Exceptions for use in lvm operations.
-
-class LvmError(Exception):
-    """An error occurred with lvm."""
-    def __init__(self, command, name=None):
-        self.command = command
-        self.name = name
-        self.log = self.getLvmOutput()
-
-    def getLvmOutput(self):
-        if not os.access(lvmErrorOutput, os.R_OK):
-            return ""
-        f = open(lvmErrorOutput, "r")
-        lines = reduce(lambda x,y: x + [string.strip(y),], f.readlines(), [])
-        lines = string.join(reduce(lambda x,y: x + ["   %s" % (y,)], \
-                                    lines, []), "\n")
-        return lines
-
-    def __str__(self):
-        s = ""
-        if not self.name is None:
-            s = " for device %s" % (self.name,)
-        return "%s failed%s\nLog:\n%s" % (self.command, s, self.log)
-
-class LVCreateError(LvmError):
-    def __init__(self, vgname, lvname, size):
-        self.vgname = vgname
-        self.lvname = lvname
-        self.size = size
-        self.log = self.getLvmOutput()
-
-    def __str__(self):
-        return "lvcreate of %d Megabyte lv \"%s\" on vg \"%s\" failed\n" \
-               "Log:\n%s" % ( \
-            self.size, self.lvname, self.vgname, self.log)
-
-class LVRemoveError(LvmError):
-    def __init__(self, vgname, lvname):
-        self.vgname = vgname
-        self.lvname = lvname
-        self.log = self.getLvmOutput()
-
-    def __str__(self):
-        return "lvremove of lv \"%s\" from vg \"%s\" failed\nLog:\n%s" % ( \
-            self.lvname, self.vgname, self.log)
-
-class LVResizeError(LvmError):
-    def __init__(self, vgname, lvname):
-        self.vgname = vgname
-        self.lvname = lvname
-        self.log = self.getLvmOutput()
-
-    def __str__(self):
-        return "lvresize of lv \"%s\" from vg \"%s\" failed\nLog:\n%s" % ( \
-            self.lvname, self.vgname, self.log)
-
-class VGCreateError(LvmError):
-    def __init__(self, vgname, PESize, nodes):
-        self.vgname = vgname
-        self.PESize = PESize
-        self.nodes = nodes
-        self.log = self.getLvmOutput()
-
-    def __str__(self):
-        nodes = string.join(self.nodes, ' ')
-        return "vgcreate failed creating vg \"%s\" (PESize=%dkB) on PVs: %s\n" \
-               "Log:\n%s" % ( \
-            self.vgname, self.PESize, nodes, self.log)
-
-class VGRemoveError(LvmError):
-    def __init__(self, vgname):
-        self.vgname = vgname
-        self.log = self.getLvmOutput()
-
-    def __str__(self):
-        return "vgremove of vg \"%s\" failed\nLog:\n%s" % ( \
-            self.vgname, self.log)
-
-class PVRemoveError(LvmError):
-    def __init__(self, pvname):
-        self.pvname = pvname
-        self.log = self.getLvmOutput()
-
-    def __str__(self):
-        return "pvremove of pv \"%s\" failed\nLog:\n%s" % ( \
-            self.pvname, self.log)
-
-class PVCreateError(LvmError):
-    def __init__(self, pvname):
-        self.pvname = pvname
-        self.log = self.getLvmOutput()
-
-    def __str__(self):
-        return "pvcreate of pv \"%s\" failed\nLog:\n%s" % ( \
-            self.pvname, self.log)
-
-# Exceptions for use in partitioning.
-
-class PartitioningError(Exception):
-    """A critical error which must be resolved to continue the installation."""
-    def __init__(self, message=""):
-        self.message = str(message)
-
-    def __str__ (self):
-        return self.message
-
-class PartitioningWarning(Exception):
-    """A warning which may be ignored and still complete the installation."""
-    def __init__(self, message=""):
-        self.message = str(message)
-
-    def __str__ (self):
-        return self.message
-
-class LabelError(Exception):
-    """The device could not be labeled."""
-    def __init__(self, message=""):
-        self.message = str(message)
-
-    def __str__(self):
-        return self.message
-
-# Exceptions for use in package selection.
-
-class NoSuchGroup(Exception):
-    def __init__ (self, value):
-        self.value = value
-
-    def __str__ (self):
-        return self.value
diff --git a/exception.py b/exception.py
deleted file mode 100644
index 1075717..0000000
--- a/exception.py
+++ /dev/null
@@ -1,132 +0,0 @@
-#
-# exception.py - general exception formatting and saving
-#
-# Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007  Red Hat, Inc.
-# 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 as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# 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, see <http://www.gnu.org/licenses/>.
-#
-# Author(s): Matt Wilson <msw@xxxxxxxxxx>
-#            Erik Troan <ewt@xxxxxxxxxx>
-#            Chris Lumens <clumens@xxxxxxxxxx>
-#
-from meh.handler import *
-from meh.dump import *
-import isys
-import sys
-import os
-import shutil
-import signal
-from flags import flags
-import kickstart
-
-import logging
-log = logging.getLogger("anaconda")
-
-class AnacondaExceptionHandler(ExceptionHandler):
-    def postWriteHook(self, (ty, value, tb), anaconda):
-        # See if /mnt/sysimage is present and put exception there as well
-        if os.access("/mnt/sysimage/root", os.X_OK):
-            try:
-                dest = "/mnt/sysimage/root/%s" % os.path.basename(self.exnFile)
-                shutil.copyfile(self.exnFile, dest)
-            except:
-                log.error("Failed to copy %s to /mnt/sysimage/root" % self.exnFile)
-                pass
-
-        # run kickstart traceback scripts (if necessary)
-        try:
-            if anaconda.ksdata:
-                kickstart.runTracebackScripts(anaconda)
-        except:
-            pass
-
-    def runDebug(self, (ty, value, tb)):
-        # vtActivate does not work on certain ppc64 machines, so just skip
-        # that and continue with the rest of the debugger setup.
-        try:
-            isys.vtActivate(1)
-        except SystemError:
-            pass
-
-        self.intf.__del__ ()
-
-        pidfl = "/tmp/vncshell.pid"
-        if os.path.exists(pidfl) and os.path.isfile(pidfl):
-            pf = open(pidfl, "r")
-            for pid in pf.readlines():
-                if not int(pid) == os.getpid():
-                    os.kill(int(pid), signal.SIGKILL)
-            pf.close()
-
-        os.open("/dev/console", os.O_RDWR)   # reclaim stdin
-        os.dup2(0, 1)                        # reclaim stdout
-        os.dup2(0, 2)                        # reclaim stderr
-        #   ^
-        #   |
-        #   +------ dup2 is magic, I tells ya!
-
-        # bring back the echo
-        import termios
-        si = sys.stdin.fileno()
-        attr = termios.tcgetattr(si)
-        attr[3] = attr[3] & termios.ECHO
-        termios.tcsetattr(si, termios.TCSADRAIN, attr)
-
-        print("\nEntering debugger...")
-        import pdb
-        pdb.post_mortem (tb)
-        os.kill(os.getpid(), signal.SIGKILL)
-
-def initExceptionHandling(anaconda):
-    fileList = [ "/tmp/anaconda.log", "/tmp/lvmout", "/tmp/resize.out",
-                 "/tmp/program.log", "/tmp/storage.log", "/tmp/yum.log",
-                 anaconda.rootPath + "/root/install.log",
-                 anaconda.rootPath + "/root/upgrade.log", "/proc/cmdline" ]
-    if flags.livecdInstall:
-        fileList.extend(["/var/log/dmesg"])
-    else:
-        fileList.extend(["/tmp/syslog"])
-
-    conf = Config(programName="anaconda",
-                  programVersion=isys.getAnacondaVersion(),
-                  attrSkipList=[ "backend.ayum",
-                                 "backend.dlpkgs",
-                                 "accounts",
-                                 "bootloader.password",
-                                 "comps",
-                                 "dispatch",
-                                 "hdList",
-                                 "ksdata",
-                                 "instLanguage.font",
-                                 "instLanguage.kbd",
-                                 "instLanguage.info",
-                                 "instLanguage.localeInfo",
-                                 "instLanguage.nativeLangNames",
-                                 "instLanguage.tz",
-                                 "keyboard._mods._modelDict",
-                                 "keyboard.modelDict",
-                                 "storage.encryptionPassphrase",
-                                 "users.rootPassword",
-                                 "tmpData",
-                                 "intf.icw.buff",
-                                 "intf.icw.currentWindow.storage.encryptionPassphrase",
-                                 "intf.icw.stockButtons",
-                               ],
-                  localSkipList=[ "passphrase", "password" ],
-                  fileList=fileList)
-    handler = AnacondaExceptionHandler(conf, anaconda.intf, ReverseExceptionDump)
-    handler.install(anaconda)
-
-    return conf
diff --git a/firewall.py b/firewall.py
deleted file mode 100644
index 750d755..0000000
--- a/firewall.py
+++ /dev/null
@@ -1,93 +0,0 @@
-#
-# firewall.py - firewall install data and installation
-#
-# Copyright (C) 2004  Red Hat, Inc.  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 as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# 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, see <http://www.gnu.org/licenses/>.
-#
-# Author(s): Bill Nottingham <notting@xxxxxxxxxx>
-#            Jeremy Katz <katzj@xxxxxxxxxx>
-#
-
-import iutil
-import os.path
-from flags import flags
-from constants import *
-
-import gettext
-_ = lambda x: gettext.ldgettext("anaconda", x)
-
-import logging
-log = logging.getLogger("anaconda")
-
-class Firewall:
-    def __init__ (self):
-	self.enabled = 1
-        self.trustdevs = []
-	self.portlist = []
-        self.servicelist = []
-
-    def writeKS(self, f):
-	f.write("firewall")
-
-        if self.enabled:
-	    for arg in self.getArgList():
-		f.write(" " + arg)
-	else:
-	    f.write(" --disabled")
-
-	f.write("\n")
-
-    def getArgList(self):
-	args = []
-
-        if not self.enabled:
-            args.append("--disabled")
-            return args
-
-        if not "ssh" in self.servicelist and not "22:tcp" in self.portlist:
-            args += ["--service=ssh"]
-
-        for dev in self.trustdevs:
-            args = args + [ "--trust=%s" %(dev,) ]
-
-	for port in self.portlist:
-	    args = args + [ "--port=%s" %(port,) ]
-
-        for service in self.servicelist:
-            args = args + [ "--service=%s" % (service,) ]
-
-	return args
-
-    def write (self, instPath):
-	args = [ "--quiet", "--nostart", "-f" ] + self.getArgList()
-
-        try:
-            if not os.path.exists("%s/etc/sysconfig/iptables" %(instPath,)):
-                iutil.execWithRedirect("/usr/sbin/lokkit", args,
-                                       root=instPath, stdout="/dev/null",
-                                       stderr="/dev/null")
-            else:
-                log.error("would have run %s", args)
-        except RuntimeError, msg:
-            log.error ("lokkit run failed: %s", msg)
-        except OSError as e:
-            log.error ("lokkit run failed: %s", e.strerror)
-        else:
-            f = open(instPath +
-                     '/etc/sysconfig/system-config-firewall', 'w')
-            f.write("# system-config-firewall config written out by anaconda\n\n")
-            for arg in args[3:]:
-                f.write("%s\n" %(arg,))
-            f.close()
diff --git a/flags.py b/flags.py
deleted file mode 100644
index af6216c..0000000
--- a/flags.py
+++ /dev/null
@@ -1,122 +0,0 @@
-#
-# flags.py: global anaconda flags
-#
-# Copyright (C) 2001  Red Hat, Inc.  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 as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# 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, see <http://www.gnu.org/licenses/>.
-#
-
-import os
-import shlex
-from constants import *
-
-# A lot of effort, but it only allows a limited set of flags to be referenced
-class Flags:
-
-    def __getattr__(self, attr):
-	if self.__dict__['flags'].has_key(attr):
-	    return self.__dict__['flags'][attr]
-
-	raise AttributeError, attr
-
-    def __setattr__(self, attr, val):
-	if self.__dict__['flags'].has_key(attr):
-	    self.__dict__['flags'][attr] = val
-	else:
-	    raise AttributeError, attr
-
-    def get(self, attr, val=None):
-        if self.__dict__['flags'].has_key(attr):
-            return self.__dict__['flags'][attr]
-        else:
-            return val
-
-    def createCmdlineDict(self):
-        cmdlineDict = {}
-        cmdline = open("/proc/cmdline", "r").read().strip()
-
-        # if the BOOT_IMAGE contains a space, pxelinux will strip one of the
-        # quotes leaving one at the end that shlex doesn't know what to do
-        # with
-        if cmdline.find("BOOT_IMAGE=") and cmdline.endswith('"'):
-            cmdline = cmdline.replace("BOOT_IMAGE=", "BOOT_IMAGE=\"")
-
-        lst = shlex.split(cmdline)
-
-        for i in lst:
-            try:
-                (key, val) = i.split("=", 1)
-            except:
-                key = i
-                val = None
-
-            cmdlineDict[key] = val
-
-        return cmdlineDict
-
-    def decideCmdlineFlag(self, flag):
-        if self.__dict__['flags']['cmdline'].has_key(flag) \
-                and not self.__dict__['flags']['cmdline'].has_key("no" + flag) \
-                and self.__dict__['flags']['cmdline'][flag] != "0":
-            self.__dict__['flags'][flag] = 1
-	
-    def __init__(self):
-	self.__dict__['flags'] = {}
-	self.__dict__['flags']['test'] = 0
-	self.__dict__['flags']['livecdInstall'] = 0
-        self.__dict__['flags']['dlabel'] = 0
-	self.__dict__['flags']['ibft'] = 1
-	self.__dict__['flags']['iscsi'] = 0
-	self.__dict__['flags']['serial'] = 0
-	self.__dict__['flags']['autostep'] = 0
-	self.__dict__['flags']['autoscreenshot'] = 0
-	self.__dict__['flags']['usevnc'] = 0
-	self.__dict__['flags']['vncquestion'] = True
-        self.__dict__['flags']['mpath'] = 1
-	self.__dict__['flags']['dmraid'] = 1
-	self.__dict__['flags']['selinux'] = SELINUX_DEFAULT
-        self.__dict__['flags']['debug'] = 0
-	self.__dict__['flags']['targetarch'] = None
-        self.__dict__['flags']['cmdline'] = self.createCmdlineDict()
-        self.__dict__['flags']['useIPv4'] = True
-        self.__dict__['flags']['useIPv6'] = True
-        self.__dict__['flags']['sshd'] = 0
-        self.__dict__['flags']['preexisting_x11'] = False
-        # for non-physical consoles like some ppc and sgi altix,
-        # we need to preserve the console device and not try to
-        # do things like bogl on them.  this preserves what that
-        # device is
-        self.__dict__['flags']['virtpconsole'] = None
-
-        for x in ['selinux']:
-            if self.__dict__['flags']['cmdline'].has_key(x):
-                if self.__dict__['flags']['cmdline'][x]:
-                    self.__dict__['flags'][x] = 1
-                else:
-                    self.__dict__['flags'][x] = 0
-
-        self.decideCmdlineFlag('sshd')
-
-        if self.__dict__['flags']['cmdline'].has_key("debug"):
-            self.__dict__['flags']['debug'] = self.__dict__['flags']['cmdline']['debug']
-
-        if self.__dict__['flags']['cmdline'].has_key("rpmarch"):
-            self.__dict__['flags']['targetarch'] = self.__dict__['flags']['cmdline']['rpmarch']             
-
-        if not os.path.exists("/selinux/load"):
-            self.__dict__['flags']['selinux'] = 0
-
-                
-global flags
-flags = Flags()
diff --git a/fonts/Makefile.am b/fonts/Makefile.am
deleted file mode 100644
index 5ad0197..0000000
--- a/fonts/Makefile.am
+++ /dev/null
@@ -1,39 +0,0 @@
-# fonts/Makefile.am for anaconda
-#
-# Copyright (C) 2009  Red Hat, Inc.
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU Lesser General Public License as published
-# by the Free Software Foundation; either version 2.1 of the License, or
-# (at your option) any later version.
-#
-# 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 Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public License
-# along with this program.  If not, see <http://www.gnu.org/licenses/>.
-#
-# Author: David Cantrell <dcantrell@xxxxxxxxxx>
-
-if IS_FONT_ARCH
-fontsdir        = $(datadir)/$(PACKAGE_NAME)
-dist_fonts_DATA = screenfont-$(ARCH).gz
-endif
-
-EXTRA_DIST = screenfont-*.gz updfonts
-
-MAINTAINERCLEANFILES = Makefile.in
-
-i386:
-	./updfonts i386
-
-alpha:
-	./updfonts alpha
-
-sparc:
-	./updfonts sparc
-
-ia64:
-	./updfonts ia64
diff --git a/fonts/screenfont-alpha.gz b/fonts/screenfont-alpha.gz
deleted file mode 100644
index b12001b59c1f93fdd4d3f292ae65fa240939f3cc..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001

literal 4893
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
DhG(MS

diff --git a/fonts/screenfont-i386.gz b/fonts/screenfont-i386.gz
deleted file mode 100644
index fa88be123eab64806ef59a2ec1b77ce104daba3f..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001

literal 5507
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
A3;+NC

diff --git a/fonts/screenfont-ia64.gz b/fonts/screenfont-ia64.gz
deleted file mode 100644
index ef0569c666a3794b79c061cee376723d65151167..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001

literal 3821
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

diff --git a/fonts/screenfont-ppc.gz b/fonts/screenfont-ppc.gz
deleted file mode 100644
index 036064c76d7ad03d81171cccb854c601822ca5e1..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001

literal 5305
zcmd6q`9Bkm<HsH443$ucb<#0M<lK<EcaqAT7;?)^TgB#z3aQlOTqU`0a&JNuG0cWJ
z=6EyPFbf-Yeczw|;`?~K9<S$bub-a3yZ~upVxbq07z+tUJ&g4A4fP8PjaCZ}e<-k)
z2ZcE};=261r-Dax4mfm}9r|2)&Fk)=BTk3JZZs85D)h?vKA-d+j}ez&d*!|+^^89I
zVU<XjyqbHs?x1A%#a9d+`i34W6nT+kME<)s!RqITzzQ{?!v?JP22m?B0s@3Yn=^bh
zk&E$<R)$^<BYLCaRlgUM+Nfm3h)*-&o*u#G=Jw|1<}~og)tWlSV2V{(oaLj($!Blb
z<TXdY*4`CEf$mzmm1@cZ52flN3$(z@y<)6}dr-YU%_XV1oYsOE=-a2raO`ynHTqms
zeVy^qMdcgCT9>SFyj86YzVB%G$lv2<zhf=Vy@j1WIs|i7aPG|)ZQQ4-+-R!AUYiJ}
zlK(E1ohp<)ACR~62&F}-Iz5iZTlRbpc_wq`ypOr9X5sCUil%dal;)%DT>JrczVH5_
z@6SqWQ3{lUUbV%eW7pXUO0SOZypALOWOEZAqeW$%YVk{g%HO5-Ptu)#^*)$~c%}9X
zug3dvqcGdr3Ww7ScKkbN&FiorSFKRjw0jW+sjkSy+b_P#C-f!sUM|mT<SIxo1U}B!
zyRUs}E|gOTOB;S!c%&ahHFKjG@tNtLg>F3R)(;H6SewtYAv_I!5=qdj2^$@<tGyER
zC_8!B*g5uc5#G&fus(WO)TX;GItA3?p#5Zu-E?B@%Gt_^8jWA!+}5iEG~#k-ZDza8
z;Fx+fvrz9)c)N#QM<|N{Y`9ev_EDg^%0A^g*R*FphE&tq+Ip$%3EvyVEz2;vJ`<4{
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
Hf&%{s?sVel

diff --git a/fonts/screenfont-sparc.gz b/fonts/screenfont-sparc.gz
deleted file mode 100644
index 0c38d3bd735cd8eb2999039a4717de870972dc12..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001

literal 6455
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
D+cO$&

diff --git a/fonts/screenfont-x86_64.gz b/fonts/screenfont-x86_64.gz
deleted file mode 100644
index fcaee505742edca8d8a8bb1c59797e27226b12c6..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001

literal 5473
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
Xy~X4eT!mU+;ov5Qb)m~ov9tXTd=@bZ

diff --git a/fonts/updfonts b/fonts/updfonts
deleted file mode 100755
index 10b74c1..0000000
--- a/fonts/updfonts
+++ /dev/null
@@ -1,11 +0,0 @@
-#!/bin/sh
-
-ARCH=$1
-if [ -z "$ARCH" ]; then
-    echo "usage: $0 <arch>"
-    exit 1
-fi
-
-setfont latarcyrheb-sun16
-../utils/snarffont > screenfont-$ARCH
-gzip -9 -f screenfont-$ARCH
diff --git a/gptsync/.gitignore b/gptsync/.gitignore
deleted file mode 100644
index 4971cfa..0000000
--- a/gptsync/.gitignore
+++ /dev/null
@@ -1,2 +0,0 @@
-gptsync
-showpart
diff --git a/gptsync/Makefile.am b/gptsync/Makefile.am
deleted file mode 100644
index 7f66432..0000000
--- a/gptsync/Makefile.am
+++ /dev/null
@@ -1,35 +0,0 @@
-# gptsync/Makefile.am for anaconda
-#
-# Copyright (C) 2009  Red Hat, Inc.
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU Lesser General Public License as published
-# by the Free Software Foundation; either version 2.1 of the License, or
-# (at your option) any later version.
-#
-# 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 Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public License
-# along with this program.  If not, see <http://www.gnu.org/licenses/>.
-#
-# Author: David Cantrell <dcantrell@xxxxxxxxxx>
-
-COMMON_SRCS      = lib.c os_unix.c
-noinst_HEADERS   = gptsync.h syslinux_mbr.h
-
-if IS_GPTSYNC_ARCH
-sbin_PROGRAMS    = gptsync showpart
-
-gptsync_CFLAGS   = -DPROGNAME=gptsync
-gptsync_SOURCES  = gptsync.c $(COMMON_SRCS)
-
-showpart_CFLAGS  = -DPROGNAME=showpart
-showpart_SOURCES = showpart.c $(COMMON_SRCS)
-endif
-
-EXTRA_DIST       = README
-
-MAINTAINERCLEANFILES = Makefile.in
diff --git a/gptsync/README b/gptsync/README
deleted file mode 100644
index cb306bd..0000000
--- a/gptsync/README
+++ /dev/null
@@ -1,41 +0,0 @@
-gptsync is from refit (refit.sf.net).  It has been modified to
-1) Not prompt if you want to copy
-2) Default to Linux native (0x83) instead of fat32 partition id
-
-The original license follows.
-
-
- rEFIt License
-===============
-
-Copyright (c) 2006-2007 Christoph Pfisterer
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are
-met:
-
- * Redistributions of source code must retain the above copyright
-   notice, this list of conditions and the following disclaimer.
-
- * Redistributions in binary form must reproduce the above copyright
-   notice, this list of conditions and the following disclaimer in the
-   documentation and/or other materials provided with the
-   distribution.
-
- * Neither the name of Christoph Pfisterer nor the names of the
-   contributors may be used to endorse or promote products derived
-   from this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
diff --git a/gptsync/gptsync.c b/gptsync/gptsync.c
deleted file mode 100644
index 3ad26bf..0000000
--- a/gptsync/gptsync.c
+++ /dev/null
@@ -1,470 +0,0 @@
-/*
- * gptsync/gptsync.c
- * Platform-independent code for syncing GPT and MBR
- *
- * Copyright (c) 2006-2007 Christoph Pfisterer
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- *  * Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- *
- *  * Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the
- *    distribution.
- *
- *  * Neither the name of Christoph Pfisterer nor the names of the
- *    contributors may be used to endorse or promote products derived
- *    from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "gptsync.h"
-
-#include "syslinux_mbr.h"
-
-//
-// MBR functions
-//
-
-static UINTN check_mbr(VOID)
-{
-    UINTN       i, k;
-    
-    // check each entry
-    for (i = 0; i < mbr_part_count; i++) {
-        // check for overlap
-        for (k = 0; k < mbr_part_count; k++) {
-            if (k != i && !(mbr_parts[i].start_lba > mbr_parts[k].end_lba || mbr_parts[k].start_lba > mbr_parts[i].end_lba)) {
-                Print(L"Status: MBR partition table is invalid, partitions overlap.\n");
-                return 1;
-            }
-        }
-        
-        // check for extended partitions
-        if (mbr_parts[i].mbr_type == 0x05 || mbr_parts[i].mbr_type == 0x0f || mbr_parts[i].mbr_type == 0x85) {
-            Print(L"Status: Extended partition found in MBR table, will not touch this disk.\n",
-                  gpt_parts[i].gpt_parttype->name);
-            return 1;
-        }
-    }
-    
-    return 0;
-}
-
-static UINTN write_mbr(VOID)
-{
-    UINTN               status;
-    UINTN               i, k;
-    UINT8               active;
-    UINT64              lba;
-    MBR_PARTITION_INFO  *table;
-    BOOLEAN             have_bootcode;
-    
-    Print(L"\nWriting new MBR...\n");
-    
-    // read MBR data
-    status = read_sector(0, sector);
-    if (status != 0)
-        return status;
-    
-    // write partition table
-    *((UINT16 *)(sector + 510)) = 0xaa55;
-    
-    table = (MBR_PARTITION_INFO *)(sector + 446);
-    active = 0x80;
-    for (i = 0; i < 4; i++) {
-        for (k = 0; k < new_mbr_part_count; k++) {
-            if (new_mbr_parts[k].index == i)
-                break;
-        }
-        if (k >= new_mbr_part_count) {
-            // unused entry
-            table[i].flags        = 0;
-            table[i].start_chs[0] = 0;
-            table[i].start_chs[1] = 0;
-            table[i].start_chs[2] = 0;
-            table[i].type         = 0;
-            table[i].end_chs[0]   = 0;
-            table[i].end_chs[1]   = 0;
-            table[i].end_chs[2]   = 0;
-            table[i].start_lba    = 0;
-            table[i].size         = 0;
-        } else {
-            if (new_mbr_parts[k].active) {
-                table[i].flags        = active;
-                active = 0x00;
-            } else
-                table[i].flags        = 0x00;
-            table[i].start_chs[0] = 0xfe;
-            table[i].start_chs[1] = 0xff;
-            table[i].start_chs[2] = 0xff;
-            table[i].type         = new_mbr_parts[k].mbr_type;
-            table[i].end_chs[0]   = 0xfe;
-            table[i].end_chs[1]   = 0xff;
-            table[i].end_chs[2]   = 0xff;
-            
-            lba = new_mbr_parts[k].start_lba;
-            if (lba > 0xffffffffULL) {
-                Print(L"Warning: Partition %d starts beyond 2 TiB limit\n", i+1);
-                lba = 0xffffffffULL;
-            }
-            table[i].start_lba    = (UINT32)lba;
-            
-            lba = new_mbr_parts[k].end_lba + 1 - new_mbr_parts[k].start_lba;
-            if (lba > 0xffffffffULL) {
-                Print(L"Warning: Partition %d extends beyond 2 TiB limit\n", i+1);
-                lba = 0xffffffffULL;
-            }
-            table[i].size         = (UINT32)lba;
-        }
-    }
-    
-    // add boot code if necessary
-    have_bootcode = FALSE;
-    for (i = 0; i < MBR_BOOTCODE_SIZE; i++) {
-        if (sector[i] != 0) {
-            have_bootcode = TRUE;
-            break;
-        }
-    }
-    if (!have_bootcode) {
-        // no boot code found in the MBR, add the syslinux MBR code
-        SetMem(sector, 0, MBR_BOOTCODE_SIZE);
-        CopyMem(sector, syslinux_mbr, SYSLINUX_MBR_SIZE);
-    }
-    
-    // write MBR data
-    status = write_sector(0, sector);
-    if (status != 0)
-        return status;
-    
-    Print(L"MBR updated successfully!\n");
-    
-    return 0;
-}
-
-//
-// GPT functions
-//
-
-static UINTN check_gpt(VOID)
-{
-    UINTN       i, k;
-    BOOLEAN     found_data_parts;
-    
-    if (gpt_part_count == 0) {
-        Print(L"Status: No GPT partition table, no need to sync.\n");
-        return 1;
-    }
-    
-    // check each entry
-    found_data_parts = FALSE;
-    for (i = 0; i < gpt_part_count; i++) {
-        // check sanity
-        if (gpt_parts[i].end_lba < gpt_parts[i].start_lba) {
-            Print(L"Status: GPT partition table is invalid.\n");
-            return 1;
-        }
-        // check for overlap
-        for (k = 0; k < gpt_part_count; k++) {
-            if (k != i && !(gpt_parts[i].start_lba > gpt_parts[k].end_lba || gpt_parts[k].start_lba > gpt_parts[i].end_lba)) {
-                Print(L"Status: GPT partition table is invalid, partitions overlap.\n");
-                return 1;
-            }
-        }
-        
-        // check for partitions kind
-        if (gpt_parts[i].gpt_parttype->kind == GPT_KIND_FATAL) {
-            Print(L"Status: GPT partition of type '%s' found, will not touch this disk.\n",
-                  gpt_parts[i].gpt_parttype->name);
-            return 1;
-        }
-        if (gpt_parts[i].gpt_parttype->kind == GPT_KIND_DATA ||
-            gpt_parts[i].gpt_parttype->kind == GPT_KIND_BASIC_DATA)
-            found_data_parts = TRUE;
-    }
-    
-    if (!found_data_parts) {
-        Print(L"Status: GPT partition table has no data partitions, no need to sync.\n");
-        return 1;
-    }
-    
-    return 0;
-}
-
-//
-// compare GPT and MBR tables
-//
-
-#define ACTION_NONE        (0)
-#define ACTION_NOP         (1)
-#define ACTION_REWRITE     (2)
-
-static UINTN analyze(VOID)
-{
-    UINTN   action;
-    UINTN   i, k, iter, count_active, detected_parttype;
-    CHARN   *fsname;
-    UINT64  min_start_lba;
-    UINTN   status;
-    BOOLEAN have_esp;
-    
-    new_mbr_part_count = 0;
-    
-    // determine correct MBR types for GPT partitions
-    if (gpt_part_count == 0) {
-        Print(L"Status: No GPT partitions defined, nothing to sync.\n");
-        return 0;
-    }
-    have_esp = FALSE;
-    for (i = 0; i < gpt_part_count; i++) {
-        gpt_parts[i].mbr_type = gpt_parts[i].gpt_parttype->mbr_type;
-        if (gpt_parts[i].gpt_parttype->kind == GPT_KIND_BASIC_DATA) {
-            // Basic Data: need to look at data in the partition
-            status = detect_mbrtype_fs(gpt_parts[i].start_lba, &detected_parttype, &fsname);
-            if (detected_parttype)
-                gpt_parts[i].mbr_type = detected_parttype;
-            else
-                gpt_parts[i].mbr_type = 0x0b;  // fallback: FAT32
-        } else if (gpt_parts[i].mbr_type == 0xef) {
-            // EFI System Partition: GNU parted can put this on any partition,
-            // need to detect file systems
-            status = detect_mbrtype_fs(gpt_parts[i].start_lba, &detected_parttype, &fsname);
-            if (!have_esp && (detected_parttype == 0x01 || detected_parttype == 0x0e || detected_parttype == 0x0c))
-                ;  // seems to be a legitimate ESP, don't change
-            else if (detected_parttype)
-                gpt_parts[i].mbr_type = detected_parttype;
-            else if (have_esp)    // make sure there's no more than one ESP per disk
-                gpt_parts[i].mbr_type = 0x83;  // fallback: Linux
-        }
-        // NOTE: mbr_type may still be 0 if content detection fails for exotic GPT types or file systems
-        
-        if (gpt_parts[i].mbr_type == 0xef)
-            have_esp = TRUE;
-    }
-    
-    // check for common scenarios
-    action = ACTION_NONE;
-    if (mbr_part_count == 0) {
-        // current MBR is empty
-        action = ACTION_REWRITE;
-    } else if (mbr_part_count == 1 && mbr_parts[0].mbr_type == 0xee) {
-        // MBR has just the EFI Protective partition (i.e. untouched)
-        action = ACTION_REWRITE;
-    }
-    if (action == ACTION_NONE && mbr_part_count > 0) {
-        if (mbr_parts[0].mbr_type == 0xee &&
-            gpt_parts[0].mbr_type == 0xef &&
-            mbr_parts[0].start_lba == 1 &&
-            mbr_parts[0].end_lba == gpt_parts[0].end_lba) {
-            // The Apple Way, "EFI Protective" covering the tables and the ESP
-            action = ACTION_NOP;
-            if ((mbr_part_count != gpt_part_count && gpt_part_count <= 4) ||
-                (mbr_part_count != 4              && gpt_part_count > 4)) {
-                // number of partitions has changed
-                action = ACTION_REWRITE;
-            } else {
-                // check partition ranges and types
-                for (i = 1; i < mbr_part_count; i++) {
-                    if (mbr_parts[i].start_lba != gpt_parts[i].start_lba ||
-                        mbr_parts[i].end_lba   != gpt_parts[i].end_lba ||
-                        (gpt_parts[i].mbr_type && mbr_parts[i].mbr_type != gpt_parts[i].mbr_type))
-                        // position or type has changed
-                        action = ACTION_REWRITE;
-                }
-            }
-            // check number of active partitions
-            count_active = 0;
-            for (i = 0; i < mbr_part_count; i++)
-                if (mbr_parts[i].active)
-                    count_active++;
-            if (count_active!= 1)
-                action = ACTION_REWRITE;
-        }
-    }
-    if (action == ACTION_NONE && mbr_part_count > 0 && mbr_parts[0].mbr_type == 0xef) {
-        // The XOM Way, all partitions mirrored 1:1
-        action = ACTION_REWRITE;
-        // check partition ranges and types
-        for (i = 0; i < mbr_part_count; i++) {
-            if (mbr_parts[i].start_lba != gpt_parts[i].start_lba ||
-                mbr_parts[i].end_lba   != gpt_parts[i].end_lba ||
-                (gpt_parts[i].mbr_type && mbr_parts[i].mbr_type != gpt_parts[i].mbr_type))
-                // position or type has changed -> better don't touch
-                action = ACTION_NONE;
-        }
-    }
-    
-    if (action == ACTION_NOP) {
-        Print(L"Status: Tables are synchronized, no need to sync.\n");
-        return 0;
-    } else if (action == ACTION_REWRITE) {
-        Print(L"Status: MBR table must be updated.\n");
-    } else {
-        Print(L"Status: Analysis inconclusive, will not touch this disk.\n");
-        return 1;
-    }
-    
-    // generate the new table
-    
-    // first entry: EFI Protective
-    new_mbr_parts[0].index     = 0;
-    new_mbr_parts[0].start_lba = 1;
-    new_mbr_parts[0].mbr_type  = 0xee;
-    new_mbr_part_count = 1;
-    
-    if (gpt_parts[0].mbr_type == 0xef) {
-        new_mbr_parts[0].end_lba = gpt_parts[0].end_lba;
-        i = 1;
-    } else {
-        min_start_lba = gpt_parts[0].start_lba;
-        for (k = 0; k < gpt_part_count; k++) {
-            if (min_start_lba > gpt_parts[k].start_lba)
-                min_start_lba = gpt_parts[k].start_lba;
-        }
-        new_mbr_parts[0].end_lba = min_start_lba - 1;
-        i = 0;
-    }
-    
-    // add other GPT partitions until the table is full
-    // TODO: in the future, prioritize partitions by kind
-    for (; i < gpt_part_count && new_mbr_part_count < 4; i++) {
-        new_mbr_parts[new_mbr_part_count].index     = new_mbr_part_count;
-        new_mbr_parts[new_mbr_part_count].start_lba = gpt_parts[i].start_lba;
-        new_mbr_parts[new_mbr_part_count].end_lba   = gpt_parts[i].end_lba;
-        new_mbr_parts[new_mbr_part_count].mbr_type  = gpt_parts[i].mbr_type;
-        new_mbr_parts[new_mbr_part_count].active    = FALSE;
-        
-        // find matching partition in the old MBR table
-        for (k = 0; k < mbr_part_count; k++) {
-            if (mbr_parts[k].start_lba == gpt_parts[i].start_lba) {
-                // keep type if not detected
-                if (new_mbr_parts[new_mbr_part_count].mbr_type == 0)
-                    new_mbr_parts[new_mbr_part_count].mbr_type = mbr_parts[k].mbr_type;
-                // keep active flag
-                new_mbr_parts[new_mbr_part_count].active = mbr_parts[k].active;
-                break;
-            }
-        }
-        
-        if (new_mbr_parts[new_mbr_part_count].mbr_type == 0)
-            // final fallback: set to a (hopefully) unused type
-            new_mbr_parts[new_mbr_part_count].mbr_type = 0xc0;
-        
-        new_mbr_part_count++;
-    }
-    
-    // make sure there's exactly one active partition
-    for (iter = 0; iter < 3; iter++) {
-        // check
-        count_active = 0;
-        for (i = 0; i < new_mbr_part_count; i++)
-            if (new_mbr_parts[i].active)
-                count_active++;
-        if (count_active == 1)
-            break;
-        
-        // set active on the first matching partition
-        if (count_active == 0) {
-            for (i = 0; i < new_mbr_part_count; i++) {
-                if ((iter >= 0 && (new_mbr_parts[i].mbr_type == 0x07 ||    // NTFS
-                                   new_mbr_parts[i].mbr_type == 0x0b ||    // FAT32
-                                   new_mbr_parts[i].mbr_type == 0x0c)) ||  // FAT32 (LBA)
-                    (iter >= 1 && (new_mbr_parts[i].mbr_type == 0x83)) ||  // Linux
-                    (iter >= 2 && i > 0)) {
-                    new_mbr_parts[i].active = TRUE;
-                    break;
-                }
-            }
-        } else if (count_active > 1 && iter == 0) {
-            // too many active partitions, try deactivating the ESP / EFI Protective entry
-            if ((new_mbr_parts[0].mbr_type == 0xee || new_mbr_parts[0].mbr_type == 0xef) &&
-                new_mbr_parts[0].active) {
-                new_mbr_parts[0].active = FALSE;
-            }
-        } else if (count_active > 1 && iter > 0) {
-            // too many active partitions, deactivate all but the first one
-            count_active = 0;
-            for (i = 0; i < new_mbr_part_count; i++)
-                if (new_mbr_parts[i].active) {
-                    if (count_active > 0)
-                        new_mbr_parts[i].active = FALSE;
-                    count_active++;
-                }
-        }
-    }
-    
-    // dump table
-    Print(L"\nProposed new MBR partition table:\n");
-    Print(L" # A    Start LBA      End LBA  Type\n");
-    for (i = 0; i < new_mbr_part_count; i++) {
-        Print(L" %d %s %12lld %12lld  %02x  %s\n",
-              new_mbr_parts[i].index + 1,
-              new_mbr_parts[i].active ? STR("*") : STR(" "),
-              new_mbr_parts[i].start_lba,
-              new_mbr_parts[i].end_lba,
-              new_mbr_parts[i].mbr_type,
-              mbr_parttype_name(new_mbr_parts[i].mbr_type));
-    }
-    
-    return 0;
-}
-
-//
-// sync algorithm entry point
-//
-
-UINTN gptsync(VOID)
-{
-    UINTN   status = 0;
-    UINTN   status_gpt, status_mbr;
-    // BOOLEAN proceed = FALSE;
-    
-    // get full information from disk
-    status_gpt = read_gpt();
-    status_mbr = read_mbr();
-    if (status_gpt != 0 || status_mbr != 0)
-        return (status_gpt || status_mbr);
-    
-    // cross-check current situation
-    Print(L"\n");
-    status = check_gpt();   // check GPT for consistency
-    if (status != 0)
-        return status;
-    status = check_mbr();   // check MBR for consistency
-    if (status != 0)
-        return status;
-    status = analyze();     // analyze the situation & compose new MBR table
-    if (status != 0)
-        return status;
-    if (new_mbr_part_count == 0)
-        return status;
-    
-    // offer user the choice what to do
-    // status = input_boolean(STR("\nMay I update the MBR as printed above? [y/N] "), &proceed);
-    // if (status != 0 || proceed != TRUE)
-    //    return status;
-    
-    // adjust the MBR and write it back
-    status = write_mbr();
-    if (status != 0)
-        return status;
-    
-    return status;
-}
diff --git a/gptsync/gptsync.h b/gptsync/gptsync.h
deleted file mode 100644
index d1bf3c2..0000000
--- a/gptsync/gptsync.h
+++ /dev/null
@@ -1,219 +0,0 @@
-/*
- * gptsync/gptsync.h
- * Common header for gptsync and showpart
- *
- * Copyright (c) 2006 Christoph Pfisterer
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- *  * Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- *
- *  * Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the
- *    distribution.
- *
- *  * Neither the name of Christoph Pfisterer nor the names of the
- *    contributors may be used to endorse or promote products derived
- *    from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-//
-// config
-//
-
-#if defined(EFI32) || defined(EFIX64)
-#define CONFIG_EFI
-#endif
-
-//
-// platform-dependent types
-//
-
-#ifdef CONFIG_EFI
-
-#include <efi.h>
-#include <efilib.h>
-
-#define copy_guid(destguid, srcguid) (CopyMem(destguid, srcguid, 16))
-#define guids_are_equal(guid1, guid2) (CompareMem(guid1, guid2, 16) == 0)
-
-typedef CHAR16 CHARN;
-#define STR(x) L##x
-
-#endif
-
-
-#ifndef CONFIG_EFI
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <stdint.h>
-#include <unistd.h>
-#include <errno.h>
-
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <sys/time.h>
-#include <fcntl.h>
-
-typedef int                 INTN;
-typedef unsigned int        UINTN;
-typedef uint8_t             UINT8;
-typedef uint16_t            UINT16;
-typedef uint32_t            UINT32;
-typedef uint64_t            UINT64;
-typedef void                VOID;
-
-typedef int                 BOOLEAN;
-#ifndef FALSE
-#define FALSE (0)
-#endif
-#ifndef TRUE
-#define TRUE  (1)
-#endif
-
-typedef unsigned short      CHAR16;
-typedef char                CHARN;
-#define STR(x) x
-
-void Print(wchar_t *format, ...);
-
-// FUTURE: use STR(),  #define Print printf
-
-#define CopyMem     memcpy
-#define SetMem      memset
-#define CompareMem  memcmp
-
-#define copy_guid(destguid, srcguid) (memcpy(destguid, srcguid, 16))
-#define guids_are_equal(guid1, guid2) (memcmp(guid1, guid2, 16) == 0)
-
-#endif
-
-//
-// platform-independent types
-//
-
-typedef struct {
-    UINT8   flags;
-    UINT8   start_chs[3];
-    UINT8   type;
-    UINT8   end_chs[3];
-    UINT32  start_lba;
-    UINT32  size;
-} MBR_PARTITION_INFO;
-
-typedef struct {
-    UINT8   type;
-    CHARN   *name;
-} MBR_PARTTYPE;
-
-typedef struct {
-    UINT64  signature;
-    UINT32  spec_revision;
-    UINT32  header_size;
-    UINT32  header_crc32;
-    UINT32  reserved;
-    UINT64  header_lba;
-    UINT64  alternate_header_lba;
-    UINT64  first_usable_lba;
-    UINT64  last_usable_lba;
-    UINT8   disk_guid[16];
-    UINT64  entry_lba;
-    UINT32  entry_count;
-    UINT32  entry_size;
-    UINT32  entry_crc32;
-} GPT_HEADER;
-
-typedef struct {
-    UINT8   type_guid[16];
-    UINT8   partition_guid[16];
-    UINT64  start_lba;
-    UINT64  end_lba;
-    UINT64  attributes;
-    CHAR16  name[36];
-} GPT_ENTRY;
-
-#define GPT_KIND_SYSTEM     (0)
-#define GPT_KIND_DATA       (1)
-#define GPT_KIND_BASIC_DATA (2)
-#define GPT_KIND_FATAL      (3)
-
-typedef struct {
-    UINT8   guid[16];
-    UINT8   mbr_type;
-    CHARN   *name;
-    UINTN   kind;
-} GPT_PARTTYPE;
-
-typedef struct {
-    UINTN   index;
-    UINT64  start_lba;
-    UINT64  end_lba;
-    UINTN   mbr_type;
-    UINT8   gpt_type[16];
-    GPT_PARTTYPE *gpt_parttype;
-    BOOLEAN active;
-} PARTITION_INFO;
-
-//
-// functions provided by the OS-specific module
-//
-
-UINTN read_sector(UINT64 lba, UINT8 *buffer);
-UINTN write_sector(UINT64 lba, UINT8 *buffer);
-UINTN input_boolean(CHARN *prompt, BOOLEAN *bool_out);
-
-//
-// vars and functions provided by the common lib module
-//
-
-extern UINT8           empty_guid[16];
-
-extern PARTITION_INFO  mbr_parts[4];
-extern UINTN           mbr_part_count;
-extern PARTITION_INFO  gpt_parts[128];
-extern UINTN           gpt_part_count;
-
-extern PARTITION_INFO  new_mbr_parts[4];
-extern UINTN           new_mbr_part_count;
-
-extern UINT8           sector[512];
-
-extern MBR_PARTTYPE    mbr_types[];
-extern GPT_PARTTYPE    gpt_types[];
-extern GPT_PARTTYPE    gpt_dummy_type;
-
-CHARN * mbr_parttype_name(UINT8 type);
-UINTN read_mbr(VOID);
-
-GPT_PARTTYPE * gpt_parttype(UINT8 *type_guid);
-UINTN read_gpt(VOID);
-
-UINTN detect_mbrtype_fs(UINT64 partlba, UINTN *parttype, CHARN **fsname);
-
-//
-// actual platform-independent programs
-//
-
-UINTN gptsync(VOID);
-UINTN showpart(VOID);
-
-/* EOF */
diff --git a/gptsync/lib.c b/gptsync/lib.c
deleted file mode 100644
index f2d71b2..0000000
--- a/gptsync/lib.c
+++ /dev/null
@@ -1,469 +0,0 @@
-/*
- * gptsync/lib.c
- * Platform-independent code common to gptsync and showpart
- *
- * Copyright (c) 2006-2007 Christoph Pfisterer
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- *  * Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- *
- *  * Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the
- *    distribution.
- *
- *  * Neither the name of Christoph Pfisterer nor the names of the
- *    contributors may be used to endorse or promote products derived
- *    from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "gptsync.h"
-
-// variables
-
-UINT8           empty_guid[16] = { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 };
-
-PARTITION_INFO  mbr_parts[4];
-UINTN           mbr_part_count = 0;
-PARTITION_INFO  gpt_parts[128];
-UINTN           gpt_part_count = 0;
-
-PARTITION_INFO  new_mbr_parts[4];
-UINTN           new_mbr_part_count = 0;
-
-UINT8           sector[512];
-
-MBR_PARTTYPE    mbr_types[] = {
-    { 0x01, STR("FAT12 (CHS)") },
-    { 0x04, STR("FAT16 <32M (CHS)") },
-    { 0x05, STR("Extended (CHS)") },
-    { 0x06, STR("FAT16 (CHS)") },
-    { 0x07, STR("NTFS/HPFS") },
-    { 0x0b, STR("FAT32 (CHS)") },
-    { 0x0c, STR("FAT32 (LBA)") },
-    { 0x0e, STR("FAT16 (LBA)") },
-    { 0x0f, STR("Extended (LBA)") },
-    { 0x11, STR("Hidden FAT12 (CHS)") },
-    { 0x14, STR("Hidden FAT16 <32M (CHS)") },
-    { 0x16, STR("Hidden FAT16 (CHS)") },
-    { 0x17, STR("Hidden NTFS/HPFS") },
-    { 0x1b, STR("Hidden FAT32 (CHS)") },
-    { 0x1c, STR("Hidden FAT32 (LBA)") },
-    { 0x1e, STR("Hidden FAT16 (LBA)") },
-    { 0x82, STR("Linux swap / Solaris") },
-    { 0x83, STR("Linux") },
-    { 0x85, STR("Linux Extended") },
-    { 0x86, STR("NT FAT volume set") },
-    { 0x87, STR("NTFS volume set") },
-    { 0x8e, STR("Linux LVM") },
-    { 0xa5, STR("FreeBSD") },
-    { 0xa6, STR("OpenBSD") },
-    { 0xa7, STR("NeXTSTEP") },
-    { 0xa8, STR("Mac OS X UFS") },
-    { 0xa9, STR("NetBSD") },
-    { 0xab, STR("Mac OS X Boot") },
-    { 0xac, STR("Apple RAID") },
-    { 0xaf, STR("Mac OS X HFS+") },
-    { 0xbe, STR("Solaris Boot") },
-    { 0xbf, STR("Solaris") },
-    { 0xeb, STR("BeOS") },
-    { 0xee, STR("EFI Protective") },
-    { 0xef, STR("EFI System (FAT)") },
-    { 0xfd, STR("Linux RAID") },
-    { 0, NULL },
-};
-
-GPT_PARTTYPE    gpt_types[] = {
-    { "\x28\x73\x2A\xC1\x1F\xF8\xD2\x11\xBA\x4B\x00\xA0\xC9\x3E\xC9\x3B", 0xef, STR("EFI System (FAT)"), GPT_KIND_SYSTEM },
-    { "\x41\xEE\x4D\x02\xE7\x33\xD3\x11\x9D\x69\x00\x08\xC7\x81\xF3\x9F", 0x00, STR("MBR partition scheme"), GPT_KIND_FATAL },
-    { "\x16\xE3\xC9\xE3\x5C\x0B\xB8\x4D\x81\x7D\xF9\x2D\xF0\x02\x15\xAE", 0x00, STR("MS Reserved"), GPT_KIND_SYSTEM },
-    { "\xA2\xA0\xD0\xEB\xE5\xB9\x33\x44\x87\xC0\x68\xB6\xB7\x26\x99\xC7", 0x00, STR("Basic Data"), GPT_KIND_BASIC_DATA },
-    { "\xAA\xC8\x08\x58\x8F\x7E\xE0\x42\x85\xD2\xE1\xE9\x04\x34\xCF\xB3", 0x00, STR("MS LDM Metadata"), GPT_KIND_FATAL },
-    { "\xA0\x60\x9B\xAF\x31\x14\x62\x4F\xBC\x68\x33\x11\x71\x4A\x69\xAD", 0x00, STR("MS LDM Data"), GPT_KIND_FATAL },
-    { "\x1E\x4C\x89\x75\xEB\x3A\xD3\x11\xB7\xC1\x7B\x03\xA0\x00\x00\x00", 0x00, STR("HP/UX Data"), GPT_KIND_DATA },
-    { "\x28\xE7\xA1\xE2\xE3\x32\xD6\x11\xA6\x82\x7B\x03\xA0\x00\x00\x00", 0x00, STR("HP/UX Service"), GPT_KIND_SYSTEM },
-    { "\x0F\x88\x9D\xA1\xFC\x05\x3B\x4D\xA0\x06\x74\x3F\x0F\x84\x91\x1E", 0xfd, STR("Linux RAID"), GPT_KIND_DATA },
-    { "\x6D\xFD\x57\x06\xAB\xA4\xC4\x43\x84\xE5\x09\x33\xC8\x4B\x4F\x4F", 0x82, STR("Linux Swap"), GPT_KIND_SYSTEM },
-    { "\x79\xD3\xD6\xE6\x07\xF5\xC2\x44\xA2\x3C\x23\x8F\x2A\x3D\xF9\x28", 0x8e, STR("Linux LVM"), GPT_KIND_DATA },
-    { "\x39\x33\xA6\x8D\x07\x00\xC0\x60\xC4\x36\x08\x3A\xC8\x23\x09\x08", 0x00, STR("Linux Reserved"), GPT_KIND_SYSTEM },
-    { "\xB4\x7C\x6E\x51\xCF\x6E\xD6\x11\x8F\xF8\x00\x02\x2D\x09\x71\x2B", 0xa5, STR("FreeBSD Data"), GPT_KIND_DATA },
-    { "\xB5\x7C\x6E\x51\xCF\x6E\xD6\x11\x8F\xF8\x00\x02\x2D\x09\x71\x2B", 0x00, STR("FreeBSD Swap"), GPT_KIND_SYSTEM },
-    { "\xB6\x7C\x6E\x51\xCF\x6E\xD6\x11\x8F\xF8\x00\x02\x2D\x09\x71\x2B", 0xa5, STR("FreeBSD UFS"), GPT_KIND_DATA },
-    { "\xB8\x7C\x6E\x51\xCF\x6E\xD6\x11\x8F\xF8\x00\x02\x2D\x09\x71\x2B", 0x00, STR("FreeBSD Vinum"), GPT_KIND_DATA },
-    { "\x00\x53\x46\x48\x00\x00\xAA\x11\xAA\x11\x00\x30\x65\x43\xEC\xAC", 0xaf, STR("Mac OS X HFS+"), GPT_KIND_DATA },
-    { "\x00\x53\x46\x55\x00\x00\xAA\x11\xAA\x11\x00\x30\x65\x43\xEC\xAC", 0xa8, STR("Mac OS X UFS"), GPT_KIND_DATA },
-    { "\x74\x6F\x6F\x42\x00\x00\xAA\x11\xAA\x11\x00\x30\x65\x43\xEC\xAC", 0xab, STR("Mac OS X Boot"), GPT_KIND_DATA },
-    { "\x44\x49\x41\x52\x00\x00\xAA\x11\xAA\x11\x00\x30\x65\x43\xEC\xAC", 0xac, STR("Apple RAID"), GPT_KIND_DATA },
-    { "\x44\x49\x41\x52\x4F\x5F\xAA\x11\xAA\x11\x00\x30\x65\x43\xEC\xAC", 0xac, STR("Apple RAID (Offline)"), GPT_KIND_DATA },
-    { "\x65\x62\x61\x4C\x00\x6C\xAA\x11\xAA\x11\x00\x30\x65\x43\xEC\xAC", 0x00, STR("Apple Label"), GPT_KIND_SYSTEM },
-    { "\x6F\x63\x65\x52\x65\x76\xAA\x11\xAA\x11\x00\x30\x65\x43\xEC\xAC", 0x00, STR("Apple Recovery"), GPT_KIND_BASIC_DATA },
-    { "\x7f\x23\x96\x6A\xD2\x1D\xB2\x11\x99\xa6\x08\x00\x20\x73\x66\x31", 0x00, STR("Solaris Reserved"), GPT_KIND_SYSTEM },
-    { "\x45\xCB\x82\x6A\xD2\x1D\xB2\x11\x99\xa6\x08\x00\x20\x73\x66\x31", 0xbf, STR("Solaris Boot"), GPT_KIND_DATA },
-    { "\x4D\xCF\x85\x6A\xD2\x1D\xB2\x11\x99\xa6\x08\x00\x20\x73\x66\x31", 0xbf, STR("Solaris Root"), GPT_KIND_DATA },
-    { "\x6F\xC4\x87\x6A\xD2\x1D\xB2\x11\x99\xa6\x08\x00\x20\x73\x66\x31", 0x00, STR("Solaris Swap"), GPT_KIND_SYSTEM },
-    { "\xC3\x8C\x89\x6A\xD2\x1D\xB2\x11\x99\xa6\x08\x00\x20\x73\x66\x31", 0xbf, STR("Solaris Usr"), GPT_KIND_DATA },
-    { "\x2B\x64\x8B\x6A\xD2\x1D\xB2\x11\x99\xa6\x08\x00\x20\x73\x66\x31", 0x00, STR("Solaris Backup"), GPT_KIND_SYSTEM },
-    { "\xC7\x2A\x8D\x6A\xD2\x1D\xB2\x11\x99\xa6\x08\x00\x20\x73\x66\x31", 0xbf, STR("Solaris Stand"), GPT_KIND_DATA },
-    { "\xE9\xF2\x8E\x6A\xD2\x1D\xB2\x11\x99\xa6\x08\x00\x20\x73\x66\x31", 0xbf, STR("Solaris Var"), GPT_KIND_DATA },
-    { "\x39\xBA\x90\x6A\xD2\x1D\xB2\x11\x99\xa6\x08\x00\x20\x73\x66\x31", 0xbf, STR("Solaris Home"), GPT_KIND_DATA },
-    { "\xA5\x83\x92\x6A\xD2\x1D\xB2\x11\x99\xa6\x08\x00\x20\x73\x66\x31", 0xbf, STR("Solaris ALTSCTR"), GPT_KIND_DATA },
-    { "\x3B\x5A\x94\x6A\xD2\x1D\xB2\x11\x99\xa6\x08\x00\x20\x73\x66\x31", 0x00, STR("Solaris Cache"), GPT_KIND_SYSTEM },
-    { { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 }, 0, NULL, 0 },
-};
-GPT_PARTTYPE    gpt_dummy_type =
-    { { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 }, 0, STR("Unknown"), GPT_KIND_FATAL };
-
-//
-// MBR functions
-//
-
-CHARN * mbr_parttype_name(UINT8 type)
-{
-    int i;
-    
-    for (i = 0; mbr_types[i].name; i++)
-        if (mbr_types[i].type == type)
-            return mbr_types[i].name;
-    return STR("Unknown");
-}
-
-UINTN read_mbr(VOID)
-{
-    UINTN               status;
-    UINTN               i;
-    BOOLEAN             used;
-    MBR_PARTITION_INFO  *table;
-    
-    Print(L"\nCurrent MBR partition table:\n");
-    
-    // read MBR data
-    status = read_sector(0, sector);
-    if (status != 0)
-        return status;
-    
-    // check for validity
-    if (*((UINT16 *)(sector + 510)) != 0xaa55) {
-        Print(L" No MBR partition table present!\n");
-        return 1;
-    }
-    table = (MBR_PARTITION_INFO *)(sector + 446);
-    for (i = 0; i < 4; i++) {
-        if (table[i].flags != 0x00 && table[i].flags != 0x80) {
-            Print(L" MBR partition table is invalid!\n");
-            return 1;
-        }
-    }
-    
-    // check if used
-    used = FALSE;
-    for (i = 0; i < 4; i++) {
-        if (table[i].start_lba > 0 && table[i].size > 0) {
-            used = TRUE;
-            break;
-        }
-    }
-    if (!used) {
-        Print(L" No partitions defined\n");
-        return 0;
-    }
-    
-    // dump current state & fill internal structures
-    Print(L" # A    Start LBA      End LBA  Type\n");
-    for (i = 0; i < 4; i++) {
-        if (table[i].start_lba == 0 || table[i].size == 0)
-            continue;
-        
-        mbr_parts[mbr_part_count].index     = i;
-        mbr_parts[mbr_part_count].start_lba = (UINT64)table[i].start_lba;
-        mbr_parts[mbr_part_count].end_lba   = (UINT64)table[i].start_lba + (UINT64)table[i].size - 1;
-        mbr_parts[mbr_part_count].mbr_type  = table[i].type;
-        mbr_parts[mbr_part_count].active    = (table[i].flags == 0x80) ? TRUE : FALSE;
-        
-        Print(L" %d %s %12lld %12lld  %02x  %s\n",
-              mbr_parts[mbr_part_count].index + 1,
-              mbr_parts[mbr_part_count].active ? STR("*") : STR(" "),
-              mbr_parts[mbr_part_count].start_lba,
-              mbr_parts[mbr_part_count].end_lba,
-              mbr_parts[mbr_part_count].mbr_type,
-              mbr_parttype_name(mbr_parts[mbr_part_count].mbr_type));
-        
-        mbr_part_count++;
-    }
-    
-    return 0;
-}
-
-//
-// GPT functions
-//
-
-GPT_PARTTYPE * gpt_parttype(UINT8 *type_guid)
-{
-    int i;
-    
-    for (i = 0; gpt_types[i].name; i++)
-        if (guids_are_equal(gpt_types[i].guid, type_guid))
-            return &(gpt_types[i]);
-    return &gpt_dummy_type;
-}
-
-UINTN read_gpt(VOID)
-{
-    UINTN       status;
-    GPT_HEADER  *header;
-    GPT_ENTRY   *entry;
-    UINT64      entry_lba;
-    UINTN       entry_count, entry_size, i;
-    
-    Print(L"\nCurrent GPT partition table:\n");
-    
-    // read GPT header
-    status = read_sector(1, sector);
-    if (status != 0)
-        return status;
-    
-    // check signature
-    header = (GPT_HEADER *)sector;
-    if (header->signature != 0x5452415020494645ULL) {
-        Print(L" No GPT partition table present!\n");
-        return 0;
-    }
-    if (header->spec_revision != 0x00010000UL) {
-        Print(L" Warning: Unknown GPT spec revision 0x%08x\n", header->spec_revision);
-    }
-    if ((512 % header->entry_size) > 0 || header->entry_size > 512) {
-        Print(L" Error: Invalid GPT entry size (misaligned or more than 512 bytes)\n");
-        return 0;
-    }
-    
-    // read entries
-    entry_lba   = header->entry_lba;
-    entry_size  = header->entry_size;
-    entry_count = header->entry_count;
-    
-    for (i = 0; i < entry_count; i++) {
-        if (((i * entry_size) % 512) == 0) {
-            status = read_sector(entry_lba, sector);
-            if (status != 0)
-                return status;
-            entry_lba++;
-        }
-        entry = (GPT_ENTRY *)(sector + ((i * entry_size) % 512));
-        
-        if (guids_are_equal(entry->type_guid, empty_guid))
-            continue;
-        if (gpt_part_count == 0) {
-            Print(L" #      Start LBA      End LBA  Type\n");
-        }
-        
-        gpt_parts[gpt_part_count].index     = i;
-        gpt_parts[gpt_part_count].start_lba = entry->start_lba;
-        gpt_parts[gpt_part_count].end_lba   = entry->end_lba;
-        gpt_parts[gpt_part_count].mbr_type  = 0;
-        copy_guid(gpt_parts[gpt_part_count].gpt_type, entry->type_guid);
-        gpt_parts[gpt_part_count].gpt_parttype = gpt_parttype(gpt_parts[gpt_part_count].gpt_type);
-        gpt_parts[gpt_part_count].active    = FALSE;
-        
-        Print(L" %d   %12lld %12lld  %s\n",
-              gpt_parts[gpt_part_count].index + 1,
-              gpt_parts[gpt_part_count].start_lba,
-              gpt_parts[gpt_part_count].end_lba,
-              gpt_parts[gpt_part_count].gpt_parttype->name);
-        
-        gpt_part_count++;
-    }
-    if (gpt_part_count == 0) {
-        Print(L" No partitions defined\n");
-        return 0;
-    }
-    
-    return 0;
-}
-
-//
-// detect file system type
-//
-
-UINTN detect_mbrtype_fs(UINT64 partlba, UINTN *parttype, CHARN **fsname)
-{
-    UINTN   status;
-    UINTN   signature, score;
-    UINTN   sectsize, clustersize, reserved, fatcount, dirsize, sectcount, fatsize, clustercount;
-    
-    *fsname = STR("Unknown");
-    *parttype = 0;
-    
-    // READ sector 0 / offset 0K
-    status = read_sector(partlba, sector);
-    if (status != 0)
-        return status;
-    
-    // detect XFS
-    memcpy(&signature, sector, sizeof(UINT32));
-    if (signature == 0x42534658) {
-        *parttype = 0x83;
-        *fsname = STR("XFS");
-        return 0;
-    }
-    
-    // detect FAT and NTFS
-    sectsize = *((UINT16 *)(sector + 11));
-    clustersize = sector[13];
-    if (sectsize >= 512 && (sectsize & (sectsize - 1)) == 0 &&
-        clustersize > 0 && (clustersize & (clustersize - 1)) == 0) {
-        // preconditions for both FAT and NTFS are now met
-        
-        if (CompareMem(sector + 3, "NTFS    ", 8) == 0) {
-            *parttype = 0x07;
-            *fsname = STR("NTFS");
-            return 0;
-        }
-        
-        score = 0;
-        // boot jump
-        if ((sector[0] == 0xEB && sector[2] == 0x90) || 
-            sector[0] == 0xE9)
-            score++;
-        // boot signature
-        if (sector[510] == 0x55 && sector[511] == 0xAA)
-            score++;
-        // reserved sectors
-        reserved = *((UINT16 *)(sector + 14));
-        if (reserved == 1 || reserved == 32)
-            score++;
-        // number of FATs
-        fatcount = sector[16];
-        if (fatcount == 2)
-            score++;
-        // number of root dir entries
-        dirsize = *((UINT16 *)(sector + 17));
-        // sector count (16-bit and 32-bit versions)
-        sectcount = *((UINT16 *)(sector + 19));
-        if (sectcount == 0)
-            sectcount = *((UINT32 *)(sector + 32));
-        // media byte
-        if (sector[21] == 0xF0 || sector[21] >= 0xF8)
-            score++;
-        // FAT size in sectors
-        fatsize = *((UINT16 *)(sector + 22));
-        if (fatsize == 0)
-            fatsize = *((UINT32 *)(sector + 36));
-        
-        // determine FAT type
-        dirsize = ((dirsize * 32) + (sectsize - 1)) / sectsize;
-        clustercount = sectcount - (reserved + (fatcount * fatsize) + dirsize);
-        clustercount /= clustersize;
-        
-        if (score >= 3) {
-            if (clustercount < 4085) {
-                *parttype = 0x01;
-                *fsname = STR("FAT12");
-            } else if (clustercount < 65525) {
-                *parttype = 0x0e;
-                *fsname = STR("FAT16");
-            } else {
-                *parttype = 0x0c;
-                *fsname = STR("FAT32");
-            }
-            // TODO: check if 0e and 0c are okay to use, maybe we should use 06 and 0b instead...
-            return 0;
-        }
-    }
-    
-    // READ sector 2 / offset 1K
-    status = read_sector(partlba + 2, sector);
-    if (status != 0)
-        return status;
-    
-    // detect HFS+
-    memcpy(&signature, sector, sizeof(UINT16));
-    if (signature == 0x4442) {
-        *parttype = 0xaf;
-        if (*((UINT16 *)(sector + 0x7c)) == 0x2B48)
-            *fsname = STR("HFS Extended (HFS+)");
-        else
-            *fsname = STR("HFS Standard");
-        return 0;
-    } else if (signature == 0x2B48) {
-        *parttype = 0xaf;
-        *fsname = STR("HFS Extended (HFS+)");
-        return 0;
-    }
-    
-    // detect ext2/ext3
-    signature = *((UINT16 *)(sector + 56));
-    if (signature == 0xEF53) {
-        *parttype = 0x83;
-        if (*((UINT16 *)(sector + 92)) & 0x0004)
-            *fsname = STR("ext3");
-        else
-            *fsname = STR("ext2");
-        return 0;
-    }
-    
-    // READ sector 128 / offset 64K
-    status = read_sector(partlba + 128, sector);
-    if (status != 0)
-        return status;
-    
-    // detect ReiserFS
-    if (CompareMem(sector + 52, "ReIsErFs", 8) == 0 ||
-        CompareMem(sector + 52, "ReIsEr2Fs", 9) == 0 ||
-        CompareMem(sector + 52, "ReIsEr3Fs", 9) == 0) {
-        *parttype = 0x83;
-        *fsname = STR("ReiserFS");
-        return 0;
-    }
-    
-    // detect Reiser4
-    if (CompareMem(sector, "ReIsEr4", 7) == 0) {
-        *parttype = 0x83;
-        *fsname = STR("Reiser4");
-        return 0;
-    }
-    
-    // READ sector 64 / offset 32K
-    status = read_sector(partlba + 64, sector);
-    if (status != 0)
-        return status;
-    
-    // detect JFS
-    if (CompareMem(sector, "JFS1", 4) == 0) {
-        *parttype = 0x83;
-        *fsname = STR("JFS");
-        return 0;
-    }
-    
-    // READ sector 16 / offset 8K
-    status = read_sector(partlba + 16, sector);
-    if (status != 0)
-        return status;
-    
-    // detect ReiserFS
-    if (CompareMem(sector + 52, "ReIsErFs", 8) == 0 ||
-        CompareMem(sector + 52, "ReIsEr2Fs", 9) == 0 ||
-        CompareMem(sector + 52, "ReIsEr3Fs", 9) == 0) {
-        *parttype = 0x83;
-        *fsname = STR("ReiserFS");
-        return 0;
-    }
-    
-    return 0;
-}
diff --git a/gptsync/os_unix.c b/gptsync/os_unix.c
deleted file mode 100644
index b43685b..0000000
--- a/gptsync/os_unix.c
+++ /dev/null
@@ -1,267 +0,0 @@
-/*
- * gptsync/os_unix.c
- * Unix OS glue for gptsync
- *
- * Copyright (c) 2006 Christoph Pfisterer
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- *  * Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- *
- *  * Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the
- *    distribution.
- *
- *  * Neither the name of Christoph Pfisterer nor the names of the
- *    contributors may be used to endorse or promote products derived
- *    from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "gptsync.h"
-
-#include <stdarg.h>
-
-#define STRINGIFY(s) #s
-#define STRINGIFY2(s) STRINGIFY(s)
-#define PROGNAME_S STRINGIFY2(PROGNAME)
-
-// variables
-
-static int      fd;
-
-//
-// error functions
-//
-
-void error(const char *msg, ...)
-{
-    va_list par;
-    char buf[4096];
-    
-    va_start(par, msg);
-    vsnprintf(buf, 4096, msg, par);
-    va_end(par);
-    
-    fprintf(stderr, PROGNAME_S ": %s\n", buf);
-}
-
-void errore(const char *msg, ...)
-{
-    va_list par;
-    char buf[4096];
-    
-    va_start(par, msg);
-    vsnprintf(buf, 4096, msg, par);
-    va_end(par);
-    
-    fprintf(stderr, PROGNAME_S ": %s: %s\n", buf, strerror(errno));
-}
-
-//
-// sector I/O functions
-//
-
-UINTN read_sector(UINT64 lba, UINT8 *buffer)
-{
-    off_t   offset;
-    off_t   result_seek;
-    ssize_t result_read;
-    
-    offset = lba * 512;
-    result_seek = lseek(fd, offset, SEEK_SET);
-    if (result_seek != offset) {
-        errore("Seek to %llu failed", offset);
-        return 1;
-    }
-    
-    result_read = read(fd, buffer, 512);
-    if (result_read < 0) {
-        errore("Data read failed at position %llu", offset);
-        return 1;
-    }
-    if (result_read != 512) {
-        errore("Data read fell short at position %llu", offset);
-        return 1;
-    }
-    return 0;
-}
-
-UINTN write_sector(UINT64 lba, UINT8 *buffer)
-{
-    off_t   offset;
-    off_t   result_seek;
-    ssize_t result_write;
-    
-    offset = lba * 512;
-    result_seek = lseek(fd, offset, SEEK_SET);
-    if (result_seek != offset) {
-        errore("Seek to %llu failed", offset);
-        return 1;
-    }
-    
-    result_write = write(fd, buffer, 512);
-    if (result_write < 0) {
-        errore("Data write failed at position %llu", offset);
-        return 1;
-    }
-    if (result_write != 512) {
-        errore("Data write fell short at position %llu", offset);
-        return 1;
-    }
-    return 0;
-}
-
-//
-// keyboard input
-//
-
-UINTN input_boolean(CHARN *prompt, BOOLEAN *bool_out)
-{
-    int c;
-    
-    printf("%s", prompt);
-    fflush(NULL);
-    
-    c = getchar();
-    if (c == EOF)
-        return 1;
-    
-    if (c == 'y' || c == 'Y') {
-        printf("Yes\n");
-        *bool_out = TRUE;
-    } else {
-        printf("No\n");
-        *bool_out = FALSE;
-    }
-    
-    return 0;
-}
-
-//
-// EFI-style print function
-//
-
-void Print(wchar_t *format, ...)
-{
-    va_list par;
-    char formatbuf[256];
-    char buf[4096];
-    int i;
-    
-    for (i = 0; format[i]; i++)
-        formatbuf[i] = (format[i] > 255) ? '?' : (char)(format[i] & 0xff);
-    formatbuf[i] = 0;
-    
-    va_start(par, format);
-    vsnprintf(buf, 4096, formatbuf, par);
-    va_end(par);
-    
-    printf("%s", buf);
-}
-
-//
-// main entry point
-//
-
-int main(int argc, char *argv[])
-{
-    char        *filename;
-    struct stat sb;
-    int         filekind;
-    UINT64      filesize;
-    char        *reason;
-    int         status;
-    
-    // argument check
-    if (argc != 2) {
-        fprintf(stderr, "Usage: " PROGNAME_S " <device>\n");
-        return 1;
-    }
-    filename = argv[1];
-    
-    // set input to unbuffered
-    fflush(NULL);
-    setvbuf(stdin, NULL, _IONBF, 0);
-    
-    // stat check
-    if (stat(filename, &sb) < 0) {
-        errore("Can't stat %.300s", filename);
-        return 1;
-    }
-    
-    filekind = 0;
-    filesize = 0;
-    reason = NULL;
-    if (S_ISREG(sb.st_mode))
-        filesize = sb.st_size;
-    else if (S_ISBLK(sb.st_mode))
-        filekind = 1;
-    else if (S_ISCHR(sb.st_mode))
-        filekind = 2;
-    else if (S_ISDIR(sb.st_mode))
-        reason = "Is a directory";
-    else if (S_ISFIFO(sb.st_mode))
-        reason = "Is a FIFO";
-#ifdef S_ISSOCK
-    else if (S_ISSOCK(sb.st_mode))
-        reason = "Is a socket";
-#endif
-    else
-        reason = "Is an unknown kind of special file";
-    
-    if (reason != NULL) {
-        error("%.300s: %s", filename, reason);
-        return 1;
-    }
-    
-    // open file
-    fd = open(filename, O_RDWR);
-    if (fd < 0 && errno == EBUSY) {
-        fd = open(filename, O_RDONLY);
-#ifndef NOREADONLYWARN
-        if (fd >= 0)
-            printf("Warning: %.300s opened read-only\n", filename);
-#endif
-    }
-    if (fd < 0) {
-        errore("Can't open %.300s", filename);
-        return 1;
-    }
-    
-    // (try to) guard against TTY character devices
-    if (filekind == 2) {
-        if (isatty(fd)) {
-            error("%.300s: Is a TTY device", filename);
-            return 1;
-        }
-    }
-    
-    // run sync algorithm
-    status = PROGNAME();
-    printf("\n");
-    
-    // close file
-    if (close(fd) != 0) {
-        errore("Error while closing %.300s", filename);
-        return 1;
-    }
-    
-    return status;
-}
diff --git a/gptsync/showpart.c b/gptsync/showpart.c
deleted file mode 100644
index 3d52ba3..0000000
--- a/gptsync/showpart.c
+++ /dev/null
@@ -1,257 +0,0 @@
-/*
- * gptsync/showpart.c
- * Platform-independent code for analyzing hard disk partitioning
- *
- * Copyright (c) 2006 Christoph Pfisterer
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- *  * Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- *
- *  * Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the
- *    distribution.
- *
- *  * Neither the name of Christoph Pfisterer nor the names of the
- *    contributors may be used to endorse or promote products derived
- *    from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "gptsync.h"
-
-//
-// memory string search
-//
-
-static INTN FindMem(VOID *Buffer, UINTN BufferLength, VOID *SearchString, UINTN SearchStringLength)
-{
-    UINT8 *BufferPtr;
-    UINTN Offset;
-    
-    BufferPtr = Buffer;
-    BufferLength -= SearchStringLength;
-    for (Offset = 0; Offset < BufferLength; Offset++, BufferPtr++) {
-        if (CompareMem(BufferPtr, SearchString, SearchStringLength) == 0)
-            return (INTN)Offset;
-    }
-    
-    return -1;
-}
-
-//
-// detect boot code
-//
-
-static UINTN detect_bootcode(UINT64 partlba, CHARN **bootcodename)
-{
-    UINTN   status;
-    BOOLEAN bootable;
-    
-    // read MBR data
-    status = read_sector(partlba, sector);
-    if (status != 0)
-        return status;
-    
-    // check bootable signature
-    if (*((UINT16 *)(sector + 510)) == 0xaa55 && sector[0] != 0)
-        bootable = TRUE;
-    else
-        bootable = FALSE;
-    *bootcodename = NULL;
-    
-    // detect specific boot codes
-    if (CompareMem(sector + 2, "LILO", 4) == 0 ||
-        CompareMem(sector + 6, "LILO", 4) == 0) {
-        *bootcodename = STR("LILO");
-        
-    } else if (CompareMem(sector + 3, "SYSLINUX", 8) == 0) {
-        *bootcodename = STR("SYSLINUX");
-        
-    } else if (FindMem(sector, 512, "ISOLINUX", 8) >= 0) {
-        *bootcodename = STR("ISOLINUX");
-        
-    } else if (FindMem(sector, 512, "Geom\0Hard Disk\0Read\0 Error\0", 27) >= 0) {
-        *bootcodename = STR("GRUB");
-        
-    } else if ((*((UINT32 *)(sector + 502)) == 0 &&
-                *((UINT32 *)(sector + 506)) == 50000 &&
-                *((UINT16 *)(sector + 510)) == 0xaa55) ||
-               FindMem(sector, 512, "Starting the BTX loader", 23) >= 0) {
-        *bootcodename = STR("FreeBSD");
-        
-    } else if (FindMem(sector, 512, "!Loading", 8) >= 0 ||
-               FindMem(sector, 512, "/cdboot\0/CDBOOT\0", 16) >= 0) {
-        *bootcodename = STR("OpenBSD");
-        
-    } else if (FindMem(sector, 512, "NTLDR", 5) >= 0) {
-        *bootcodename = STR("Windows NTLDR");
-        
-    } else if (FindMem(sector, 512, "BOOTMGR", 7) >= 0) {
-        *bootcodename = STR("Windows BOOTMGR (Vista)");
-        
-    } else if (FindMem(sector, 512, "CPUBOOT SYS", 11) >= 0 ||
-               FindMem(sector, 512, "KERNEL  SYS", 11) >= 0) {
-        *bootcodename = STR("FreeDOS");
-        
-    } else if (FindMem(sector, 512, "OS2LDR", 6) >= 0 ||
-               FindMem(sector, 512, "OS2BOOT", 7) >= 0) {
-        *bootcodename = STR("eComStation");
-        
-    } else if (FindMem(sector, 512, "Be Boot Loader", 14) >= 0) {
-        *bootcodename = STR("BeOS");
-        
-    } else if (FindMem(sector, 512, "yT Boot Loader", 14) >= 0) {
-        *bootcodename = STR("ZETA");
-        
-    } else if (FindMem(sector, 512, "\x04" "beos\x06" "system\x05" "zbeos", 18) >= 0) {
-        *bootcodename = STR("Haiku");
-        
-    }
-    
-    if (FindMem(sector, 512, "Non-system disk", 15) >= 0)   // dummy FAT boot sector
-        *bootcodename = STR("None (Non-system disk message)");
-    
-    // TODO: Add a note if a specific code was detected, but the sector is not bootable?
-    
-    if (*bootcodename == NULL) {
-        if (bootable)
-            *bootcodename = STR("Unknown, but bootable");
-        else
-            *bootcodename = STR("None");
-    }
-    
-    return 0;
-}
-
-//
-// check one partition
-//
-
-static UINTN analyze_part(UINT64 partlba)
-{
-    UINTN   status;
-    UINTN   i;
-    CHARN   *bootcodename;
-    UINTN   parttype;
-    CHARN   *fsname;
-    
-    if (partlba == 0)
-        Print(L"\nMBR contents:\n");
-    else
-        Print(L"\nPartition at LBA %lld:\n", partlba);
-    
-    // detect boot code
-    status = detect_bootcode(partlba, &bootcodename);
-    if (status)
-        return status;
-    Print(L" Boot Code: %s\n", bootcodename);
-    
-    if (partlba == 0)
-        return 0;   // short-circuit MBR analysis
-    
-    // detect file system
-    status = detect_mbrtype_fs(partlba, &parttype, &fsname);
-    if (status)
-        return status;
-    Print(L" File System: %s\n", fsname);
-    
-    // cross-reference with partition table
-    for (i = 0; i < gpt_part_count; i++) {
-        if (gpt_parts[i].start_lba == partlba) {
-            Print(L" Listed in GPT as partition %d, type %s\n", i+1,
-                  gpt_parts[i].gpt_parttype->name);
-        }
-    }
-    for (i = 0; i < mbr_part_count; i++) {
-        if (mbr_parts[i].start_lba == partlba) {
-            Print(L" Listed in MBR as partition %d, type %02x  %s%s\n", i+1,
-                  mbr_parts[i].mbr_type,
-                  mbr_parttype_name(mbr_parts[i].mbr_type),
-                  mbr_parts[i].active ? STR(", active") : STR(""));
-        }
-    }
-    
-    return 0;
-}
-
-//
-// check all partitions
-//
-
-static UINTN analyze_parts(VOID)
-{
-    UINTN   i, k;
-    UINTN   status;
-    BOOLEAN is_dupe;
-    
-    // check MBR (bootcode only)
-    status = analyze_part(0);
-    if (status)
-        return status;
-    
-    // check partitions listed in GPT
-    for (i = 0; i < gpt_part_count; i++) {
-        status = analyze_part(gpt_parts[i].start_lba);
-        if (status)
-            return status;
-    }
-    
-    // check partitions listed in MBR, but not in GPT
-    for (i = 0; i < mbr_part_count; i++) {
-        if (mbr_parts[i].start_lba == 1 && mbr_parts[i].mbr_type == 0xee)
-            continue;   // skip EFI Protective entry
-        
-        is_dupe = FALSE;
-        for (k = 0; k < gpt_part_count; k++)
-            if (gpt_parts[k].start_lba == mbr_parts[i].start_lba)
-                is_dupe = TRUE;
-        
-        if (!is_dupe) {
-            status = analyze_part(mbr_parts[i].start_lba);
-            if (status)
-                return status;
-        }
-    }
-    
-    return 0;
-}
-
-//
-// display algorithm entry point
-//
-
-UINTN showpart(VOID)
-{
-    UINTN   status = 0;
-    UINTN   status_gpt, status_mbr;
-    
-    // get full information from disk
-    status_gpt = read_gpt();
-    status_mbr = read_mbr();
-    if (status_gpt != 0 || status_mbr != 0)
-        return (status_gpt || status_mbr);
-    
-    // analyze all partitions
-    status = analyze_parts();
-    if (status != 0)
-        return status;
-    
-    return status;
-}
diff --git a/gptsync/syslinux_mbr.h b/gptsync/syslinux_mbr.h
deleted file mode 100644
index 1c33e11..0000000
--- a/gptsync/syslinux_mbr.h
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- * include/syslinux_mbr.h
- * MBR boot code
- *
- * The boot code in this file was taken from syslinux-3.11. It is covered
- * by the following license:
- *
- ; -----------------------------------------------------------------------
- ;   
- ;   Copyright 2003-2004 H. Peter Anvin - All Rights Reserved
- ;
- ;   Permission is hereby granted, free of charge, to any person
- ;   obtaining a copy of this software and associated documentation
- ;   files (the "Software"), to deal in the Software without
- ;   restriction, including without limitation the rights to use,
- ;   copy, modify, merge, publish, distribute, sublicense, and/or
- ;   sell copies of the Software, and to permit persons to whom
- ;   the Software is furnished to do so, subject to the following
- ;   conditions:
- ;   
- ;   The above copyright notice and this permission notice shall
- ;   be included in all copies or substantial portions of the Software.
- ;   
- ;   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- ;   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- ;   OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- ;   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- ;   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- ;   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- ;   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- ;   OTHER DEALINGS IN THE SOFTWARE.
- ;
- ; -----------------------------------------------------------------------
- *
- */
-
-#ifndef __SYSLINUX_MBR_H__
-#define __SYSLINUX_MBR_H__
-
-
-#define MBR_BOOTCODE_SIZE (440)
-
-
-#define SYSLINUX_MBR_SIZE (304)
-
-static UINT8 syslinux_mbr[SYSLINUX_MBR_SIZE] = {
-    0xfa, 0x31, 0xc0, 0x8e, 0xd8, 0x8e, 0xc0, 0x8e,
-    0xd0, 0xbc, 0x00, 0x7c, 0xfb, 0xfc, 0x89, 0xe6,
-    0xbf, 0x00, 0x06, 0xb9, 0x00, 0x01, 0xf3, 0xa5,
-    0xea, 0x1d, 0x06, 0x00, 0x00, 0x88, 0x16, 0x00,
-    0x08, 0xb4, 0x08, 0xcd, 0x13, 0x31, 0xc0, 0x88,
-    0xf0, 0x40, 0xa3, 0xf0, 0x06, 0x80, 0xe1, 0x3f,
-    0x88, 0x0e, 0xf2, 0x06, 0xbe, 0xbe, 0x07, 0x31,
-    0xc0, 0xb9, 0x04, 0x00, 0xf6, 0x04, 0x80, 0x74,
-    0x03, 0x40, 0x89, 0xf7, 0x83, 0xc6, 0x10, 0xe2,
-    0xf3, 0x83, 0xf8, 0x01, 0x75, 0x73, 0x8a, 0x16,
-    0x00, 0x08, 0xb8, 0x00, 0x41, 0xbb, 0xaa, 0x55,
-    0x31, 0xc9, 0x30, 0xf6, 0xf9, 0xcd, 0x13, 0x72,
-    0x23, 0x81, 0xfb, 0x55, 0xaa, 0x75, 0x1d, 0xf6,
-    0xc1, 0x01, 0x74, 0x18, 0x57, 0xbe, 0xe0, 0x06,
-    0x8b, 0x5d, 0x08, 0x89, 0x5c, 0x08, 0x8b, 0x5d,
-    0x0a, 0x89, 0x5c, 0x0a, 0x8a, 0x16, 0x00, 0x08,
-    0xb4, 0x42, 0xeb, 0x2a, 0x57, 0x8b, 0x45, 0x08,
-    0x8b, 0x55, 0x0a, 0xf7, 0x36, 0xf2, 0x06, 0x42,
-    0x89, 0xd1, 0x31, 0xd2, 0xf7, 0x36, 0xf0, 0x06,
-    0x88, 0xc5, 0xd1, 0xe8, 0xd1, 0xe8, 0x24, 0xc0,
-    0x08, 0xc1, 0x88, 0xd6, 0x8a, 0x16, 0x00, 0x08,
-    0xbb, 0x00, 0x7c, 0xb8, 0x01, 0x02, 0xcd, 0x13,
-    0x72, 0x16, 0x5e, 0x81, 0x3e, 0xfe, 0x7d, 0x55,
-    0xaa, 0x75, 0x08, 0xfa, 0xea, 0x00, 0x7c, 0x00,
-    0x00, 0x77, 0x05, 0xbe, 0xf4, 0x06, 0xeb, 0x03,
-    0xbe, 0x0f, 0x07, 0xac, 0x20, 0xc0, 0x74, 0x0c,
-    0xb4, 0x0e, 0x8a, 0x3e, 0x62, 0x04, 0xb3, 0x07,
-    0xcd, 0x10, 0xeb, 0xef, 0xeb, 0xfe, 0x00, 0x00,
-    0x10, 0x00, 0x01, 0x00, 0x00, 0x7c, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x4d, 0x69, 0x73, 0x73,
-    0x69, 0x6e, 0x67, 0x20, 0x6f, 0x70, 0x65, 0x72,
-    0x61, 0x74, 0x69, 0x6e, 0x67, 0x20, 0x73, 0x79,
-    0x73, 0x74, 0x65, 0x6d, 0x0d, 0x0a, 0x00, 0x4f,
-    0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6e, 0x67,
-    0x20, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x20,
-    0x6c, 0x6f, 0x61, 0x64, 0x69, 0x6e, 0x67, 0x20,
-    0x65, 0x72, 0x72, 0x6f, 0x72, 0x0d, 0x0a, 0x00
-};
-
-
-#endif /* __SYSLINUX_MBR_H__ */
-
-/* EOF */
diff --git a/gui.py b/gui.py
deleted file mode 100755
index a27a834..0000000
--- a/gui.py
+++ /dev/null
@@ -1,1530 +0,0 @@
-#
-# gui.py - Graphical front end for anaconda
-#
-# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007
-# Red Hat, Inc.  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 as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# 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, see <http://www.gnu.org/licenses/>.
-#
-# Author(s): Matt Wilson <msw@xxxxxxxxxx>
-#            Michael Fulbright <msf@xxxxxxxxxx>
-#
-
-import os
-from flags import flags
-os.environ["GNOME_DISABLE_CRASH_DIALOG"] = "1"
-
-# we only want to enable the accessibility stuff if requested for now...
-if flags.cmdline.has_key("dogtail"):
-    os.environ["GTK_MODULES"] = "gail:atk-bridge"
-
-import string
-import time
-import isys
-import iutil
-import sys
-import shutil
-import gtk
-import gtk.glade
-import gobject
-from language import expandLangs
-from constants import *
-from product import *
-from network import hasActiveNetDev
-from installinterfacebase import InstallInterfaceBase
-import xutils
-import imputil
-
-import gettext
-_ = lambda x: gettext.ldgettext("anaconda", x)
-
-import logging
-log = logging.getLogger("anaconda")
-
-isys.bind_textdomain_codeset("redhat-dist", "UTF-8")
-
-class StayOnScreen(Exception):
-    pass
-
-mainWindow = None
-
-stepToClass = {
-    "language" : ("language_gui", "LanguageWindow"),
-    "keyboard" : ("kbd_gui", "KeyboardWindow"),
-    "welcome" : ("welcome_gui", "WelcomeWindow"),
-    "filtertype" : ("filter_type", "FilterTypeWindow"),
-    "filter" : ("filter_gui", "FilterWindow"), 
-    "zfcpconfig" : ("zfcp_gui", "ZFCPWindow"),
-    "partition" : ("partition_gui", "PartitionWindow"),
-    "parttype" : ("autopart_type", "PartitionTypeWindow"),
-    "cleardiskssel": ("cleardisks_gui", "ClearDisksWindow"),
-    "findinstall" : ("examine_gui", "UpgradeExamineWindow"),
-    "addswap" : ("upgrade_swap_gui", "UpgradeSwapWindow"),
-    "upgrademigratefs" : ("upgrade_migratefs_gui", "UpgradeMigrateFSWindow"),
-    "bootloader": ("bootloader_main_gui", "MainBootloaderWindow"),
-    "upgbootloader": ("upgrade_bootloader_gui", "UpgradeBootloaderWindow"),
-    "network" : ("network_gui", "NetworkWindow"),
-    "timezone" : ("timezone_gui", "TimezoneWindow"),
-    "accounts" : ("account_gui", "AccountWindow"),
-    "tasksel": ("task_gui", "TaskWindow"),    
-    "group-selection": ("package_gui", "GroupSelectionWindow"),
-    "install" : ("progress_gui", "InstallProgressWindow"),
-    "complete" : ("congrats_gui", "CongratulationWindow"),
-}
-
-if iutil.isS390():
-    stepToClass["bootloader"] = ("zipl_gui", "ZiplWindow")
-
-#
-# Stuff for screenshots
-#
-screenshotDir = None
-screenshotIndex = 0
-
-def copyScreenshots():
-    global screenshotIndex
-    global screenshotDir
-    
-    # see if any screenshots taken
-    if screenshotIndex == 0:
-        return
-
-    destDir = "/mnt/sysimage/root/anaconda-screenshots"
-    if not os.access(destDir, os.R_OK):
-        try:
-            os.mkdir(destDir, 0750)
-        except:
-            window = MessageWindow("Error Saving Screenshot", 
-                                   _("An error occurred saving screenshots "
-                                     "to disk."), type="warning")
-            return
-
-    # copy all png's over
-    for f in os.listdir(screenshotDir):
-        (path, fname) = os.path.split(f)
-        (b, ext) = os.path.splitext(f)
-        if ext == ".png":
-            shutil.copyfile(screenshotDir + '/' + f, destDir + '/' + fname)
-
-    window = MessageWindow(_("Screenshots Copied"), 
-                           _("The screenshots have been saved in the "
-                             "directory:\n\n"
-                             "\t/root/anaconda-screenshots/\n\n"
-                             "You can access these when you reboot and "
-                             "login as root."))
-
-def takeScreenShot():
-    global screenshotIndex
-    global screenshotDir
-
-    if screenshotDir is None:
-        screenshotDir = "/tmp/anaconda-screenshots"
-
-    if not os.access(screenshotDir, os.R_OK):
-        try:
-            os.mkdir(screenshotDir)
-        except:
-            screenshotDir = None
-            return
-
-    try:
-        screenshot = gtk.gdk.Pixbuf(gtk.gdk.COLORSPACE_RGB, False, 8,
-                     gtk.gdk.screen_width(), gtk.gdk.screen_height())
-        screenshot.get_from_drawable(gtk.gdk.get_default_root_window(),
-                                     gtk.gdk.colormap_get_system(),
-                                     0, 0, 0, 0,
-                                     gtk.gdk.screen_width(),
-                                     gtk.gdk.screen_height())
-
-        if screenshot:
-            while (1):
-                sname = "screenshot-%04d.png" % ( screenshotIndex,)
-                if not os.access(screenshotDir + '/' + sname, os.R_OK):
-                    break
-
-                screenshotIndex = screenshotIndex + 1
-                if screenshotIndex > 9999:
-                    log.error("Too many screenshots!")
-                    return
-
-            screenshot.save (screenshotDir + '/' + sname, "png")
-            screenshotIndex = screenshotIndex + 1
-
-            window = MessageWindow(_("Saving Screenshot"), 
-               _("A screenshot named '%s' has been saved.") % (sname,) ,
-               type="ok")
-    except:
-        window = MessageWindow(_("Error Saving Screenshot"), 
-                               _("An error occurred while saving "
-                                 "the screenshot.  If this occurred "
-                                 "during package installation, you may need "
-                                 "to try several times for it to succeed."),
-                               type="warning")
-
-def handleShiftPrintScrnRelease (window, event):
-    if (event.keyval == gtk.keysyms.Print and event.state & gtk.gdk.SHIFT_MASK):
-        takeScreenShot()
-        
-#
-# HACK to make treeview work
-# 
- 
-def setupTreeViewFixupIdleHandler(view, store):
-    id = {}
-    id["id"] = gobject.idle_add(scrollToIdleHandler, (view, store, id))
-
-def scrollToIdleHandler((view, store, iddict)):
-    if not view or not store or not iddict:
-        return
-
-    try:
-        id = iddict["id"]
-    except:
-        return
-    
-    selection = view.get_selection()
-    if not selection:
-        return
-    
-    model, iter = selection.get_selected()
-    if not iter:
-        return
-
-    path = store.get_path(iter)
-    col = view.get_column(0)
-    view.scroll_to_cell(path, col, True, 0.5, 0.5)
-
-    if id:
-        gobject.source_remove(id)
-
-# setup globals
-def processEvents():
-    gtk.gdk.flush()
-    while gtk.events_pending():
-        gtk.main_iteration(False)
-
-def widgetExpander(widget, growTo=None):
-    widget.connect("size-allocate", growToParent, growTo)
-
-def growToParent(widget, rect, growTo=None):
-    if not widget.parent:
-        return
-    ignore = widget.__dict__.get("ignoreEvents")
-    if not ignore:
-        if growTo:
-            x, y, width, height = growTo.get_allocation()
-            widget.set_size_request(width, -1)
-        else:
-            widget.set_size_request(rect.width, -1)
-        widget.ignoreEvents = 1
-    else:
-        widget.ignoreEvents = 0
-
-_busyCursor = 0
-
-def setCursorToBusy(process=1):
-    root = gtk.gdk.get_default_root_window()
-    cursor = gtk.gdk.Cursor(gtk.gdk.WATCH)
-    root.set_cursor(cursor)
-    if process:
-        processEvents()
-
-def setCursorToNormal():
-    root = gtk.gdk.get_default_root_window()
-    cursor = gtk.gdk.Cursor(gtk.gdk.LEFT_PTR)
-    root.set_cursor(cursor)
-
-def rootPushBusyCursor(process=1):
-    global _busyCursor
-    _busyCursor += 1
-    if _busyCursor > 0:
-        setCursorToBusy(process)
-
-def rootPopBusyCursor():
-    global _busyCursor
-    _busyCursor -= 1
-    if _busyCursor <= 0:
-        setCursorToNormal()
-
-def getBusyCursorStatus():
-    global _busyCursor
-    
-    return _busyCursor
-
-class MnemonicLabel(gtk.Label):
-    def __init__(self, text="", alignment = None):
-        gtk.Label.__init__(self, "")
-        self.set_text_with_mnemonic(text)
-        if alignment is not None:
-            apply(self.set_alignment, alignment)
-
-class WrappingLabel(gtk.Label):
-    def __init__(self, label=""):
-        gtk.Label.__init__(self, label)
-        self.set_line_wrap(True)
-        self.ignoreEvents = 0
-        widgetExpander(self)
-
-def titleBarMousePressCB(widget, event, data):
-    if event.type & gtk.gdk.BUTTON_PRESS:
-        (x, y) = data["window"].get_position()
-        data["state"] = 1
-        data["button"] = event.button
-        data["deltax"] = event.x_root - x
-        data["deltay"] = event.y_root - y
-    
-def titleBarMouseReleaseCB(widget, event, data):
-    if data["state"] and event.button == data["button"]:
-        data["state"] = 0
-        data["button"] = 0
-        data["deltax"] = 0
-        data["deltay"] = 0
-
-def titleBarMotionEventCB(widget, event, data):
-    if data["state"]:
-        newx = event.x_root - data["deltax"]
-        newy = event.y_root - data["deltay"]
-        if newx < 0:
-            newx = 0
-        if newy < 0:
-            newy = 0
-        (w, h) = data["window"].get_size()
-        if (newx+w) > gtk.gdk.screen_width():
-            newx = gtk.gdk.screen_width() - w
-        if (newy+20) > (gtk.gdk.screen_height()):
-            newy = gtk.gdk.screen_height() - 20
-
-        data["window"].move(int(newx), int(newy))
-
-def addFrame(dialog, title=None):
-    # make screen shots work
-    dialog.connect ("key-release-event", handleShiftPrintScrnRelease)
-    if title:
-        dialog.set_title(title)
-
-def findGladeFile(file):
-    path = os.environ.get("GLADEPATH", "./:ui/:/tmp/updates/:/tmp/updates/ui/")
-    for dir in path.split(":"):
-        fn = dir + file
-        if os.access(fn, os.R_OK):
-            return fn
-    raise RuntimeError, "Unable to find glade file %s" % file
-
-def getGladeWidget(file, rootwidget, i18ndomain="anaconda"):
-    f = findGladeFile(file)
-    xml = gtk.glade.XML(f, root = rootwidget, domain = i18ndomain)
-    w = xml.get_widget(rootwidget)
-    if w is None:
-        raise RuntimeError, "Unable to find root widget %s in %s" %(rootwidget, file)
-
-    return (xml, w)
-
-def findPixmap(file):
-    path = os.environ.get("PIXMAPPATH", "./:pixmaps/:/tmp/updates/:/tmp/updates/pixmaps/")
-    for dir in path.split(":"):
-        fn = dir + file
-        if os.access(fn, os.R_OK):
-            return fn
-    return None
-
-def getPixbuf(file):
-    fn = findPixmap(file)
-    if not fn:
-        log.error("unable to load %s" %(file,))
-        return None
-
-    try:
-        pixbuf = gtk.gdk.pixbuf_new_from_file(fn)
-    except RuntimeError, msg:
-        log.error("unable to read %s: %s" %(file, msg))
-        pixbuf = None
-    
-    return pixbuf
-
-def readImageFromFile(file, width = None, height = None, dither = None,
-                      image = None):
-    pixbuf = getPixbuf(file)
-    if pixbuf is None:
-        log.warning("can't find pixmap %s" %(file,))
-        return None
-
-    if (width is not None and height is not None
-        and height != pixbuf.get_height()
-        and width != pixbuf.get_width()):
-        pixbuf = pixbuf.scale_simple(width, height,
-                                     gtk.gdk.INTERP_BILINEAR)
-
-    if image is None:
-        p = gtk.Image()
-    else:
-        p = image
-    if dither:
-        (pixmap, mask) = pixbuf.render_pixmap_and_mask()
-        pixmap.draw_pixbuf(gtk.gdk.GC(pixmap), pixbuf, 0, 0, 0, 0,
-                           pixbuf.get_width(), pixbuf.get_height(),
-                           gtk.gdk.RGB_DITHER_MAX, 0, 0)
-        p = gtk.Image()
-        p.set_from_pixmap(pixmap, mask)
-    else:
-        source = gtk.IconSource()
-        source.set_pixbuf(pixbuf)
-        source.set_size(gtk.ICON_SIZE_DIALOG)
-        source.set_size_wildcarded(False)
-        iconset = gtk.IconSet()
-        iconset.add_source(source)
-        p.set_from_icon_set(iconset, gtk.ICON_SIZE_DIALOG)
-
-    return p
-
-class WaitWindow:
-    def __init__(self, title, text, parent = None):
-        if flags.livecdInstall:
-            self.window = gtk.Window()
-            if parent:
-                self.window.set_transient_for(parent)
-        else:
-            self.window = gtk.Window()
-        self.window.set_modal(True)
-        self.window.set_type_hint (gtk.gdk.WINDOW_TYPE_HINT_DIALOG)
-        self.window.set_title(title)
-        self.window.set_position(gtk.WIN_POS_CENTER)
-        label = WrappingLabel(text)
-        box = gtk.Frame()
-        box.set_border_width(10)
-        box.add(label)
-        box.set_shadow_type(gtk.SHADOW_NONE)
-        self.window.add(box)
-        box.show_all()
-        addFrame(self.window)
-        # Displaying windows should not be done outside of the gtk
-        # mainloop. With metacity this bites us and we have to do
-        # window.show_now() AND refresh() to correctly display the window and
-        # its contents:
-        self.window.show_now()
-        rootPushBusyCursor()
-        self.refresh()
-
-    def refresh(self):
-        processEvents()
-            
-    def pop(self):
-        self.window.destroy()
-        rootPopBusyCursor()
-
-class ProgressWindow:
-    def __init__(self, title, text, total, updpct = 0.05, updsecs=10,
-                 parent = None, pulse = False):
-        if flags.livecdInstall:
-            self.window = gtk.Window()
-            if parent:
-                self.window.set_transient_for(parent)
-        else:
-            self.window = gtk.Window()
-
-        self.window.set_modal(True)
-        self.window.set_type_hint (gtk.gdk.WINDOW_TYPE_HINT_DIALOG)
-        self.window.set_title (title)
-        self.window.set_position (gtk.WIN_POS_CENTER)
-        self.lastUpdate = time.time()
-        self.updsecs = updsecs
-        box = gtk.VBox (False, 5)
-        box.set_border_width (10)
-
-        label = WrappingLabel (text)
-        label.set_alignment (0.0, 0.5)
-        box.pack_start (label, False)
-
-        self.total = total
-        self.updpct = updpct
-        self.progress = gtk.ProgressBar ()
-        box.pack_start (self.progress, True)
-        box.show_all()
-        self.window.add(box)
-        addFrame(self.window)
-        # see comment at WaitWindow.__init__():
-        self.window.show_now ()
-        rootPushBusyCursor()
-        self.refresh()
-
-    def refresh(self):
-        processEvents()
-
-    def pulse(self):
-        then = self.lastUpdate
-        now = time.time()
-        delta = now-then
-        if delta < 0.01:
-            return
-        self.progress.set_pulse_step(self.updpct)
-        self.lastUpdate = now
-        # if we've had a largish gap, some smoothing does actually help,
-        # but don't go crazy
-        if delta > 2:
-            delta=2
-        while delta > 0:
-            self.progress.pulse()
-            processEvents()
-            delta -= 0.05
-
-    def set (self, amount):
-        # only update widget if we've changed by 5% or our timeout has
-        # expired
-        curval = self.progress.get_fraction()
-        newval = float (amount) / self.total
-        then = self.lastUpdate
-        now = time.time()
-        if newval < 0.998:
-            if ((newval - curval) < self.updpct and (now-then) < self.updsecs):
-                return
-        self.lastUpdate = now
-        self.progress.set_fraction (newval)
-        processEvents ()
-
-    def pop(self):
-        self.window.destroy ()
-        rootPopBusyCursor()
-
-class InstallKeyWindow:
-    def __init__(self, anaconda, key):
-        (keyxml, self.win) = getGladeWidget("instkey.glade", "instkeyDialog")
-        if anaconda.instClass.instkeydesc is not None:
-            w = keyxml.get_widget("instkeyLabel")
-            w.set_text(_(anaconda.instClass.instkeydesc))
-
-        if not anaconda.instClass.allowinstkeyskip:
-            keyxml.get_widget("skipRadio").hide()
-
-        keyName = _(anaconda.instClass.instkeyname)
-        if anaconda.instClass.instkeyname is None:
-            keyName = _("Installation Key")
-
-        # set the install key name based on the installclass
-        for l in ("instkeyLabel", "keyEntryLabel", "skipLabel"):
-            w = keyxml.get_widget(l)
-            t = w.get_text()
-            w.set_text(t % {"instkey": keyName})
-
-        self.entry = keyxml.get_widget("keyEntry")
-        self.entry.set_text(key)
-        self.entry.set_sensitive(True)
-
-        self.keyradio = keyxml.get_widget("keyRadio")
-        self.skipradio = keyxml.get_widget("skipRadio")
-        self.rc = 0
-
-        if anaconda.instClass.skipkey:
-            self.skipradio.set_active(True)
-        else:
-            self.entry.grab_focus()
-
-        self.win.connect("key-release-event", self.keyRelease)
-        addFrame(self.win, title=keyName)        
-
-    def keyRelease(self, window, event):
-        # XXX hack: remove this, too, when the accelerators work again
-        if event.keyval == gtk.keysyms.F12:
-            window.response(1)
-
-    def run(self):
-        self.win.show()
-        self.rc = self.win.run()
-        return self.rc
-
-    def get_key(self):
-        if self.skipradio.get_active():
-            return SKIP_KEY
-        key = self.entry.get_text()
-        key.strip()
-        return key
-
-    def destroy(self):
-        self.win.destroy()
-
-class luksPassphraseWindow:
-    def __init__(self, passphrase=None, preexist = False, parent = None):
-        luksxml = gtk.glade.XML(findGladeFile("lukspassphrase.glade"),
-                                domain="anaconda",
-                                root="luksPassphraseDialog")
-        self.passphraseEntry = luksxml.get_widget("passphraseEntry")
-        self.passphraseEntry.set_visibility(False)
-        self.confirmEntry = luksxml.get_widget("confirmEntry")
-        self.confirmEntry.set_visibility(False)
-        self.win = luksxml.get_widget("luksPassphraseDialog")
-        self.okButton = luksxml.get_widget("okbutton1")
-        self.globalcheckbutton = luksxml.get_widget("globalcheckbutton")
-
-        self.isglobal = preexist
-        if not preexist:
-            self.globalcheckbutton.hide()
-        else:
-            self.globalcheckbutton.set_active(True)
-
-        self.minimumLength = 8  # arbitrary; should probably be much larger
-        if passphrase:
-            self.initialPassphrase = passphrase
-            self.passphraseEntry.set_text(passphrase)
-            self.confirmEntry.set_text(passphrase)
-        else:
-            self.initialPassphrase = ""
-
-        txt = _("Choose a passphrase for the encrypted devices. "
-                "You will be prompted for this passphrase during system "
-                "boot.")
-        luksxml.get_widget("mainLabel").set_text(txt)
-
-        if parent:
-            self.win.set_transient_for(parent)
-
-        addFrame(self.win)
-
-    def run(self):
-        self.win.show()
-        while True:
-            self.passphraseEntry.grab_focus()
-            self.rc = self.win.run()
-            if self.rc == gtk.RESPONSE_OK:
-                passphrase = self.passphraseEntry.get_text()
-                confirm = self.confirmEntry.get_text()
-                if passphrase != confirm:
-                    MessageWindow(_("Error with passphrase"),
-                                  _("The passphrases you entered were "
-                                    "different.  Please try again."),
-                                  type = "ok", custom_icon = "error")
-                    self.confirmEntry.set_text("")
-                    continue
-
-                if len(passphrase) < self.minimumLength:
-                    MessageWindow(_("Error with passphrase"),
-                                    _("The passphrase must be at least "
-                                      "eight characters long."),
-                                  type = "ok", custom_icon = "error")
-                    self.passphraseEntry.set_text("")
-                    self.confirmEntry.set_text("")
-                    continue
-
-                if self.isglobal:
-                    self.isglobal = self.globalcheckbutton.get_active()
-            else:
-                self.passphraseEntry.set_text(self.initialPassphrase)
-                self.confirmEntry.set_text(self.initialPassphrase)
-
-            return self.rc
-
-    def getPassphrase(self):
-        return self.passphraseEntry.get_text()
-
-    def getGlobal(self):
-        return self.isglobal
-
-    def getrc(self):
-        return self.rc
-
-    def destroy(self):
-        self.win.destroy()
-
-class PassphraseEntryWindow:
-    def __init__(self, device, parent = None):
-        def ok(*args):
-            self.win.response(gtk.RESPONSE_OK)
-        xml = gtk.glade.XML(findGladeFile("lukspassphrase.glade"),
-                            domain="anaconda",
-                            root="passphraseEntryDialog")
-        self.txt = _("Device %s is encrypted. In order to "
-                     "access the device's contents during "
-                     "installation you must enter the device's "
-                     "passphrase below.") % (device,)
-        self.win = xml.get_widget("passphraseEntryDialog")
-        self.passphraseLabel = xml.get_widget("passphraseLabel")
-        self.passphraseEntry = xml.get_widget("passphraseEntry2")
-        self.globalcheckbutton = xml.get_widget("globalcheckbutton")
-
-        if parent:
-            self.win.set_transient_for(parent)
-
-        self.passphraseEntry.connect('activate', ok)
-        addFrame(self.win)
-
-    def run(self):
-        self.win.show()
-        self.passphraseLabel.set_text(self.txt)
-        self.passphraseEntry.grab_focus()
-
-        busycursor = getBusyCursorStatus()
-        setCursorToNormal()
-
-        rc = self.win.run()
-        passphrase = None
-        isglobal = False
-        if rc == gtk.RESPONSE_OK:
-            passphrase = self.passphraseEntry.get_text()
-            isglobal = self.globalcheckbutton.get_active()
-
-        if busycursor:
-            setCursorToBusy()
-
-        self.rc = (passphrase, isglobal)
-        return self.rc
-
-    def getrc(self):
-        return self.rc
-
-    def destroy(self):
-        self.win.destroy()
-
-class MessageWindow:
-    def getrc (self):
-        return self.rc
-
-    def __init__ (self, title, text, type="ok", default=None, custom_buttons=None, custom_icon=None, run = True, parent = None, destroyAfterRun = True):
-        self.debugRid = None
-        self.title = title
-        if flags.autostep:
-            self.rc = 1
-            return
-        self.rc = None
-        self.framed = False
-        self.doCustom = False
-
-        style = 0
-        if type == 'ok':
-            buttons = gtk.BUTTONS_OK
-            style = gtk.MESSAGE_INFO
-        elif type == 'warning':
-            buttons = gtk.BUTTONS_OK
-            style = gtk.MESSAGE_WARNING
-        elif type == 'okcancel':
-            buttons = gtk.BUTTONS_OK_CANCEL
-            style = gtk.MESSAGE_WARNING
-        elif type == 'yesno':
-            buttons = gtk.BUTTONS_YES_NO
-            style = gtk.MESSAGE_QUESTION
-        elif type == 'custom':
-            self.doCustom = True
-            buttons = gtk.BUTTONS_NONE
-            style = gtk.MESSAGE_QUESTION
-
-        if custom_icon == "warning":
-            style = gtk.MESSAGE_WARNING
-        elif custom_icon == "question":
-            style = gtk.MESSAGE_QUESTION
-        elif custom_icon == "error":
-            style = gtk.MESSAGE_ERROR
-        elif custom_icon == "info":
-            style = gtk.MESSAGE_INFO
-
-        self.dialog = gtk.MessageDialog(mainWindow, 0, style, buttons, str(text))
-
-        if parent:
-            self.dialog.set_transient_for(parent)
-
-        if self.doCustom:
-            rid=0
-            for button in custom_buttons:
-                if button == _("Cancel"):
-                    tbutton = "gtk-cancel"
-                else:
-                    tbutton = button
-
-                widget = self.dialog.add_button(tbutton, rid)
-                rid = rid + 1
-
-            if default is not None:
-                defaultchoice = default
-            else:
-                defaultchoice = rid - 1
-            if flags.debug and not _("_Debug") in custom_buttons:
-                widget = self.dialog.add_button(_("_Debug"), rid)
-                self.debugRid = rid
-                rid += 1
-
-        else:
-            if default == "no":
-                defaultchoice = 0
-            elif default == "yes" or default == "ok":
-                defaultchoice = 1
-            else:
-                defaultchoice = 0
-
-        self.dialog.set_position (gtk.WIN_POS_CENTER)
-        self.dialog.set_default_response(defaultchoice)
-        if run:
-            self.run(destroyAfterRun)
-
-    def run(self, destroy = False):
-        if not self.framed:
-            addFrame(self.dialog, title=self.title)
-            self.framed = True
-        self.dialog.show_all ()
-
-        # XXX - Messy - turn off busy cursor if necessary
-        busycursor = getBusyCursorStatus()
-        setCursorToNormal()
-        self.rc = self.dialog.run()
-
-        if not self.doCustom:
-            if self.rc in [gtk.RESPONSE_OK, gtk.RESPONSE_YES]:
-                self.rc = 1
-            elif self.rc in [gtk.RESPONSE_CANCEL, gtk.RESPONSE_NO,
-                             gtk.RESPONSE_CLOSE, gtk.RESPONSE_DELETE_EVENT]:
-                self.rc = 0
-        else:
-            # generated by Esc key
-            if self.rc == gtk.RESPONSE_DELETE_EVENT:
-                self.rc = 0
-
-        if not self.debugRid is None and self.rc == self.debugRid:
-            self.debugClicked(self)
-            return self.run(destroy)
-
-        if destroy:
-            self.dialog.destroy()
-
-        # restore busy cursor
-        if busycursor:
-            setCursorToBusy()
-
-    def debugClicked (self, *args):
-        try:
-            # switch to VC1 so we can debug
-            isys.vtActivate (1)
-        except SystemError:
-            pass
-        import pdb
-        try:
-            pdb.set_trace()
-        except:
-            sys.exit(-1)
-        try:
-            # switch back
-            isys.vtActivate (6)
-        except SystemError:
-            pass
-
-class DetailedMessageWindow(MessageWindow):
-    def __init__(self, title, text, longText=None, type="ok", default=None, custom_buttons=None, custom_icon=None, run=True, parent=None, destroyAfterRun=True, expanded=False):
-        self.title = title
-
-        if flags.autostep:
-            self.rc = 1
-            return
-
-        self.debugRid = None
-        self.rc = None
-        self.framed = False
-        self.doCustom = False
-
-        if type == 'ok':
-            buttons = ["gtk-ok"]
-        elif type == 'warning':
-            buttons = ["gtk-ok"]
-        elif type == 'okcancel':
-            buttons = ["gtk-ok", "gtk-cancel"]
-        elif type == 'yesno':
-            buttons = ["gtk-yes", "gtk-no"]
-        elif type == 'custom':
-            self.doCustom = True
-            buttons = custom_buttons
-
-        xml = gtk.glade.XML(findGladeFile("detailed-dialog.glade"), domain="anaconda")
-        self.dialog = xml.get_widget("detailedDialog")
-        self.mainVBox = xml.get_widget("mainVBox")
-        self.hbox = xml.get_widget("hbox1")
-        self.info = xml.get_widget("info")
-        self.detailedExpander = xml.get_widget("detailedExpander")
-        self.detailedView = xml.get_widget("detailedView")
-
-        self.detailedExpander.set_expanded(expanded)
-
-        if parent:
-            self.dialog.set_transient_for(parent)
-
-        if custom_icon:
-            img = gtk.Image()
-            img.set_from_file(custom_icon)
-            self.hbox.pack_start(img)
-            self.hbox.reorder_child(img, 0)
-
-        rid = 0
-        for button in buttons:
-            self.dialog.add_button(button, rid)
-            rid += 1
-
-        if self.doCustom:
-            defaultchoice = rid-1
-            if flags.debug and not _("_Debug") in buttons:
-                self.dialog.add_button(_("_Debug"), rid)
-                self.debugRid = rid
-                rid += 1
-        else:
-            if default == "no":
-                defaultchoice = 0
-            elif default == "yes" or default == "ok":
-                defaultchoice = 1
-            else:
-                defaultchoice = 0
-
-        self.info.set_text(text)
-
-        if longText:
-            textbuf = gtk.TextBuffer()
-            iter = textbuf.get_start_iter()
-
-            for line in longText:
-                if __builtins__.get("type")(line) != unicode:
-                    try:
-                        line = unicode(line, encoding='utf-8')
-                    except UnicodeDecodeError, e:
-                        log.error("UnicodeDecodeException: line = %s" % (line,))
-                        log.error("UnicodeDecodeException: %s" % (str(e),))
-
-                textbuf.insert(iter, line)
-
-            self.detailedView.set_buffer(textbuf)
-        else:
-            self.mainVBox.remove(self.detailedExpander)
-
-        self.dialog.set_position (gtk.WIN_POS_CENTER)
-        self.dialog.set_default_response(defaultchoice)
-
-        if run:
-            self.run(destroyAfterRun)
-
-class EntryWindow(MessageWindow):
-    def __init__ (self, title, text, prompt, entrylength = None):
-        mainWindow = None
-        MessageWindow.__init__(self, title, text, type = "okcancel", custom_icon="question", run = False)
-        self.entry = gtk.Entry()
-        if entrylength:
-            self.entry.set_width_chars(entrylength)
-            self.entry.set_max_length(entrylength)
-
-        # eww, eww, eww... but if we pack in the vbox, it goes to the right
-        # place!
-        self.dialog.child.pack_start(self.entry)
-
-    def run(self):
-        MessageWindow.run(self)
-        if self.rc == 0:
-            return None
-        t = self.entry.get_text()
-        t.strip()
-        if len(t) == 0:
-            return None
-        return t
-
-    def destroy(self):
-        self.dialog.destroy()
-
-class InstallInterface(InstallInterfaceBase):
-    def __init__ (self):
-        InstallInterfaceBase.__init__(self)
-        self.icw = None
-        self.installProgress = None
-
-        # figure out if we want to run interface at 800x600 or 640x480
-        if gtk.gdk.screen_width() >= 800:
-            self.runres = "800x600"
-        else:
-            self.runres = "640x480"
-        root = gtk.gdk.get_default_root_window()
-        cursor = gtk.gdk.Cursor(gtk.gdk.LEFT_PTR)
-        root.set_cursor(cursor)
-        self._initLabelAnswers = {}
-        self._inconsistentLVMAnswers = {}
-
-    def __del__ (self):
-        pass
-
-    def shutdown (self):
-        pass
-
-    def suspend(self):
-        pass
-    
-    def resume(self):
-        pass
-
-    def enableNetwork(self):
-        if len(self.anaconda.network.netdevices) == 0:
-            return False
-        from netconfig_dialog import NetworkConfigurator
-        net = NetworkConfigurator(self.anaconda.network)
-        ret = net.run()
-        net.destroy()
-
-        return ret not in [gtk.RESPONSE_CANCEL, gtk.RESPONSE_DELETE_EVENT]
-
-    def setInstallProgressClass(self, c):
-        self.instProgress = c
-
-    def setPackageProgressWindow (self, ppw):
-        self.ppw = ppw
-
-    def waitWindow (self, title, text):
-        if self.icw:
-            return WaitWindow (title, text, self.icw.window)
-        else:
-            return WaitWindow (title, text)
-
-    def progressWindow (self, title, text, total, updpct = 0.05, pulse = False):
-        if self.icw:
-            return ProgressWindow (title, text, total, updpct,
-                                   parent = self.icw.window, pulse = pulse)
-        else:
-            return ProgressWindow (title, text, total, updpct, pulse = pulse)
-
-    def messageWindow(self, title, text, type="ok", default = None,
-             custom_buttons=None,  custom_icon=None):
-        if self.icw:
-            parent = self.icw.window
-        else:
-            parent = None
-
-        rc = MessageWindow (title, text, type, default,
-                custom_buttons, custom_icon, run=True, parent=parent).getrc()
-        return rc
-
-    def createRepoWindow(self):
-        from task_gui import RepoCreator
-        dialog = RepoCreator(self.anaconda)
-        dialog.createDialog()
-        dialog.run()
-
-    def editRepoWindow(self, repoObj):
-        from task_gui import RepoEditor
-        dialog = RepoEditor(self.anaconda, repoObj)
-        dialog.createDialog()
-        dialog.run()
-
-    def methodstrRepoWindow(self, methodstr):
-        from task_gui import RepoMethodstrEditor
-        dialog = RepoMethodstrEditor(self.anaconda, methodstr)
-        dialog.createDialog()
-        return dialog.run()
-
-    def entryWindow(self, title, text, type="ok", entrylength = None):
-        d = EntryWindow(title, text, type, entrylength)
-        rc = d.run()
-        d.destroy()
-        return rc
-
-    def detailedMessageWindow(self, title, text, longText=None, type="ok",
-                              default=None, custom_buttons=None,
-                              custom_icon=None, expanded=False):
-        if self.icw:
-            parent = self.icw.window
-        else:
-            parent = None
-
-        rc = DetailedMessageWindow (title, text, longText, type, default,
-                                    custom_buttons, custom_icon, run=True,
-                                    parent=parent, expanded=expanded).getrc()
-        return rc
-
-    def mainExceptionWindow(self, shortText, longTextFile):
-        from meh.ui.gui import MainExceptionWindow
-        log.critical(shortText)
-        win = MainExceptionWindow (shortText, longTextFile)
-        addFrame(win.dialog)
-        return win
-
-    def saveExceptionWindow(self, accountManager, signature):
-        from meh.ui.gui import SaveExceptionWindow
-        win = SaveExceptionWindow (accountManager, signature)
-        win.run()
-
-    def exitWindow(self, title, text):
-        if self.icw:
-            parent = self.icw.window
-        else:
-            parent = None
-
-        rc = MessageWindow (title, text, type="custom",
-                            custom_icon="info", parent=parent,
-                            custom_buttons=[_("_Exit installer")]).getrc()
-        return rc
-
-    def getLuksPassphrase(self, passphrase = "", preexist = False):
-        if self.icw:
-            parent = self.icw.window
-        else:
-            parent = None
-
-        d = luksPassphraseWindow(passphrase, parent = parent,
-                                 preexist = preexist)
-        rc = d.run()
-        passphrase = d.getPassphrase()
-        isglobal = d.getGlobal()
-        d.destroy()
-        return (passphrase, isglobal)
-
-    def passphraseEntryWindow(self, device):
-        if self.icw:
-            parent = self.icw.window
-        else:
-            parent = None
-
-        d = PassphraseEntryWindow(device, parent = parent)
-        rc = d.run()
-        d.destroy()
-        return rc
-
-    def resetInitializeDiskQuestion(self):
-        self._initLabelAnswers = {}
-
-    def questionInitializeDisk(self, path, description, size, details=""):
-
-        retVal = False # The less destructive default
-
-        if not path:
-            return retVal
-
-        # we are caching answers so that we don't
-        # ask in each storage.reset() again
-        if path in self._initLabelAnswers:
-            log.info("UI not asking about disk initialization, "
-                     "using cached answer: %s" % self._initLabelAnswers[path])
-            return self._initLabelAnswers[path]
-        elif "all" in self._initLabelAnswers:
-            log.info("UI not asking about disk initialization, "
-                     "using cached answer: %s" % self._initLabelAnswers["all"])
-            return self._initLabelAnswers["all"]
-
-        rc = self.messageWindow(_("Warning"),
-                _("Error processing drive:\n\n"
-                  "%(path)s\n%(size)-0.fMB\n%(description)s\n\n"
-                  "This device may need to be reinitialized.\n\n"
-                  "REINITIALIZING WILL CAUSE ALL DATA TO BE LOST!\n\n"
-                  "This action may also be applied to all other disks "
-                  "needing reinitialization.%(details)s")
-                % {'path': path, 'size': size,
-                   'description': description, 'details': details},
-                type="custom",
-                custom_buttons = [ _("_Ignore"),
-                                   _("Ignore _all"),
-                                   _("_Re-initialize"),
-                                   _("Re-ini_tialize all") ],
-                custom_icon="question")
-        if rc == 0:
-            retVal = False
-        elif rc == 1:
-            path = "all"
-            retVal = False
-        elif rc == 2:
-            retVal = True
-        elif rc == 3:
-            path = "all"
-            retVal = True
-
-        self._initLabelAnswers[path] = retVal
-        return retVal
-
-    def resetReinitInconsistentLVMQuestion(self):
-        self._inconsistentLVMAnswers = {}
-
-    def questionReinitInconsistentLVM(self, pv_names=None, lv_name=None, vg_name=None):
-
-        retVal = False # The less destructive default
-        allSet = frozenset(["all"])
-
-        if not pv_names or (lv_name is None and vg_name is None):
-            return retVal
-
-        # We are caching answers so that we don't ask for ignoring
-        # in each storage.reset() again (note that reinitialization is
-        # done right after confirmation in dialog, not as a planned
-        # action).
-        key = frozenset(pv_names)
-        if key in self._inconsistentLVMAnswers:
-            log.info("UI not asking about disk initialization, "
-                     "using cached answer: %s" % self._inconsistentLVMAnswers[key])
-            return self._inconsistentLVMAnswers[key]
-        elif allSet in self._inconsistentLVMAnswers:
-            log.info("UI not asking about disk initialization, "
-                     "using cached answer: %s" % self._inconsistentLVMAnswers[allSet])
-            return self._inconsistentLVMAnswers[allSet]
-
-        if vg_name is not None:
-            message = "Volume Group %s" % vg_name
-        elif lv_name is not None:
-            message = "Logical Volume %s" % lv_name
-
-        na = {'msg': message, 'pvs': ", ".join(pv_names)}
-        rc = self.messageWindow(_("Warning"),
-                  _("Error processing LVM.\n"
-                    "There is inconsistent LVM data on %(msg)s.  You can "
-                    "reinitialize all related PVs (%(pvs)s) which will erase "
-                    "the LVM metadata, or ignore which will preserve the "
-                    "contents.  This action may also be applied to all other "
-                    "PVs with inconsistent metadata.") % na,
-                type="custom",
-                custom_buttons = [ _("_Ignore"),
-                                   _("Ignore _all"),
-                                   _("_Re-initialize"),
-                                   _("Re-ini_tialize all") ],
-                custom_icon="question")
-        if rc == 0:
-            retVal = False
-        elif rc == 1:
-            key = allSet
-            retVal = False
-        elif rc == 2:
-            retVal = True
-        elif rc == 3:
-            key = allSet
-            retVal = True
-
-        self._inconsistentLVMAnswers[key] = retVal
-        return retVal
-
-    def beep(self):
-        gtk.gdk.beep()
-
-    def kickstartErrorWindow(self, text):
-        s = _("The following error was found while parsing the "
-              "kickstart configuration file:\n\n%s") %(text,)
-        return self.messageWindow(_("Error Parsing Kickstart Config"),
-                                  s,
-                                  type = "custom",
-                                  custom_buttons = [_("_Exit installer")],
-                                  custom_icon = "error")
-
-    def getBootdisk (self):
-        return None
-
-    def run(self, anaconda):
-        self.anaconda = anaconda
-
-        if anaconda.keyboard and not flags.livecdInstall:
-            anaconda.keyboard.activate()
-
-        self.icw = InstallControlWindow (self.anaconda)
-        self.icw.run (self.runres)
-
-    def setSteps(self, anaconda):
-        pass
-
-class InstallControlWindow:
-    def setLanguage (self):
-        if not self.__dict__.has_key('window'): return
-        self.reloadRcQueued = 1
-        self.setup_window(True)
-
-    def setLtR(self):
-        ltrrtl = gettext.dgettext("gtk20", "default:LTR")
-        if ltrrtl == "default:RTL":
-            gtk.widget_set_default_direction (gtk.TEXT_DIR_RTL)
-        elif ltrrtl == "default:LTR":
-            gtk.widget_set_default_direction (gtk.TEXT_DIR_LTR)
-        else:
-            log.error("someone didn't translate the ltr bits right: %s" %(ltrrtl,))
-            gtk.widget_set_default_direction (gtk.TEXT_DIR_LTR)            
-        
-    def prevClicked (self, *args):
-        try:
-            self.currentWindow.getPrev ()
-        except StayOnScreen:
-            return
-
-        self.anaconda.dispatch.gotoPrev()
-        self.setScreen ()
-
-    def nextClicked (self, *args):
-        try:
-            rc = self.currentWindow.getNext ()
-        except StayOnScreen:
-            return
-
-        self.anaconda.dispatch.gotoNext()
-        self.setScreen ()
-
-    def debugClicked (self, *args):
-        try:
-            # switch to VC1 so we can debug
-            isys.vtActivate (1)
-        except SystemError:
-            pass
-        import pdb
-        try:
-            pdb.set_trace()
-        except:
-            sys.exit(-1)
-        try:
-            # switch back
-            isys.vtActivate (6)
-        except SystemError:
-            pass
-
-    def handleRenderCallback(self):
-        self.currentWindow.renderCallback()
-        if flags.autostep:
-            if flags.autoscreenshot:
-                # let things settle down graphically
-                processEvents()
-                time.sleep(1)
-                takeScreenShot()
-            self.nextClicked()
-        else:
-            gobject.source_remove(self.handle)
-
-    def setScreen (self):
-        (step, anaconda) = self.anaconda.dispatch.currentStep()
-        if step is None:
-            gtk.main_quit()
-            return
-
-        if not stepToClass[step]:
-            if self.anaconda.dispatch.dir == DISPATCH_FORWARD:
-                return self.nextClicked()
-            else:
-                return self.prevClicked()
-
-        (file, className) = stepToClass[step]
-        newScreenClass = None
-
-        while True:
-            try:
-                found = imputil.imp.find_module(file)
-                loaded = imputil.imp.load_module(className, found[0], found[1],
-                                                 found[2])
-                newScreenClass = loaded.__dict__[className]
-                break
-            except ImportError, e:
-                print(e)
-                win = MessageWindow(_("Error!"),
-                                    _("An error occurred when attempting "
-                                      "to load an installer interface "
-                                      "component.\n\nclassName = %s")
-                                    % (className,),
-                                    type="custom", custom_icon="warning",
-                                    custom_buttons=[_("_Exit"),
-                                                    _("_Retry")])
-                if not win.getrc():
-                    msg =  _("The system will now reboot.")
-                    buttons = [_("_Reboot")]
-
-                    MessageWindow(_("Exiting"),
-                                  msg,
-                                  type="custom",
-                                  custom_icon="warning",
-                                  custom_buttons=buttons)
-                    sys.exit(0)
-
-        ics = InstallControlState (self)
-        ics.setPrevEnabled(self.anaconda.dispatch.canGoBack())
-        self.destroyCurrentWindow()
-        self.currentWindow = newScreenClass(ics)
-
-        new_screen = self.currentWindow.getScreen(anaconda)
-
-        # If the getScreen method returned None, that means the screen did not
-        # want to be displayed for some reason and we should skip to the next
-        # step.  However, we do not want to remove the current step from the
-        # list as later events may cause the screen to be displayed.
-        if not new_screen:
-            if self.anaconda.dispatch.dir == DISPATCH_FORWARD:
-                self.anaconda.dispatch.gotoNext()
-            else:
-                self.anaconda.dispatch.gotoPrev()
-
-            return self.setScreen()
-
-        self.update (ics)
-
-        self.installFrame.add(new_screen)
-        self.installFrame.show_all()
-
-        self.currentWindow.focus()
-
-        self.handle = gobject.idle_add(self.handleRenderCallback)
-
-        if self.reloadRcQueued:
-            self.window.reset_rc_styles()
-            self.reloadRcQueued = 0
-
-    def destroyCurrentWindow(self):
-        children = self.installFrame.get_children ()
-        if children:
-            child = children[0]
-            self.installFrame.remove (child)
-            child.destroy ()
-        self.currentWindow = None
-
-    def update (self, ics):
-        self.mainxml.get_widget("backButton").set_sensitive(ics.getPrevEnabled())
-        self.mainxml.get_widget("nextButton").set_sensitive(ics.getNextEnabled())
-
-        if ics.getGrabNext():
-            self.mainxml.get_widget("nextButton").grab_focus()
-
-        self.mainxml.get_widget("nextButton").set_flags(gtk.HAS_DEFAULT)
-
-    def __init__ (self, anaconda):
-        self.reloadRcQueued = 0
-        self.currentWindow = None
-        self.anaconda = anaconda
-        self.handle = None
-        self.window = None
-
-    def keyRelease (self, window, event):
-        if ((event.keyval == gtk.keysyms.KP_Delete
-             or event.keyval == gtk.keysyms.Delete)
-            and (event.state & (gtk.gdk.CONTROL_MASK | gtk.gdk.MOD1_MASK))):
-            self._doExit()
-        # XXX hack: remove me when the accelerators work again.
-        elif (event.keyval == gtk.keysyms.F12
-              and self.currentWindow.getICS().getNextEnabled()):
-            self.nextClicked()
-        elif (event.keyval == gtk.keysyms.Print
-              and event.state & gtk.gdk.SHIFT_MASK):
-            takeScreenShot()
-
-    def _doExit (self, *args):
-        gtk.main_quit()
-        os._exit(0)
-
-    def _doExitConfirm (self, win = None, *args):
-        # FIXME: translate the string
-        win = MessageWindow(_("Exit installer"),
-                            _("Are you sure you wish to exit the installer?"),
-                            type="custom", custom_icon="question",
-                            custom_buttons = [_("Cancel"), _("_Exit installer")],
-                            parent = win)
-        if win.getrc() == 0:
-            return True
-        self._doExit()
-
-    def createWidgets (self):
-        self.window.set_title(_("%s Installer") %(productName,))
-        
-        i = self.mainxml.get_widget("headerImage")        
-        p = readImageFromFile("anaconda_header.png",
-                              dither = False, image = i)
-        if p is None:
-            print(_("Unable to load title bar"))
-        if (gtk.gdk.screen_height() < 600) or \
-                (gtk.gdk.screen_height() <= 675 and flags.livecdInstall):
-            i.hide()
-            self.window.set_resizable(True)
-            self.window.set_size_request(-1, -1)
-            self.window.fullscreen()
-        else:
-            self.window.set_size_request(800, 600)
-            # if we're running in the live mode and the dpi is something weird,
-            # give ourselves as much space as we can.  this gets things to fit
-            # with a dpi of up to 147
-            if flags.livecdInstall:
-                i.hide()
-            elif flags.preexisting_x11:
-                # running on a pre-existing X, probably through X11 forwarding
-                pass 
-            else:
-                self.window.set_type_hint(gtk.gdk.WINDOW_TYPE_HINT_DESKTOP)
-
-        if flags.debug:
-            self.mainxml.get_widget("debugButton").show_now()
-        self.installFrame = self.mainxml.get_widget("installFrame")
-
-    def connectSignals(self):
-        sigs = { "on_nextButton_clicked": self.nextClicked,
-            "on_rebootButton_clicked": self._doExit,
-            "on_closeButton_clicked": self._doExit,                 
-            "on_backButton_clicked": self.prevClicked,
-            "on_debugButton_clicked": self.debugClicked,
-            "on_mainWindow_key_release_event": self.keyRelease,
-            "on_mainWindow_delete_event": self._doExitConfirm, }
-        self.mainxml.signal_autoconnect(sigs)
-
-    def loadGlade(self):
-        self.mainxml = gtk.glade.XML(findGladeFile("anaconda.glade"),
-                                     domain="anaconda")
-
-    def setup_theme(self):
-        settings = gtk.settings_get_default()
-        settings.set_long_property("gtk-button-images", 0, "gui.py:setup_theme")
-
-    def setup_window (self, window_reload):
-        self.setLtR()
-
-        if window_reload:
-            self.window.destroy()
-
-        self.loadGlade()
-        self.window = self.mainxml.get_widget("mainWindow")
-
-        self.createWidgets()
-        self.connectSignals()
-        self.setScreen()
-        self.window.show()
-        # calling present() will focus the window in the winodw manager so
-        # the mnemonics work without additional clicking
-        self.window.present()
-            
-    def busyCursorPush(self):
-        rootPushBusyCursor()
-        
-    def busyCursorPop(self):
-        rootPopBusyCursor()
-        
-    def run (self, runres):
-        self.setup_theme()
-        self.setup_window(False)
-        gtk.main()
-            
-class InstallControlState:
-    def __init__ (self, cw):
-        self.cw = cw
-        self.prevEnabled = True
-        self.nextEnabled = True
-        self.title = _("Install Window")
-        self.grabNext = True
-
-    def setTitle (self, title):
-        self.title = title
-        self.cw.update (self)
-        
-    def getTitle (self):
-        return self.title
-
-    def setPrevEnabled (self, value):
-        if value == self.prevEnabled: return
-        self.prevEnabled = value
-        self.cw.update (self)
-
-    def getPrevEnabled (self):
-        return self.prevEnabled
-    
-    def setNextEnabled (self, value):
-        if value == self.nextEnabled: return
-        self.nextEnabled = value
-        self.cw.update (self)
-
-    def getNextEnabled (self):
-        return self.nextEnabled
-
-    def setScreenPrev (self):
-        self.cw.prevClicked ()
-
-    def setScreenNext (self):
-        self.cw.nextClicked ()
-
-    def setGrabNext (self, value):
-        self.grabNext = value
-        self.cw.update (self)
-
-    def getGrabNext (self):
-        return self.grabNext
-
-    def getICW (self):
-        return self.cw
diff --git a/icons/Makefile.am b/icons/Makefile.am
deleted file mode 100644
index 0fdcec3..0000000
--- a/icons/Makefile.am
+++ /dev/null
@@ -1,22 +0,0 @@
-# icons/Makefile.am for anaconda
-#
-# Copyright (C) 2010  Red Hat, Inc.
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU Lesser General Public License as published
-# by the Free Software Foundation; either version 2.1 of the License, or
-# (at your option) any later version.
-#
-# 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 Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public License
-# along with this program.  If not, see <http://www.gnu.org/licenses/>.
-#
-# Author: David Cantrell <dcantrell@xxxxxxxxxx>
-
-SUBDIRS = hicolor
-
-MAINTAINERCLEANFILES = Makefile.in
diff --git a/icons/hicolor/16x16/Makefile.am b/icons/hicolor/16x16/Makefile.am
deleted file mode 100644
index ab8a795..0000000
--- a/icons/hicolor/16x16/Makefile.am
+++ /dev/null
@@ -1,22 +0,0 @@
-# icons/hicolor/16x16/Makefile.am for anaconda
-#
-# Copyright (C) 2010  Red Hat, Inc.
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU Lesser General Public License as published
-# by the Free Software Foundation; either version 2.1 of the License, or
-# (at your option) any later version.
-#
-# 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 Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public License
-# along with this program.  If not, see <http://www.gnu.org/licenses/>.
-#
-# Author: David Cantrell <dcantrell@xxxxxxxxxx>
-
-SUBDIRS = apps
-
-MAINTAINERCLEANFILES = Makefile.in
diff --git a/icons/hicolor/16x16/apps/Makefile.am b/icons/hicolor/16x16/apps/Makefile.am
deleted file mode 100644
index 6b600a4..0000000
--- a/icons/hicolor/16x16/apps/Makefile.am
+++ /dev/null
@@ -1,23 +0,0 @@
-# icons/hicolor/16x16/apps/Makefile.am for anaconda
-#
-# Copyright (C) 2010  Red Hat, Inc.
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU Lesser General Public License as published
-# by the Free Software Foundation; either version 2.1 of the License, or
-# (at your option) any later version.
-#
-# 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 Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public License
-# along with this program.  If not, see <http://www.gnu.org/licenses/>.
-#
-# Author: David Cantrell <dcantrell@xxxxxxxxxx>
-
-iconsdir        = $(datadir)/icons/hicolor/16x16/apps
-dist_icons_DATA = anaconda.png
-
-MAINTAINERCLEANFILES = Makefile.in
diff --git a/icons/hicolor/16x16/apps/anaconda.png b/icons/hicolor/16x16/apps/anaconda.png
deleted file mode 100644
index c58fae5b8fb5958853d2d53a33d5af95edfc2bf3..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001

literal 925
zcmV;O17iG%P)<h;3K|Lk000e1NJLTq000mG000mO1^@s6AM^iV00004b3#c}2nYxW
zd<bNS00009a7bBm000fw000fw0YWI7cmMzZ8FWQhbW?9;ba!ELWdL_~cP?peYja~^
zaAhuUa%Y?FJQ@H101$LVSaeirbZlh+NMUkhAVhL$c4etgw=w_#02FjZSad;kbZBpK
z07_wNbz&e>bY*F7Wpd{G_b&hd03&ooSaefwb#h~60BCe{a5^t9bYX61Z!TtXWo2Y#
zb8B>Oa4v6hXMM7arvLx~uSrBfR5*=|ld*4GRTPK6`|dT*#O5`5PC^pbNNJO_baDj}
zGZNCX7#NV~LR2Bqfwe>V3z)i81tGN*rCnIssjVsus@PDZ{sAOusDd5zlteOlaqfGu
z{c`VRpt2jL{-iUVb3T1%I3kK70GiF_=jQn@pY-oFE{WnP5FRJuEUtHe|3&k@T#6nw
z8jYU-L=;6_yLR=Xf?xQ4>FmN%;n7$46BSAyUIjY<=fIPszulmh?4zS^`Tg0mr2EhQ
zXAd7fdFlaJVQ<#!@3-HcsjZhTKOouNCtmpy+CM|<3GvDmIy(tRAKxO)a%LuH#=Dum
z37}pIUI@y8h~sz#xb9!NL+9>g{`&PX0NRGw=o^mW9gdHW3BwARPA>qwdT1%n^NYq9
zlCEawgReO-<7D0x>eKIVLNYe?CIFu2k!2aL8UTzLW8Pa^|ATNM<m|$E?3ugddCp)k
zz}lS6%}r)!t4Jx)I%Q~(rWt_x^Tp=k<m41nQ`1N(nVz1eTCL*yJ^<qrA&2@9rPR>i
zB_PE)S4g!M<x-hE&)MDGWqW&@t*tFutrpf=%B2!<{5Mic27|%qgj8z)b-H%?L^F<K
zgb)NlfH8(3IK}Mj98yYz5F>#8&p^FVC^9!UN0KCTyWQcS@B4&dh?J7Oy*-ptCjqHW
zan8wpzt7s*8r5o*TCGO0Sj1XOnx=F*9op?SN-305c%C-`^m;v<b8KvEu(-HLyWK_z
zfpZQiCBE;Yl%i6pu)4ZRy<W#!I|B531GLsGFE3+^K?s2m0&6YKxnUV&n4h0VDMg;=
zBfz0P+`04P?U{4u-lf%Qk);_rOUaIU2qAc@TxNVCBuNt1H=eU_W*+P8i{Uc`!B_)N
z`~afHYs6aHlES-kaG;+mfNnQy0`I)e^8fQMOcy_BH0|Ys00000NkvXXu0mjfn&+U)

diff --git a/icons/hicolor/22x22/Makefile.am b/icons/hicolor/22x22/Makefile.am
deleted file mode 100644
index 3b94dde..0000000
--- a/icons/hicolor/22x22/Makefile.am
+++ /dev/null
@@ -1,22 +0,0 @@
-# icons/hicolor/22x22/Makefile.am for anaconda
-#
-# Copyright (C) 2010  Red Hat, Inc.
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU Lesser General Public License as published
-# by the Free Software Foundation; either version 2.1 of the License, or
-# (at your option) any later version.
-#
-# 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 Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public License
-# along with this program.  If not, see <http://www.gnu.org/licenses/>.
-#
-# Author: David Cantrell <dcantrell@xxxxxxxxxx>
-
-SUBDIRS = apps
-
-MAINTAINERCLEANFILES = Makefile.in
diff --git a/icons/hicolor/22x22/apps/Makefile.am b/icons/hicolor/22x22/apps/Makefile.am
deleted file mode 100644
index d189b10..0000000
--- a/icons/hicolor/22x22/apps/Makefile.am
+++ /dev/null
@@ -1,23 +0,0 @@
-# icons/hicolor/22x22/apps/Makefile.am for anaconda
-#
-# Copyright (C) 2010  Red Hat, Inc.
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU Lesser General Public License as published
-# by the Free Software Foundation; either version 2.1 of the License, or
-# (at your option) any later version.
-#
-# 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 Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public License
-# along with this program.  If not, see <http://www.gnu.org/licenses/>.
-#
-# Author: David Cantrell <dcantrell@xxxxxxxxxx>
-
-iconsdir        = $(datadir)/icons/hicolor/22x22/apps
-dist_icons_DATA = anaconda.png
-
-MAINTAINERCLEANFILES = Makefile.in
diff --git a/icons/hicolor/22x22/apps/anaconda.png b/icons/hicolor/22x22/apps/anaconda.png
deleted file mode 100644
index 062eb7687b7d4f58f4a6348413e021910fd41b30..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001

literal 1326
zcmV+}1=0G6P)<h;3K|Lk000e1NJLTq000&M000&U1^@s6#I$TX00004b3#c}2nYxW
zd<bNS00009a7bBm000fw000fw0YWI7cmMzZ8FWQhbW?9;ba!ELWdL_~cP?peYja~^
zaAhuUa%Y?FJQ@H101$LVSaeirbZlh+NMUkhAVhL$c4etgw=w_#02FjZSad;kbZBpK
z07_wNbz&e>bY*F7Wpd{G_b&hd03&ooSaefwb#h~60BCe{a5^t9bYX61Z!TtXWo2Y#
zb8B>Oa4v6hXMM7arvLy1KuJVFR5*>bl}%_|RTRg6_r8yL^Jd<>WRiJNORY^4i`7I+
zied>AO6|}utczd~KdRV8-3Wq^jZj1|%erwR2t{3pA_}^A65Lcl?83TG+O&)GD{V4P
zCX-Cwo5_9eT^DJFf)zyUfwQ<D=YRj_f6l#ERI63)g~@w@3Yh=2@YSyAZ_)Y?R{riA
zRD_W7%jeGRoA_72larGsU@lMp_O4Wm<Gs(mS2DNm5oBwC24S)`6YAzSr<U4gWomNr
zm;(<bQ&UsPoj77c<1h@x_tW3KvDj#y?(gdph9MEnYXsA88^OpJ<;R}}ol^hxM;8A0
zol8%?lXi0bXq~a#TuGfm?!aefKL6owj3*{0tW@jw_wLzeMp1<8y0qKdi5~cx8=t;R
zv=X7Urhat}b@U7a`CdaxNxfbtpDP;mM(u+z3`eWgs)pOe3&T)6b71d&ujt#IP6x+v
zNYfOpHNp!>CqAZjqfYHslScJ4iyc9;*`(2EAf?3fN<?w|@TpUiTQ`VqbcM7G>-C|*
zVLOgvY}+QwGL%v%r4WT)a<6`Y@xmwg!6y3p`tW@p&-3W*?ZvVzHgDQu2*WuZhN0*J
zkByDxq%^AK-m;KVa&cycBuU8Sa(JGHUn*hSHu-!W+qN+b11Tk1Yvyj=BuP_tJhH>k
zS@zlnrVPVS965Sq|D!ub%rs5;`ImD9l?rK^qLd;@5`5pMQmGIG0i{xjPNzebWoWJG
z@qOmzZqn1!L(X=B6DN+3gkdO5K;|s_<j}Su^U~$ZY<X}qNs=Ih03gdU&YwSz@B3)2
zSz216SS*rdS=aBsZ-5IIXLw@gPV4&h8z+I2a&&amQHk2)c^<2+RhrG^uC^PDgCM{(
zO-$3o_x<jHS(X8CYoW&C;vz%ahKS?%c|e-Gcke#5eR#VW$1#>=G7wZ47#Lu6b(L1D
zMUo`lw9_>0x)6eLxxCI^YbyQyxUNgFSS%bqe0bc<=ksrljqNh#=jTyMA*Ez?c9vqX
zNDu@FA&^ocgg|RemSv=AN|t5RYBlEP=jrX~!7vPzQjCv}n^6?KWj30Pr><PNg4UWs
zq0kLpSy^FaWd)!+cPDEh1eRrC+jiGyXJ;vw%d}dp{btmPvf<%jqf)7mWf?+<ZsCLw
zU4~lgb>Q3MPP@%gvq=<1EH)a%aZKE9bM@MFlu|j<^NPAuD)G`QFXB1{Ov~){ss@rI
zK_v+Vw}9g~6pBR(1(*6_g9{ffuu%JxBuPlK^{h<OWO&PFOd+H^`_ow}{Q)D7jo`X2
zN+}j<3n-<C+ig^m;5rU&(Zh9J+<YDo3=R%r+c}anL1*ioA`O9*G7$$49{k9*?PGvp
z7>3-CL9dGopwl$fhGF11j<77NTc|aqbR5TMtv3Pyk|>Hk6hI#E0OxKG_J6Q7U|9g-
k_Wc(B6R-xfxL2R)UmimdRwD1#!~g&Q07*qoM6N<$f{ycQ(f|Me

diff --git a/icons/hicolor/24x24/Makefile.am b/icons/hicolor/24x24/Makefile.am
deleted file mode 100644
index c4a4745..0000000
--- a/icons/hicolor/24x24/Makefile.am
+++ /dev/null
@@ -1,22 +0,0 @@
-# icons/hicolor/24x24/Makefile.am for anaconda
-#
-# Copyright (C) 2010  Red Hat, Inc.
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU Lesser General Public License as published
-# by the Free Software Foundation; either version 2.1 of the License, or
-# (at your option) any later version.
-#
-# 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 Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public License
-# along with this program.  If not, see <http://www.gnu.org/licenses/>.
-#
-# Author: David Cantrell <dcantrell@xxxxxxxxxx>
-
-SUBDIRS = apps
-
-MAINTAINERCLEANFILES = Makefile.in
diff --git a/icons/hicolor/24x24/apps/Makefile.am b/icons/hicolor/24x24/apps/Makefile.am
deleted file mode 100644
index 2e1f206..0000000
--- a/icons/hicolor/24x24/apps/Makefile.am
+++ /dev/null
@@ -1,23 +0,0 @@
-# icons/hicolor/24x24/apps/Makefile.am for anaconda
-#
-# Copyright (C) 2010  Red Hat, Inc.
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU Lesser General Public License as published
-# by the Free Software Foundation; either version 2.1 of the License, or
-# (at your option) any later version.
-#
-# 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 Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public License
-# along with this program.  If not, see <http://www.gnu.org/licenses/>.
-#
-# Author: David Cantrell <dcantrell@xxxxxxxxxx>
-
-iconsdir        = $(datadir)/icons/hicolor/24x24/apps
-dist_icons_DATA = anaconda.png
-
-MAINTAINERCLEANFILES = Makefile.in
diff --git a/icons/hicolor/24x24/apps/anaconda.png b/icons/hicolor/24x24/apps/anaconda.png
deleted file mode 100644
index e69f822ffa25a4d13a53b01874e235a6ae83b6d9..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001

literal 1368
zcmV-e1*iInP)<h;3K|Lk000e1NJLTq000;O000;W1^@s6;CDUv00004b3#c}2nYxW
zd<bNS00009a7bBm000fw000fw0YWI7cmMzZ8FWQhbW?9;ba!ELWdL_~cP?peYja~^
zaAhuUa%Y?FJQ@H101$LVSaeirbZlh+NMUkhAVhL$c4etgw=w_#02FjZSad;kbZBpK
z07_wNbz&e>bY*F7Wpd{G_b&hd03&ooSaefwb#h~60BCe{a5^t9bYX61Z!TtXWo2Y#
zb8B>Oa4v6hXMM7arvLy1YDq*vR7i=vl}n6NMHGg=s$2Kj-P7H44?WN@A|qyah%Xd1
zvvM;eKnxp#iBTsIBqqj$s2dXFj*T0m3l^@x#ApnzjCA6LC?v{)urZ7igD||Lr@Lo{
z?&+R;>sGm#2gC;p0-ofg7FG5C=bZmk9WgpO%EL7IP|^Pn0(Gy=lh6Hd3~OJ#*BK$4
z@AsU0dEb2z%*~}=S;u?5xcB40scsWsu>jVRUO&&wH}B7r^uD-f0Dl+x@CWbiPLkxf
z=X!wv;kPEl%F`cum6t}zZ`cY})A{2f*H3@P?@t|0=2mPp#uyvNaTjBEpE&X5ng7h7
zR;xLO-+SlSmf@`hDIFZgLF-M-uieDu<F8SfnMV0OSARZ3Z|7$eN{_iE$6;z}3dvk>
zyFLARtybGKIy!2XFy&p~;@GiIpLSh;MG%B2wZLtyCGD$X_Z{cvuNRp-_Y2cIK4Dt*
zGd(>`v)ROP914XZ-EMdN(W4&?-5vDZT_j!K-#@healg~)5JeHL=Ml#-I!)0*5jl1e
z^TxMCt2R(97AX`8WV2cN`}=WSmuhv;Nv#~K)oS8j351Y)D=RC)bzLrwkJD<l2*Z%R
zT#izyM3~7D<?@7Ki0isIj)M?_%U7;ot!3lzMn@-l>~37SRGuS8j%;7|$fJEyN`5+f
zmX-bec%F;a8m%?CT#j<N%<9#vDV0hjNrJT&Yc0h>ft!EcBA+i11Y!B$!LcWovRD#X
zX0qXd&6~HVYuBzbP^pk42||cv9WGqBK)GB7pw()jl)`ZwthE?p7^tjd{I?07eP)|`
zb@JLF;1FOJQrV27b-HIoaRsebi`(rsNs=tP)|yJCf|L>=1lepBr4+^(j4=Q-nk}wO
zPBJt!M7P)7yHp)ntJTDT7Y~dK3=BkRnqo}Ks!D}{fdPUbAWhR{k|arp<CukWhBQqH
z!;rzjK{A<$%^QdDeV=?^KH9Zw*GR2a6AF--O!W5l=U-6udL6AbQc5mex<s*9q*|?F
zj6n#2)*53Bj^kjAK}t!h)uPd8P%f2FN|7W9BO@d3?Ck7e;70|>cBiwe*=#a7IY~aB
zM@os5l6t*Py<T6|Vd-u3dOft(0C=8<=XoflP)ac|F+mhXbUK|KfTM<ohx=w{X4RUt
zYZzQRh?I9acS&Sp%yRU`7*b<MwPt>Po_4#<T(?WN*P}T-LuxEjQw`!ccB<8CP6;8h
zK@gb!a@iT%|0aPKpj;Qv^^nd2S-MCNgdx5kkj+G7vN;-!1{cT2xmBMcNfL~)q-lzf
zlHv91@O?j{;y5-+DS7_<c?yLBPi)yr6h^e$Z5qu6iPofA6Kjp{`9x7fl+6$YAtp^1
zvUVJjIKfzpH5P<GDaDN&H;e$HojZ4)h@$8fYpqzQ%<@ae+U0)>*L7_slOYHKlv2cT
zOt06Y-EJ?p>*5{T>2$t6b?Vex0&oByC@!vd(C^<8pb7L?oCk7|NIgK8fcVG2dC>OI
ahyGuJ!1PR%sa<pc0000<MNUMnLSTYvNN;=q

diff --git a/icons/hicolor/32x32/Makefile.am b/icons/hicolor/32x32/Makefile.am
deleted file mode 100644
index 0dee034..0000000
--- a/icons/hicolor/32x32/Makefile.am
+++ /dev/null
@@ -1,22 +0,0 @@
-# icons/hicolor/32x32/Makefile.am for anaconda
-#
-# Copyright (C) 2010  Red Hat, Inc.
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU Lesser General Public License as published
-# by the Free Software Foundation; either version 2.1 of the License, or
-# (at your option) any later version.
-#
-# 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 Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public License
-# along with this program.  If not, see <http://www.gnu.org/licenses/>.
-#
-# Author: David Cantrell <dcantrell@xxxxxxxxxx>
-
-SUBDIRS = apps
-
-MAINTAINERCLEANFILES = Makefile.in
diff --git a/icons/hicolor/32x32/apps/Makefile.am b/icons/hicolor/32x32/apps/Makefile.am
deleted file mode 100644
index 378201b..0000000
--- a/icons/hicolor/32x32/apps/Makefile.am
+++ /dev/null
@@ -1,23 +0,0 @@
-# icons/hicolor/32x32/apps/Makefile.am for anaconda
-#
-# Copyright (C) 2010  Red Hat, Inc.
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU Lesser General Public License as published
-# by the Free Software Foundation; either version 2.1 of the License, or
-# (at your option) any later version.
-#
-# 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 Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public License
-# along with this program.  If not, see <http://www.gnu.org/licenses/>.
-#
-# Author: David Cantrell <dcantrell@xxxxxxxxxx>
-
-iconsdir        = $(datadir)/icons/hicolor/32x32/apps
-dist_icons_DATA = anaconda.png
-
-MAINTAINERCLEANFILES = Makefile.in
diff --git a/icons/hicolor/32x32/apps/anaconda.png b/icons/hicolor/32x32/apps/anaconda.png
deleted file mode 100644
index 51bbdc74f968ac0d26c0c9a2bc7dd4302fa0cd0c..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001

literal 1860
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

diff --git a/icons/hicolor/48x48/Makefile.am b/icons/hicolor/48x48/Makefile.am
deleted file mode 100644
index 9d23a6e..0000000
--- a/icons/hicolor/48x48/Makefile.am
+++ /dev/null
@@ -1,22 +0,0 @@
-# icons/hicolor/48x48/Makefile.am for anaconda
-#
-# Copyright (C) 2010  Red Hat, Inc.
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU Lesser General Public License as published
-# by the Free Software Foundation; either version 2.1 of the License, or
-# (at your option) any later version.
-#
-# 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 Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public License
-# along with this program.  If not, see <http://www.gnu.org/licenses/>.
-#
-# Author: David Cantrell <dcantrell@xxxxxxxxxx>
-
-SUBDIRS = apps
-
-MAINTAINERCLEANFILES = Makefile.in
diff --git a/icons/hicolor/48x48/apps/Makefile.am b/icons/hicolor/48x48/apps/Makefile.am
deleted file mode 100644
index 3cf250f..0000000
--- a/icons/hicolor/48x48/apps/Makefile.am
+++ /dev/null
@@ -1,23 +0,0 @@
-# icons/hicolor/48x48/apps/Makefile.am for anaconda
-#
-# Copyright (C) 2010  Red Hat, Inc.
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU Lesser General Public License as published
-# by the Free Software Foundation; either version 2.1 of the License, or
-# (at your option) any later version.
-#
-# 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 Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public License
-# along with this program.  If not, see <http://www.gnu.org/licenses/>.
-#
-# Author: David Cantrell <dcantrell@xxxxxxxxxx>
-
-iconsdir        = $(datadir)/icons/hicolor/48x48/apps
-dist_icons_DATA = anaconda.png
-
-MAINTAINERCLEANFILES = Makefile.in
diff --git a/icons/hicolor/48x48/apps/anaconda.png b/icons/hicolor/48x48/apps/anaconda.png
deleted file mode 100644
index c633dd38c8be549c6529b0275fb6c4301bc24e78..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001

literal 3020
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
O0000<MNUMnLSTYxaNte=

diff --git a/icons/hicolor/Makefile.am b/icons/hicolor/Makefile.am
deleted file mode 100644
index 97e9d5f..0000000
--- a/icons/hicolor/Makefile.am
+++ /dev/null
@@ -1,22 +0,0 @@
-# icons/hicolor/Makefile.am for anaconda
-#
-# Copyright (C) 2010  Red Hat, Inc.
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU Lesser General Public License as published
-# by the Free Software Foundation; either version 2.1 of the License, or
-# (at your option) any later version.
-#
-# 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 Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public License
-# along with this program.  If not, see <http://www.gnu.org/licenses/>.
-#
-# Author: David Cantrell <dcantrell@xxxxxxxxxx>
-
-SUBDIRS = 16x16 22x22 24x24 32x32 48x48
-
-MAINTAINERCLEANFILES = Makefile.in
diff --git a/image.py b/image.py
deleted file mode 100644
index 60f03aa..0000000
--- a/image.py
+++ /dev/null
@@ -1,326 +0,0 @@
-#
-# image.py: Support methods for CD/DVD and ISO image installations.
-#
-# Copyright (C) 2007  Red Hat, Inc.  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 as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# 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, see <http://www.gnu.org/licenses/>.
-#
-
-import isys, iutil
-import os, os.path, stat, string, sys
-from constants import *
-
-import gettext
-_ = lambda x: gettext.ldgettext("anaconda", x)
-
-import logging
-log = logging.getLogger("anaconda")
-
-_arch = iutil.getArch()
-
-def findIsoImages(path, messageWindow):
-    flush = os.stat(path)
-    files = os.listdir(path)
-    arch = _arch
-    discImages = {}
-
-    for file in files:
-        what = path + '/' + file
-        if not isys.isIsoImage(what):
-            continue
-
-        try:
-            isys.losetup("/dev/loop2", what, readOnly = 1)
-        except SystemError:
-            continue
-
-        try:
-            isys.mount("/dev/loop2", "/mnt/cdimage", fstype = "iso9660",
-                       readOnly = True)
-            for num in range(1, 10):
-                if os.access("/mnt/cdimage/.discinfo", os.R_OK):
-                    f = open("/mnt/cdimage/.discinfo")
-                    try:
-                        f.readline() # skip timestamp
-                        f.readline() # skip release description
-                        discArch = string.strip(f.readline()) # read architecture
-                        discNum = getDiscNums(f.readline().strip())
-                    except:
-                        discArch = None
-                        discNum = [ 0 ]
-
-                    f.close()
-
-                    if num not in discNum or discArch != arch:
-                        continue
-
-                    # if it's disc1, it needs to have images/install.img
-                    if (num == 1 and not
-                        os.access("/mnt/cdimage/images/install.img", os.R_OK)):
-                        log.warning("%s doesn't have a install.img, skipping" %(what,))
-                        continue
-                    # we only install binary packages, so let's look for a
-                    # product/ dir and hope that this avoids getting
-                    # discs from the src.rpm set
-                    if not os.path.isdir("/mnt/cdimage/%s" %(productPath,)):
-                        log.warning("%s doesn't have binary RPMS, skipping" %(what,))
-                        continue
-
-                    # warn user if images appears to be wrong size
-                    if os.stat(what)[stat.ST_SIZE] % 2048:
-                        rc = messageWindow(_("Warning"),
-                             _("The ISO image %s has a size which is not "
-                               "a multiple of 2048 bytes.  This may mean "
-                               "it was corrupted on transfer to this computer."
-                               "\n\n"
-                               "It is recommended that you exit and abort your "
-                               "installation, but you can choose to continue if "
-                               "you think this is in error.") % (file,),
-                               type="custom", custom_icon="warning",
-                               custom_buttons= [_("_Exit installer"),
-                                                _("_Continue")])
-                        if rc == 0:
-                            sys.exit(0)
-
-                    discImages[num] = file
-
-            isys.umount("/mnt/cdimage", removeDir=False)
-        except SystemError:
-            pass
-
-        isys.unlosetup("/dev/loop2")
-
-    return discImages
-
-def getDiscNums(line):
-    # get the disc numbers for this disc
-    nums = line.split(",")
-    if nums == ['ALL']: # Treat "ALL" DVD as disc 1
-        return [1]
-    discNums = []
-    for num in nums:
-        discNums.append(int(num))
-    return discNums
-
-def getMediaId(path):
-    if os.access("%s/.discinfo" % path, os.R_OK):
-        f = open("%s/.discinfo" % path)
-        newStamp = f.readline().strip()
-        f.close()
-
-        return newStamp
-    else:
-        return None
-
-# This mounts the directory containing the iso images, and places the
-# mount point in /mnt/isodir.
-def mountDirectory(methodstr, messageWindow):
-    if methodstr.startswith("hd:"):
-        method = methodstr[3:]
-        if method.count(":") == 1:
-            (device, path) = method.split(":")
-            fstype = "auto"
-        else:
-            (device, fstype, path) = method.split(":")
-
-        if not device.startswith("/dev/") and not device.startswith("UUID=") \
-           and not device.startswith("LABEL="):
-            device = "/dev/%s" % device
-    elif methodstr.startswith("nfsiso:"):
-        device = methodstr[7:]
-        fstype = "nfs"
-    else:
-        return
-
-    # No need to mount it again.
-    if os.path.ismount("/mnt/isodir"):
-        return
-
-    while True:
-        try:
-            isys.mount(device, "/mnt/isodir", fstype = fstype)
-            break
-        except SystemError, msg:
-            log.error("couldn't mount ISO source directory: %s" % msg)
-            ans = messageWindow(_("Couldn't Mount ISO Source"),
-                          _("An error occurred mounting the source "
-                            "device %s.  This may happen if your ISO "
-                            "images are located on an advanced storage "
-                            "device like LVM or RAID, or if there was a "
-                            "problem mounting a partition.  Click exit "
-                            "to abort the installation.")
-                          % (device,), type="custom", custom_icon="error",
-                          custom_buttons=[_("_Exit"), _("_Retry")])
-
-            if ans == 0:
-                sys.exit(0)
-            else:
-                continue
-
-def mountImage(isodir, tree, discnum, messageWindow, discImages={}):
-    if os.path.ismount(tree):
-        raise SystemError, "trying to mount already-mounted iso image!"
-
-    if discImages == {}:
-        discImages = findIsoImages(isodir, messageWindow)
-
-    while True:
-        try:
-            isoImage = "%s/%s" % (isodir, discImages[discnum])
-            isys.losetup("/dev/loop1", isoImage, readOnly = 1)
-            isys.mount("/dev/loop1", tree, fstype = 'iso9660', readOnly = True)
-            break
-        except:
-            ans = messageWindow(_("Missing ISO 9660 Image"),
-                                _("The installer has tried to mount "
-                                  "image #%s, but cannot find it on "
-                                  "the hard drive.\n\n"
-                                  "Please copy this image to the "
-                                  "drive and click Retry.  Click Exit "
-                                  "to abort the installation.")
-                                  % (discnum,), type="custom",
-                                  custom_icon="warning",
-                                  custom_buttons=[_("_Exit"), _("_Retry")])
-            if ans == 0:
-                sys.exit(0)
-            elif ans == 1:
-                discImages = findIsoImages(isodir, messageWindow)
-
-    return discImages
-
-# given groupset containing information about selected packages, use
-# the disc number info in the headers to come up with message describing
-# the required CDs
-#
-# dialog returns a value of 0 if user selected to abort install
-def presentRequiredMediaMessage(anaconda):
-    reqcds = anaconda.backend.getRequiredMedia()
-
-    # if only one CD required no need to pop up a message
-    if len(reqcds) < 2:
-        return
-
-    # check what discs our currently mounted one provides
-    if os.access("%s/.discinfo" % anaconda.backend.ayum.tree, os.R_OK):
-        discNums = []
-        try:
-            f = open("%s/.discinfo" % anaconda.backend.ayum.tree)
-            stamp = f.readline().strip()
-            descr = f.readline().strip()
-            arch = f.readline().strip()
-            discNums = getDiscNums(f.readline().strip())
-            f.close()
-        except Exception, e:
-            log.critical("Exception reading discinfo: %s" %(e,))
-
-        log.info("discNums is %s" %(discNums,))
-        haveall = 0
-        s = set(reqcds)
-        t = set(discNums)
-        if s.issubset(t):
-            haveall = 1
-
-        if haveall == 1:
-            return
-
-    reqcds.sort()
-    reqcds = map(lambda disc: "#%s" % disc, filter(lambda disc: disc != -99, reqcds))
-    reqcdstr = ", ".join(reqcds)
-
-    return anaconda.intf.messageWindow(_("Required Install Media"),
-               _("The software you have selected to install will require the "
-                 "following %(productName)s %(productVersion)s "
-                 "discs:\n\n%(reqcdstr)s\nPlease have these ready "
-                 "before proceeding with the installation.  If you need to "
-                 "abort the installation and exit please select "
-                 "\"Reboot\".") % {'productName': product.productName,
-                                   'productVersion': product.productVersion,
-                                   'reqcdstr': reqcdstr},
-                 type="custom", custom_icon="warning",
-                 custom_buttons=[_("_Reboot"), _("_Back"), _("_Continue")])
-
-# Find an attached CD/DVD drive with media in it that contains packages,
-# and return that device name.
-def scanForMedia(tree, storage):
-    for dev in storage.devicetree.devices:
-        if dev.type != "cdrom":
-            continue
-
-        storage.devicetree.updateDeviceFormat(dev)
-        try:
-            dev.format.mount(mountpoint=tree)
-        except:
-            continue
-
-        if not verifyMedia(tree, 1):
-            dev.format.unmount()
-            continue
-
-        return dev.name
-
-    return None
-
-def umountImage(tree, currentMedia):
-    if currentMedia is not None:
-        isys.umount(tree, removeDir=False)
-        isys.unlosetup("/dev/loop1")
-
-def unmountCD(dev, messageWindow):
-    if not dev:
-        return
-
-    while True:
-        try:
-            dev.format.unmount()
-            break
-        except Exception, e:
-            log.error("exception in _unmountCD: %s" %(e,))
-            messageWindow(_("Error"),
-                          _("An error occurred unmounting the disc.  "
-                            "Please make sure you're not accessing "
-                            "%s from the shell on tty2 "
-                            "and then click OK to retry.")
-                          % (dev.path,))
-
-def verifyMedia(tree, discnum, timestamp=None):
-    if os.access("%s/.discinfo" % tree, os.R_OK):
-        f = open("%s/.discinfo" % tree)
-
-        newStamp = f.readline().strip()
-
-        try:
-            descr = f.readline().strip()
-        except:
-            descr = None
-
-        try:
-            arch = f.readline().strip()
-        except:
-            arch = None
-
-        try:
-            discs = getDiscNums(f.readline().strip())
-        except:
-            discs = [ 0 ]
-
-        f.close()
-
-        if timestamp is not None:
-            if newStamp == timestamp and arch == _arch and discnum in discs:
-                return True
-        else:
-            if arch == _arch and discnum in discs:
-                return True
-
-    return False
diff --git a/installclass.py b/installclass.py
deleted file mode 100644
index 2e8fcf6..0000000
--- a/installclass.py
+++ /dev/null
@@ -1,336 +0,0 @@
-#
-# installclass.py:  This is the prototypical class for workstation, server, and
-# kickstart installs.  The interface to BaseInstallClass is *public* --
-# ISVs/OEMs can customize the install by creating a new derived type of this
-# class.
-#
-# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007
-# Red Hat, Inc.  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 as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# 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, see <http://www.gnu.org/licenses/>.
-#
-
-from distutils.sysconfig import get_python_lib
-import os, sys, iutil
-import isys
-import string
-import language
-import imputil
-import types
-
-from constants import *
-from product import *
-from storage.partspec import *
-
-import gettext
-_ = lambda x: gettext.ldgettext("anaconda", x)
-
-import logging
-log = logging.getLogger("anaconda")
-
-from flags import flags
-
-class BaseInstallClass(object):
-    # default to not being hidden
-    hidden = 0
-    pixmap = None
-    showMinimal = 1
-    showLoginChoice = 0
-    _description = ""
-    _descriptionFields = ()
-    name = "base"
-    pkgstext = ""
-    # default to showing the upgrade option
-    showUpgrade = True
-    bootloaderTimeoutDefault = None
-    bootloaderExtraArgs = ""
-
-    # list of of (txt, grplist) tuples for task selection screen
-    tasks = []
-
-    # don't select this class by default
-    default = 0
-
-    # by default, place this under the "install" category; it gets it's
-    # own toplevel category otherwise
-    parentClass = ( _("Install on System"), "install.png" )
-
-    def _get_description(self):
-        return _(self._description) % self._descriptionFields
-    description = property(_get_description)
-
-    def postAction(self, anaconda):
-        anaconda.backend.postAction(anaconda)
-
-    def setSteps(self, anaconda):
-        dispatch = anaconda.dispatch
-	dispatch.setStepList(
-		 "language",
-		 "keyboard",
-		 "welcome",
-                 "filtertype",
-                 "filter",
-                 "storageinit",
-                 "findrootparts",
-		 "betanag",
-		 "installtype",
-                 "cleardiskssel",
-                 "parttype",
-                 "autopartitionexecute",
-                 "partition",
-		 "storagedone",
-		 "bootloadersetup",                 
-		 "bootloader",
-		 "network",
-		 "timezone",
-		 "accounts",
-                 "reposetup",
-                 "basepkgsel",
-		 "tasksel",                                  
-		 "postselection",
-		 "confirminstall",
-                 "reipl",
-		 "install",
-		 "enablefilesystems",
-                 "setuptime",
-                 "preinstallconfig",
-		 "installpackages",
-                 "postinstallconfig",
-		 "writeconfig",
-                 "firstboot",
-		 "instbootloader",
-                 "dopostaction",
-                 "postscripts",
-		 "writeksconfig",
-                 "methodcomplete",
-                 "copylogs",
-                 "setfilecon",
-		 "complete"
-		)
-
-	if not BETANAG:
-	    dispatch.skipStep("betanag", permanent=1)
-
-        if not iutil.isX86():
-            dispatch.skipStep("bootloader", permanent=1)
-
-        # allow backends to disable interactive package selection
-        if not anaconda.backend.supportsPackageSelection:
-            dispatch.skipStep("tasksel", skip = 1, permanent=1)
-            dispatch.skipStep("group-selection", skip = 1, permanent=1)
-
-        # allow install classes to turn off the upgrade 
-        if not self.showUpgrade or not anaconda.backend.supportsUpgrades:
-            dispatch.skipStep("findrootparts", skip = 1)
-
-        # 'noupgrade' can be used on the command line to force not looking
-        # for partitions to upgrade.  useful in some cases...
-        if flags.cmdline.has_key("noupgrade"):
-            dispatch.skipStep("findrootparts", skip = 1)
-
-        # upgrade will also always force looking for an upgrade. 
-        if flags.cmdline.has_key("upgrade"):
-            dispatch.skipStep("findrootparts", skip = 0)
-
-        # if there's only one install class, it doesn't make much sense
-        # to show it
-        if len(availableClasses()) < 2:
-            dispatch.skipStep("installtype", permanent=1)
-
-        # allow interface backends to skip certain steps.
-        anaconda.intf.setSteps(anaconda)
-
-    # modifies the uri from installmethod.getMethodUri() to take into
-    # account any installclass specific things including multiple base
-    # repositories.  takes a string or list of strings, returns a dict 
-    # with string keys and list values {%repo: %uri_list}
-    def getPackagePaths(self, uri):
-        if not type(uri) == types.ListType:
-            uri = [uri,]
-
-        return {'base': uri}
-
-    def setPackageSelection(self, anaconda):
-	pass
-
-    def setGroupSelection(self, anaconda):
-        grps = anaconda.backend.getDefaultGroups(anaconda)
-        map(lambda x: anaconda.backend.selectGroup(x), grps)
-
-    def getBackend(self):
-        # this should be overriden in distro install classes
-        from backend import AnacondaBackend
-        return AnacondaBackend
-
-    def setDefaultPartitioning(self, storage, platform):
-        autorequests = [PartSpec(mountpoint="/", fstype=storage.defaultFSType,
-                                 size=1024, maxSize=50*1024, grow=True,
-                                 asVol=True),
-                        PartSpec(mountpoint="/home", fstype=storage.defaultFSType,
-                                 size=100, grow=True, asVol=True, requiredSpace=50*1024)]
-
-        bootreq = platform.setDefaultPartitioning()
-        if bootreq:
-            autorequests.extend(bootreq)
-
-        (minswap, maxswap) = iutil.swapSuggestion()
-        autorequests.append(PartSpec(fstype="swap", size=minswap, maxSize=maxswap,
-                                     grow=True, asVol=True))
-
-        storage.autoPartitionRequests = autorequests
-
-    def configure(self, anaconda):
-        anaconda.bootloader.timeout = self.bootloaderTimeoutDefault
-        anaconda.bootloader.args.append(self.bootloaderExtraArgs)
-
-    def versionMatches(self, oldver):
-        pass
-
-    def productMatches(self, oldprod):
-        pass
-
-    def productUpgradable(self, oldprod, oldver):
-        return self.productMatches(oldprod) and self.versionMatches(oldver)
-
-    def __init__(self):
-	pass
-
-allClasses = []
-allClasses_hidden = []
-
-# returns ( className, classObject, classLogo ) tuples
-def availableClasses(showHidden=0):
-    global allClasses
-    global allClasses_hidden
-
-    def _ordering(first, second):
-        ((name1, obj, logo), priority1) = first
-        ((name2, obj, logo), priority2) = second
-
-        if priority1 < priority2:
-            return -1
-        elif priority1 > priority2:
-            return 1
-
-        if name1 < name2:
-            return -1
-        elif name1 > name2:
-            return 1
-
-        return 0
-
-    if not showHidden:
-        if allClasses: return allClasses
-    else:
-        if allClasses_hidden: return allClasses_hidden
-
-    path = []
-
-    for dir in ["installclasses",
-                "/tmp/updates/pyanaconda/installclasses",
-                "/tmp/product/pyanaconda/installclasses",
-                "%s/pyanaconda/installclasses" % get_python_lib(plat_specific=1) ]:
-        if os.access(dir, os.R_OK):
-            path.append(dir)
-
-    # append the location of installclasses to the python path so we
-    # can import them
-    sys.path = path + sys.path
-
-    files = []
-    for p in reversed(path):
-        files += os.listdir(p)
-
-    done = {}
-    list = []
-    for file in files:
-	if file[0] == '.': continue
-        if len (file) < 4:
-	    continue
-	if file[-3:] != ".py" and file[-4:-1] != ".py":
-	    continue
-	mainName = string.split(file, ".")[0]
-	if done.has_key(mainName): continue
-	done[mainName] = 1
-
-        try:
-            found = imputil.imp.find_module(mainName)
-        except:
-            log.warning ("module import of %s failed: %s" % (mainName, sys.exc_type))
-            continue
-
-        try:
-            loaded = imputil.imp.load_module(mainName, found[0], found[1], found[2])
-
-            obj = loaded.InstallClass
-
-	    if obj.__dict__.has_key('sortPriority'):
-		sortOrder = obj.sortPriority
-	    else:
-		sortOrder = 0
-
-	    if obj.__dict__.has_key('arch'):
-                if obj.arch != iutil.getArch():
-                    obj.hidden = 1
-                
-            if obj.hidden == 0 or showHidden == 1:
-                list.append(((obj.name, obj, obj.pixmap), sortOrder))
-        except:
-            log.warning ("module import of %s failed: %s" % (mainName, sys.exc_type))
-            if flags.debug: raise
-            else: continue
-
-    list.sort(_ordering)
-    for (item, priority) in list:
-        if showHidden:
-            allClasses_hidden.append(item)
-        else:
-            allClasses.append(item)
-
-    if showHidden:
-        return allClasses_hidden
-    else:
-        return allClasses
-
-def getBaseInstallClass():
-    # figure out what installclass we should base on.
-    allavail = availableClasses(showHidden = 1)
-    avail = availableClasses(showHidden = 0)
-    if len(avail) == 1:
-        (cname, cobject, clogo) = avail[0]
-        log.info("using only installclass %s" %(cname,))
-    elif len(allavail) == 1:
-        (cname, cobject, clogo) = allavail[0]
-        log.info("using only installclass %s" %(cname,))
-
-    # Use the highest priority install class if more than one found.
-    elif len(avail) > 1:
-        (cname, cobject, clogo) = avail.pop()
-        log.info('%s is the highest priority installclass, using it' % cname)
-    elif len(allavail) > 1:
-        (cname, cobject, clogo) = allavail.pop()
-        log.info('%s is the highest priority installclass, using it' % cname)
-
-    # Default to the base installclass if nothing else is found.
-    else:
-        raise RuntimeError, "Unable to find an install class to use!!!"
-
-    return cobject
-
-baseclass = getBaseInstallClass()
-
-# we need to be able to differentiate between this and custom
-class DefaultInstall(baseclass):
-    def __init__(self):
-        baseclass.__init__(self)
diff --git a/installclasses/Makefile.am b/installclasses/Makefile.am
deleted file mode 100644
index d7bd1eb..0000000
--- a/installclasses/Makefile.am
+++ /dev/null
@@ -1,24 +0,0 @@
-# installclasses/Makefile.am for anaconda
-#
-# Copyright (C) 2009  Red Hat, Inc.
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU Lesser General Public License as published
-# by the Free Software Foundation; either version 2.1 of the License, or
-# (at your option) any later version.
-#
-# 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 Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public License
-# along with this program.  If not, see <http://www.gnu.org/licenses/>.
-#
-# Author: David Cantrell <dcantrell@xxxxxxxxxx>
-
-pkgpyexecdir = $(pyexecdir)/py$(PACKAGE_NAME)
-installclassesdir = $(pkgpyexecdir)/installclasses
-installclasses_PYTHON = *.py
-
-MAINTAINERCLEANFILES = Makefile.in
diff --git a/installclasses/fedora.py b/installclasses/fedora.py
deleted file mode 100644
index 189aa2a..0000000
--- a/installclasses/fedora.py
+++ /dev/null
@@ -1,127 +0,0 @@
-#
-# fedora.py
-#
-# Copyright (C) 2007  Red Hat, Inc.  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 as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# 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, see <http://www.gnu.org/licenses/>.
-#
-
-from installclass import BaseInstallClass
-from constants import *
-from product import *
-from flags import flags
-import os, types
-import iutil
-
-import gettext
-_ = lambda x: gettext.ldgettext("anaconda", x)
-
-import installmethod
-import yuminstall
-
-import rpmUtils.arch
-
-class InstallClass(BaseInstallClass):
-    # name has underscore used for mnemonics, strip if you dont need it
-    id = "fedora"
-    name = N_("_Fedora")
-    _description = N_("The default installation of %s includes a set of "
-                      "software applicable for general internet usage. "
-                      "You can optionally select a different set of software "
-                      "now.")
-    _descriptionFields = (productName,)
-    sortPriority = 10000
-    if productName.startswith("Red Hat Enterprise"):
-        hidden = 1
-
-    tasks = [(N_("Graphical Desktop"),
-              ["admin-tools", "base", "base-x", "core", "editors", "fonts",
-               "games", "gnome-desktop", "graphical-internet", "graphics",
-               "hardware-support", "input-methods", "java", "office",
-               "printing", "sound-and-video", "text-internet"]),
-             (N_("Software Development"),
-              ["base", "base-x", "core", "development-libs",
-               "development-tools", "editors", "fonts", "gnome-desktop",
-               "gnome-software-development", "graphical-internet", "graphics",
-               "hardware-support", "input-methods", "java", "text-internet",
-               "x-software-development"]),
-             (N_("Web Server"),
-              ["admin-tools", "base", "base-x", "core", "editors",
-               "gnome-desktop", "graphical-internet", "hardware-support",
-               "java", "text-internet", "web-server"]),
-             (N_("Minimal"), ["core"])]
-
-    def getPackagePaths(self, uri):
-        if not type(uri) == types.ListType:
-            uri = [uri,]
-
-        return {'Installation Repo': uri}
-
-    def configure(self, anaconda):
-	BaseInstallClass.configure(self, anaconda)
-        BaseInstallClass.setDefaultPartitioning(self,
-                                                anaconda.storage,
-                                                anaconda.platform)
-
-    def setGroupSelection(self, anaconda):
-        BaseInstallClass.setGroupSelection(self, anaconda)
-        map(lambda x: anaconda.backend.selectGroup(x), ["core"])
-
-    def setSteps(self, anaconda):
-	BaseInstallClass.setSteps(self, anaconda)
-	anaconda.dispatch.skipStep("partition")
-
-    def getBackend(self):
-        if flags.livecdInstall:
-            import livecd
-            return livecd.LiveCDCopyBackend
-        else:
-            return yuminstall.YumBackend
-
-    def productMatches(self, oldprod):
-        if oldprod is None:
-            return False
-
-        if oldprod.startswith(productName):
-            return True
-
-        productUpgrades = {
-                "Fedora Core": ("Red Hat Linux", ),
-                "Fedora": ("Fedora Core", )
-        }
-
-        if productUpgrades.has_key(productName):
-            acceptable = productUpgrades[productName]
-        else:
-            acceptable = ()
-
-        for p in acceptable:
-            if oldprod.startswith(p):
-                return True
-
-        return False
-
-    def versionMatches(self, oldver):
-        try:
-            oldVer = float(oldver)
-            newVer = float(productVersion)
-        except ValueError:
-            return True
-
-        # This line means we do not support upgrading from anything older
-        # than two versions ago!
-        return newVer > oldVer and newVer - oldVer <= 2
-
-    def __init__(self):
-	BaseInstallClass.__init__(self)
diff --git a/installclasses/rhel.py b/installclasses/rhel.py
deleted file mode 100644
index bcb592b..0000000
--- a/installclasses/rhel.py
+++ /dev/null
@@ -1,113 +0,0 @@
-#
-# rhel.py
-#
-# Copyright (C) 2010  Red Hat, Inc.  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 as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# 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, see <http://www.gnu.org/licenses/>.
-#
-
-from installclass import BaseInstallClass
-from constants import *
-from product import *
-from flags import flags
-import os
-import types
-
-import installmethod
-import yuminstall
-
-class InstallClass(BaseInstallClass):
-    # name has underscore used for mnemonics, strip if you dont need it
-    id = "rhel"
-    name = N_("Red Hat Enterprise Linux")
-    _description = N_("The default installation of %s is a minimum install. "
-                     "You can optionally select a different set of software "
-                     "now.")
-    _descriptionFields = (productName,)
-    sortPriority = 10000
-    hidden = 1
-
-    bootloaderTimeoutDefault = 5
-    bootloaderExtraArgs = "crashkernel=auto"
-
-    tasks = [(N_("Minimal"),
-              ["core"])]
-
-    def getPackagePaths(self, uri):
-        if not type(uri) == types.ListType:
-            uri = [uri,]
-
-        return {productName: uri}
-
-    def configure(self, anaconda):
-        BaseInstallClass.configure(self, anaconda)
-        BaseInstallClass.setDefaultPartitioning(self,
-                                                anaconda.storage,
-                                                anaconda.platform)
-
-    def setSteps(self, anaconda):
-        BaseInstallClass.setSteps(self, anaconda)
-        anaconda.dispatch.skipStep("partition")
-
-    def getBackend(self):
-        if flags.livecdInstall:
-            import livecd
-            return livecd.LiveCDCopyBackend
-        else:
-            return yuminstall.YumBackend
-
-    def productMatches(self, oldprod):
-        if oldprod is None:
-            return False
-
-        if oldprod.startswith(productName):
-            return True
-
-        productUpgrades = {
-            "Red Hat Enterprise Linux AS": ("Red Hat Linux Advanced Server", ),
-            "Red Hat Enterprise Linux WS": ("Red Hat Linux Advanced Workstation",),
-            # FIXME: this probably shouldn't be in a release...
-            "Red Hat Enterprise Linux": ("Red Hat Linux Advanced Server",
-                                         "Red Hat Linux Advanced Workstation",
-                                         "Red Hat Enterprise Linux AS",
-                                         "Red Hat Enterprise Linux ES",
-                                         "Red Hat Enterprise Linux WS"),
-            "Red Hat Enterprise Linux Server": ("Red Hat Enterprise Linux AS",
-                                                "Red Hat Enterprise Linux ES",
-                                                "Red Hat Enterprise Linux WS",
-                                                "Red Hat Enterprise Linux"),
-            "Red Hat Enterprise Linux Client": ("Red Hat Enterprise Linux WS",
-                                                "Red Hat Enterprise Linux Desktop",
-                                                "Red Hat Enterprise Linux"),
-        }
-
-        if productUpgrades.has_key(productName):
-            acceptable = productUpgrades[productName]
-        else:
-            acceptable = ()
-
-        for p in acceptable:
-            if oldprod.startswith(p):
-                return True
-
-        return False
-
-    def versionMatches(self, oldver):
-        oldMajor = oldver.split(".")[0]
-        newMajor = productVersion.split(".")[0]
-
-        return oldMajor == newMajor
-
-    def __init__(self):
-        BaseInstallClass.__init__(self)
diff --git a/installinterfacebase.py b/installinterfacebase.py
deleted file mode 100644
index 1adfd2a..0000000
--- a/installinterfacebase.py
+++ /dev/null
@@ -1,76 +0,0 @@
-#
-# installinterfacebase.py: a baseclass for anaconda interface classes
-#
-# Copyright (C) 2010  Red Hat, Inc.  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 as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# 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, see <http://www.gnu.org/licenses/>.
-#
-# Author(s): Hans de Goede <hdegoede@xxxxxxxxxx>
-
-import gettext
-_ = lambda x: gettext.ldgettext("anaconda", x)
-P_ = lambda x, y, z: gettext.ldngettext("anaconda", x, y, z)
-
-class InstallInterfaceBase(object):
-    def __init__(self):
-        self._warnedUnusedRaidMembers = []
-
-    def messageWindow(self, title, text, type="ok", default = None,
-             custom_buttons=None,  custom_icon=None):
-        raise NotImplementedError
-
-    def detailedMessageWindow(self, title, text, longText=None, type="ok",
-                              default=None, custom_icon=None,
-                              custom_buttons=[], expanded=False):
-        raise NotImplementedError
-
-    def unusedRaidMembersWarning(self, unusedRaidMembers):
-        """Warn about unused BIOS RAID members"""
-        unusedRaidMembers = \
-            filter(lambda m: m not in self._warnedUnusedRaidMembers,
-                   unusedRaidMembers)
-        if unusedRaidMembers:
-            self._warnedUnusedRaidMembers.extend(unusedRaidMembers)
-            unusedRaidMembers.sort()
-            self.messageWindow(_("Warning"),
-                P_("Disk %s contains BIOS RAID metadata, but is not part of "
-                   "any recognized BIOS RAID sets. Ignoring disk %s.",
-                   "Disks %s contain BIOS RAID metadata, but are not part of "
-                   "any recognized BIOS RAID sets. Ignoring disks %s.",
-                   len(unusedRaidMembers)) %
-                   (", ".join(unusedRaidMembers),
-                    ", ".join(unusedRaidMembers)),
-                custom_icon="warning")
-
-    def questionInitializeDASD(self, c, devs):
-        """Ask if unformatted DASD's should be formatted"""
-        title = P_("Unformatted DASD Device Found",
-                   "Unformatted DASD Devices Found", c)
-        msg = P_("Format uninitialized DASD device?\n\n"
-                 "There is %d uninitialized DASD device on this "
-                 "system.  To continue installation, the device must "
-                 "be formatted.  Formatting will remove any data on "
-                 "this device.",
-                 "Format uninitialized DASD devices?\n\n"
-                 "There are %d uninitialized DASD devices on this "
-                 "system.  To continue installation, the devices must "
-                 "be formatted.  Formatting will remove any data on "
-                 "these devices.", c) % c
-        icon = "/usr/share/icons/gnome/32x32/status/dialog-error.png"
-        buttons = [_("_Format"), _("_Ignore")]
-        return self.detailedMessageWindow(title, msg, devs.strip(),
-                                             type="custom",
-                                             custom_icon=icon,
-                                             custom_buttons=buttons,
-                                             expanded=True)
diff --git a/installmethod.py b/installmethod.py
deleted file mode 100644
index 17f1d3a..0000000
--- a/installmethod.py
+++ /dev/null
@@ -1,56 +0,0 @@
-#
-# installmethod.py - Base class for install methods
-#
-# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007
-# Red Hat, Inc.  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 as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# 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, see <http://www.gnu.org/licenses/>.
-#
-
-import os, shutil, string
-from constants import *
-
-import logging
-log = logging.getLogger("anaconda")
-
-import isys, product
-
-def doMethodComplete(anaconda):
-    def _ejectDevice():
-        # Ejecting the CD/DVD for kickstart is handled only after %post scripts
-        # have been run.
-        if anaconda.ksdata:
-            return None
-
-        if anaconda.mediaDevice:
-            return anaconda.storage.devicetree.getDeviceByName(anaconda.mediaDevice)
-
-        # If we booted off the boot.iso instead of disc 1, eject that as well.
-        if anaconda.stage2 and anaconda.stage2.startswith("cdrom://"):
-            dev = anaconda.stage2[8:].split(':')[0]
-            return anaconda.storage.devicetree.getDeviceByName(dev)
-
-    anaconda.backend.complete(anaconda)
-    dev = _ejectDevice()
-    if dev:
-        dev.eject()
-
-    mtab = "/dev/root / ext3 ro 0 0\n"
-    rootDevice = anaconda.storage.rootDevice
-    if rootDevice:
-        mtab = "/dev/root / %s ro 0 0\n" % rootDevice.format.type
-
-    f = open(anaconda.rootPath + "/etc/mtab", "w+")
-    f.write(mtab)
-    f.close()
diff --git a/isys/.gitignore b/isys/.gitignore
deleted file mode 100644
index 0b04e81..0000000
--- a/isys/.gitignore
+++ /dev/null
@@ -1,6 +0,0 @@
-*.pyc
-.depend
-*.lo
-*.do
-nfs_mountversion.h
-auditd
diff --git a/isys/Makefile.am b/isys/Makefile.am
deleted file mode 100644
index 1a7ca81..0000000
--- a/isys/Makefile.am
+++ /dev/null
@@ -1,56 +0,0 @@
-# isys/Makefile.am for anaconda
-#
-# Copyright (C) 2009  Red Hat, Inc.
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU Lesser General Public License as published
-# by the Free Software Foundation; either version 2.1 of the License, or
-# (at your option) any later version.
-#
-# 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 Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public License
-# along with this program.  If not, see <http://www.gnu.org/licenses/>.
-#
-# Author: David Cantrell <dcantrell@xxxxxxxxxx>
-
-pkgpyexecdir = $(pyexecdir)/py$(PACKAGE_NAME)
-
-ISYS_SRCS = devices.c imount.c cpio.c uncpio.c lang.c \
-            isofs.c linkdetect.c vio.c ethtool.c eddsupport.c iface.c \
-            auditd.c log.c
-
-dist_noinst_HEADERS = *.h
-
-ISYS_CFLAGS = -DVERSION='"$(PACKAGE_VERSION)"' $(NFS_CFLAGS) \
-              $(NETWORKMANAGER_CFLAGS) $(LIBNL_CFLAGS) $(LIBNM_GLIB_CFLAGS) \
-              $(SELINUX_CFLAGS)
-ISYS_LIBS   = $(RESOLV_LIBS) $(EXT2FS_LIBS) $(ZLIB_LIBS) \
-              $(DEVMAPPER_LIBS) $(BLKID_LIBS) $(X11_LIBS) $(SELINUX_LIBS) \
-              $(LIBNL_LIBS) $(LIBNM_GLIB_LIBS)
-
-isysdir     = $(pkgpyexecdir)
-isys_PYTHON = *.py
-
-pkgpyexec_LTLIBRARIES = _isys.la
-_isys_la_CFLAGS       = $(PYTHON_INCLUDES) $(ISYS_CFLAGS)
-_isys_la_LDFLAGS      = -module -avoid-version $(PYTHON_LDFLAGS)
-_isys_la_LIBADD       = $(PYTHON_LIBS) $(ISYS_LIBS)
-_isys_la_SOURCES      = isys.c $(ISYS_SRCS)
-
-noinst_LTLIBRARIES    = libisys.la
-libisys_la_CFLAGS     = $(ISYS_CFLAGS)
-libisys_la_LDFLAGS    = -static
-libisys_la_LIBADD     = $(ISYS_LIBS)
-libisys_la_SOURCES    = $(ISYS_SRCS)
-
-auditddir             = $(libexecdir)/$(PACKAGE_NAME)
-auditd_PROGRAMS       = auditd
-auditd_SOURCES        = auditd.c
-auditd_CFLAGS         = -DSTANDALONE $(SELINUX_CFLAGS)
-auditd_LDADD          = $(SELINUX_LIBS) $(LIBNL_LIBS)
-
-MAINTAINERCLEANFILES = Makefile.in
diff --git a/isys/auditd.c b/isys/auditd.c
deleted file mode 100644
index 2ca6d04..0000000
--- a/isys/auditd.c
+++ /dev/null
@@ -1,134 +0,0 @@
-/*
- * auditd.c: This is a simple audit daemon that throws all messages away.
- *
- * Copyright (C) 2006  Red Hat, Inc.  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 as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * 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, see <http://www.gnu.org/licenses/>.
- *
- * Author(s): Peter Jones <pjones@xxxxxxxxxx>
- */
-
-#define _GNU_SOURCE 1
-
-#include <sys/types.h>
-#include <sys/syscall.h>
-#include <sys/poll.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <signal.h>
-#include <string.h>
-#include <stdlib.h>
-#include <errno.h>
-
-#include <libaudit.h>
-
-#include "auditd.h"
-
-#ifdef USESELINUX
-static int done;
-
-static void sig_done(int sig)
-{
-    done = 1;
-}
-
-static void do_auditd(int fd) {
-    struct audit_reply rep;
-    sigset_t sigs;
-    struct sigaction sa;
-    struct pollfd pds = {
-        .events = POLLIN,
-        .revents = 0,
-        .fd = fd,
-    };
-
-    if (audit_set_pid(fd, getpid(), WAIT_YES) < 0)
-        return;
-
-    if (audit_set_enabled(fd, 1) < 0)
-        return;
-
-    memset(&sa, '\0', sizeof (sa));
-    sa.sa_handler = sig_done;
-    sigaction(SIGTERM, &sa, NULL);
-    sigaction(SIGINT, &sa, NULL);
-    sigaction(SIGHUP, &sa, NULL);
-
-    sigfillset(&sigs);
-    sigdelset(&sigs, SIGTERM);
-    sigdelset(&sigs, SIGINT);
-    sigdelset(&sigs, SIGHUP);
-
-    while (1) {
-        int retval;
-
-        memset(&rep, 0, sizeof(rep));
-
-        do {
-            retval = ppoll(&pds, 1, NULL, &sigs);
-        } while (retval == -1 && errno == EINTR && !done);
-
-        if (done)
-            break;
-
-        if (audit_get_reply(fd, &rep, GET_REPLY_NONBLOCKING, 0) > 0) {
-            /* we don't actually want to do anything here. */
-            ;
-        }
-    }
-    return;
-}
-#endif /* USESELINUX */
-
-int audit_daemonize(void) {
-#ifdef USESELINUX
-    int fd;
-    pid_t child;
-    int i;
-    if ((child = fork()) > 0)
-        return 0;
-
-#ifndef STANDALONE 
-    for (i = 0; i < getdtablesize(); i++)
-        close(i);
-    signal(SIGTTOU, SIG_IGN);
-    signal(SIGTTIN, SIG_IGN);
-    signal(SIGTSTP, SIG_IGN);
-#endif /* !defined(STANDALONE) */
-
-    if ((fd = open("/proc/self/oom_adj", O_RDWR)) >= 0) {
-        i = write(fd, "-17", 3);
-        close(fd);
-    }
-    fd = audit_open();
-    do_auditd(fd);
-    audit_close(fd);
-
-#ifndef STANDALONE
-    exit(0);
-#endif /* !defined(STANDALONE) */
-
-#endif /* USESELINUX */
-    return 0;
-}
-
-#ifdef STANDALONE
-int main(void) {
-    return audit_daemonize();
-}
-#endif /* STANDALONE */
-
-/*
- * vim:ts=8:sw=4:sts=4:et
- */
diff --git a/isys/auditd.h b/isys/auditd.h
deleted file mode 100644
index 55ec5ce..0000000
--- a/isys/auditd.h
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * auditd.h: This is a simple audit daemon that throws all messages away.
- *
- * Copyright (C) 2006  Red Hat, Inc.  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 as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * 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, see <http://www.gnu.org/licenses/>.
- *
- * Author(s): Peter Jones <pjones@xxxxxxxxxx>
- */
-
-#ifndef ISYS_AUDIT_H
-#define ISYS_AUDIT_H 1
-
-extern int audit_daemonize(void);
-
-#endif /* ISYS_AUDIT_H */
-/*
- * vim:ts=8:sw=4:sts=4:et
- */
diff --git a/isys/cpio.c b/isys/cpio.c
deleted file mode 100644
index fd83605..0000000
--- a/isys/cpio.c
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * cpio.c
- *
- * Copyright (C) 2007  Red Hat, Inc.  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 as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * 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, see <http://www.gnu.org/licenses/>.
- */
-
-#include <fcntl.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-
-#include "cpio.h"
-
-int installCpioFile(gzFile fd, char * cpioName, char * outName, int inWin) {
-    struct cpioFileMapping map;
-    int rc;
-    const char * failedFile;
-
-    if (outName) {
-	map.archivePath = cpioName;
-	map.fsPath = outName;
-	map.mapFlags = CPIO_MAP_PATH;
-    }
-
-    rc = myCpioInstallArchive(fd, outName ? &map : NULL, 1, NULL, NULL, 
-			    &failedFile);
-
-    if (rc || access(outName, R_OK)) {
-	return -1;
-    }
-
-    return 0;
-}
diff --git a/isys/cpio.h b/isys/cpio.h
deleted file mode 100644
index 4cbb7c0..0000000
--- a/isys/cpio.h
+++ /dev/null
@@ -1,102 +0,0 @@
-/*
- * cpio.h
- *
- * Copyright (C) 2007  Red Hat, Inc.  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 as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * 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, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef H_CPIO
-#define H_CPIO
-
-#include <sys/types.h>
-
-#include "stubs.h"
-
-/* Note the CPIO_CHECK_ERRNO bit is set only if errno is valid. These have to
-   be positive numbers or this setting the high bit stuff is a bad idea. */
-#define CPIOERR_CHECK_ERRNO	0x80000000
-
-#define CPIOERR_BAD_MAGIC	(2			)
-#define CPIOERR_BAD_HEADER	(3			)
-#define CPIOERR_OPEN_FAILED	(4    | CPIOERR_CHECK_ERRNO)
-#define CPIOERR_CHMOD_FAILED	(5    | CPIOERR_CHECK_ERRNO)
-#define CPIOERR_CHOWN_FAILED	(6    | CPIOERR_CHECK_ERRNO)
-#define CPIOERR_WRITE_FAILED	(7    | CPIOERR_CHECK_ERRNO)
-#define CPIOERR_UTIME_FAILED	(8    | CPIOERR_CHECK_ERRNO)
-#define CPIOERR_UNLINK_FAILED	(9    | CPIOERR_CHECK_ERRNO)
-
-#define CPIOERR_SYMLINK_FAILED	(11   | CPIOERR_CHECK_ERRNO)
-#define CPIOERR_STAT_FAILED	(12   | CPIOERR_CHECK_ERRNO)
-#define CPIOERR_MKDIR_FAILED	(13   | CPIOERR_CHECK_ERRNO)
-#define CPIOERR_MKNOD_FAILED	(14   | CPIOERR_CHECK_ERRNO)
-#define CPIOERR_MKFIFO_FAILED	(15   | CPIOERR_CHECK_ERRNO)
-#define CPIOERR_LINK_FAILED	(16   | CPIOERR_CHECK_ERRNO)
-#define CPIOERR_READLINK_FAILED	(17   | CPIOERR_CHECK_ERRNO)
-#define CPIOERR_READ_FAILED	(18   | CPIOERR_CHECK_ERRNO)
-#define CPIOERR_COPY_FAILED	(19   | CPIOERR_CHECK_ERRNO)
-#define CPIOERR_INTERNAL	(20			)
-#define CPIOERR_HDR_SIZE	(21			)
-#define CPIOERR_UNKNOWN_FILETYPE (22			)
-
-
-/* Don't think this behaves just like standard cpio. It's pretty close, but
-   it has some behaviors which are more to RPM's liking. I tried to document
-   them inline in cpio.c, but I may have missed some. */
-
-#define CPIO_MAP_PATH		(1 << 0)
-#define CPIO_MAP_MODE		(1 << 1)
-#define CPIO_MAP_UID		(1 << 2)
-#define CPIO_MAP_GID		(1 << 3)
-#define CPIO_FOLLOW_SYMLINKS	(1 << 4)  /* only for building */
-
-struct cpioFileMapping {
-    char * archivePath;
-    char * fsPath;
-    mode_t finalMode;
-    uid_t finalUid;
-    gid_t finalGid;
-    int mapFlags;
-};
-
-/* on cpio building, only "file" is filled in */
-struct cpioCallbackInfo {
-    char * file;
-    long fileSize;			/* total file size */
-    long fileComplete;			/* amount of file unpacked */
-    long bytesProcessed;		/* bytes in archive read */
-};
-
-typedef void (*cpioCallback)(struct cpioCallbackInfo * filespec, void * data);
-
-/* If no mappings are passed, this installs everything! If one is passed
-   it should be sorted according to cpioFileMapCmp() and only files included
-   in the map are installed. Files are installed relative to the current
-   directory unless a mapping is given which specifies an absolute 
-   directory. The mode mapping is only used for the permission bits, not
-   for the file type. The owner/group mappings are ignored for the nonroot
-   user. If *failedFile is non-NULL on return, it should be free()d. */
-int myCpioInstallArchive(gzFile stream, struct cpioFileMapping * mappings, 
-		       int numMappings, cpioCallback cb, void * cbData,
-		       const char ** failedFile);
-int myCpioFilterArchive(gzFile inStream, gzFile outStream, char ** pattern);
-
-/* This is designed to be qsort/bsearch compatible */
-int myCpioFileMapCmp(const void * a, const void * b);
-
-const char *myCpioStrerror(int rc);
-
-int installCpioFile(gzFile fd, char * cpioName, char * outName, int inWin);
-
-#endif
diff --git a/isys/devices.c b/isys/devices.c
deleted file mode 100644
index 53130d1..0000000
--- a/isys/devices.c
+++ /dev/null
@@ -1,221 +0,0 @@
-/*
- * devices.c - various hardware probing functionality
- *
- * Copyright (C) 2007  Red Hat, Inc.
- * 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 as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * 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, see <http://www.gnu.org/licenses/>.
- *
- * Author(s): Bill Nottingham <notting@xxxxxxxxxx>
- */
-
-#include <ctype.h>
-#include <dirent.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <sys/types.h>
-#include <limits.h>
-
-#include "devices.h"
-
-/* for 'disks', to filter out weird stuff */
-#define MINIMUM_INTERESTING_SIZE	32*1024 	/* 32MB */
-
-/* from genhd.h, kernel side */
-#define GENHD_FL_REMOVABLE                      1
-#define GENHD_FL_DRIVERFS                       2
-#define GENHD_FL_MEDIA_CHANGE_NOTIFY            4
-#define GENHD_FL_CD                             8
-#define GENHD_FL_UP                             16
-#define GENHD_FL_SUPPRESS_PARTITION_INFO        32
-#define GENHD_FL_FAIL                           64
-
-
-struct device **getDevices(enum deviceType type) {
-    struct device **ret = NULL;
-    struct device *new;
-    int numdevices = 0;
-
-    if (type & (DEVICE_DISK | DEVICE_CDROM)) {
-        DIR *dir;
-        struct dirent *ent;
-
-        dir = opendir("/sys/block");
-
-        if (!dir) goto storagedone;
-
-        while ((ent = readdir(dir))) {
-            char path[64];
-            char buf[64];
-            int fd, caps, devtype;
-
-            snprintf(path, 64, "/sys/block/%s/capability", ent->d_name);
-            fd = open(path, O_RDONLY);
-            if (fd == -1)
-                continue;
-            if (read(fd, buf, 63) <= 0) {
-                close(fd);
-                continue;
-            }
-
-            close(fd);
-            errno = 0;
-            caps = strtol(buf, NULL, 16);
-
-            if ((errno == ERANGE && (caps == LONG_MIN || caps == LONG_MAX)) ||
-                (errno != 0 && caps == 0)) {
-                return NULL;
-            }
-
-            if (caps & GENHD_FL_CD)
-                devtype = DEVICE_CDROM;
-            else
-                devtype = DEVICE_DISK;
-            if (!(devtype & type))
-                continue;
-
-            if (devtype == DEVICE_DISK && !(caps & GENHD_FL_REMOVABLE)) {
-                int size;
-
-                snprintf(path, 64, "/sys/block/%s/size", ent->d_name);
-                fd = open(path, O_RDONLY);
-
-                if (fd == -1)
-                    continue;
-                if (read(fd, buf, 63) <= 0) {
-                    close(fd);
-                    continue;
-                }
-
-                close(fd);
-                errno = 0;
-                size = strtol(buf, NULL, 10);
-
-                if ((errno == ERANGE && (size == LONG_MIN ||
-                                         size == LONG_MAX)) ||
-                    (errno != 0 && size == 0)) {
-                    return NULL;
-                }
-
-                if (size < MINIMUM_INTERESTING_SIZE)
-                    continue;
-            }
-
-            new = calloc(1, sizeof(struct device));
-            new->device = strdup(ent->d_name);
-            /* FIXME */
-            if (asprintf(&new->description, "Storage device %s",
-                         new->device) == -1) {
-                fprintf(stderr, "%s: %d: %s\n", __func__, __LINE__,
-                        strerror(errno));
-                fflush(stderr);
-                abort();
-            }
-            new->type = devtype;
-            if (caps & GENHD_FL_REMOVABLE) {
-                new->priv.removable = 1;
-            }
-            ret = realloc(ret, (numdevices+2) * sizeof(struct device));
-            ret[numdevices] = new;
-            ret[numdevices+1] = NULL;
-            numdevices++;
-        }
-
-        closedir(dir);
-    }
-storagedone:
-
-    if (type & DEVICE_NETWORK) {
-        DIR *dir;
-        struct dirent *ent;
-
-        dir = opendir("/sys/class/net");
-
-        if (!dir) goto netdone;
-
-        while ((ent = readdir(dir))) {
-            char path[64];
-            int fd, type;
-            char buf[64];
-
-            snprintf(path, 64, "/sys/class/net/%s/type", ent->d_name);
-            fd = open(path, O_RDONLY);
-            if (fd == -1)
-                continue;
-            if (read(fd, buf, 63) <= 0) {
-                close(fd);
-                continue;
-            }
-
-            close(fd);
-            errno = 0;
-            type = strtol(buf, NULL, 10);
-
-            if ((errno == ERANGE && (type == LONG_MIN || type == LONG_MAX)) ||
-                (errno != 0 && type == 0)) {
-                return NULL;
-            }
-
-            if (type != 1)
-                continue;
-
-            new = calloc(1, sizeof(struct device));
-            new->device = strdup(ent->d_name);
-            /* FIXME */
-            snprintf(path, 64, "/sys/class/net/%s/address", ent->d_name);
-            fd = open(path, O_RDONLY);
-            if (fd != -1) {
-                memset(buf, '\0', 64);
-                if (read(fd, buf, 63) > 0) {
-                    int i;
-                    for (i = (strlen(buf)-1); isspace(buf[i]); i--)
-                        buf[i] = '\0';
-                    new->priv.hwaddr = strdup(buf);
-                }
-            }
-
-            if (new->priv.hwaddr) {
-                if (asprintf(&new->description, "Ethernet device %s - %s",
-                             new->device, new->priv.hwaddr) == -1) {
-                    fprintf(stderr, "%s: %d: %s\n", __func__, __LINE__,
-                            strerror(errno));
-                    fflush(stderr);
-                    abort();
-                }
-            } else {
-                if (asprintf(&new->description, "Ethernet device %s",
-                             new->device) == -1) {
-                    fprintf(stderr, "%s: %d: %s\n", __func__, __LINE__,
-                            strerror(errno));
-                    fflush(stderr);
-                    abort();
-                }
-            }
-
-            ret = realloc(ret, (numdevices+2) * sizeof(struct device));
-            ret[numdevices] = new;
-            ret[numdevices+1] = NULL;
-            numdevices++;
-        }
-
-        closedir(dir);
-    }
-netdone:
-    return ret;
-}
-
diff --git a/isys/devices.h b/isys/devices.h
deleted file mode 100644
index 9428a77..0000000
--- a/isys/devices.h
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * devices.h
- *
- * Copyright (C) 2007  Red Hat, Inc.  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 as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * 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, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef DEVICES_H
-#define DEVICES_H
-
-enum deviceType {
-    DEVICE_ANY = ~0,
-    DEVICE_NETWORK = (1 << 0),
-    DEVICE_DISK = (1 << 1),
-    DEVICE_CDROM = (1 << 2)
-};
-
-struct device {
-    char *device;
-    char *description;
-    enum deviceType type;
-    union {
-        char *hwaddr;
-        int removable;
-    } priv;
-};
-
-struct device **getDevices(enum deviceType type);
-
-#endif
diff --git a/isys/eddsupport.c b/isys/eddsupport.c
deleted file mode 100644
index c50278e..0000000
--- a/isys/eddsupport.c
+++ /dev/null
@@ -1,339 +0,0 @@
-/*
- * eddsupport.c - handling of mapping disk drives in Linux to disk drives
- * according to the BIOS using the edd kernel module
- *
- * Copyright (C) 2004  Dell, Inc.  All rights reserved.
- * Copyright (C) 2004  Red Hat, Inc.  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 as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * 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, see <http://www.gnu.org/licenses/>.
- *
- * Author(s): Rezwanul_Kabir@xxxxxxxx
- *            Jeremy Katz <katzj@xxxxxxxxxx>
- */
-
-#include <ctype.h>
-#include <dirent.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <stdint.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-#include <sys/stat.h>
-#include <sys/reboot.h>
-#include <sys/types.h>
-#include <linux/types.h>
-
-
-#include "eddsupport.h"
-#include "devices.h"
-#include "isys.h"
-
-#define EDD_DIR "/sys/firmware/edd"
-#define SIG_FILE "mbr_signature"
-#define MBRSIG_OFFSET 0x1b8
-
-#define HASH_TABLE_SIZE 17
-
-
-struct diskMapEntry{
-    uint32_t key;
-    char *diskname;
-    struct diskMapEntry *next;
-};
-
-struct diskMapTable {
-    struct diskMapEntry **table;
-    int tableSize;
-};
-
-static struct diskMapTable *mbrSigToName = NULL;
-static int diskHashInit = 0;
-
-
-
-static struct diskMapTable*  initializeHashTable(int);
-static int insertHashItem(struct diskMapTable *, struct diskMapEntry *);
-static struct diskMapEntry* lookupHashItem(struct diskMapTable *, uint32_t);
-static int addToHashTable(struct diskMapTable *, uint32_t , char *);
-static struct device ** createDiskList();
-static int mapBiosDisks(struct device ** , const char *);
-static int readDiskSig(char *,  uint32_t *);
-static int readMbrSig(char *, uint32_t *);
-
-/* This is the top level function that creates a disk list present in the
- * system, checks to see if unique signatures exist on the disks at offset 
- * 0x1b8.  If a unique signature exists then it will map BIOS disks to their 
- * corresponding hd/sd device names.  Otherwise, we'll avoid mapping drives.
- */
-
-int probeBiosDisks() {
-    struct device ** devices = NULL;
-
-    devices = createDiskList();
-    if(!devices){
-#ifdef STANDALONE
-        fprintf(stderr, "No disks!\n");
-#endif
-        return -1;
-    }
-
-    if(!mapBiosDisks(devices, EDD_DIR)){
-#ifdef STANDALONE
-            fprintf(stderr, "WARNING: couldn't map BIOS disks\n");
-#endif
-            return -1;
-    }
-    return 0;
-}
-
-
-static struct device ** createDiskList(){
-    return getDevices (DEVICE_DISK);
-}
-
-static int readDiskSig(char *device, uint32_t *disksig) {
-    int fd, rc;
-    char devnodeName[64];
-
-    snprintf(devnodeName, sizeof(devnodeName), "/dev/%s", device);
-    fd = open(devnodeName, O_RDONLY);
-    if (fd < 0) {
-#ifdef STANDALONE 
-        fprintf(stderr, "Error opening device %s: %s\n ", device, 
-                strerror(errno));
-#endif 
-        return -errno;
-    }
-
-    rc = lseek(fd, MBRSIG_OFFSET, SEEK_SET);
-    if (rc < 0){
-        close(fd);
-
-#ifdef STANDALONE
-        fprintf(stderr, "Error seeking to MBRSIG_OFFSET in %s: %s\n", 
-                device, strerror(errno));
-#endif
-        return -1;
-    }
-
-    rc = read(fd, disksig, sizeof(uint32_t));
-    if (rc < sizeof(uint32_t)) {
-        close(fd);
-
-#ifdef STANDALONE
-        fprintf(stderr, "Failed to read signature from %s\n", device); 
-#endif
-        return -1;
-    }
-
-    close(fd);
-    return 0;
-}
-
-static int mapBiosDisks(struct device** devices,const char *path) {
-    DIR *dirHandle;
-    struct dirent *entry;
-    char * sigFileName;
-    uint32_t mbrSig, biosNum, currentSig;
-    struct device **currentDev, **foundDisk;
-    int i, rc, ret, dm_nr, highest_dm;
-
-    dirHandle = opendir(path);
-    if(!dirHandle){
-#ifdef STANDALONE
-        fprintf(stderr, "Failed to open directory %s: %s\n", path, 
-                strerror(errno));
-#endif
-        return 0;
-    }
-
-    mbrSigToName = initializeHashTable(HASH_TABLE_SIZE);
-    if(!mbrSigToName){
-#ifdef STANDALONE
-        fprintf(stderr, "Error initializing mbrSigToName table\n");
-#endif
-        closedir(dirHandle);
-        return 0;
-    }
-
-    while ((entry = readdir(dirHandle)) != NULL) {
-        if(!strncmp(entry->d_name,".",1) || !strncmp(entry->d_name,"..",2)) {
-            continue;
-        }
-        ret = sscanf((entry->d_name+9), "%x", &biosNum);
-        
-        sigFileName = malloc(strlen(path) + strlen(entry->d_name) + 20);
-        sprintf(sigFileName, "%s/%s/%s", path, entry->d_name, SIG_FILE);
-        if (readMbrSig(sigFileName, &mbrSig) == 0) {
-            for (currentDev = devices, i = 0, foundDisk=NULL, highest_dm=-1;
-                    (*currentDev) != NULL;
-                    currentDev++) {
-                if (!(*currentDev)->device)
-                    continue;
-
-                if ((rc=readDiskSig((*currentDev)->device, &currentSig)) < 0) {
-                    if (rc == -ENOMEDIUM || rc == -ENXIO)
-                        continue;
-                    closedir(dirHandle);
-                    return 0;
-                } 
-
-                if (mbrSig == currentSig) {
-                    /* When we have a fakeraid setup we will find multiple hits
-                       a number for the raw disks (1 when striping, 2 when
-                       mirroring, more with raid on raid like raid 01 or 10)
-                       and a number for the dm devices (normally only one dm
-                       device will match, but more with raid on raid).
-                       Since with raid on raid the last dm device created
-                       will be the top layer raid, we want the highest matching
-                       dm device. */
-                    if (!strncmp((*currentDev)->device, "dm-", 3) &&
-                         sscanf((*currentDev)->device+3, "%d", &dm_nr) == 1) {
-                        if (dm_nr > highest_dm) {
-                            highest_dm = dm_nr;
-                            foundDisk=currentDev;
-                            i = 1;
-                        }
-                    } else if (!foundDisk ||
-                               strncmp((*foundDisk)->device, "dm-", 3)) {
-                        foundDisk=currentDev;
-                        i++;
-                    }
-                }
-            }
-
-            if (i==1) {
-                if(!addToHashTable(mbrSigToName, (uint32_t)biosNum, 
-                               (*foundDisk)->device)) {
-                    closedir(dirHandle);
-                    return 0;
-                }
-            }
-        } 
-    }
-    closedir(dirHandle);
-    return 1;
-} 
-
-
-static int readMbrSig(char *filename, uint32_t *int_sig){
-    FILE* fh;
-
-    fh = fopen(filename,"r");
-    if(fh == NULL) {
-#ifdef STANDALONE
-        fprintf(stderr, "Error opening mbr_signature file %s: %s\n", filename,
-                strerror(errno));
-#endif
-        return -1;
-    }
-    fseek(fh, 0, SEEK_SET);
-    if (fscanf(fh, "%x", int_sig) != 1) {
-#ifdef STANDALONE
-        fprintf(stderr, "Error reading %s\n", filename);
-#endif
-        fclose(fh);
-        return -1;
-    }
-
-    fclose(fh);
-    return 0;
-}                                                   
-
-
-static struct diskMapTable* initializeHashTable(int size) {
-    struct diskMapTable *hashTable;
-
-    hashTable = malloc(sizeof(struct diskMapTable));
-    hashTable->tableSize = size;
-    hashTable->table = malloc(sizeof(struct diskMapEntry *) * size);
-    memset(hashTable->table,0,(sizeof(struct diskMapEntry *) * size));
-    return hashTable;
-}
-
-
-static int insertHashItem(struct diskMapTable *hashTable,
-                          struct diskMapEntry *hashItem) {
-    int index;
-
-    index = (hashItem->key) % (hashTable->tableSize);
-
-    if(hashTable->table[index] == NULL){
-        hashTable->table[index] = hashItem;
-        return index;
-    } else {
-        hashItem->next = hashTable->table[index];
-        hashTable->table[index] = hashItem;
-        return index;
-    }
-}
-
-
-static struct diskMapEntry * lookupHashItem(struct diskMapTable *hashTable,
-                                            uint32_t itemKey) {
-    int index;
-    struct diskMapEntry *hashItem;
-
-    index = itemKey % (hashTable->tableSize);
-    for (hashItem = hashTable->table[index]; 
-         (hashItem != NULL) && (hashItem->key != itemKey); 
-         hashItem = hashItem->next) { 
-        ;
-    }
-    return hashItem;
-}
-
-
-static int addToHashTable(struct diskMapTable *hashTable, 
-                          uint32_t itemKey, char *diskName) {
-    int index;
-    struct diskMapEntry *diskSigToNameEntry;
-
-    diskSigToNameEntry = malloc(sizeof(struct diskMapEntry));
-    diskSigToNameEntry->next = NULL;
-    diskSigToNameEntry->key = itemKey;
-    diskSigToNameEntry->diskname = diskName;
-
-    if ((index = insertHashItem(hashTable, diskSigToNameEntry)) < 0){
-#ifdef STANDALONE
-        fprintf(stderr, "Unable to insert item\n");
-#endif
-        return 0;
-    } else {
-        return 1;
-    }
-}
-
-
-char * getBiosDisk(char *biosStr) {
-    uint32_t biosNum;
-    struct diskMapEntry * disk;
-    int ret;
-
-    if (diskHashInit == 0) {
-        probeBiosDisks();
-        diskHashInit = 1;
-    }
-
-    if (mbrSigToName == NULL)
-        return NULL;
-
-    ret = sscanf(biosStr,"%x",&biosNum);
-    disk = lookupHashItem(mbrSigToName, biosNum);
-    if (disk) return disk->diskname;
-
-    return NULL;
-}
diff --git a/isys/eddsupport.h b/isys/eddsupport.h
deleted file mode 100644
index 77fc4c4..0000000
--- a/isys/eddsupport.h
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * eddsupport.h
- *
- * Copyright (C) 2007  Red Hat, Inc.  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 as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * 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, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef EDDSUPPORT_H
-#define EDDSUPPORT_H
-
-int probeBiosDisks();
-char* getBiosDisk(char *);
-
-#endif
-
-
diff --git a/isys/ethtool.c b/isys/ethtool.c
deleted file mode 100644
index 871f1d4..0000000
--- a/isys/ethtool.c
+++ /dev/null
@@ -1,119 +0,0 @@
-/*
- * ethtool.c - setting of basic ethtool options
- *
- * Copyright (C) 2003  Red Hat, Inc.  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 as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * 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, see <http://www.gnu.org/licenses/>.
- *
- * Author(s): Jeremy Katz <katzj@xxxxxxxxxx>
- */
-
-#include <errno.h>
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-#include <unistd.h>
-
-#include <sys/ioctl.h>
-#include <sys/socket.h>
-#include <sys/types.h>
-#include <net/if.h>
-
-#include <linux/sockios.h>
-#include "ethtool.h"
-
-static int set_intf_up(struct ifreq ifr, int sock) {
-    if (ioctl(sock, SIOCGIFFLAGS, &ifr) < 0) {
-        return (-1);
-    }
-    ifr.ifr_flags |= (IFF_UP | IFF_RUNNING);
-    if (ioctl(sock, SIOCSIFFLAGS, &ifr) < 0) {
-        fprintf(stderr, "failed to bring up interface %s: %s", ifr.ifr_name,
-                strerror(errno));
-        return -1;
-    }
-    return (0);
-}
-
-int setEthtoolSettings(char * dev, ethtool_speed speed, 
-                       ethtool_duplex duplex) {
-    int sock, err;
-    struct ethtool_cmd ecmd;
-    struct ifreq ifr;
-
-    if ((sock = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
-        perror("Unable to create socket");
-        return -1;
-    }
-
-    /* Setup our control structures. */
-    memset(&ifr, 0, sizeof(ifr));
-    strcpy(ifr.ifr_name, dev);
-
-    if (set_intf_up(ifr, sock) == -1) {
-        fprintf(stderr, "unable to bring up interface %s: %s", dev, 
-                strerror(errno));
-        return -1;
-    }
-
-    ecmd.cmd = ETHTOOL_GSET;
-    ifr.ifr_data = (caddr_t)&ecmd;
-    err = ioctl(sock, SIOCETHTOOL, &ifr);
-    if (err < 0) {
-        perror("Unable to get settings via ethtool.  Not setting");
-        return -1;
-    }
-
-    if (speed != ETHTOOL_SPEED_UNSPEC)
-        ecmd.speed = speed;
-    if (duplex != ETHTOOL_DUPLEX_UNSPEC)
-        ecmd.duplex = duplex;
-    if ((duplex != ETHTOOL_DUPLEX_UNSPEC) || (speed != ETHTOOL_SPEED_UNSPEC))
-        ecmd.autoneg = AUTONEG_DISABLE;
-
-    ecmd.cmd = ETHTOOL_SSET;
-    ifr.ifr_data = (caddr_t)&ecmd;
-    err = ioctl(sock, SIOCETHTOOL, &ifr);
-    if (err < 0) {
-        //        perror("Unable to set settings via ethtool.  Not setting");
-        return -1;
-    }
-
-    return 0;
-}
-
-int identifyNIC(char *iface, int seconds) {
-    int sock;
-    struct ethtool_value edata;
-    struct ifreq ifr;
-
-    if ((sock = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
-        perror("Unable to create socket");
-        return -1;
-    }
-
-    memset(&ifr, 0, sizeof(ifr));
-    memset(&edata, 0, sizeof(edata));
-
-    strcpy(ifr.ifr_name, iface);
-    edata.cmd = ETHTOOL_PHYS_ID;
-    edata.data = seconds;
-    ifr.ifr_data = (caddr_t) &edata;
-
-    if (ioctl(sock, SIOCETHTOOL, &ifr) < 0) {
-        perror("Unable to identify NIC");
-    }
-
-    return 0;
-}
diff --git a/isys/ethtool.h b/isys/ethtool.h
deleted file mode 100644
index 57b4ffc..0000000
--- a/isys/ethtool.h
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * net.h
- *
- * Copyright (C) 2007  Red Hat, Inc.  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 as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * 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, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef ISYSNET_H
-#define ISYSNET_H
-
-#include <linux/types.h>
-#include <linux/ethtool.h>
-
-/* returns 1 for link, 0 for no link, -1 for unknown */
-int get_link_status(char *ifname);
-
-typedef enum ethtool_speed_t { ETHTOOL_SPEED_UNSPEC = -1, 
-                               ETHTOOL_SPEED_10 = SPEED_10, 
-                               ETHTOOL_SPEED_100 = SPEED_100,
-                               ETHTOOL_SPEED_1000 = SPEED_1000 } ethtool_speed;
-typedef enum ethtool_duplex_t { ETHTOOL_DUPLEX_UNSPEC = -1, 
-                                ETHTOOL_DUPLEX_HALF = DUPLEX_HALF,
-                                ETHTOOL_DUPLEX_FULL = DUPLEX_FULL } ethtool_duplex;
-
-/* set ethtool settings */
-int setEthtoolSettings(char * dev, ethtool_speed speed, ethtool_duplex duplex);
-int identifyNIC(char *iface, int seconds);
-
-#endif
diff --git a/isys/iface.c b/isys/iface.c
deleted file mode 100644
index 5897286..0000000
--- a/isys/iface.c
+++ /dev/null
@@ -1,543 +0,0 @@
-/*
- * iface.c - Network interface configuration API
- *
- * Copyright (C) 2006, 2007, 2008  Red Hat, 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; either version 2 of the License, or
- * (at your option) any later version.
- *
- * 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, see <http://www.gnu.org/licenses/>.
- *
- * Author(s): David Cantrell <dcantrell@xxxxxxxxxx>
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <errno.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <sys/stat.h>
-#include <sys/types.h>
-#include <sys/wait.h>
-#include <sys/utsname.h>
-#include <arpa/inet.h>
-#include <dirent.h>
-#include <fcntl.h>
-#include <netdb.h>
-#include <signal.h>
-#include <netinet/in.h>
-
-#include <netlink/netlink.h>
-#include <netlink/socket.h>
-#include <netlink/route/rtnl.h>
-#include <netlink/route/route.h>
-#include <netlink/route/addr.h>
-#include <netlink/route/link.h>
-
-#include <glib.h>
-#include <NetworkManager.h>
-#include <nm-client.h>
-#include <nm-device.h>
-#include <nm-ip4-config.h>
-#include <nm-setting-ip4-config.h>
-
-#include "isys.h"
-#include "iface.h"
-
-/* Internal-only function prototypes. */
-static struct nl_handle *_iface_get_handle(void);
-static struct nl_cache *_iface_get_link_cache(struct nl_handle **);
-static int _iface_have_valid_addr(void *addr, int family, int length);
-static int _iface_redirect_io(char *device, int fd, int mode);
-
-/*
- * Return a libnl handle for NETLINK_ROUTE.
- */
-static struct nl_handle *_iface_get_handle(void) {
-    struct nl_handle *handle = NULL;
-
-    if ((handle = nl_handle_alloc()) == NULL) {
-        return NULL;
-    }
-
-    if (nl_connect(handle, NETLINK_ROUTE)) {
-        nl_handle_destroy(handle);
-        return NULL;
-    }
-
-    return handle;
-}
-
-/*
- * Return an NETLINK_ROUTE cache.
- */
-static struct nl_cache *_iface_get_link_cache(struct nl_handle **handle) {
-    struct nl_cache *cache = NULL;
-
-    if ((*handle = _iface_get_handle()) == NULL) {
-        return NULL;
-    }
-
-    if ((cache = rtnl_link_alloc_cache(*handle)) == NULL) {
-        nl_close(*handle);
-        nl_handle_destroy(*handle);
-        return NULL;
-    }
-
-    return cache;
-}
-
-/*
- * Determine if a struct in_addr or struct in6_addr contains a valid address.
- */
-static int _iface_have_valid_addr(void *addr, int family, int length) {
-    char buf[length+1];
-
-    if ((addr == NULL) || (family != AF_INET && family != AF_INET6)) {
-        return 0;
-    }
-
-    memset(buf, '\0', sizeof(buf));
-
-    if (inet_ntop(family, addr, buf, length) == NULL) {
-        return 0;
-    } else {
-        /* check for unknown addresses */
-        if (family == AF_INET) {
-            if (!strncmp(buf, "0.0.0.0", 7)) {
-                return 0;
-            }
-        } else if (family == AF_INET6) {
-            if (!strncmp(buf, "::", 2)) {
-                return 0;
-            }
-        }
-    }
-
-    return 1;
-}
-
-/*
- * Redirect I/O to another device (e.g., stdout to /dev/tty5)
- */
-int _iface_redirect_io(char *device, int fd, int mode) {
-    int io = -1;
-
-    if ((io = open(device, mode)) == -1) {
-        return 1;
-    }
-
-    if (close(fd) == -1) {
-        return 2;
-    }
-
-    if (dup2(io, fd) == -1) {
-        return 3;
-    }
-
-    if (close(io) == -1) {
-        return 4;
-    }
-
-    return 0;
-}
-
-/*
- * Given an interface name (e.g., eth0) and address family (e.g., AF_INET),
- * return the IP address in human readable format (i.e., the output from
- * inet_ntop()).  Return NULL for no match or error.
- */
-char *iface_ip2str(char *ifname, int family) {
-    int i;
-    NMClient *client = NULL;
-    NMIP4Config *ip4config = NULL;
-    NMIP4Address *ipaddr = NULL;
-    NMDevice *candidate = NULL;
-    struct in_addr tmp_addr;
-    const GPtrArray *devices;
-    const char *iface;
-    char ipstr[INET_ADDRSTRLEN+1];
-
-    if (ifname == NULL) {
-        return NULL;
-    }
-
-    /* DCFIXME: add IPv6 once NM gains support */
-    if (family != AF_INET) {
-        return NULL;
-    }
-
-    g_type_init();
-
-    client = nm_client_new();
-    if (!client) {
-        return NULL;
-    }
-
-    if (nm_client_get_state(client) != NM_STATE_CONNECTED) {
-        g_object_unref(client);
-        return NULL;
-    }
-
-    devices = nm_client_get_devices(client);
-    for (i=0; i < devices->len; i++) {
-        candidate = g_ptr_array_index(devices, i);
-        iface = nm_device_get_iface(candidate);
-
-        if (nm_device_get_state(candidate) != NM_DEVICE_STATE_ACTIVATED)
-            continue;
-
-        if (!iface || strcmp(iface, ifname))
-            continue;
-
-        if (!(ip4config = nm_device_get_ip4_config(candidate)))
-            continue;
-
-        if (!(ipaddr = nm_ip4_config_get_addresses(ip4config)->data))
-            continue;
-
-        memset(&ipstr, '\0', sizeof(ipstr));
-        tmp_addr.s_addr = nm_ip4_address_get_address(ipaddr);
-
-        if (inet_ntop(AF_INET, &tmp_addr, ipstr, INET_ADDRSTRLEN) == NULL) {
-            g_object_unref(client);
-            return NULL;
-        }
-
-        g_object_unref(client);
-        return g_strdup(ipstr);
-    }
-
-    g_object_unref(client);
-    return NULL;
-}
-
-/* Given an interface's MAC address, return the name (e.g., eth0) in human
- * readable format.  Return NULL for no match
- */
-char *iface_mac2device(char *mac) {
-    struct nl_handle *handle = NULL;
-    struct nl_cache *cache = NULL;
-    struct rtnl_link *link = NULL;
-    struct nl_addr *mac_as_nl_addr = NULL;
-    char *retval = NULL;
-    int i, n;
-
-    if (mac == NULL) {
-        return NULL;
-    }
-
-    if ((mac_as_nl_addr = nl_addr_parse(mac, AF_LLC)) == NULL) {
-        return NULL;
-    }
-
-    if ((cache = _iface_get_link_cache(&handle)) == NULL) {
-        return NULL;
-    }
-
-    n = nl_cache_nitems(cache);
-    for (i = 0; i <= n; i++) {
-        struct nl_addr *addr;
-
-        if ((link = rtnl_link_get(cache, i)) == NULL) {
-            continue;
-        }
-
-        addr = rtnl_link_get_addr(link);
-
-        if (!nl_addr_cmp(mac_as_nl_addr, addr)) {
-            retval = strdup(rtnl_link_get_name(link));
-            rtnl_link_put(link);
-            break;
-        }
-
-        rtnl_link_put(link);
-    }
-
-    nl_close(handle);
-    nl_handle_destroy(handle);
-
-    return retval;
-}
-
-/*
- * Given an interface name (e.g., eth0), return the MAC address in human
- * readable format (e.g., 00:11:52:12:D9:A0).  Return NULL for no match.
- */
-char *iface_mac2str(char *ifname) {
-    int buflen = 20;
-    char *buf = NULL;
-    struct nl_handle *handle = NULL;
-    struct nl_cache *cache = NULL;
-    struct rtnl_link *link = NULL;
-    struct nl_addr *addr = NULL;
-
-    if (ifname == NULL) {
-        return NULL;
-    }
-
-    if ((cache = _iface_get_link_cache(&handle)) == NULL) {
-        return NULL;
-    }
-
-    if ((link = rtnl_link_get_by_name(cache, ifname)) == NULL) {
-        goto mac2str_error2;
-    }
-
-    if ((addr = rtnl_link_get_addr(link)) == NULL) {
-        goto mac2str_error3;
-    }
-
-    if ((buf = calloc(sizeof(char *), buflen)) == NULL) {
-        goto mac2str_error4;
-    }
-
-    if ((buf = nl_addr2str(addr, buf, buflen)) != NULL) {
-        char *oldbuf = buf;
-        buf = g_ascii_strup(buf, -1);
-        free(oldbuf);
-    }
-
-mac2str_error4:
-    nl_addr_destroy(addr);
-mac2str_error3:
-    rtnl_link_put(link);
-mac2str_error2:
-    nl_close(handle);
-    nl_handle_destroy(handle);
-
-    return buf;
-}
-
-/*
- * Convert an IPv4 CIDR prefix to a dotted-quad netmask.  Return NULL on
- * failure.
- */
-struct in_addr *iface_prefix2netmask(int prefix) {
-    int mask = 0;
-    char *buf = NULL;
-    struct in_addr *ret;
-
-    if ((buf = calloc(sizeof(char *), INET_ADDRSTRLEN + 1)) == NULL) {
-        return NULL;
-    }
-
-    mask = htonl(~((1 << (32 - prefix)) - 1));
-
-    if (inet_ntop(AF_INET, (struct in_addr *) &mask, buf,
-                  INET_ADDRSTRLEN) == NULL) {
-        return NULL;
-    }
-
-    if ((ret = calloc(sizeof(struct in_addr), 1)) == NULL) {
-        return NULL;
-    }
-
-    memcpy(ret, (struct in_addr *) &mask, sizeof(struct in_addr));
-    return ret;
-}
-
-/*
- * Initialize a new iface_t structure to default values.
- */
-void iface_init_iface_t(iface_t *iface) {
-    int i;
-
-    memset(&iface->device, '\0', sizeof(iface->device));
-    memset(&iface->ipaddr, 0, sizeof(iface->ipaddr));
-    memset(&iface->netmask, 0, sizeof(iface->netmask));
-    memset(&iface->broadcast, 0, sizeof(iface->broadcast));
-    memset(&iface->ip6addr, 0, sizeof(iface->ip6addr));
-    memset(&iface->gateway, 0, sizeof(iface->gateway));
-    memset(&iface->gateway6, 0, sizeof(iface->gateway6));
-
-    for (i = 0; i < MAXNS; i++) {
-        iface->dns[i] = NULL;
-    }
-
-    iface->macaddr = NULL;
-    iface->ip6prefix = 0;
-    iface->nextserver = NULL;
-    iface->bootfile = NULL;
-    iface->numdns = 0;
-    iface->hostname = NULL;
-    iface->domain = NULL;
-    iface->search = NULL;
-    iface->dhcptimeout = 0;
-    iface->vendorclass = NULL;
-    iface->ssid = NULL;
-    iface->wepkey = NULL;
-    iface->mtu = 0;
-    iface->subchannels = NULL;
-    iface->portname = NULL;
-    iface->peerid = NULL;
-    iface->nettype = NULL;
-    iface->ctcprot = NULL;
-    iface->layer2 = NULL;
-    iface->portno = NULL;
-    iface->flags = 0;
-    iface->ipv4method = IPV4_UNUSED_METHOD;
-    iface->ipv6method = IPV6_UNUSED_METHOD;
-
-    return;
-}
-
-/*
- * Given a pointer to a struct in_addr, return 1 if it contains a valid
- * address, 0 otherwise.
- */
-int iface_have_in_addr(struct in_addr *addr) {
-    return _iface_have_valid_addr(addr, AF_INET, INET_ADDRSTRLEN);
-}
-
-/*
- * Given a pointer to a struct in6_addr, return 1 if it contains a valid
- * address, 0 otherwise.
- */
-int iface_have_in6_addr(struct in6_addr *addr6) {
-    return _iface_have_valid_addr(addr6, AF_INET6, INET6_ADDRSTRLEN);
-}
-
-/* Check if NM has an active connection */
-gboolean is_nm_connected(void) {
-    NMState state;
-    NMClient *client = NULL;
-
-    g_type_init();
-
-    client = nm_client_new();
-    if (!client)
-        return FALSE;
-
-    state = nm_client_get_state(client);
-    g_object_unref(client);
-
-    if (state == NM_STATE_CONNECTED)
-        return TRUE;
-    else
-        return FALSE;
-}
-
-/* Check if NM is already running */
-gboolean is_nm_running(void) {
-    gboolean running;
-    NMClient *client = NULL;
-
-    g_type_init();
-
-    client = nm_client_new();
-    if (!client)
-        return FALSE;
-
-    running = nm_client_get_manager_running(client);
-    g_object_unref(client);
-    return running;
-}
-
-/*
- * Wait for NetworkManager to appear on the system bus
- */
-int wait_for_nm(void) {
-    int count = 0;
-
-    /* send message and block until a reply or error comes back */
-    while (count < 45) {
-        if (is_nm_running())
-            return 0;
-
-        sleep(1);
-        count++;
-    }
-
-    return 1;
-}
-
-/*
- * Start NetworkManager -- requires that you have already written out the
- * control files in /etc/sysconfig for the interface.
- */
-int iface_start_NetworkManager(void) {
-    pid_t pid;
-
-    if (is_nm_running())
-        return 0;  /* already running */
-
-    /* Start NetworkManager */
-    pid = fork();
-    if (pid == 0) {
-        if (setpgrp() == -1) {
-            exit(1);
-        }
-
-        if (_iface_redirect_io("/dev/null", STDIN_FILENO, O_RDONLY) ||
-            _iface_redirect_io(OUTPUT_TERMINAL, STDOUT_FILENO, O_WRONLY) ||
-            _iface_redirect_io(OUTPUT_TERMINAL, STDERR_FILENO, O_WRONLY)) {
-            exit(2);
-        }
-
-        if (execl(NETWORKMANAGER, NETWORKMANAGER,
-                  "--pid-file=/var/run/NetworkManager/NetworkManager.pid",
-                  NULL) == -1) {
-            exit(3);
-        }
-    } else if (pid == -1) {
-        return 1;
-    } else {
-        return wait_for_nm();
-    }
-
-    return 0;
-}
-
-/*
- * Set the MTU on the specified device.
- */
-int iface_set_interface_mtu(char *ifname, int mtu) {
-    int ret = 0;
-    struct nl_handle *handle = NULL;
-    struct nl_cache *cache = NULL;
-    struct rtnl_link *link = NULL;
-    struct rtnl_link *request = NULL;
-
-    if (ifname == NULL) {
-        return -1;
-    }
-
-    if (mtu <= 0) {
-        return -2;
-    }
-
-    if ((cache = _iface_get_link_cache(&handle)) == NULL) {
-        return -3;
-    }
-
-    if ((link = rtnl_link_get_by_name(cache, ifname)) == NULL) {
-        ret = -4;
-        goto ifacemtu_error1;
-    }
-
-    request = rtnl_link_alloc();
-    rtnl_link_set_mtu(request, mtu);
-
-    if (rtnl_link_change(handle, link, request, 0)) {
-        ret = -5;
-        goto ifacemtu_error2;
-    }
-
-ifacemtu_error2:
-    rtnl_link_put(link);
-ifacemtu_error1:
-    nl_close(handle);
-    nl_handle_destroy(handle);
-
-    return ret;
-}
diff --git a/isys/iface.h b/isys/iface.h
deleted file mode 100644
index 820d10b..0000000
--- a/isys/iface.h
+++ /dev/null
@@ -1,166 +0,0 @@
-/*
- * iface.h - Network interface configuration API
- *
- * Copyright (C) 2006, 2007, 2008  Red Hat, 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; either version 2 of the License, or
- * (at your option) any later version.
- *
- * 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, see <http://www.gnu.org/licenses/>.
- *
- * Author(s): David Cantrell <dcantrell@xxxxxxxxxx>
- */
-
-#ifndef ISYSIFACE_H
-#define ISYSIFACE_H
-
-#include <resolv.h>
-#include <net/if.h>
-#include <netlink/cache.h>
-#include <netlink/socket.h>
-#include <glib.h>
-
-/* Enumerated types used in iface.c as well as loader's network code */
-enum { IPUNUSED = -1, IPV4, IPV6 };
-
-enum { IPV4_UNUSED_METHOD, IPV4_DHCP_METHOD, IPV4_MANUAL_METHOD, IPV4_IBFT_METHOD, IPV4_IBFT_DHCP_METHOD };
-enum { IPV6_UNUSED_METHOD, IPV6_AUTO_METHOD, IPV6_DHCP_METHOD,
-       IPV6_MANUAL_METHOD };
-
-#define IPV4_FIRST_METHOD IPV4_DHCP_METHOD
-#define IPV4_LAST_METHOD  IPV4_MANUAL_METHOD
-
-#define IPV6_FIRST_METHOD IPV6_AUTO_METHOD
-#define IPV6_LAST_METHOD  IPV6_MANUAL_METHOD
-
-/* Flags for the iface_t (do we need these?) */
-#define IFACE_FLAGS_NO_WRITE_RESOLV_CONF (((uint64_t) 1) << 0)
-#define IFACE_NO_WRITE_RESOLV_CONF(a)    ((a) & IFACE_FLAGS_NO_WRITE_RESOLV_CONF)
-
-/* Macros for starting NetworkManager */
-#define NETWORKMANAGER  "/usr/sbin/NetworkManager"
-
-/* Per-interface configuration information */
-typedef struct _iface_t {
-    /* device name (e.g., eth0) */
-    char device[IF_NAMESIZE];
-
-    /* MAC address as xx:xx:xx:xx:xx:xx */
-    char *macaddr;
-
-    /* IPv4 (store addresses in in_addr format, use inet_pton() to display) */
-    struct in_addr ipaddr;
-    struct in_addr netmask;
-    struct in_addr broadcast;
-
-    /* IPv6 (store addresses in in6_addr format, prefix is just an int) */
-    struct in6_addr ip6addr;
-    int ip6prefix;
-
-    /* Gateway settings */
-    struct in_addr gateway;
-    struct in6_addr gateway6;
-
-    /* BOOTP (these can be IPv4 or IPv6, store human-readable version as str) */
-    char *nextserver;
-    char *bootfile;
-
-    /* DNS (these can be IPv4 or IPv6, store human-readable version as str) */
-    char *dns[MAXNS];
-    int numdns;
-    char *hostname;
-    char *domain;
-    char *search;
-
-    /* Misc DHCP settings */
-    int dhcptimeout;
-    char *vendorclass;
-
-    /* Wireless settings */
-    char *ssid;
-    char *wepkey;
-
-    /* s390 specifics */
-    int mtu;
-    char *subchannels;
-    char *portname;
-    char *peerid;
-    char *nettype;
-    char *ctcprot;
-    char *layer2;
-    char *portno;
-
-    /* flags */
-    uint64_t flags;
-    int ipv4method;
-    int ipv6method;
-    int isiBFT;
-} iface_t;
-
-/* Function prototypes */
-
-/*
- * Given an interface name (e.g., eth0) and address family (e.g., AF_INET),
- * return the IP address in human readable format (i.e., the output from
- * inet_ntop()).  Return NULL for no match or error.
- */
-char *iface_ip2str(char *, int);
-
-/*
- * Given an interface name (e.g., eth0), return the MAC address in human
- * readable format (e.g., 00:11:52:12:D9:A0).  Return NULL for no match.
- */
-char *iface_mac2str(char *);
-
-/* Given an interface's MAC address, return the name (e.g., eth0) in human
- * readable format.  Return NULL for no match
- */
-char *iface_mac2device(char *);
-
-/*
- * Convert an IPv4 CIDR prefix to a dotted-quad netmask.  Return NULL on
- * failure.
- */
-struct in_addr *iface_prefix2netmask(int);
-
-/*
- * Initialize a new iface_t structure to default values.
- */
-void iface_init_iface_t(iface_t *);
-
-/*
- * Given a pointer to a struct in_addr, return 1 if it contains a valid
- * address, 0 otherwise.
- */
-int iface_have_in_addr(struct in_addr *addr);
-
-/*
- * Given a pointer to a struct in6_addr, return 1 if it contains a valid
- * address, 0 otherwise.
- */
-int iface_have_in6_addr(struct in6_addr *addr6);
-
-/*
- * Checks if NetworkManager has an active connection.
- */
-gboolean is_nm_connected(void);
-
-/*
- * Start NetworkManager
- */
-int iface_start_NetworkManager(void);
-
-/*
- * Set Maximum Transfer Unit (MTU) on specified interface
- */
-int iface_set_interface_mtu(char *ifname, int mtu);
-
-#endif /* ISYSIFACE_H */
diff --git a/isys/imount.c b/isys/imount.c
deleted file mode 100644
index ed0f5a7..0000000
--- a/isys/imount.c
+++ /dev/null
@@ -1,328 +0,0 @@
-/*
- * imount.c
- *
- * Copyright (C) 2007, 2008, 2009  Red Hat, Inc.  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 as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * 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, see <http://www.gnu.org/licenses/>.
- */
-
-#include <errno.h>
-#include <fcntl.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/mount.h>
-#include <sys/stat.h>
-#include <sys/types.h>
-#include <sys/wait.h>
-#include <unistd.h>
-
-#include "imount.h"
-#include "log.h"
-
-#define _(foo) foo
-
-static int mkdirIfNone(char * directory);
-
-static int readFD(int fd, char **buf) {
-    char *p;
-    size_t size = 4096;
-    int s, filesize = 0;
-
-    *buf = calloc(4096, sizeof (char));
-    if (*buf == NULL)
-        abort();
-
-    do {
-        p = &(*buf)[filesize];
-        s = read(fd, p, 4096);
-        if (s < 0)
-            break;
-
-        filesize += s;
-        if (s == 0)
-           break;
-
-        size += s;
-        *buf = realloc(*buf, size);
-        if (*buf == NULL)
-            abort();
-    } while (1);
-
-    if (filesize == 0 && s < 0) {
-        free(*buf);
-        *buf = NULL;
-        return -1;
-    }
-
-    return filesize;
-}
-
-static size_t rstrip(char *str) {
-    size_t len = strlen(str);
-    if (len > 0 && str[len-1] == '\n') {
-        str[len-1] = '\0';
-        --len;
-    }
-    return len;
-}
-
-int mountCommandWrapper(int mode, char *dev, char *where, char *fs,
-                        char *options, char **err) {
-    int rc, child, status;
-    int stdout_pipe[2], stderr_pipe[2];
-    char *opts = NULL, *device = NULL, *cmd = NULL;
-
-    switch (mode) {
-    case IMOUNT_MODE_MOUNT:
-    case IMOUNT_MODE_BIND:
-        cmd = "/bin/mount";
-        if (mkdirChain(where))
-            return IMOUNT_ERR_ERRNO;
-        break;
-    case IMOUNT_MODE_UMOUNT:
-        cmd = "/bin/umount";
-        break;
-    default:
-        return IMOUNT_ERR_MODE;
-    }
-
-    if (mode == IMOUNT_MODE_MOUNT) {
-        if (strstr(fs, "nfs")) {
-            if (options) {
-                if (asprintf(&opts, "%s,nolock", options) == -1) {
-                    fprintf(stderr, "%s: %d: %s\n", __func__, __LINE__,
-                            strerror(errno));
-                    fflush(stderr);
-                    abort();
-                }
-            } else {
-                opts = strdup("nolock");
-            }
-
-            device = strdup(dev);
-        } else {
-            if ((options && strstr(options, "bind") == NULL) &&
-                strncmp(dev, "LABEL=", 6) && strncmp(dev, "UUID=", 5) &&
-                *dev != '/') {
-               if (asprintf(&device, "/dev/%s", dev) == -1) {
-                   fprintf(stderr, "%s: %d: %s\n", __func__, __LINE__,
-                           strerror(errno));
-                   fflush(stderr);
-                   abort();
-               }
-            } else {
-               device = strdup(dev);
-            }
-
-            if (options)
-                opts = strdup(options);
-        }
-    }
-
-    if (pipe(stdout_pipe))
-        return IMOUNT_ERR_ERRNO;
-    if (pipe(stderr_pipe))
-        return IMOUNT_ERR_ERRNO;
-
-    if (!(child = fork())) {
-        int tty_fd;
-
-        close(stdout_pipe[0]);
-        close(stderr_pipe[0]);
-
-        /* Pull stdin from /dev/tty5 and redirect stdout and stderr to the pipes
-         *  so we can log the output and put error messages into exceptions.
-         *  We'll only use these messages should mount also return an error
-         *  code.
-         */
-        tty_fd = open("/dev/tty5", O_RDONLY);
-        close(STDIN_FILENO);
-        dup2(tty_fd, STDIN_FILENO);
-        close(tty_fd);
-
-        close(STDOUT_FILENO);
-        dup2(stdout_pipe[1], STDOUT_FILENO);
-        close(STDERR_FILENO);
-        dup2(stderr_pipe[1], STDERR_FILENO);
-
-        if (mode == IMOUNT_MODE_MOUNT) {
-            if (opts) {
-                logProgramMessage(INFO, "Running... %s -n -t %s -o %s %s %s",
-                        cmd, fs, opts, device, where);
-                rc = execl(cmd, cmd,
-                           "-n", "-t", fs, "-o", opts, device, where, NULL);
-                exit(1);
-            } else {
-                logProgramMessage(INFO, "Running... %s -n -t %s %s %s",
-                        cmd, fs, device, where);
-                rc = execl(cmd, cmd, "-n", "-t", fs, device, where, NULL);
-                exit(1);
-            }
-        } else if (mode == IMOUNT_MODE_BIND) {
-            logProgramMessage(INFO, "Running... %s --bind %s %s",
-                              cmd, dev, where);
-            rc = execl(cmd, cmd, "--bind", dev, where, NULL);
-            exit(1);
-        } else if (mode == IMOUNT_MODE_UMOUNT) {
-            logProgramMessage(INFO, "Running... %s %s", cmd, where);
-            rc = execl(cmd, cmd, where, NULL);
-            exit(1);
-        } else {
-            logProgramMessage(ERROR, "Running... Unknown imount mode: %d\n", mode);
-            exit(1);
-        }
-    }
-
-    close(stdout_pipe[1]);
-    close(stderr_pipe[1]);
-
-    char *buffer = NULL;
-    /* In case when when the stderr pipe gets enough data to fill the kernel
-     * buffer we might see a deadlock as this will block the mount program on
-     * its next write(). The buffer size is 65kB though so we should be safe.
-     */
-    rc = readFD(stdout_pipe[0], &buffer);
-    if (rc > 0) {
-        rstrip(buffer);
-        logProgramMessage(INFO, buffer);
-        free(buffer);
-        buffer = NULL;
-    }
-    rc = readFD(stderr_pipe[0], &buffer);
-    if (rc > 0) {
-        rstrip(buffer);
-        logProgramMessage(ERROR, buffer);
-        if (err != NULL)
-            *err = buffer;
-        else
-            free(buffer);
-    }
-    close(stdout_pipe[0]);
-    close(stderr_pipe[0]);
-
-    waitpid(child, &status, 0);
-
-    if (opts) {
-        free(opts);
-    }
-
-    if (device) {
-        free(device);
-    }
-
-    if (!WIFEXITED(status))
-        return IMOUNT_ERR_OTHER;
-    else if ( (rc = WEXITSTATUS(status)) ) {
-        /* Refer to 'man mount' for the meaning of the error codes. */
-        switch (rc) {
-        case 1:
-            return IMOUNT_ERR_PERMISSIONS;
-        case 2:
-            return IMOUNT_ERR_SYSTEM;
-        case 4:
-            return IMOUNT_ERR_MOUNTINTERNAL;
-        case 8:
-            return IMOUNT_ERR_USERINTERRUPT;
-        case 16:
-            return IMOUNT_ERR_MTAB;
-        case 32:
-            return IMOUNT_ERR_MOUNTFAILURE;
-        case 64:
-            return IMOUNT_ERR_PARTIALSUCC;
-        default:
-            return IMOUNT_ERR_OTHER;
-        }
-    }
-
-    return 0;
-}
-
-int doBindMount(char* path, char *where, char **err) {
-    return mountCommandWrapper(IMOUNT_MODE_BIND,
-                               path, where, NULL, NULL, err);
-}
-
-int doPwMount(char *dev, char *where, char *fs, char *options, char **err) {
-    return mountCommandWrapper(IMOUNT_MODE_MOUNT,
-                               dev, where, fs, options, err);
-}
-
-int doPwUmount(char *where, char **err) {
-    return mountCommandWrapper(IMOUNT_MODE_UMOUNT,
-                               NULL, where, NULL, NULL, err);
-}
-
-int mkdirChain(char * origChain) {
-    char * chain;
-    char * chptr;
-
-    chain = alloca(strlen(origChain) + 1);
-    strcpy(chain, origChain);
-    chptr = chain;
-
-    while ((chptr = strchr(chptr, '/'))) {
-	*chptr = '\0';
-	if (mkdirIfNone(chain)) {
-	    *chptr = '/';
-	    return IMOUNT_ERR_ERRNO;
-	}
-
-	*chptr = '/';
-	chptr++;
-    }
-
-    if (mkdirIfNone(chain))
-	return IMOUNT_ERR_ERRNO;
-
-    return 0;
-}
-
-/* Returns true iff it is possible that the mount command that have returned
- * 'errno' might succeed at a later time (think e.g. not yet initialized USB
- * device, etc.) */
-int mountMightSucceedLater(int mountRc)
-{
-    int rc;
-    switch (mountRc) {
-    case IMOUNT_ERR_MOUNTFAILURE:
-        rc = 1;
-        break;
-    default:
-        rc = 0;
-    }
-    return rc;
-}
-
-static int mkdirIfNone(char * directory) {
-    int rc, mkerr;
-    char * chptr;
-
-    /* If the file exists it *better* be a directory -- I'm not going to
-       actually check or anything */
-    if (!access(directory, X_OK)) return 0;
-
-    /* if the path is '/' we get ENOFILE not found" from mkdir, rather
-       then EEXIST which is weird */
-    for (chptr = directory; *chptr; chptr++)
-        if (*chptr != '/') break;
-    if (!*chptr) return 0;
-
-    rc = mkdir(directory, 0755);
-    mkerr = errno;
-
-    if (!rc || mkerr == EEXIST) return 0;
-
-    return IMOUNT_ERR_ERRNO;
-}
diff --git a/isys/imount.h b/isys/imount.h
deleted file mode 100644
index d1b7cf3..0000000
--- a/isys/imount.h
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * imount.h
- *
- * Copyright (C) 2007, 2008, 2009  Red Hat, Inc.  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 as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * 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, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef H_IMOUNT
-#define H_IMOUNT
-
-#define IMOUNT_ERR_ERRNO          1
-#define IMOUNT_ERR_OTHER          2
-#define IMOUNT_ERR_MODE           3
-#define IMOUNT_ERR_PERMISSIONS    4
-#define IMOUNT_ERR_SYSTEM         5
-#define IMOUNT_ERR_MOUNTINTERNAL  6
-#define IMOUNT_ERR_USERINTERRUPT  7
-#define IMOUNT_ERR_MTAB           8
-#define IMOUNT_ERR_MOUNTFAILURE   9
-#define IMOUNT_ERR_PARTIALSUCC    10
-
-#include <sys/mount.h>		/* for umount() */
-
-#define IMOUNT_RDONLY  1
-#define IMOUNT_BIND    2
-#define IMOUNT_REMOUNT 4
-
-#define IMOUNT_MODE_MOUNT  1
-#define IMOUNT_MODE_UMOUNT 2
-#define IMOUNT_MODE_BIND   3
-
-int doBindMount(char* path, char *where, char **err);
-int doPwMount(char *dev, char *where, char *fs, char *options, char **err);
-int doPwUmount(char *where, char **err);
-int mkdirChain(char * origChain);
-int mountMightSucceedLater(int mountRc);
-
-#endif
diff --git a/isys/isofs.c b/isys/isofs.c
deleted file mode 100644
index bb5a44a..0000000
--- a/isys/isofs.c
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * isofs.c
- *
- * Copyright (C) 2007  Red Hat, Inc.  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 as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * 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, see <http://www.gnu.org/licenses/>.
- */
-
-#include <fcntl.h>
-#include <string.h>
-#include <unistd.h>
-
-#define BLOCK_SIZE 2048
- 
-/* returns 1 if file is an ISO, 0 otherwise */
-int fileIsIso(const char * file) {
-    int blkNum;
-    char magic[5];
-    int fd;
-
-    fd = open(file, O_RDONLY);
-    if (fd < 0)
-	return 0;
-
-    for (blkNum = 16; blkNum < 100; blkNum++) {
-	if (lseek(fd, blkNum * BLOCK_SIZE + 1, SEEK_SET) < 0) {
-	    close(fd);
-	    return 0;
-	}
-
-	if (read(fd, magic, sizeof(magic)) != sizeof(magic)) {
-	    close(fd);
-	    return 0;
-	}
-
-	if (!strncmp(magic, "CD001", 5)) {
-	    close(fd);
-	    return 1;
-	}
-    }
-
-    close(fd); 
-    return 0;
-}
diff --git a/isys/isys.c b/isys/isys.c
deleted file mode 100644
index 409170b..0000000
--- a/isys/isys.c
+++ /dev/null
@@ -1,701 +0,0 @@
-/*
- * isys.c
- *
- * Copyright (C) 2007, 2008, 2009  Red Hat, Inc.  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 as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * 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, see <http://www.gnu.org/licenses/>.
- */
-
-#include <Python.h>
-
-#include <stdio.h>
-#include <dirent.h>
-#include <errno.h>
-#define u32 __u32
-#include <ext2fs/ext2fs.h>
-#include <fcntl.h>
-/* Need to tell loop.h what the actual dev_t type is. */
-#undef dev_t
-#if defined(__alpha) || (defined(__sparc__) && defined(__arch64__))
-#define dev_t unsigned int
-#else
-#if defined(__x86_64__)
-#define dev_t unsigned long
-#else
-#define dev_t unsigned short
-#endif
-#endif
-#include <linux/loop.h>
-#undef dev_t
-#define dev_t dev_t
-#include <sys/ioctl.h>
-#include <sys/stat.h>
-#include <sys/sysmacros.h>
-#include <sys/time.h>
-#include <sys/utsname.h>
-#include <sys/vfs.h>
-#include <unistd.h>
-#include <resolv.h>
-#include <scsi/scsi.h>
-#include <scsi/scsi_ioctl.h>
-#include <sys/vt.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <arpa/inet.h>
-#include <linux/fb.h>
-#include <libintl.h>
-#include <libgen.h>
-#include <linux/cdrom.h>
-#include <linux/major.h>
-#include <linux/raid/md_u.h>
-#include <linux/raid/md_p.h>
-#include <signal.h>
-#include <execinfo.h>
-
-#include <blkid/blkid.h>
-
-#include <X11/Xlib.h>
-#include <X11/XKBlib.h>
-#include <X11/keysym.h>
-
-#include "iface.h"
-#include "isys.h"
-#include "imount.h"
-#include "ethtool.h"
-#include "lang.h"
-#include "eddsupport.h"
-#include "auditd.h"
-#include "imount.h"
-#include "log.h"
-
-#ifndef CDROMEJECT
-#define CDROMEJECT 0x5309
-#endif
-
-static PyObject * doMount(PyObject * s, PyObject * args);
-static PyObject * doUMount(PyObject * s, PyObject * args);
-static PyObject * doSwapon(PyObject * s, PyObject * args);
-static PyObject * doSwapoff(PyObject * s, PyObject * args);
-static PyObject * doLoSetup(PyObject * s, PyObject * args);
-static PyObject * doUnLoSetup(PyObject * s, PyObject * args);
-static PyObject * doLoChangeFd(PyObject * s, PyObject * args);
-static PyObject * doWipeRaidSuperblock(PyObject * s, PyObject * args);
-static PyObject * doGetRaidChunkSize(PyObject * s, PyObject * args);
-static PyObject * doDevSpaceFree(PyObject * s, PyObject * args);
-static PyObject * doResetResolv(PyObject * s, PyObject * args);
-static PyObject * doLoadKeymap(PyObject * s, PyObject * args);
-static PyObject * doExt2Dirty(PyObject * s, PyObject * args);
-static PyObject * doExt2HasJournal(PyObject * s, PyObject * args);
-static PyObject * doEjectCdrom(PyObject * s, PyObject * args);
-static PyObject * doVtActivate(PyObject * s, PyObject * args);
-static PyObject * doisPseudoTTY(PyObject * s, PyObject * args);
-static PyObject * doisVioConsole(PyObject * s);
-static PyObject * doSync(PyObject * s, PyObject * args);
-static PyObject * doisIsoImage(PyObject * s, PyObject * args);
-static PyObject * printObject(PyObject * s, PyObject * args);
-static PyObject * py_bind_textdomain_codeset(PyObject * o, PyObject * args);
-static PyObject * doSegvHandler(PyObject *s, PyObject *args);
-static PyObject * doAuditDaemon(PyObject *s);
-static PyObject * doPrefixToNetmask(PyObject *s, PyObject *args);
-static PyObject * doGetBlkidData(PyObject * s, PyObject * args);
-static PyObject * doIsCapsLockEnabled(PyObject * s, PyObject * args);
-static PyObject * doGetLinkStatus(PyObject * s, PyObject * args);
-static PyObject * doGetAnacondaVersion(PyObject * s, PyObject * args);
-static PyObject * doInitLog(PyObject * s);
-
-static PyMethodDef isysModuleMethods[] = {
-    { "ejectcdrom", (PyCFunction) doEjectCdrom, METH_VARARGS, NULL },
-    { "e2dirty", (PyCFunction) doExt2Dirty, METH_VARARGS, NULL },
-    { "e2hasjournal", (PyCFunction) doExt2HasJournal, METH_VARARGS, NULL },
-    { "devSpaceFree", (PyCFunction) doDevSpaceFree, METH_VARARGS, NULL },
-    { "wiperaidsb", (PyCFunction) doWipeRaidSuperblock, METH_VARARGS, NULL },
-    { "getraidchunk", (PyCFunction) doGetRaidChunkSize, METH_VARARGS, NULL },
-    { "lochangefd", (PyCFunction) doLoChangeFd, METH_VARARGS, NULL },
-    { "losetup", (PyCFunction) doLoSetup, METH_VARARGS, NULL },
-    { "unlosetup", (PyCFunction) doUnLoSetup, METH_VARARGS, NULL },
-    { "mount", (PyCFunction) doMount, METH_VARARGS, NULL },
-    { "umount", (PyCFunction) doUMount, METH_VARARGS, NULL },
-    { "resetresolv", (PyCFunction) doResetResolv, METH_VARARGS, NULL },
-    { "swapon",  (PyCFunction) doSwapon, METH_VARARGS, NULL },
-    { "swapoff",  (PyCFunction) doSwapoff, METH_VARARGS, NULL },
-    { "loadKeymap", (PyCFunction) doLoadKeymap, METH_VARARGS, NULL },
-    { "vtActivate", (PyCFunction) doVtActivate, METH_VARARGS, NULL},
-    { "isPseudoTTY", (PyCFunction) doisPseudoTTY, METH_VARARGS, NULL},
-    { "isVioConsole", (PyCFunction) doisVioConsole, METH_NOARGS, NULL},
-    { "sync", (PyCFunction) doSync, METH_VARARGS, NULL},
-    { "isisoimage", (PyCFunction) doisIsoImage, METH_VARARGS, NULL},
-    { "printObject", (PyCFunction) printObject, METH_VARARGS, NULL},
-    { "bind_textdomain_codeset", (PyCFunction) py_bind_textdomain_codeset, METH_VARARGS, NULL},
-    { "handleSegv", (PyCFunction) doSegvHandler, METH_VARARGS, NULL },
-    { "auditdaemon", (PyCFunction) doAuditDaemon, METH_NOARGS, NULL },
-    { "prefix2netmask", (PyCFunction) doPrefixToNetmask, METH_VARARGS, NULL },
-    { "getblkid", (PyCFunction) doGetBlkidData, METH_VARARGS, NULL },
-    { "isCapsLockEnabled", (PyCFunction) doIsCapsLockEnabled, METH_VARARGS, NULL },
-    { "getLinkStatus", (PyCFunction) doGetLinkStatus, METH_VARARGS, NULL },
-    { "getAnacondaVersion", (PyCFunction) doGetAnacondaVersion, METH_VARARGS, NULL },
-    { "initLog", (PyCFunction) doInitLog, METH_VARARGS, NULL },
-    { NULL, NULL, 0, NULL }
-} ;
-
-static PyObject * doUnLoSetup(PyObject * s, PyObject * args) {
-    int loopfd;
-
-    if (!PyArg_ParseTuple(args, "i", &loopfd)) return NULL;
-    if (ioctl(loopfd, LOOP_CLR_FD, 0)) {
-	PyErr_SetFromErrno(PyExc_SystemError);
-	return NULL;
-    }
-
-    Py_INCREF(Py_None);
-    return Py_None;
-}
-
-/* XXX - msw */
-#ifndef LOOP_CHANGE_FD
-#define LOOP_CHANGE_FD	0x4C06
-#endif
-
-static PyObject * doLoChangeFd(PyObject * s, PyObject * args) {
-    int loopfd;
-    int targfd;
-
-    if (!PyArg_ParseTuple(args, "ii", &loopfd, &targfd)) 
-	return NULL;
-    if (ioctl(loopfd, LOOP_CHANGE_FD, targfd)) {
-	PyErr_SetFromErrno(PyExc_SystemError);
-	return NULL;
-    }
-
-    Py_INCREF(Py_None);
-    return Py_None;
-}
-
-static PyObject * doLoSetup(PyObject * s, PyObject * args) {
-    int loopfd;
-    int targfd;
-    struct loop_info loopInfo;
-    char * loopName;
-
-    if (!PyArg_ParseTuple(args, "iis", &loopfd, &targfd, &loopName)) 
-	return NULL;
-    if (ioctl(loopfd, LOOP_SET_FD, targfd)) {
-	PyErr_SetFromErrno(PyExc_SystemError);
-	return NULL;
-    }
-
-    memset(&loopInfo, 0, sizeof(loopInfo));
-    strncpy(loopInfo.lo_name, basename(loopName), 63);
-
-    if (ioctl(loopfd, LOOP_SET_STATUS, &loopInfo)) {
-	PyErr_SetFromErrno(PyExc_SystemError);
-	return NULL;
-    }
-
-    Py_INCREF(Py_None);
-    return Py_None;
-}
-
-static PyObject * doUMount(PyObject * s, PyObject * args) {
-    char *err = NULL, *mntpoint = NULL;
-    int rc;
-
-    if (!PyArg_ParseTuple(args, "s", &mntpoint)) {
-        return NULL;
-    }
-
-    rc = doPwUmount(mntpoint, &err);
-    if (rc == IMOUNT_ERR_ERRNO) {
-        PyErr_SetFromErrno(PyExc_SystemError);
-    } else if (rc) {
-        PyObject *tuple = PyTuple_New(2);
-
-        PyTuple_SetItem(tuple, 0, PyInt_FromLong(rc));
-
-        if (err == NULL) {
-            Py_INCREF(Py_None);
-            PyTuple_SetItem(tuple, 1, Py_None);
-        } else {
-            PyTuple_SetItem(tuple, 1, PyString_FromString(err));
-        }
-
-        PyErr_SetObject(PyExc_SystemError, tuple);
-    }
-
-    if (rc) {
-        return NULL;
-    }
-
-    Py_INCREF(Py_None);
-    return Py_None;
-}
-
-static PyObject * doMount(PyObject * s, PyObject * args) {
-    char *err = NULL, *fs, *device, *mntpoint, *flags = NULL;
-    int rc;
-
-    if (!PyArg_ParseTuple(args, "sss|z", &fs, &device, &mntpoint,
-			  &flags)) return NULL;
-
-    rc = doPwMount(device, mntpoint, fs, flags, &err);
-    if (rc == IMOUNT_ERR_ERRNO)
-	PyErr_SetFromErrno(PyExc_SystemError);
-    else if (rc) {
-        PyObject *tuple = PyTuple_New(2);
-
-        PyTuple_SetItem(tuple, 0, PyInt_FromLong(rc));
-
-        if (err == NULL) {
-            Py_INCREF(Py_None);
-            PyTuple_SetItem(tuple, 1, Py_None);
-        } else {
-            PyTuple_SetItem(tuple, 1, PyString_FromString(err));
-        }
-
-        PyErr_SetObject(PyExc_SystemError, tuple);
-    }
-
-    if (rc) return NULL;
-
-    Py_INCREF(Py_None);
-    return Py_None;
-}
-
-#define BOOT_SIGNATURE	0xaa55	/* boot signature */
-#define BOOT_SIG_OFFSET	510	/* boot signature offset */
-
-int swapoff(const char * path);
-int swapon(const char * path, int priorty);
-
-static PyObject * doSwapoff (PyObject * s, PyObject * args) {
-    char * path;
-
-    if (!PyArg_ParseTuple(args, "s", &path)) return NULL;
-
-    if (swapoff (path)) {
-	PyErr_SetFromErrno(PyExc_SystemError);
-	return NULL;
-    }
-    
-    Py_INCREF(Py_None);
-    return Py_None;
-}
-
-static PyObject * doSwapon (PyObject * s, PyObject * args) {
-    char * path;
-
-    if (!PyArg_ParseTuple(args, "s", &path)) return NULL;
-
-    if (swapon (path, 0)) {
-	PyErr_SetFromErrno(PyExc_SystemError);
-	return NULL;
-    }
-    
-    Py_INCREF(Py_None);
-    return Py_None;
-}
-
-void init_isys(void) {
-    PyObject * m, * d;
-
-    m = Py_InitModule("_isys", isysModuleMethods);
-    d = PyModule_GetDict(m);
-
-    PyDict_SetItemString(d, "MIN_RAM", PyInt_FromLong(MIN_RAM));
-    PyDict_SetItemString(d, "MIN_GUI_RAM", PyInt_FromLong(MIN_GUI_RAM));
-    PyDict_SetItemString(d, "URL_INSTALL_EXTRA_RAM", PyInt_FromLong(URL_INSTALL_EXTRA_RAM));
-    PyDict_SetItemString(d, "EARLY_SWAP_RAM", PyInt_FromLong(EARLY_SWAP_RAM));
-}
-
-static PyObject * doPrefixToNetmask (PyObject * s, PyObject * args) {
-    int prefix = 0;
-    struct in_addr *mask = NULL;
-    char dst[INET_ADDRSTRLEN+1];
-
-    if (!PyArg_ParseTuple(args, "i", &prefix))
-        return NULL;
-
-    if ((mask = iface_prefix2netmask(prefix)) == NULL)
-        return NULL;
-
-    if (inet_ntop(AF_INET, mask, dst, INET_ADDRSTRLEN) == NULL)
-        return NULL;
-
-    return Py_BuildValue("s", dst);
-}
-
-static PyObject * doResetResolv(PyObject * s, PyObject * args) {
-    if (!PyArg_ParseTuple(args, "")) {
-        return NULL;
-    }
-
-    /* reinit the resolver so DNS changes take affect */
-    res_init();
-
-    Py_INCREF(Py_None);
-    return Py_None;
-}
-
-static PyObject * doWipeRaidSuperblock(PyObject * s, PyObject * args) {
-    int fd;
-    unsigned long size;
-    struct mdp_super_t * sb;
-
-    if (!PyArg_ParseTuple(args, "i", &fd)) return NULL;
-
-    if (ioctl(fd, BLKGETSIZE, &size)) {
-	PyErr_SetFromErrno(PyExc_SystemError);
-	return NULL;
-    }
-
-    /* put the size in 1k blocks */
-    size >>= 1;
-
-    if (lseek64(fd, ((off64_t) 512) * (off64_t) MD_NEW_SIZE_SECTORS(size), SEEK_SET) < 0) {
-	PyErr_SetFromErrno(PyExc_SystemError);
-	return NULL;
-    } 
-
-    sb = malloc(sizeof(mdp_super_t));
-    sb = memset(sb, '\0', sizeof(mdp_super_t));
-
-    if (write(fd, sb, sizeof(sb)) != sizeof(sb)) {
-	PyErr_SetFromErrno(PyExc_SystemError);
-	return NULL;
-    }
-
-    return Py_None;
-}
-
-static PyObject * doGetRaidChunkSize(PyObject * s, PyObject * args) {
-    int fd;
-    unsigned long size;
-    mdp_super_t sb;
-
-    if (!PyArg_ParseTuple(args, "i", &fd)) return NULL;
-
-    if (ioctl(fd, BLKGETSIZE, &size)) {
-	PyErr_SetFromErrno(PyExc_SystemError);
-	return NULL;
-    }
-
-    /* put the size in 1k blocks */
-    size >>= 1;
-
-    if (lseek64(fd, ((off64_t) 512) * (off64_t) MD_NEW_SIZE_SECTORS(size), SEEK_SET) < 0) {
-	PyErr_SetFromErrno(PyExc_SystemError);
-	return NULL;
-    } 
-
-    if (read(fd, &sb, sizeof(sb)) != sizeof(sb)) {
-	PyErr_SetFromErrno(PyExc_SystemError);
-	return NULL;
-    }
-
-    if (sb.md_magic != MD_SB_MAGIC) {
-	PyErr_SetString(PyExc_ValueError, "bad md magic on device");
-	return NULL;
-    }
-
-    return Py_BuildValue("i", sb.chunk_size / 1024);
-}
-
-static int get_bits(unsigned long long v) {
-    int  b = 0;
-    
-    if ( v & 0xffffffff00000000LLU ) { b += 32; v >>= 32; }
-    if ( v & 0xffff0000LLU ) { b += 16; v >>= 16; }
-    if ( v & 0xff00LLU ) { b += 8; v >>= 8; }
-    if ( v & 0xf0LLU ) { b += 4; v >>= 4; }
-    if ( v & 0xcLLU ) { b += 2; v >>= 2; }
-    if ( v & 0x2LLU ) b++;
-    
-    return v ? b + 1 : b;
-}
-
-static PyObject * doDevSpaceFree(PyObject * s, PyObject * args) {
-    char * path;
-    struct statfs sb;
-    unsigned long long size;
-
-    if (!PyArg_ParseTuple(args, "s", &path)) return NULL;
-
-    if (statfs(path, &sb)) {
-	PyErr_SetFromErrno(PyExc_SystemError);
-	return NULL;
-    }
-
-    /* Calculate a saturated addition to prevent oveflow. */
-    if ( get_bits(sb.f_bfree) + get_bits(sb.f_bsize) <= 64 )
-        size = (unsigned long long)sb.f_bfree * sb.f_bsize;
-    else
-        size = ~0LLU;
-
-    return PyLong_FromUnsignedLongLong(size>>20);
-}
-
-static PyObject * doLoadKeymap (PyObject * s, PyObject * args) {
-    char * keymap;
-    int ret;
-
-    if (!PyArg_ParseTuple(args, "s", &keymap)) return NULL;
-
-    ret = isysLoadKeymap (keymap);
-    if (ret) {
-	errno = -ret;
-	PyErr_SetFromErrno(PyExc_SystemError);
-	return NULL;
-    }
-    
-    Py_INCREF(Py_None);
-    return Py_None;
-}
-
-static PyObject * doExt2Dirty(PyObject * s, PyObject * args) {
-    char * device;
-    ext2_filsys fsys;
-    int rc;
-    int clean;
-
-    if (!PyArg_ParseTuple(args, "s", &device)) return NULL;
-
-    rc = ext2fs_open(device, EXT2_FLAG_FORCE, 0, 0, unix_io_manager,
-		     &fsys);
-    if (rc) {
-	Py_INCREF(Py_None);
-	return Py_None;
-    }
-
-    clean = fsys->super->s_state & EXT2_VALID_FS;
-
-    ext2fs_close(fsys);
-
-    return Py_BuildValue("i", !clean); 
-}
-static PyObject * doExt2HasJournal(PyObject * s, PyObject * args) {
-    char * device;
-    ext2_filsys fsys;
-    int rc;
-    int hasjournal;
-
-    if (!PyArg_ParseTuple(args, "s", &device)) return NULL;
-    rc = ext2fs_open(device, EXT2_FLAG_FORCE, 0, 0, unix_io_manager,
-		     &fsys);
-    if (rc) {
-	Py_INCREF(Py_None);
-	return Py_None;
-    }
-
-    hasjournal = fsys->super->s_feature_compat & EXT3_FEATURE_COMPAT_HAS_JOURNAL;
-
-    ext2fs_close(fsys);
-
-    return Py_BuildValue("i", hasjournal); 
-}
-
-static PyObject * doEjectCdrom(PyObject * s, PyObject * args) {
-    int fd;
-
-    if (!PyArg_ParseTuple(args, "i", &fd)) return NULL;
-
-    /* Ask it to unlock the door and then eject the disc. There's really
-     * nothing to do if unlocking doesn't work, so just eject without
-     * worrying about it. -- pjones
-     */
-    ioctl(fd, CDROM_LOCKDOOR, 0);
-    if (ioctl(fd, CDROMEJECT, 1)) {
-	PyErr_SetFromErrno(PyExc_SystemError);
-	return NULL;
-    }
-
-    Py_INCREF(Py_None);
-    return Py_None;
-}
-
-static PyObject * doVtActivate(PyObject * s, PyObject * args) {
-    int vtnum;
-
-    if (!PyArg_ParseTuple(args, "i", &vtnum)) return NULL;
-
-    if (ioctl(0, VT_ACTIVATE, vtnum)) {
-	PyErr_SetFromErrno(PyExc_SystemError);
-	return NULL;
-    }
-
-    Py_INCREF(Py_None);
-    return Py_None;
-}
-
-static PyObject * doisPseudoTTY(PyObject * s, PyObject * args) {
-    int fd;
-    struct stat sb;
-
-    if (!PyArg_ParseTuple(args, "i", &fd)) return NULL;
-    fstat(fd, &sb);
-
-    /* XXX close enough for now */
-    return Py_BuildValue("i", ((major(sb.st_rdev) >= 136) && (major(sb.st_rdev) <= 143)));
-}
-
-static PyObject * doisVioConsole(PyObject * s) {
-    return Py_BuildValue("i", isVioConsole());
-}
-
-static PyObject * doSync(PyObject * s, PyObject * args) {
-    int fd;
-
-    if (!PyArg_ParseTuple(args, "", &fd)) return NULL;
-    sync();
-
-    Py_INCREF(Py_None);
-    return Py_None;
-}
-
-int fileIsIso(const char * file);
-
-static PyObject * doisIsoImage(PyObject * s, PyObject * args) {
-    char * fn;
-    int rc;
-
-    if (!PyArg_ParseTuple(args, "s", &fn)) return NULL;
-
-    rc = fileIsIso(fn);
-    
-    return Py_BuildValue("i", rc);
-}
-
-static PyObject * printObject (PyObject * o, PyObject * args) {
-    PyObject * obj;
-    char buf[256];
-
-    if (!PyArg_ParseTuple(args, "O", &obj))
-	return NULL;
-    
-    snprintf(buf, 256, "<%s object at %lx>", obj->ob_type->tp_name,
-	     (long) obj);
-
-    return PyString_FromString(buf);
-}
-
-static PyObject *
-py_bind_textdomain_codeset(PyObject * o, PyObject * args) {
-    char *domain, *codeset, *ret;
-	
-    if (!PyArg_ParseTuple(args, "ss", &domain, &codeset))
-	return NULL;
-
-    ret = bind_textdomain_codeset(domain, codeset);
-
-    if (ret)
-	return PyString_FromString(ret);
-
-    PyErr_SetFromErrno(PyExc_SystemError);
-    return NULL;
-}
-
-static PyObject * doSegvHandler(PyObject *s, PyObject *args) {
-    void *array[20];
-    size_t size;
-    char **strings;
-    size_t i;
-
-    signal(SIGSEGV, SIG_DFL); /* back to default */
-    
-    size = backtrace (array, 20);
-    strings = backtrace_symbols (array, size);
-    
-    printf ("Anaconda received SIGSEGV!.  Backtrace:\n");
-    for (i = 0; i < size; i++)
-        printf ("%s\n", strings[i]);
-     
-    free (strings);
-    exit(1);
-}
-
-static PyObject * doAuditDaemon(PyObject *s) {
-    audit_daemonize();
-    Py_INCREF(Py_None);
-    return Py_None;
-}
-
-static PyObject * doGetBlkidData(PyObject * s, PyObject * args) {
-    char * dev, * key;
-    blkid_cache cache;
-    blkid_dev bdev = NULL;
-    blkid_tag_iterate titer;
-    const char * type, * data;
-
-    if (!PyArg_ParseTuple(args, "ss", &dev, &key)) return NULL;
-
-    blkid_get_cache(&cache, NULL);
-
-    bdev = blkid_get_dev(cache, dev, BLKID_DEV_NORMAL);
-    if (bdev == NULL)
-        goto out;
-    titer = blkid_tag_iterate_begin(bdev);
-    while (blkid_tag_next(titer, &type, &data) >= 0) {
-        if (!strcmp(type, key)) {
-            blkid_tag_iterate_end(titer);
-            return Py_BuildValue("s", data);
-        }
-    }
-    blkid_tag_iterate_end(titer);
-
- out:
-    Py_INCREF(Py_None);
-    return Py_None;
-}
-
-static PyObject * doIsCapsLockEnabled(PyObject * s, PyObject * args) {
-    Display *d = NULL;
-    XkbStateRec state;
-
-    if ((d = XOpenDisplay(NULL)) == NULL) {
-        return NULL;
-    }
-
-    memset(&state, 0, sizeof(state));
-    XkbGetState(d, XkbUseCoreKbd, &state);
-
-    if (XCloseDisplay(d)) {
-        return NULL;
-    }
-
-    return PyBool_FromLong(state.locked_mods & LockMask);
-}
-
-static PyObject * doGetLinkStatus(PyObject * s, PyObject * args) {
-    char *dev = NULL;
-
-    if (!PyArg_ParseTuple(args, "s", &dev)) {
-        return NULL;
-    }
-
-    if (get_link_status(dev) == 1) {
-        return PyBool_FromLong(1);
-    }
-
-    return PyBool_FromLong(0);
-}
-
-static PyObject * doGetAnacondaVersion(PyObject * s, PyObject * args) {
-    return Py_BuildValue("s", VERSION);
-}
-
-static PyObject * doInitLog(PyObject * s) {
-    openLog();
-    Py_INCREF(Py_None);
-    return Py_None;
-}
-
-/* vim:set shiftwidth=4 softtabstop=4: */
diff --git a/isys/isys.h b/isys/isys.h
deleted file mode 100644
index e3cb1fc..0000000
--- a/isys/isys.h
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * isys.h
- *
- * Copyright (C) 2007  Red Hat, Inc.  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 as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * 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, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef H_ISYS
-#define H_ISYS
-
-#define MIN_RAM			262144 // 256 MB
-#define MIN_GUI_RAM		524288 // 512 MB
-#define URL_INSTALL_EXTRA_RAM   131072 // 128 MB
-#define EARLY_SWAP_RAM		524288
-
-#define OUTPUT_TERMINAL "/dev/tty5"
-
-int insmod(char * modName, char * path, char ** args);
-int rmmod(char * modName);
-
-/* returns 0 for true, !0 for false */
-int fileIsIso(const char * file);
-
-/* returns 1 if on an iSeries vio console, 0 otherwise */
-int isVioConsole(void);
-
-#endif
diff --git a/isys/isys.py b/isys/isys.py
deleted file mode 100755
index 38eafe7..0000000
--- a/isys/isys.py
+++ /dev/null
@@ -1,560 +0,0 @@
-#
-# isys.py - installer utility functions and glue for C module
-#
-# Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007  Red Hat, Inc.
-# 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 as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# 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, see <http://www.gnu.org/licenses/>.
-#
-# Author(s): Matt Wilson <msw@xxxxxxxxxx>
-#            Erik Troan <ewt@xxxxxxxxxx>
-#            Jeremy Katz <katzj@xxxxxxxxxx>
-#
-
-import _isys
-import string
-import os
-import os.path
-import socket
-import stat
-import posix
-import sys
-import iutil
-import warnings
-import resource
-import re
-import struct
-import block
-import dbus
-import selinux
-
-import logging
-log = logging.getLogger("anaconda")
-
-NM_SERVICE = "org.freedesktop.NetworkManager"
-NM_MANAGER_PATH = "/org/freedesktop/NetworkManager"
-NM_MANAGER_IFACE = "org.freedesktop.NetworkManager"
-NM_ACTIVE_CONNECTION_IFACE = "org.freedesktop.NetworkManager.Connection.Active"
-NM_CONNECTION_IFACE = "org.freedesktop.NetworkManagerSettings.Connection"
-NM_DEVICE_IFACE = "org.freedesktop.NetworkManager.Device"
-
-NM_STATE_UNKNOWN = 0
-NM_STATE_ASLEEP = 1
-NM_STATE_CONNECTING = 2
-NM_STATE_CONNECTED = 3
-NM_STATE_DISCONNECTED = 4
-
-DBUS_PROPS_IFACE = "org.freedesktop.DBus.Properties"
-
-mountCount = {}
-
-MIN_RAM = _isys.MIN_RAM
-MIN_GUI_RAM = _isys.MIN_GUI_RAM
-URL_INSTALL_EXTRA_RAM = _isys.URL_INSTALL_EXTRA_RAM
-EARLY_SWAP_RAM = _isys.EARLY_SWAP_RAM
-
-## Get the amount of free space available under a directory path.
-# @param path The directory path to check.
-# @return The amount of free space available, in 
-def pathSpaceAvailable(path):
-    return _isys.devSpaceFree(path)
-
-## Set up an already existing device node to be used as a loopback device.
-# @param device The full path to a device node to set up as a loopback device.
-# @param file The file to mount as loopback on device.
-# @param readOnly Should this loopback device be used read-only?
-def losetup(device, file, readOnly = 0):
-    # FIXME: implement this as a storage.devices.Device subclass
-    if readOnly:
-	mode = os.O_RDONLY
-    else:
-	mode = os.O_RDWR
-    targ = os.open(file, mode)
-    loop = os.open(device, mode)
-    try:
-        _isys.losetup(loop, targ, file)
-    finally:
-        os.close(loop)
-        os.close(targ)
-
-def lochangefd(device, file):
-    # FIXME: implement this as a storage.devices.Device subclass
-    loop = os.open(device, os.O_RDONLY)
-    targ = os.open(file, os.O_RDONLY)
-    try:
-        _isys.lochangefd(loop, targ)
-    finally:
-        os.close(loop)
-        os.close(targ)
-
-## Disable a previously setup loopback device.
-# @param device The full path to an existing loopback device node.
-def unlosetup(device):
-    # FIXME: implement this as a storage.devices.Device subclass
-    loop = os.open(device, os.O_RDONLY)
-    try:
-        _isys.unlosetup(loop)
-    finally:
-        os.close(loop)
-
-## Mount a filesystem, similar to the mount system call.
-# @param device The device to mount.  If bindMount is True, this should be an
-#               already mounted directory.  Otherwise, it should be a device
-#               name.
-# @param location The path to mount device on.
-# @param fstype The filesystem type on device.  This can be disk filesystems
-#               such as vfat or ext3, or pseudo filesystems such as proc or
-#               selinuxfs.
-# @param readOnly Should this filesystem be mounted readonly?
-# @param bindMount Is this a bind mount?  (see the mount(8) man page)
-# @param remount Are we mounting an already mounted filesystem?
-# @return The return value from the mount system call.
-def mount(device, location, fstype = "ext2", readOnly = False,
-          bindMount = False, remount = False, options = None):
-    flags = None
-    location = os.path.normpath(location)
-    if not options:
-        opts = ["defaults"]
-    else:
-        opts = options.split(",")
-
-    # We don't need to create device nodes for devices that start with '/'
-    # (like '/usbdevfs') and also some special fake devices like 'proc'.
-    # First try to make a device node and if that fails, assume we can
-    # mount without making a device node.  If that still fails, the caller
-    # will have to deal with the exception.
-    # We note whether or not we created a node so we can clean up later.
-
-    if mountCount.has_key(location) and mountCount[location] > 0:
-	mountCount[location] = mountCount[location] + 1
-	return
-
-    if readOnly or bindMount or remount:
-        if readOnly:
-            opts.append("ro")
-        if bindMount:
-            opts.append("bind")
-        if remount:
-            opts.append("remount")
-
-    flags = ",".join(opts)
-
-    log.debug("isys.py:mount()- going to mount %s on %s as %s with options %s" %(device, location, fstype, flags))
-    rc = _isys.mount(fstype, device, location, flags)
-
-    if not rc:
-	mountCount[location] = 1
-
-    return rc
-
-## Unmount a filesystem, similar to the umount system call.
-# @param what The directory to be unmounted.  This does not need to be the
-#             absolute path.
-# @param removeDir Should the mount point be removed after being unmounted?
-# @return The return value from the umount system call.
-def umount(what, removeDir = True):
-    what = os.path.normpath(what)
-
-    if not os.path.isdir(what):
-	raise ValueError, "isys.umount() can only umount by mount point"
-
-    if mountCount.has_key(what) and mountCount[what] > 1:
-	mountCount[what] = mountCount[what] - 1
-	return
-
-    log.debug("isys.py:umount()- going to unmount %s, removeDir = %s" % (what, removeDir))
-    rc = _isys.umount(what)
-
-    if removeDir and os.path.isdir(what):
-        try:
-            os.rmdir(what)
-        except:
-            pass
-
-    if not rc and mountCount.has_key(what):
-	del mountCount[what]
-
-    return rc
-
-## Disable swap.
-# @param path The full path of the swap device to disable.
-def swapoff (path):
-    return _isys.swapoff (path)
-
-## Enable swap.
-# @param path The full path of the swap device to enable.
-def swapon (path):
-    return _isys.swapon (path)
-
-## Load a keyboard layout for text mode installs.
-# @param keymap The keyboard layout to load.  This must be one of the values
-#               from rhpl.KeyboardModels.
-def loadKeymap(keymap):
-    return _isys.loadKeymap (keymap)
-
-def resetResolv():
-    return _isys.resetresolv()
-
-def readFSUuid(device):
-    if not os.path.exists(device):
-        device = "/dev/%s" % device
-
-    label = _isys.getblkid(device, "UUID")
-    return label
-
-def readFSLabel(device):
-    if not os.path.exists(device):
-        device = "/dev/%s" % device
-
-    label = _isys.getblkid(device, "LABEL")
-    return label
-
-def readFSType(device):
-    if not os.path.exists(device):
-        device = "/dev/%s" % device
-
-    fstype = _isys.getblkid(device, "TYPE")
-    if fstype is None:
-        # FIXME: libblkid doesn't show physical volumes as having a filesystem
-        # so let's sniff for that.(#409321)
-        try:
-            fd = os.open(device, os.O_RDONLY)
-            buf = os.read(fd, 2048)
-        except:
-            return fstype
-        finally:
-            try:
-                os.close(fd)
-            except:
-                pass
-
-        if buf.startswith("HM"):
-            return "physical volume (LVM)"
-        for sec in range(0, 4):
-            off = (sec * 512) + 24
-            if len(buf) < off:
-                continue
-            if buf[off:].startswith("LVM2"):
-                return "physical volume (LVM)"
-    elif fstype == "lvm2pv":
-        return "physical volume (LVM)"
-    return fstype
-
-def ext2IsDirty(device):
-    label = _isys.e2dirty(device)
-    return label
-
-def ext2HasJournal(device):
-    hasjournal = _isys.e2hasjournal(device)
-    return hasjournal
-
-def modulesWithPaths():
-    mods = []
-    for modline in open("/proc/modules", "r"):
-        modName = modline.split(" ", 1)[0]
-        modInfo = iutil.execWithCapture("modinfo",
-                ["-F", "filename", modName]).splitlines()
-        modPaths = [ line.strip() for line in modInfo if line!="" ]
-        mods.extend(modPaths)
-    return mods
-
-def driveUsesModule(device, modules):
-    """Returns true if a drive is using a prticular module.  Only works
-       for SCSI devices right now."""
-
-    if not isinstance(modules, ().__class__) and not \
-            isinstance(modules, [].__class__):
-        modules = [modules]
-
-    if device[:2] == "hd":
-        return False
-    rc = False
-    if os.access("/tmp/scsidisks", os.R_OK):
-        sdlist=open("/tmp/scsidisks", "r")
-        sdlines = sdlist.readlines()
-        sdlist.close()
-        for l in sdlines:
-            try:
-                # each line has format of:  <device>  <module>
-                (sddev, sdmod) = string.split(l)
-
-                if sddev == device:
-                    if sdmod in modules:
-                        rc = True
-                        break
-            except:
-                    pass
-    return rc
-
-def vtActivate (num):
-    if iutil.isS390():
-        return
-    _isys.vtActivate (num)
-
-def isPseudoTTY (fd):
-    return _isys.isPseudoTTY (fd)
-
-## Flush filesystem buffers.
-def sync ():
-    return _isys.sync ()
-
-## Determine if a file is an ISO image or not.
-# @param file The full path to a file to check.
-# @return True if ISO image, False otherwise.
-def isIsoImage(file):
-    return _isys.isisoimage(file)
-
-# Return number of network devices
-def getNetworkDeviceCount():
-    bus = dbus.SystemBus()
-    nm = bus.get_object(NM_SERVICE, NM_MANAGER_PATH)
-    devlist = nm.get_dbus_method("GetDevices")()
-    return len(devlist)
-
-# Get a D-Bus interface for the specified device's (e.g., eth0) properties.
-# If dev=None, return a hash of the form 'hash[dev] = props_iface' that
-# contains all device properties for all interfaces that NetworkManager knows
-# about.
-def getDeviceProperties(dev=None):
-    bus = dbus.SystemBus()
-    nm = bus.get_object(NM_SERVICE, NM_MANAGER_PATH)
-    devlist = nm.get_dbus_method("GetDevices")()
-    all = {}
-
-    for path in devlist:
-        device = bus.get_object(NM_SERVICE, path)
-        device_props_iface = dbus.Interface(device, DBUS_PROPS_IFACE)
-
-        device_interface = str(device_props_iface.Get(NM_MANAGER_IFACE, "Interface"))
-
-        if dev is None:
-            all[device_interface] = device_props_iface
-        elif device_interface == dev:
-            return device_props_iface
-
-    if dev is None:
-        return all
-    else:
-        return None
-
-# Return true if method is currently 'dhcp' for the specified device.
-def isDeviceDHCP(dev=None):
-    if dev is None:
-        return False
-
-    bus = dbus.SystemBus()
-    nm = bus.get_object(NM_SERVICE, NM_MANAGER_PATH)
-    nm_props_iface = dbus.Interface(nm, DBUS_PROPS_IFACE)
-    active_connections = nm_props_iface.Get(NM_MANAGER_IFACE, "ActiveConnections")
-
-    for path in active_connections:
-        active = bus.get_object(NM_SERVICE, path)
-        active_props_iface = dbus.Interface(active, DBUS_PROPS_IFACE)
-
-        active_service_name = active_props_iface.Get(NM_ACTIVE_CONNECTION_IFACE, "ServiceName")
-        active_path = active_props_iface.Get(NM_ACTIVE_CONNECTION_IFACE, "Connection")
-        active_devices = active_props_iface.Get(NM_ACTIVE_CONNECTION_IFACE, "Devices")
-
-        device = bus.get_object(NM_SERVICE, active_devices[0])
-        device_props_iface = dbus.Interface(device, DBUS_PROPS_IFACE)
-        iface = device_props_iface.Get(NM_DEVICE_IFACE, "Interface")
-
-        if iface != dev:
-            continue
-
-        connection = bus.get_object(active_service_name, active_path)
-        connection_iface = dbus.Interface(connection, NM_CONNECTION_IFACE)
-        settings = connection_iface.GetSettings()
-
-        ip4_setting = settings.get('ipv4')
-        if not ip4_setting or not ip4_setting['method'] or ip4_setting['method'] == 'auto':
-            return True
-
-    return False
-
-# Get the MAC address for a network device.
-def getMacAddress(dev):
-    if dev == '' or dev is None:
-        return False
-
-    device_props_iface = getDeviceProperties(dev=dev)
-    if device_props_iface is None:
-        return None
-
-    device_macaddr = None
-    try:
-        device_macaddr = device_props_iface.Get(NM_MANAGER_IFACE, "HwAddress").upper()
-    except dbus.exceptions.DBusException as e:
-        if e.get_dbus_name() != 'org.freedesktop.DBus.Error.InvalidArgs':
-            raise
-    return device_macaddr
-
-# Get a description string for a network device (e.g., eth0)
-def getNetDevDesc(dev):
-    from baseudev import udev_get_device
-    desc = "Network Interface"
-
-    if dev == '' or dev is None:
-        return desc
-
-    bus = dbus.SystemBus()
-    nm = bus.get_object(NM_SERVICE, NM_MANAGER_PATH)
-    devlist = nm.get_dbus_method("GetDevices")()
-
-    for path in devlist:
-        device = bus.get_object(NM_SERVICE, path)
-        device_iface = dbus.Interface(device, DBUS_PROPS_IFACE)
-        device_props = device_iface.get_dbus_method("GetAll")(NM_DEVICE_IFACE)
-
-        if dev == device_props['Interface']:
-            # This is the sysfs path (for now).
-            udev_path = device_props['Udi']
-            dev = udev_get_device(udev_path[4:])
-
-            if dev is None:
-                log.debug("weird, we have a None dev with path %s" % path)
-            elif dev.has_key("ID_VENDOR_ENC") and dev.has_key("ID_MODEL_ENC"):
-                desc = "%s %s" % (dev["ID_VENDOR_ENC"], dev["ID_MODEL_ENC"])
-            elif dev.has_key("ID_VENDOR_FROM_DATABASE") and dev.has_key("ID_MODEL_FROM_DATABASE"):
-                desc = "%s %s" % (dev["ID_VENDOR_FROM_DATABASE"], dev["ID_MODEL_FROM_DATABASE"])
-
-            return desc
-
-    return desc
-
-# Determine if a network device is a wireless device.
-def isWireless(dev):
-    if dev == '' or dev is None:
-        return False
-
-    device_props_iface = getDeviceProperties(dev=dev)
-    if device_props_iface is None:
-        return None
-
-    device_type = int(device_props_iface.Get(NM_MANAGER_IFACE, "DeviceType"))
-
-    # from include/NetworkManager.h in the NM source code
-    #    0 == NM_DEVICE_TYPE_UNKNOWN
-    #    1 == NM_DEVICE_TYPE_ETHERNET
-    #    2 == NM_DEVICE_TYPE_WIFI
-    #    3 == NM_DEVICE_TYPE_GSM
-    #    4 == NM_DEVICE_TYPE_CDMA
-    if device_type == 2:
-        return True
-    else:
-        return False
-
-# Get the IP address for a network device.
-def getIPAddress(dev):
-    if dev == '' or dev is None:
-       return None
-
-    device_props_iface = getDeviceProperties(dev=dev)
-    if device_props_iface is None:
-        return None
-
-    # XXX: add support for IPv6 addresses when NM can do that
-    device_ip4addr = device_props_iface.Get(NM_MANAGER_IFACE, "Ip4Address")
-
-    try:
-        tmp = struct.pack('I', device_ip4addr)
-        address = socket.inet_ntop(socket.AF_INET, tmp)
-    except ValueError, e:
-        return None
-
-    return address
-
-## Get the correct context for a file from loaded policy.
-# @param fn The filename to query.
-def matchPathContext(fn):
-    con = None
-    try:
-        con = selinux.matchpathcon(os.path.normpath(fn), 0)[1]
-    except OSError as e:
-        log.info("failed to get default SELinux context for %s: %s" % (fn, e))
-    return con
-
-## Set the SELinux file context of a file
-# @param fn The filename to fix.
-# @param con The context to use.
-# @param instroot An optional root filesystem to look under for fn.
-def setFileContext(fn, con, instroot = '/'):
-    full_path = os.path.normpath("%s/%s" % (instroot, fn))
-    rc = False
-    if con is not None and os.access(full_path, os.F_OK):
-        try:
-            rc = (selinux.lsetfilecon(full_path, con) == 0)
-        except OSError as e:
-            log.info("failed to set SELinux context for %s: %s" % (full_path, e))
-    return rc
-
-## Restore the SELinux file context of a file to its default.
-# @param fn The filename to fix.
-# @param instroot An optional root filesystem to look under for fn.
-def resetFileContext(fn, instroot = '/'):
-    con = matchPathContext(fn)
-    if con:
-        if setFileContext(fn, con, instroot):
-            return con
-    return None
-
-def prefix2netmask(prefix):
-    return _isys.prefix2netmask(prefix)
-
-def netmask2prefix (netmask):
-    prefix = 0
-
-    while prefix < 33:
-        if (prefix2netmask(prefix) == netmask):
-            return prefix
-
-        prefix += 1
-
-    return prefix
-
-isPAE = None
-def isPaeAvailable():
-    global isPAE
-    if isPAE is not None:
-        return isPAE
-
-    isPAE = False
-    if not iutil.isX86():
-        return isPAE
-
-    f = open("/proc/cpuinfo", "r")
-    lines = f.readlines()
-    f.close()
-
-    for line in lines:
-        if line.startswith("flags") and line.find("pae") != -1:
-            isPAE = True
-            break
-
-    return isPAE
-
-def getLinkStatus(dev):
-    return _isys.getLinkStatus(dev)
-
-def getAnacondaVersion():
-    return _isys.getAnacondaVersion()
-
-auditDaemon = _isys.auditdaemon
-
-handleSegv = _isys.handleSegv
-
-printObject = _isys.printObject
-bind_textdomain_codeset = _isys.bind_textdomain_codeset
-isVioConsole = _isys.isVioConsole
-initLog = _isys.initLog
diff --git a/isys/lang.c b/isys/lang.c
deleted file mode 100644
index b6e2a36..0000000
--- a/isys/lang.c
+++ /dev/null
@@ -1,207 +0,0 @@
-/*
- * lang.c
- *
- * Copyright (C) 2007  Red Hat, Inc.  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 as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * 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, see <http://www.gnu.org/licenses/>.
- */
-
-#include <alloca.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/ioctl.h>
-#include <sys/stat.h>
-#include <unistd.h>
-
-#include <linux/keyboard.h>
-#ifdef NR_KEYS
-#undef NR_KEYS
-#define NR_KEYS 128
-#endif
-
-#include "linux/kd.h"
-
-#include "cpio.h"
-#include "isys.h"
-#include "lang.h"
-#include "stubs.h"
-
-int isysLoadFont(void) {
-    unsigned char font[65536];
-    struct console_font_op cfo;
-    unsigned short map[E_TABSZ];
-    struct unimapdesc d;
-    struct unimapinit u;
-    struct unipair desc[2048];
-    gzFile stream;
-    int rc;
-
-#if defined (__s390__) || defined (__s390x__)
-    return 0;
-#endif
-    stream = gunzip_open("/etc/screenfont.gz");
-    if (!stream)
-	return -EACCES;
-
-    gunzip_read(stream, &cfo, sizeof(cfo));
-    gunzip_read(stream, font, sizeof(font));
-    gunzip_read(stream, map, sizeof(map));
-    gunzip_read(stream, &d.entry_ct, sizeof(d.entry_ct));
-    d.entries = desc;
-    gunzip_read(stream, desc, d.entry_ct * sizeof(desc[0]));
-    gunzip_close(stream);
-
-    cfo.data = font;
-    cfo.op = KD_FONT_OP_SET;
-
-    rc = ioctl(1, KDFONTOP, &cfo);
-    if (rc) return rc;
-    rc = ioctl(1, PIO_UNIMAPCLR, &u);
-    if (rc) return rc;
-    rc = ioctl(1, PIO_UNIMAP, &d);
-    if (rc) return rc;
-    rc = ioctl(1, PIO_UNISCRNMAP, map);
-    if (rc) return rc;
-    /* activate the font map */
-    fprintf(stderr, "\033(K");
-    return 0;
-}
-
-int isysSetUnicodeKeymap(void) {
-    int console;
-
-#if defined (__s390__) || defined (__s390x__)
-    return 0;
-#endif
-    console = open("/dev/console", O_RDWR);
-    if (console < 0)
-	return -EACCES;
-
-    /* place keyboard in unicode mode */
-    ioctl(console, KDSKBMODE, K_UNICODE);
-    close(console);
-    return 0;
-}
-
-/* the file pointer must be at the beginning of the section already! */
-int loadKeymap(gzFile stream) {
-    int console;
-    int kmap, key;
-    struct kbentry entry;
-    int keymaps[MAX_NR_KEYMAPS];
-    int count = 0;
-    unsigned int magic;
-    short keymap[NR_KEYS];
-    struct stat sb;
-
-#if defined (__s390__) || defined (__s390x__)
-    return 0;
-#endif
-    if (isVioConsole())
-        return 0;
-
-    /* assume that if we're already on a pty loading a keymap is silly */
-    fstat(0, &sb);
-    if (major(sb.st_rdev) == 3 || major(sb.st_rdev) == 136)
-	return 0;
-
-    if (gunzip_read(stream, &magic, sizeof(magic)) != sizeof(magic))
-	return -EIO;
-
-    if (magic != KMAP_MAGIC) return -EINVAL;
-
-    if (gunzip_read(stream, keymaps, sizeof(keymaps)) != sizeof(keymaps))
-	return -EINVAL;
-
-    console = open("/dev/tty0", O_RDWR);
-    if (console < 0)
-	return -EACCES;
-
-    for (kmap = 0; kmap < MAX_NR_KEYMAPS; kmap++) {
-	if (!keymaps[kmap]) continue;
-
-	if (gunzip_read(stream, keymap, sizeof(keymap)) != sizeof(keymap)) {
-	    close(console);
-	    return -EIO;
-	}
-
-	count++;
-	for (key = 0; key < NR_KEYS; key++) {
-	    entry.kb_index = key;
-	    entry.kb_table = kmap;
-	    entry.kb_value = keymap[key];
-	    if (KTYP(entry.kb_value) != KT_SPEC) {
-		if (ioctl(console, KDSKBENT, &entry)) {
-		    int ret = errno;
-		    close(console);
-		    return ret;
-		}
-	    }
-	}
-    }
-    close(console);
-    return 0;
-}
-
-int isysLoadKeymap(char * keymap) {
-    int num = -1;
-    int rc;
-    gzFile f;
-    struct kmapHeader hdr;
-    struct kmapInfo * infoTable;
-    char buf[16384]; 			/* I hope this is big enough */
-    int i;
-
-    f = gunzip_open("/etc/keymaps.gz");
-    if (!f) return -EACCES;
-
-    if (gunzip_read(f, &hdr, sizeof(hdr)) != sizeof(hdr)) {
-	gunzip_close(f);
-	return -EINVAL;
-    }
-
-    i = hdr.numEntries * sizeof(*infoTable);
-    infoTable = alloca(i);
-    if (gunzip_read(f, infoTable, i) != i) {
-	gunzip_close(f);
-	return -EIO;
-    }
-
-    for (i = 0; i < hdr.numEntries; i++)
-	if (!strcmp(infoTable[i].name, keymap)) {
-	    num = i;
-	    break;
-	}
-
-    if (num == -1) {
-	gunzip_close(f);
-	return -ENOENT;
-    }
-
-    for (i = 0; i < num; i++) {
-	if (gunzip_read(f, buf, infoTable[i].size) != infoTable[i].size) {
-	    gunzip_close(f);
-	    return -EIO;
-	}
-    }
-
-    rc = loadKeymap(f);
-
-    gunzip_close(f);
-
-    return rc;
-}
diff --git a/isys/lang.h b/isys/lang.h
deleted file mode 100644
index a08adbd..0000000
--- a/isys/lang.h
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * lang.h
- *
- * Copyright (C) 2007  Red Hat, Inc.  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 as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * 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, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef ISYS_LANG_H
-#define ISYS_LANG_H
-
-#include "stubs.h"
-
-/* define ask johnsonm@xxxxxxxxxx where this came from */
-#define KMAP_MAGIC 0x8B39C07F
-#define KMAP_NAMELEN 40         /* including '\0' */
-
-struct kmapHeader {
-    int magic;
-    int numEntries;
-};
-        
-struct kmapInfo {
-    int size;
-    char name[KMAP_NAMELEN];
-};
-
-int loadKeymap(gzFile stream);
-int isysLoadFont(void);
-int isysLoadKeymap(char * keymap);
-int isysSetUnicodeKeymap(void);
-
-#endif
diff --git a/isys/linkdetect.c b/isys/linkdetect.c
deleted file mode 100644
index f97a291..0000000
--- a/isys/linkdetect.c
+++ /dev/null
@@ -1,202 +0,0 @@
-/*
- * linkdetect.c - simple link detection
- *
- * pulls code from mii-tool.c in net-toools and ethtool so
- * that we can do everything that jgarzik says we should check
- *
- * Copyright (C) 2002, 2003  Red Hat, Inc.  All rights reserved.
- * Portions Copyright (C) 2000 David A. Hinds -- dhinds@xxxxxxxxxxxxxxxxxxxxxx
- *
- * 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; either version 2 of the License, or
- * (at your option) any later version.
- *
- * 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, see <http://www.gnu.org/licenses/>.
- *
- * Author(s): Jeremy Katz <katzj@xxxxxxxxxx>
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <stdint.h>
-#include <sys/ioctl.h>
-#include <string.h>
-#include <unistd.h>
-#include <errno.h>
-
-#include <sys/socket.h>
-#include <sys/types.h>
-#include <net/if.h>
-
-#include <linux/sockios.h>
-#include <linux/mii.h>
-#include <linux/ethtool.h>
-#include "ethtool.h"
-
-static struct ifreq ifr;
-
-static int mdio_read(int skfd, uint16_t location)
-{
-    struct mii_ioctl_data mii;
-
-    memset(&mii, 0, sizeof(mii));
-    memcpy(&mii, &ifr.ifr_data, sizeof(mii));
-    mii.reg_num = location;
-    memcpy(&ifr.ifr_data, &mii, sizeof(mii));
-
-    if (ioctl(skfd, SIOCGMIIREG, &ifr) < 0) {
-#ifdef STANDALONE
-        fprintf(stderr, "SIOCGMIIREG on %s failed: %s\n", ifr.ifr_name,
-                strerror(errno));
-#endif
-        return -1;
-    } else {
-        memcpy(&mii, &ifr.ifr_data, sizeof(mii));
-    }
-
-    return mii.val_out;
-}
-
-/* we don't need writing right now */
-#if 0
-static void mdio_write(int skfd, int location, int value)
-{
-    struct mii_ioctl_data *mii = (struct mii_ioctl_data *)&ifr.ifr_data;
-    mii->reg_num = location;
-    mii->val_in = value;
-    if (ioctl(skfd, SIOCSMIIREG, &ifr) < 0) {
-#ifdef STANDALONE
-	fprintf(stderr, "SIOCSMIIREG on %s failed: %s\n", ifr.ifr_name,
-		strerror(errno));
-#endif
-    }
-}
-#endif
-
-
-
-static int get_mii_link_status(int sock) {
-    int i, mii_val[32];
-
-    if (ioctl(sock, SIOCGMIIPHY, &ifr) < 0) {
-	if (errno != ENODEV)
-#ifdef STANDALONE
-	    fprintf(stderr, "SIOCGMIIPHY on '%s' failed: %s\n",
-		    ifr.ifr_name, strerror(errno));
-#endif
-	return -1;
-    }
-
-    /* Some bits in the BMSR are latched, but we can't rely on being
-       the only reader, so only the current values are meaningful */
-    mdio_read(sock, MII_BMSR);
-    for (i = 0; i < 8; i++)
-	mii_val[i] = mdio_read(sock, i);
-
-    if (mii_val[MII_BMCR] == 0xffff) {
-#ifdef STANDALONE
-	fprintf(stderr, "  No MII transceiver present!.\n");
-#endif
-	return -1;
-    }
-
-    if (mii_val[MII_BMSR] & BMSR_LSTATUS)
-        return 1;
-    else
-        return 0;
-}
-
-static int get_ethtool_link_status(int sock) {
-    struct ethtool_value edata;
-    int rc;
-
-    edata.cmd = ETHTOOL_GLINK;
-    ifr.ifr_data = (caddr_t)&edata;
-    rc = ioctl(sock, SIOCETHTOOL, &ifr);
-    if (rc == 0) {
-        return edata.data;
-    } else if (errno != EOPNOTSUPP) {
-#ifdef STANDALONE
-        fprintf(stderr, "Cannot get link status (%d): %s\n", errno, strerror(errno));
-#endif
-    }
-
-    return -1;
-}
-
-
-
-int get_link_status(char * devname) {
-    int sock, rc;
-
-    if ((sock = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
-#ifdef STANDALONE
-        fprintf(stderr, "Error creating socket: %s\n", strerror(errno));
-#endif
-        return -1;
-    }
-
-    /* make sure interface is up and activated */
-    memset(&ifr, 0, sizeof(ifr));
-    strcpy(ifr.ifr_name, devname);
-
-    if (ioctl(sock, SIOCGIFFLAGS, &ifr) < 0) {
-        return -1;
-    }
-
-    ifr.ifr_flags |= (IFF_UP | IFF_RUNNING);
-
-    if (ioctl(sock, SIOCSIFFLAGS, &ifr) < 0) {
-        return -1;
-    }
-
-    /* Setup our control structures. */
-    memset(&ifr, 0, sizeof(ifr));
-    strcpy(ifr.ifr_name, devname);
-
-    /* check for link with both ethtool and mii registers.  ethtool is
-     * supposed to be the One True Way (tm), but it seems to not work
-     * with much yet :/ */
-
-    rc = get_ethtool_link_status(sock);
-#ifdef STANDALONE
-    printf("ethtool link status of %s is: %d\n", devname, rc);
-#endif
-    if (rc == 1) {
-        close(sock);
-        return 1;
-    }
-
-    rc = get_mii_link_status(sock);
-#ifdef STANDALONE
-    printf("MII link status of %s is: %d\n", devname, rc);
-#endif
-    if (rc == 1) {
-        close(sock);
-        return 1;
-    }
-
-    return 0;
-}
-
-#ifdef STANDALONE
-/* hooray for stupid test programs! */
-int main(int argc, char **argv) {
-    char * dev;
-
-    if (argc >= 2) 
-        dev = argv[1];
-    else
-        dev = strdup("eth0");
-
-    printf("link status of %s is %d\n", dev, get_link_status(dev));
-    return 0;
-}
-#endif
diff --git a/isys/log.c b/isys/log.c
deleted file mode 100644
index da39c7b..0000000
--- a/isys/log.c
+++ /dev/null
@@ -1,224 +0,0 @@
-/*
- * log.c - logging functionality
- *
- * Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002  Red Hat, Inc.
- * 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 as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * 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, see <http://www.gnu.org/licenses/>.
- *
- * Author(s): Erik Troan <ewt@xxxxxxxxxx>
- *            Matt Wilson <msw@xxxxxxxxxx>
- *            Michael Fulbright <msf@xxxxxxxxxx>
- *            Jeremy Katz <katzj@xxxxxxxxxx>
- */
-
-#include <fcntl.h>
-#include <stdarg.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <time.h>
-#include <unistd.h>
-#include <sys/time.h>
-#include <syslog.h>
-
-#include "log.h"
-
-static FILE * main_log_tty = NULL;
-static FILE * main_log_file = NULL;
-static FILE * program_log_file = NULL;
-static int minLevel = INFO;
-static const char * main_tag = "loader";
-static const char * program_tag = "program";
-static const int syslog_facility = LOG_LOCAL0;
-
-/* maps our loglevel to syslog loglevel */
-static int mapLogLevel(int level)
-{
-    switch (level) {
-    case DEBUGLVL:
-        return LOG_DEBUG;
-    case INFO:
-        return LOG_INFO;
-    case WARNING:
-        return LOG_WARNING;
-    case CRITICAL:
-        return LOG_CRIT;
-    case ERROR:
-    default:
-        /* if someone called us with an invalid level value, log it as an error
-           too. */
-        return LOG_ERR;
-    }
-}
-
-static void printLogHeader(int level, const char *tag, FILE *outfile) {
-    struct timeval current_time;
-    struct tm *t;
-    int msecs;
-
-    gettimeofday(&current_time, NULL);
-    t = gmtime(&current_time.tv_sec);
-    msecs = current_time.tv_usec / 1000;
-    switch (level) {
-        case DEBUGLVL:
-            fprintf (outfile, "%02d:%02d:%02d,%03d DEBUG %s: ", t->tm_hour,
-                     t->tm_min, t->tm_sec, msecs, tag);
-            break;
-
-        case INFO:
-            fprintf (outfile, "%02d:%02d:%02d,%03d INFO %s: ", t->tm_hour,
-                     t->tm_min, t->tm_sec, msecs, tag);
-            break;
-
-        case WARNING:
-            fprintf (outfile, "%02d:%02d:%02d,%03d WARNING %s: ", t->tm_hour,
-                     t->tm_min, t->tm_sec, msecs, tag);
-            break;
-
-        case ERROR:
-            fprintf (outfile, "%02d:%02d:%02d,%03d ERROR %s: ", t->tm_hour,
-                     t->tm_min, t->tm_sec, msecs, tag);
-            break;
-
-        case CRITICAL:
-            fprintf (outfile, "%02d:%02d:%02d,%03d CRITICAL %s: ", t->tm_hour,
-                     t->tm_min, t->tm_sec, msecs, tag);
-            break;
-    }
-}
-
-static void printLogMessage(int level, const char *tag, FILE *outfile, const char *s, va_list ap)
-{
-    printLogHeader(level, tag, outfile);
-
-    va_list apc;
-    va_copy(apc, ap);
-    vfprintf(outfile, s, apc);
-    va_end(apc);
-
-    fprintf(outfile, "\n");
-    fflush(outfile);
-}
-
-static void retagSyslog(const char* new_tag)
-{
-    closelog();
-    openlog(new_tag, 0, syslog_facility);
-}
-
-void logMessageV(enum logger_t logger, int level, const char * s, va_list ap) {
-    FILE *log_tty = main_log_tty;
-    FILE *log_file = main_log_file;
-    const char *tag = main_tag;
-    if (logger == PROGRAM_LOG) {
-        /* tty output is done directly for programs */
-        log_tty = NULL;
-        log_file = program_log_file;
-        tag = program_tag;
-        /* close and reopen syslog so we get the tagging right */
-        retagSyslog(tag);
-    }
-
-    va_list apc;
-    /* Log everything into syslog */
-    va_copy(apc, ap);
-    vsyslog(mapLogLevel(level), s, apc);
-    va_end(apc);
-
-    /* Only log to the screen things that are above the minimum level. */
-    if (main_log_tty && level >= minLevel && log_tty) {
-        printLogMessage(level, tag, log_tty, s, ap);
-    }
-
-    /* But log everything to the file. */
-    if (main_log_file) {
-        printLogMessage(level, tag, log_file, s, ap);
-    }
-
-    /* change the syslog tag back to the default again */
-    if (logger == PROGRAM_LOG)
-        retagSyslog(main_tag);
-}
-
-void logMessage(int level, const char * s, ...) {
-    va_list args;
-
-    va_start(args, s);
-    logMessageV(MAIN_LOG, level, s, args);
-    va_end(args);
-}
-
-void logProgramMessage(int level, const char * s, ...) {
-    va_list args;
-
-    va_start(args, s);
-    logMessageV(PROGRAM_LOG, level, s, args);
-    va_end(args);
-}
-
-int tty_logfd = -1;
-int file_logfd = -1;
-
-void openLog() {
-    /* init syslog logging (so loader messages can also be forwarded to a remote
-       syslog daemon */
-    openlog(main_tag, 0, syslog_facility);
-
-    int flags;
-    main_log_tty = fopen("/dev/tty3", "a");
-    main_log_file = fopen("/tmp/anaconda.log", "a");
-    program_log_file = fopen("/tmp/program.log", "a");
-
-    if (main_log_tty) {
-        tty_logfd = fileno(main_log_tty);
-        flags = fcntl(tty_logfd, F_GETFD, 0) | FD_CLOEXEC;
-        fcntl(tty_logfd, F_SETFD, flags);
-    }
-
-    if (main_log_file) {
-        file_logfd = fileno(main_log_file);
-        flags = fcntl(file_logfd, F_GETFD, 0) | FD_CLOEXEC;
-        fcntl(file_logfd, F_SETFD, flags);
-    }
-    
-    if (program_log_file) {
-        int fd;
-        fd = fileno(program_log_file);
-        flags = fcntl(fd, F_GETFD, 0) | FD_CLOEXEC;
-        fcntl(file_logfd, F_SETFD, flags);
-    }
-}
-
-void closeLog(void) {
-    if (main_log_tty)
-        fclose(main_log_tty);
-    if (main_log_file)
-        fclose(main_log_file);
-    if (program_log_file)
-        fclose(program_log_file);
-    
-    /* close syslog logger */
-    closelog();
-}
-
-/* set the level.  higher means you see more verbosity */
-void setLogLevel(int level) {
-    minLevel = level;
-}
-
-int getLogLevel(void) {
-    return minLevel;
-}
-
-/* vim:set shiftwidth=4 softtabstop=4: */
diff --git a/isys/log.h b/isys/log.h
deleted file mode 100644
index 51de2de..0000000
--- a/isys/log.h
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * log.h
- *
- * Copyright (C) 2007  Red Hat, Inc.  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 as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * 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, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef _LOG_H_
-#define _LOG_H_
-
-#include <stdio.h>
-#include <stdarg.h>
-
-#define DEBUGLVL 10
-#define INFO     20
-#define WARNING  30
-#define ERROR    40
-#define CRITICAL 50
-
-enum logger_t {
-    MAIN_LOG = 1,
-    PROGRAM_LOG = 2
-};
-
-void logMessageV(enum logger_t logger, int level, const char * s, va_list ap)
-    __attribute__ ((format (printf, 3, 0)));
-void logMessage(int level, const char * s, ...)
-    __attribute__ ((format (printf, 2, 3)));
-void logProgramMessage(int level, const char * s, ...)
-    __attribute__ ((format (printf, 2, 3)));
-void openLog();
-void closeLog(void);
-void setLogLevel(int minLevel);
-int getLogLevel(void);
-
-extern int tty_logfd;
-extern int file_logfd;
-
-#endif /* _LOG_H_ */
diff --git a/isys/stubs.h b/isys/stubs.h
deleted file mode 100644
index 40ecb22..0000000
--- a/isys/stubs.h
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * stubs.h
- *
- * Copyright (C) 2007  Red Hat, Inc.  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 as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * 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, see <http://www.gnu.org/licenses/>.
- */
-
-/* we use gzlib when linked against dietlibc, but otherwise, we should use
-   zlib.  it would make more sense to do the defines in the other direction, 
-   but that causes symbol wackiness because both gunzip_open and gzip_open in
-   gzlib are gzopen from zlib
-*/
-
-#ifndef ISYS_STUB
-#define ISYS_STUB
-
-#ifndef GZLIB
-#include <zlib.h>
-
-#define gunzip_open(x) gzopen(x, "r")
-#define gunzip_dopen gzdopen(x, "r")
-#define gunzip_close gzclose
-#define gunzip_read gzread
-#define gzip_write gzwrite
-#define gzip_open(x, y, z) gzopen(x, "w")
-
-#else
-#include "gzlib/gzlib.h"
-
-#endif
-
-#endif
diff --git a/isys/uncpio.c b/isys/uncpio.c
deleted file mode 100644
index 171eb6b..0000000
--- a/isys/uncpio.c
+++ /dev/null
@@ -1,798 +0,0 @@
-/*
- * uncpio.c
- *
- * Copyright (C) 2007  Red Hat, Inc.  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 as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * 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, see <http://www.gnu.org/licenses/>.
- */
-
-#define HAVE_ALLOCA_H 1
-#define MAJOR_IN_SYSMACROS 1
-
-#if HAVE_ALLOCA_H
-# include <alloca.h>
-#endif
-
-#define _(foo) (foo)
-
-#include <errno.h>
-#include <fcntl.h>
-#include <fnmatch.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <unistd.h>
-#include <utime.h>
-
-#include "cpio.h"
-#include "stubs.h"
-
-#if MAJOR_IN_SYSMACROS 
-#include <sys/sysmacros.h>
-#elif MAJOR_IN_MKDEV 
-#include <sys/mkdev.h>
-#endif
-
-#define CPIO_NEWC_MAGIC	"070701"
-#define CPIO_CRC_MAGIC	"070702"
-#define TRAILER		"TRAILER!!!"
-
-/* FIXME: We don't translate between cpio and system mode bits! These
-   should both be the same, but really odd things are going to happen if
-   that's not true! */
-
-/* We need to maintain our oun file pointer to allow padding */
-struct ourfd {
-    gzFile fd;
-    size_t pos;
-};
-
-struct hardLink {
-    struct hardLink * next;
-    char ** files;		/* there are nlink of these, used by install */
-    int * fileMaps;		/* used by build */
-    dev_t dev;
-    ino_t inode;
-    int nlink;			
-    int linksLeft;
-    int createdPath;
-    struct stat sb;
-};
-
-struct cpioCrcPhysicalHeader {
-    char magic[6];
-    char inode[8];
-    char mode[8];
-    char uid[8];
-    char gid[8];
-    char nlink[8];
-    char mtime[8];
-    char filesize[8];
-    char devMajor[8];
-    char devMinor[8];
-    char rdevMajor[8];
-    char rdevMinor[8];
-    char namesize[8];
-    char checksum[8];			/* ignored !! */
-};
-
-#define PHYS_HDR_SIZE	110		/* don't depend on sizeof(struct) */
-
-struct cpioHeader {
-    ino_t inode;
-    mode_t mode;
-    uid_t uid;
-    gid_t gid;
-    int nlink;
-    time_t mtime;
-    unsigned long size;
-    dev_t dev, rdev;
-    char * path;
-};
-
-static inline off_t ourread(struct ourfd * thefd, void * buf, size_t size) {
-    off_t i;
-
-    i = gunzip_read(thefd->fd, buf, size);
-    thefd->pos += i;
-    
-    return i;
-}
-
-static inline void padinfd(struct ourfd * fd, int modulo) {
-    int buf[10];
-    int amount;
-    
-    amount = (modulo - fd->pos % modulo) % modulo;
-    ourread(fd, buf, amount);
-}
-
-static inline int padoutfd(struct ourfd * fd, size_t * where, int modulo) {
-    /*static int buf[10] = { '\0', '\0', '\0', '\0', '\0', 
-			   '\0', '\0', '\0', '\0', '\0' };*/
-    int amount;
-    static int buf[512];
-
-    amount = (modulo - *where % modulo) % modulo;
-    *where += amount;
-
-    if (gzip_write(fd->fd, buf, amount) != amount)
-	return CPIOERR_WRITE_FAILED;
-
-    return 0;
-}
-
-static int strntoul(const char * str, char ** endptr, int base, int num) {
-    char * buf, * end;
-    unsigned long ret;
-
-    buf = alloca(num + 1);
-    strncpy(buf, str, num);
-    buf[num] = '\0';
-
-    ret = strtoul(buf, &end, base);
-    if (*end)
-	*endptr = (char *)(str + (end - buf));	/* XXX discards const */
-    else
-	*endptr = "";
-
-    return strtoul(buf, endptr, base);
-}
-
-#define GET_NUM_FIELD(phys, log) \
-	log = strntoul(phys, &end, 16, sizeof(phys)); \
-	if (*end) return CPIOERR_BAD_HEADER;
-#define SET_NUM_FIELD(phys, val, space) \
-	sprintf(space, "%8.8lx", (unsigned long) (val)); \
-	memcpy(phys, space, 8);
-
-static int getNextHeader(struct ourfd * fd, struct cpioHeader * chPtr,
-			 struct cpioCrcPhysicalHeader * physHeaderPtr) {
-    struct cpioCrcPhysicalHeader physHeader;
-    int nameSize;
-    char * end;
-    int major, minor;
-
-    if (ourread(fd, &physHeader, PHYS_HDR_SIZE) != PHYS_HDR_SIZE) 
-	return CPIOERR_READ_FAILED;
-
-    if (physHeaderPtr)
-	memcpy(physHeaderPtr, &physHeader, PHYS_HDR_SIZE);
-
-    if (strncmp(CPIO_CRC_MAGIC, physHeader.magic, strlen(CPIO_CRC_MAGIC)) &&
-	strncmp(CPIO_NEWC_MAGIC, physHeader.magic, strlen(CPIO_NEWC_MAGIC)))
-	return CPIOERR_BAD_MAGIC;
-
-    GET_NUM_FIELD(physHeader.inode, chPtr->inode);
-    GET_NUM_FIELD(physHeader.mode, chPtr->mode);
-    GET_NUM_FIELD(physHeader.uid, chPtr->uid);
-    GET_NUM_FIELD(physHeader.gid, chPtr->gid);
-    GET_NUM_FIELD(physHeader.nlink, chPtr->nlink);
-    GET_NUM_FIELD(physHeader.mtime, chPtr->mtime);
-    GET_NUM_FIELD(physHeader.filesize, chPtr->size);
-
-    GET_NUM_FIELD(physHeader.devMajor, major);
-    GET_NUM_FIELD(physHeader.devMinor, minor);
-    chPtr->dev = makedev(major, minor);
-
-    GET_NUM_FIELD(physHeader.rdevMajor, major);
-    GET_NUM_FIELD(physHeader.rdevMinor, minor);
-    chPtr->rdev = makedev(major, minor);
-
-    GET_NUM_FIELD(physHeader.namesize, nameSize);
-
-    chPtr->path = malloc(nameSize + 1);
-    if (ourread(fd, chPtr->path, nameSize) != nameSize) {
-	free(chPtr->path);
-	return CPIOERR_BAD_HEADER;
-    }
-
-    /* this is unecessary chPtr->path[nameSize] = '\0'; */
-
-    padinfd(fd, 4);
-
-    return 0;
-}
-
-int myCpioFileMapCmp(const void * a, const void * b) {
-    const struct cpioFileMapping * first = a;
-    const struct cpioFileMapping * second = b;
-
-    return (strcmp(first->archivePath, second->archivePath));
-}
-
-/* This could trash files in the path! I'm not sure that's a good thing */
-static int createDirectory(char * path, mode_t perms) {
-    struct stat sb;
-    int dounlink;
-
-    if (!lstat(path, &sb)) {
-	if (S_ISDIR(sb.st_mode)) {
-	    return 0;
-	} else if (S_ISLNK(sb.st_mode)) {
-	    if (stat(path, &sb)) {
-		if (errno != ENOENT) 
-		    return CPIOERR_STAT_FAILED;
-		dounlink = 1;
-	    } else {
-		if (S_ISDIR(sb.st_mode))
-		    return 0;
-		dounlink = 1;
-	    }
-	} else {
-	    dounlink = 1;
-	}
-
-	if (dounlink && unlink(path)) {
-	    return CPIOERR_UNLINK_FAILED;
-	}
-    }
-
-    if (mkdir(path, 000))
-	return CPIOERR_MKDIR_FAILED;
-
-    if (chmod(path, perms))
-	return CPIOERR_CHMOD_FAILED;
-
-    return 0;
-}
-
-static int setInfo(struct cpioHeader * hdr) {
-    int rc = 0;
-    struct utimbuf stamp;
-
-    stamp.actime = hdr->mtime; 
-    stamp.modtime = hdr->mtime;
-
-    if (!S_ISLNK(hdr->mode)) {
-	if (!getuid() && chown(hdr->path, hdr->uid, hdr->gid))
-	    rc = CPIOERR_CHOWN_FAILED;
-	if (!rc && chmod(hdr->path, hdr->mode & 07777))
-	    rc = CPIOERR_CHMOD_FAILED;
-	if (!rc && utime(hdr->path, &stamp))
-	    rc = CPIOERR_UTIME_FAILED;
-    } else {
-#       if ! CHOWN_FOLLOWS_SYMLINK
-	    if (!getuid() && !rc && lchown(hdr->path, hdr->uid, hdr->gid))
-		rc = CPIOERR_CHOWN_FAILED;
-#       endif
-    }
-
-    return rc;
-}
-
-static int checkDirectory(char * filename) {
-    static char * lastDir = NULL;
-    static int lastDirLength = 0;
-    static int lastDirAlloced = 0;
-    int length = strlen(filename);
-    char * buf;
-    char * chptr;
-    int rc = 0;
-
-    buf = alloca(length + 1);
-    strcpy(buf, filename);
-
-    for (chptr = buf + length - 1; chptr > buf; chptr--) {
-	if (*chptr == '/') break;
-    }
-
-    if (chptr == buf) return 0;     /* /filename - no directories */
-
-    *chptr = '\0';                  /* buffer is now just directories */
-
-    length = strlen(buf);
-    if (lastDirLength == length && !strcmp(buf, lastDir)) return 0;
-
-    if (lastDirAlloced < (length + 1)) {
-	lastDirAlloced = length + 100;
-	lastDir = realloc(lastDir, lastDirAlloced);
-    }
-
-    strcpy(lastDir, buf);
-    lastDirLength = length;
-
-    for (chptr = buf + 1; *chptr; chptr++) {
-	if (*chptr == '/') {
-	    *chptr = '\0';
-	    rc = createDirectory(buf, 0755);
-	    *chptr = '/';
-	    if (rc) return rc;
-	}
-    }
-    rc = createDirectory(buf, 0755);
-
-    return rc;
-}
-
-static int expandRegular(struct ourfd * fd, struct cpioHeader * hdr,
-			 cpioCallback cb, void * cbData) {
-    int out;
-    char buf[8192];
-    int bytesRead;
-    unsigned long left = hdr->size;
-    int rc = 0;
-    struct cpioCallbackInfo cbInfo;
-    struct stat sb;
-
-    if (!lstat(hdr->path, &sb))
-	if (unlink(hdr->path))
-	    return CPIOERR_UNLINK_FAILED;
-
-    out = open(hdr->path, O_CREAT | O_WRONLY, 0);
-    if (out < 0) 
-	return CPIOERR_OPEN_FAILED;
-
-    cbInfo.file = hdr->path;
-    cbInfo.fileSize = hdr->size;
-
-    while (left) {
-	bytesRead = ourread(fd, buf, left < sizeof(buf) ? left : sizeof(buf));
-	if (bytesRead <= 0) {
-	    rc = CPIOERR_READ_FAILED;
-	    break;
-	}
-
-	if (write(out, buf, bytesRead) != bytesRead) {
-	    rc = CPIOERR_COPY_FAILED;
-	    break;
-	}
-
-	left -= bytesRead;
-
-	/* don't call this with fileSize == fileComplete */
-	if (!rc && cb && left) {
-	    cbInfo.fileComplete = hdr->size - left;
-	    cbInfo.bytesProcessed = fd->pos;
-	    cb(&cbInfo, cbData);
-	}
-    }
-
-    close(out);
-    
-    return rc;
-}
-
-static int expandSymlink(struct ourfd * fd, struct cpioHeader * hdr) {
-    char buf[2048], buf2[2048];
-    struct stat sb;
-    int len;
-
-    if ((hdr->size + 1)> sizeof(buf))
-	return CPIOERR_INTERNAL;
-
-    if (ourread(fd, buf, hdr->size) != hdr->size)
-	return CPIOERR_READ_FAILED;
-
-    buf[hdr->size] = '\0';
-
-    if (!lstat(hdr->path, &sb)) {
-	if (S_ISLNK(sb.st_mode)) {
-	    len = readlink(hdr->path, buf2, sizeof(buf2) - 1);
-	    if (len > 0) {
-		buf2[len] = '\0';
-		if (!strcmp(buf, buf2)) return 0;
-	    }
-	}
-
-	if (unlink(hdr->path))
-	    return CPIOERR_UNLINK_FAILED;
-    }
-
-    if (symlink(buf, hdr->path) < 0)
-	return CPIOERR_SYMLINK_FAILED;
-
-    return 0;
-}
-
-static int expandFifo(struct ourfd * fd, struct cpioHeader * hdr) {
-    struct stat sb;
-
-    if (!lstat(hdr->path, &sb)) {
-	if (S_ISFIFO(sb.st_mode)) return 0;
-
-	if (unlink(hdr->path))
-	    return CPIOERR_UNLINK_FAILED;
-    }
-
-    if (mkfifo(hdr->path, 0))
-	return CPIOERR_MKFIFO_FAILED;
-
-    return 0; 
-}
-
-static int expandDevice(struct ourfd * fd, struct cpioHeader * hdr) {
-    struct stat sb;
-
-    if (!lstat(hdr->path, &sb)) {
-	if ((S_ISCHR(sb.st_mode) || S_ISBLK(sb.st_mode)) && 
-		(sb.st_rdev == hdr->rdev))
-	    return 0;
-	if (unlink(hdr->path))
-	    return CPIOERR_UNLINK_FAILED;
-    }
-
-    if (mknod(hdr->path, hdr->mode & (~0777), hdr->rdev))
-	return CPIOERR_MKNOD_FAILED;
-    
-    return 0;
-}
-
-static void freeLink(struct hardLink * li) {
-    int i;
-
-    for (i = 0; i < li->nlink; i++) {
-	if (li->files[i]) free(li->files[i]);
-    }
-    free(li->files);
-}
-
-static int createLinks(struct hardLink * li, const char ** failedFile) {
-    int i;
-    struct stat sb;
-
-    for (i = 0; i < li->nlink; i++) {
-	if (i == li->createdPath) continue;
-	if (!li->files[i]) continue;
-
-	if (!lstat(li->files[i], &sb)) {
-	    if (unlink(li->files[i])) {
-		*failedFile = strdup(li->files[i]);
-		return CPIOERR_UNLINK_FAILED;
-	    }
-	}
-
-	if (link(li->files[li->createdPath], li->files[i])) {
-	    *failedFile = strdup(li->files[i]);
-	    return CPIOERR_LINK_FAILED;
-	}
-
-	free(li->files[i]);
-	li->files[i] = NULL;
-	li->linksLeft--;
-    }
-
-    return 0;
-}
-
-static int eatBytes(struct ourfd * fd, unsigned long amount) {
-    char buf[4096];
-    unsigned long bite;
-   
-    while (amount) {
-	bite = (amount > sizeof(buf)) ? sizeof(buf) : amount;
-	if (ourread(fd, buf, bite) != bite)
-	    return CPIOERR_READ_FAILED;
-	amount -= bite;
-    }
-
-    return 0;
-}
-
-int myCpioInstallArchive(gzFile stream, struct cpioFileMapping * mappings, 
-		       int numMappings, cpioCallback cb, void * cbData,
-		       const char ** failedFile) {
-    struct cpioHeader ch;
-    struct ourfd fd;
-    int rc = 0;
-    int linkNum = 0;
-    struct cpioFileMapping * map = NULL;
-    struct cpioFileMapping needle;
-    mode_t cpioMode;
-    int olderr;
-    struct cpioCallbackInfo cbInfo;
-    struct hardLink * links = NULL;
-    struct hardLink * li = NULL;
-
-    fd.fd = stream;
-    fd.pos = 0;
-
-    *failedFile = NULL;
-
-    do {
-	if ((rc = getNextHeader(&fd, &ch, NULL))) {
-	    fprintf(stderr, _("error %d reading header: %s\n"), rc, 
-		    myCpioStrerror(rc));
-	    return CPIOERR_BAD_HEADER;
-	}
-
-	if (!strcmp(ch.path, TRAILER)) {
-	    free(ch.path);
-	    break;
-	}
-
-	if (mappings) {
-	    needle.archivePath = ch.path;
-	    map = bsearch(&needle, mappings, numMappings, sizeof(needle),
-			  myCpioFileMapCmp);
-	}
-
-	if (mappings && !map) {
-	    eatBytes(&fd, ch.size);
-	} else {
-	    cpioMode = ch.mode;
-
-	    if (map) {
-		if (map->mapFlags & CPIO_MAP_PATH) {
-		    free(ch.path);
-		    ch.path = strdup(map->fsPath);
-		} 
-
-		if (map->mapFlags & CPIO_MAP_MODE)
-		    ch.mode = map->finalMode;
-		if (map->mapFlags & CPIO_MAP_UID)
-		    ch.uid = map->finalUid;
-		if (map->mapFlags & CPIO_MAP_GID)
-		    ch.gid = map->finalGid;
-	    }
-
-	    /* This won't get hard linked symlinks right, but I can't seem 
-	       to create those anyway */
-
-	    if (S_ISREG(ch.mode) && ch.nlink > 1) {
-		li = links;
-		for (li = links; li; li = li->next) {
-		    if (li->inode == ch.inode && li->dev == ch.dev) break;
-		}
-
-		if (!li) {
-		    li = malloc(sizeof(*li));
-		    li->inode = ch.inode;
-		    li->dev = ch.dev;
-		    li->nlink = ch.nlink;
-		    li->linksLeft = ch.nlink;
-		    li->createdPath = -1;
-		    li->files = calloc(sizeof(char *), li->nlink);
-		    li->next = links;
-		    links = li;
-		}
-
-		for (linkNum = 0; linkNum < li->nlink; linkNum++)
-		    if (!li->files[linkNum]) break;
-		li->files[linkNum] = strdup(ch.path);
-	    }
-		
-	    if ((ch.nlink > 1) && S_ISREG(ch.mode) && !ch.size &&
-		li->createdPath == -1) {
-		/* defer file creation */
-	    } else if ((ch.nlink > 1) && S_ISREG(ch.mode) && 
-		       (li->createdPath != -1)) {
-		createLinks(li, failedFile);
-
-		/* this only happens for cpio archives which contain
-		   hardlinks w/ the contents of each hardlink being
-		   listed (intead of the data being given just once. This
-		   shouldn't happen, but I've made it happen w/ buggy
-		   code, so what the heck? GNU cpio handles this well fwiw */
-		if (ch.size) eatBytes(&fd, ch.size);
-	    } else {
-		rc = checkDirectory(ch.path);
-
-		if (!rc) {
-		    if (S_ISREG(ch.mode))
-			rc = expandRegular(&fd, &ch, cb, cbData);
-		    else if (S_ISDIR(ch.mode))
-			rc = createDirectory(ch.path, 000);
-		    else if (S_ISLNK(ch.mode))
-			rc = expandSymlink(&fd, &ch);
-		    else if (S_ISFIFO(ch.mode))
-			rc = expandFifo(&fd, &ch);
-		    else if (S_ISCHR(ch.mode) || S_ISBLK(ch.mode))
-			rc = expandDevice(&fd, &ch);
-		    else if (S_ISSOCK(ch.mode)) {
-			/* this mimicks cpio but probably isnt' right */
-			rc = expandFifo(&fd, &ch);
-		    } else {
-			rc = CPIOERR_INTERNAL;
-		    }
-		}
-
-		if (!rc)
-		    rc = setInfo(&ch);
-
-		if (S_ISREG(ch.mode) && ch.nlink > 1) {
-		    li->createdPath = linkNum;
-		    li->linksLeft--;
-		    rc = createLinks(li, failedFile);
-		}
-	    }
-
-	    if (rc && !*failedFile) {
-		*failedFile = strdup(ch.path);
-
-		olderr = errno;
-		unlink(ch.path);
-		errno = olderr;
-	    }
-	}
-
-	padinfd(&fd, 4);
-
-	if (!rc && cb) {
-	    cbInfo.file = ch.path;
-	    cbInfo.fileSize = ch.size;
-	    cbInfo.fileComplete = ch.size;
-	    cbInfo.bytesProcessed = fd.pos;
-	    cb(&cbInfo, cbData);
-	}
-
-	free(ch.path);
-    } while (1 && !rc);
-
-    li = links;
-    while (li && !rc) {
-	if (li->linksLeft) {
-	    if (li->createdPath == -1)
-		rc = CPIOERR_INTERNAL;
-	    else 
-		rc = createLinks(li, failedFile);
-	}
-
-	freeLink(li);
-
-	links = li;
-	li = li->next;
-	free(links);
-	links = li;
-    }
-
-    li = links;
-    /* if an error got us here links will still be eating some memory */
-    while (li) {
-	freeLink(li);
-	links = li;
-	li = li->next;
-	free(links);
-    }
-
-    return rc;
-}
-
-const char * myCpioStrerror(int rc)
-{
-    static char msg[256];
-    char *s;
-    int l, myerrno = errno;
-
-    strcpy(msg, "cpio: ");
-    switch (rc) {
-    default:
-	s = msg + strlen(msg);
-	sprintf(s, _("(error 0x%x)"), rc);
-	s = NULL;
-	break;
-    case CPIOERR_BAD_MAGIC:	s = _("Bad magic");		break;
-    case CPIOERR_BAD_HEADER:	s = _("Bad header");		break;
-
-    case CPIOERR_OPEN_FAILED:	s = "open";	break;
-    case CPIOERR_CHMOD_FAILED:	s = "chmod";	break;
-    case CPIOERR_CHOWN_FAILED:	s = "chown";	break;
-    case CPIOERR_WRITE_FAILED:	s = "write";	break;
-    case CPIOERR_UTIME_FAILED:	s = "utime";	break;
-    case CPIOERR_UNLINK_FAILED:	s = "unlink";	break;
-    case CPIOERR_SYMLINK_FAILED: s = "symlink";	break;
-    case CPIOERR_STAT_FAILED:	s = "stat";	break;
-    case CPIOERR_MKDIR_FAILED:	s = "mkdir";	break;
-    case CPIOERR_MKNOD_FAILED:	s = "mknod";	break;
-    case CPIOERR_MKFIFO_FAILED:	s = "mkfifo";	break;
-    case CPIOERR_LINK_FAILED:	s = "link";	break;
-    case CPIOERR_READLINK_FAILED: s = "readlink";	break;
-    case CPIOERR_READ_FAILED:	s = "read";	break;
-    case CPIOERR_COPY_FAILED:	s = "copy";	break;
-
-    case CPIOERR_INTERNAL:	s = _("Internal error");	break;
-    case CPIOERR_HDR_SIZE:	s = _("Header size too big");	break;
-    case CPIOERR_UNKNOWN_FILETYPE: s = _("Unknown file type");	break;
-    }
-
-    l = sizeof(msg) - strlen(msg) - 1;
-    if (s != NULL) {
-	if (l > 0) strncat(msg, s, l);
-	l -= strlen(s);
-    }
-    if (rc & CPIOERR_CHECK_ERRNO) {
-	s = _(" failed - ");
-	if (l > 0) strncat(msg, s, l);
-	l -= strlen(s);
-	if (l > 0) strncat(msg, strerror(myerrno), l);
-    }
-    return msg;
-}
-
-static int copyFile(struct ourfd * inFd, struct ourfd * outFd, 
-	     struct cpioHeader * chp, struct cpioCrcPhysicalHeader * pHdr) {
-    char buf[8192];
-    int amount;
-    size_t size = chp->size;
-
-    amount = strlen(chp->path) + 1;
-    memcpy(pHdr->magic, CPIO_NEWC_MAGIC, sizeof(pHdr->magic));
-
-    gzip_write(outFd->fd, pHdr, PHYS_HDR_SIZE);
-    gzip_write(outFd->fd, chp->path, amount);
-
-    outFd->pos += PHYS_HDR_SIZE + amount;
-
-    padoutfd(outFd, &outFd->pos, 4);
-
-    while (size) {
-	amount = ourread(inFd, buf, size > sizeof(buf) ? sizeof(buf) : size);
-	gzip_write(outFd->fd, buf, amount);
-	size -= amount;
-    }
-
-    outFd->pos += chp->size;
-
-    padoutfd(outFd, &outFd->pos, 4);
-
-    return 0;
-}
-
-int myCpioFilterArchive(gzFile inStream, gzFile outStream, char ** patterns) {
-    struct ourfd inFd, outFd;
-    char ** aPattern;
-    struct cpioHeader ch;
-    int rc;
-    struct cpioCrcPhysicalHeader pHeader;
-
-    inFd.fd = inStream;
-    inFd.pos = 0;
-    outFd.fd = outStream;
-    outFd.pos = 0;
-
-    do {
-	if ((rc = getNextHeader(&inFd, &ch, &pHeader))) {
-	    fprintf(stderr, _("error %d reading header: %s\n"), rc, 
-		    myCpioStrerror(rc));
-	    return CPIOERR_BAD_HEADER;
-	}
-
-	if (!strcmp(ch.path, TRAILER)) {
-	    free(ch.path);
-	    break;
-	}
-
-	for (aPattern = patterns; *aPattern; aPattern++)
-	    if (!fnmatch(*aPattern, ch.path, FNM_PATHNAME | FNM_PERIOD))
-		break;
-
-	if (!*aPattern)
-	    eatBytes(&inFd, ch.size);
-	else
-	    copyFile(&inFd, &outFd, &ch, &pHeader);
-
-	padinfd(&inFd, 4);
-
-	free(ch.path);
-    } while (1 && !rc);
-
-    memset(&pHeader, '0', sizeof(pHeader));
-    memcpy(pHeader.magic, CPIO_NEWC_MAGIC, sizeof(pHeader.magic));
-    memcpy(pHeader.nlink, "00000001", 8);
-    memcpy(pHeader.namesize, "0000000b", 8);
-    gzip_write(outFd.fd, &pHeader, PHYS_HDR_SIZE);
-    gzip_write(outFd.fd, "TRAILER!!!", 11);
-
-    outFd.pos += PHYS_HDR_SIZE + 11;
-
-    if ((rc = padoutfd(&outFd, &outFd.pos, 4)))
-	return rc;
-
-    if ((rc = padoutfd(&outFd, &outFd.pos, 512)))
-	return rc;
-
-    return 0;
-}
diff --git a/isys/vio.c b/isys/vio.c
deleted file mode 100644
index 9b06a3e..0000000
--- a/isys/vio.c
+++ /dev/null
@@ -1,106 +0,0 @@
-/*
- * vio.c - probing for vio devices on the iSeries (viocd and viodasd)
- *
- * Copyright (C) 2003  Red Hat, Inc.  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 as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * 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, see <http://www.gnu.org/licenses/>.
- *
- * Author(s): Jeremy Katz <katzj@xxxxxxxxxx>
- */
-
-#include <ctype.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-
-#if defined(__powerpc__)
-static int readFD (int fd, char **buf)
-{
-    char *p;
-    size_t size = 4096;
-    int s, filesize;
-
-    *buf = malloc (size);
-    if (*buf == 0)
-	return -1;
-
-    filesize = 0;
-    do {
-	p = &(*buf) [filesize];
-	s = read (fd, p, 4096);
-	if (s < 0)
-	    break;
-	filesize += s;
-	if (s == 0)
-	    break;
-	size += 4096;
-	*buf = realloc (*buf, size);
-    } while (1);
-
-    if (filesize == 0 && s < 0) {
-	free (*buf);
-	*buf = NULL;
-	return -1;
-    }
-
-    return filesize;
-}
-#endif
-
-int isVioConsole(void) {
-#if !defined(__powerpc__)
-    return 0;
-#else
-    int fd, i;
-    char *buf, *start;
-    char driver[50], device[50];
-    static int isviocons = -1;
-
-    if (isviocons != -1)
-	return isviocons;
-    
-    fd = open("/proc/tty/drivers", O_RDONLY);
-    if (fd < 0) {
-	fprintf(stderr, "failed to open /proc/tty/drivers!\n");
-	return 0;
-    }
-    i = readFD(fd, &buf);
-    if (i < 1) {
-        close(fd);
-	fprintf(stderr, "error reading /proc/tty/drivers!\n");
-        return 0;
-    }
-    close(fd);
-    buf[i] = '\0';
-
-    isviocons = 0;
-    start = buf;
-    while (start && *start) {
-	if (sscanf(start, "%s %s", (char *) &driver, (char *) &device) == 2) {
-	    if (!strcmp(driver, "vioconsole") && !strcmp(device, "/dev/tty")) {
-		isviocons = 1;
-		break;
-	    }
-	}		
-        start = strchr(start, '\n');
-        if (start)
-	    start++;
-    }
-    free(buf);
-    return isviocons;
-#endif
-}
diff --git a/iutil.py b/iutil.py
deleted file mode 100644
index b2dabd1..0000000
--- a/iutil.py
+++ /dev/null
@@ -1,1073 +0,0 @@
-#
-# iutil.py - generic install utility functions
-#
-# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007
-# Red Hat, Inc.  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 as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# 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, see <http://www.gnu.org/licenses/>.
-#
-# Author(s): Erik Troan <ewt@xxxxxxxxxx>
-#
-
-import glob
-import os, string, stat, sys
-import signal
-import os.path
-from errno import *
-import warnings
-import subprocess
-from flags import flags
-from constants import *
-import re
-import threading
-
-import gettext
-_ = lambda x: gettext.ldgettext("anaconda", x)
-
-import logging
-log = logging.getLogger("anaconda")
-program_log = logging.getLogger("program")
-
-#Python reimplementation of the shell tee process, so we can
-#feed the pipe output into two places at the same time
-class tee(threading.Thread):
-    def __init__(self, inputdesc, outputdesc, logmethod):
-        threading.Thread.__init__(self)
-        self.inputdesc = os.fdopen(inputdesc, "r")
-        self.outputdesc = outputdesc
-        self.logmethod = logmethod
-        self.running = True
-
-    def run(self):
-        while self.running:
-            data = self.inputdesc.readline()
-            if data == "":
-                self.running = False
-            else:
-                self.logmethod(data.rstrip('\n'))
-                os.write(self.outputdesc, data)
-
-    def stop(self):
-        self.running = False
-        return self
-
-## Run an external program and redirect the output to a file.
-# @param command The command to run.
-# @param argv A list of arguments.
-# @param stdin The file descriptor to read stdin from.
-# @param stdout The file descriptor to redirect stdout to.
-# @param stderr The file descriptor to redirect stderr to.
-# @param root The directory to chroot to before running command.
-# @return The return code of command.
-def execWithRedirect(command, argv, stdin = None, stdout = None,
-                     stderr = None, root = '/'):
-    def chroot ():
-        os.chroot(root)
-
-    stdinclose = stdoutclose = stderrclose = lambda : None
-
-    argv = list(argv)
-    if isinstance(stdin, str):
-        if os.access(stdin, os.R_OK):
-            stdin = os.open(stdin, os.O_RDONLY)
-            stdinclose = lambda : os.close(stdin)
-        else:
-            stdin = sys.stdin.fileno()
-    elif isinstance(stdin, int):
-        pass
-    elif stdin is None or not isinstance(stdin, file):
-        stdin = sys.stdin.fileno()
-
-    if isinstance(stdout, str):
-        stdout = os.open(stdout, os.O_RDWR|os.O_CREAT)
-        stdoutclose = lambda : os.close(stdout)
-    elif isinstance(stdout, int):
-        pass
-    elif stdout is None or not isinstance(stdout, file):
-        stdout = sys.stdout.fileno()
-
-    if isinstance(stderr, str):
-        stderr = os.open(stderr, os.O_RDWR|os.O_CREAT)
-        stderrclose = lambda : os.close(stderr)
-    elif isinstance(stderr, int):
-        pass
-    elif stderr is None or not isinstance(stderr, file):
-        stderr = sys.stderr.fileno()
-
-    program_log.info("Running... %s" % (" ".join([command] + argv),))
-
-    #prepare os pipes for feeding tee proceses
-    pstdout, pstdin = os.pipe()
-    perrout, perrin = os.pipe()
-   
-    env = os.environ.copy()
-    env.update({"LC_ALL": "C"})
-
-    try:
-        #prepare tee proceses
-        proc_std = tee(pstdout, stdout, program_log.info)
-        proc_err = tee(perrout, stderr, program_log.error)
-
-        #start monitoring the outputs
-        proc_std.start()
-        proc_err.start()
-
-        proc = subprocess.Popen([command] + argv, stdin=stdin,
-                                stdout=pstdin,
-                                stderr=perrin,
-                                preexec_fn=chroot, cwd=root,
-                                env=env)
-
-        proc.wait()
-        ret = proc.returncode
-
-        #close the input ends of pipes so we get EOF in the tee processes
-        os.close(pstdin)
-        os.close(perrin)
-
-        #wait for the output to be written and destroy them
-        proc_std.join()
-        del proc_std
-
-        proc_err.join()
-        del proc_err
-
-        stdinclose()
-        stdoutclose()
-        stderrclose()
-    except OSError as e:
-        errstr = "Error running %s: %s" % (command, e.strerror)
-        log.error(errstr)
-        program_log.error(errstr)
-        #close the input ends of pipes so we get EOF in the tee processes
-        os.close(pstdin)
-        os.close(perrin)
-        proc_std.join()
-        proc_err.join()
-
-        stdinclose()
-        stdoutclose()
-        stderrclose()
-        raise RuntimeError, errstr
-
-    return ret
-
-## Run an external program and capture standard out.
-# @param command The command to run.
-# @param argv A list of arguments.
-# @param stdin The file descriptor to read stdin from.
-# @param stderr The file descriptor to redirect stderr to.
-# @param root The directory to chroot to before running command.
-# @return The output of command from stdout.
-def execWithCapture(command, argv, stdin = None, stderr = None, root='/'):
-    def chroot():
-        os.chroot(root)
-
-    def closefds ():
-        stdinclose()
-        stderrclose()
-
-    stdinclose = stderrclose = lambda : None
-    rc = ""
-    argv = list(argv)
-
-    if isinstance(stdin, str):
-        if os.access(stdin, os.R_OK):
-            stdin = os.open(stdin, os.O_RDONLY)
-            stdinclose = lambda : os.close(stdin)
-        else:
-            stdin = sys.stdin.fileno()
-    elif isinstance(stdin, int):
-        pass
-    elif stdin is None or not isinstance(stdin, file):
-        stdin = sys.stdin.fileno()
-
-    if isinstance(stderr, str):
-        stderr = os.open(stderr, os.O_RDWR|os.O_CREAT)
-        stderrclose = lambda : os.close(stderr)
-    elif isinstance(stderr, int):
-        pass
-    elif stderr is None or not isinstance(stderr, file):
-        stderr = sys.stderr.fileno()
-
-    program_log.info("Running... %s" % (" ".join([command] + argv),))
-
-    env = os.environ.copy()
-    env.update({"LC_ALL": "C"})
-
-    try:
-        proc = subprocess.Popen([command] + argv, stdin=stdin,
-                                stdout=subprocess.PIPE,
-                                stderr=subprocess.PIPE,
-                                preexec_fn=chroot, cwd=root,
-                                env=env)
-
-        while True:
-            (outStr, errStr) = proc.communicate()
-            if outStr:
-                map(program_log.info, outStr.splitlines())
-                rc += outStr
-            if errStr:
-                map(program_log.error, errStr.splitlines())
-                os.write(stderr, errStr)
-
-            if proc.returncode is not None:
-                break
-    except OSError as e:
-        log.error ("Error running " + command + ": " + e.strerror)
-        closefds()
-        raise RuntimeError, "Error running " + command + ": " + e.strerror
-
-    closefds()
-    return rc
-
-def execWithCallback(command, argv, stdin = None, stdout = None,
-                     stderr = None, echo = True, callback = None,
-                     callback_data = None, root = '/'):
-    def chroot():
-        os.chroot(root)
-
-    def closefds ():
-        stdinclose()
-        stdoutclose()
-        stderrclose()
-
-    stdinclose = stdoutclose = stderrclose = lambda : None
-
-    argv = list(argv)
-    if isinstance(stdin, str):
-        if os.access(stdin, os.R_OK):
-            stdin = os.open(stdin, os.O_RDONLY)
-            stdinclose = lambda : os.close(stdin)
-        else:
-            stdin = sys.stdin.fileno()
-    elif isinstance(stdin, int):
-        pass
-    elif stdin is None or not isinstance(stdin, file):
-        stdin = sys.stdin.fileno()
-
-    if isinstance(stdout, str):
-        stdout = os.open(stdout, os.O_RDWR|os.O_CREAT)
-        stdoutclose = lambda : os.close(stdout)
-    elif isinstance(stdout, int):
-        pass
-    elif stdout is None or not isinstance(stdout, file):
-        stdout = sys.stdout.fileno()
-
-    if isinstance(stderr, str):
-        stderr = os.open(stderr, os.O_RDWR|os.O_CREAT)
-        stderrclose = lambda : os.close(stderr)
-    elif isinstance(stderr, int):
-        pass
-    elif stderr is None or not isinstance(stderr, file):
-        stderr = sys.stderr.fileno()
-
-    program_log.info("Running... %s" % (" ".join([command] + argv),))
-
-    p = os.pipe()
-    p_stderr = os.pipe()
-    childpid = os.fork()
-    if not childpid:
-        os.close(p[0])
-        os.close(p_stderr[0])
-        os.dup2(p[1], 1)
-        os.dup2(p_stderr[1], 2)
-        os.dup2(stdin, 0)
-        os.close(stdin)
-        os.close(p[1])
-        os.close(p_stderr[1])
-
-        os.execvp(command, [command] + argv)
-        os._exit(1)
-
-    os.close(p[1])
-    os.close(p_stderr[1])
-
-    logline = ''
-    while 1:
-        try:
-            s = os.read(p[0], 1)
-        except OSError as e:
-            if e.errno != 4:
-                raise IOError, e.args
-
-        if echo:
-            os.write(stdout, s)
-
-        if s == '\n':
-            program_log.info(logline)
-            logline = ''
-        else:
-            logline += s
-
-        if callback:
-            callback(s, callback_data=callback_data)
-
-        # break out early if the sub-process changes status.
-        # no need to flush the stream if the process has exited
-        try:
-            (pid, status) = os.waitpid(childpid,os.WNOHANG)
-            if pid != 0:
-                break
-        except OSError as e:
-            log.critical("exception from waitpid: %s %s" %(e.errno, e.strerror))
-
-        if len(s) < 1:
-            break
-    if len(logline) > 0:
-        program_log.info(logline)
-
-    log_errors = ''
-    while 1:
-        try:
-            err = os.read(p_stderr[0], 128)
-        except OSError as e:
-            if e.errno != 4:
-                raise IOError, e.args
-            break
-        log_errors += err
-        if len(err) < 1:
-            break
-    map(program_log.error, log_errors.splitlines())
-    os.close(p[0])
-    os.close(p_stderr[0])
-
-    try:
-        #if we didn't already get our child's exit status above, do so now.
-        if not pid:
-            (pid, status) = os.waitpid(childpid, 0)
-    except OSError as e:
-        log.critical("exception from waitpid: %s %s" %(e.errno, e.strerror))
-
-    closefds()
-    # *shrug*  no clue why this would happen, but hope that things are fine
-    if status is None:
-        return 0
-
-    if os.WIFEXITED(status):
-        return os.WEXITSTATUS(status)
-
-    return 1
-
-def _pulseProgressCallback(data, callback_data=None):
-    if callback_data:
-        callback_data.pulse()
-
-def execWithPulseProgress(command, argv, stdin = None, stdout = None,
-                          stderr = None, echo = True, progress = None,
-                          root = '/'):
-    return execWithCallback(command, argv, stdin=stdin, stdout=stdout,
-                     stderr=stderr, echo=echo, callback=_pulseProgressCallback,
-                     callback_data=progress, root=root)
-
-## Run a shell.
-def execConsole():
-    try:
-        proc = subprocess.Popen(["/bin/sh"])
-        proc.wait()
-    except OSError as e:
-        raise RuntimeError, "Error running /bin/sh: " + e.strerror
-
-## Get the size of a directory and all its subdirectories.
-# @param dir The name of the directory to find the size of.
-# @return The size of the directory in kilobytes.
-def getDirSize(dir):
-    def getSubdirSize(dir):
-	# returns size in bytes
-        mydev = os.lstat(dir)[stat.ST_DEV]
-
-        dsize = 0
-        for f in os.listdir(dir):
-	    curpath = '%s/%s' % (dir, f)
-	    sinfo = os.lstat(curpath)
-            if stat.S_ISDIR(sinfo[stat.ST_MODE]):
-                if mydev == sinfo[stat.ST_DEV]:
-                    dsize += getSubdirSize(curpath)
-            elif stat.S_ISREG(sinfo[stat.ST_MODE]):
-                dsize += sinfo[stat.ST_SIZE]
-            else:
-                pass
-
-        return dsize
-    return getSubdirSize(dir)/1024
-
-## Get the amount of RAM not used by /tmp.
-# @return The amount of available memory in kilobytes.
-def memAvailable():
-    tram = memInstalled()
-
-    ramused = getDirSize("/tmp")
-    return tram - ramused
-
-## Get the amount of RAM installed in the machine.
-# @return The amount of installed memory in kilobytes.
-def memInstalled():
-    f = open("/proc/meminfo", "r")
-    lines = f.readlines()
-    f.close()
-
-    for l in lines:
-        if l.startswith("MemTotal:"):
-            fields = string.split(l)
-            mem = fields[1]
-            break
-
-    return int(mem)
-
-## Suggest the size of the swap partition that will be created.
-# @param quiet Should size information be logged?
-# @return A tuple of the minimum and maximum swap size, in megabytes.
-def swapSuggestion(quiet=0):
-    mem = memInstalled()/1024
-    mem = ((mem/16)+1)*16
-    if not quiet:
-	log.info("Detected %sM of memory", mem)
-	
-    if mem <= 256:
-        minswap = 256
-        maxswap = 512
-    else:
-        if mem > 2048:
-            minswap = 1024
-            maxswap = 2048 + mem
-        else:
-            minswap = mem
-            maxswap = 2*mem
-
-    if isS390():
-        minswap = 1
-
-    if not quiet:
-	log.info("Swap attempt of %sM to %sM", minswap, maxswap)
-
-    return (minswap, maxswap)
-
-## Create a directory path.  Don't fail if the directory already exists.
-# @param dir The directory path to create.
-def mkdirChain(dir):
-    try:
-        os.makedirs(dir, 0755)
-    except OSError as e:
-        try:
-            if e.errno == EEXIST and stat.S_ISDIR(os.stat(dir).st_mode):
-                return
-        except:
-            pass
-
-        log.error("could not create directory %s: %s" % (dir, e.strerror))
-
-## Get the total amount of swap memory.
-# @return The total amount of swap memory in kilobytes, or 0 if unknown.
-def swapAmount():
-    f = open("/proc/meminfo", "r")
-    lines = f.readlines()
-    f.close()
-
-    for l in lines:
-        if l.startswith("SwapTotal:"):
-            fields = string.split(l)
-            return int(fields[1])
-    return 0
-
-## Copy a device node.
-# Copies a device node by looking at the device type, major and minor device
-# numbers, and doing a mknod on the new device name.
-#
-# @param src The name of the source device node.
-# @param dest The name of the new device node to create.
-def copyDeviceNode(src, dest):
-    filestat = os.lstat(src)
-    mode = filestat[stat.ST_MODE]
-    if stat.S_ISBLK(mode):
-        type = stat.S_IFBLK
-    elif stat.S_ISCHR(mode):
-        type = stat.S_IFCHR
-    else:
-        # XXX should we just fallback to copying normally?
-        raise RuntimeError, "Tried to copy %s which isn't a device node" % (src,)
-
-    os.mknod(dest, mode | type, filestat.st_rdev)
-
-## Get the SPARC machine variety type.
-# @return The SPARC machine type, or 0 if not SPARC.
-def getSparcMachine():
-    if not isSparc():
-        return 0
-
-    machine = None
-
-
-    f = open('/proc/cpuinfo', 'r')
-    lines = f.readlines()
-    f.close()
-    for line in lines:
-        if line.find('type') != -1:
-            machine = line.split(':')[1].strip()
-            return machine
-
-    return None
-
-## Get the PPC machine variety type.
-# @return The PPC machine type, or 0 if not PPC.
-def getPPCMachine():
-    if not isPPC():
-        return 0
-
-    ppcMachine = None
-    machine = None
-    platform = None
-
-    # ppc machine hash
-    ppcType = { 'Mac'      : 'PMac',
-                'Book'     : 'PMac',
-                'CHRP IBM' : 'pSeries',
-                'Pegasos'  : 'Pegasos',
-                'Efika'    : 'Efika',
-                'iSeries'  : 'iSeries',
-                'pSeries'  : 'pSeries',
-                'PReP'     : 'PReP',
-                'CHRP'     : 'pSeries',
-                'Amiga'    : 'APUS',
-                'Gemini'   : 'Gemini',
-                'Shiner'   : 'ANS',
-                'BRIQ'     : 'BRIQ',
-                'Teron'    : 'Teron',
-                'AmigaOne' : 'Teron',
-                'Maple'    : 'pSeries',
-                'Cell'     : 'pSeries',
-                'Momentum' : 'pSeries',
-                'PS3'      : 'PS3'
-                }
-
-    f = open('/proc/cpuinfo', 'r')
-    lines = f.readlines()
-    f.close()
-    for line in lines:
-        if line.find('machine') != -1:
-            machine = line.split(':')[1]
-        elif line.find('platform') != -1:
-            platform = line.split(':')[1]
-
-    for part in (machine, platform):
-        if ppcMachine is None and part is not None:
-            for type in ppcType.items():
-                if part.find(type[0]) != -1:
-                    ppcMachine = type[1]
-
-    if ppcMachine is None:
-        log.warning("Unable to find PowerPC machine type")
-    elif ppcMachine == 0:
-        log.warning("Unknown PowerPC machine type: %s" %(ppcMachine,))
-
-    return ppcMachine
-
-## Get the powermac machine ID.
-# @return The powermac machine id, or 0 if not PPC.
-def getPPCMacID():
-    machine = None
-
-    if not isPPC():
-        return 0
-    if getPPCMachine() != "PMac":
-        return 0
-
-    f = open('/proc/cpuinfo', 'r')
-    lines = f.readlines()
-    f.close()
-    for line in lines:
-      if line.find('machine') != -1:
-        machine = line.split(':')[1]
-        machine = machine.strip()
-        return machine
-
-    log.warning("No Power Mac machine id")
-    return 0
-
-## Get the powermac generation.
-# @return The powermac generation, or 0 if not powermac.
-def getPPCMacGen():
-    # XXX: should NuBus be here?
-    pmacGen = ['OldWorld', 'NewWorld', 'NuBus']
-
-    if not isPPC():
-        return 0
-    if getPPCMachine() != "PMac":
-        return 0
-
-    f = open('/proc/cpuinfo', 'r')
-    lines = f.readlines()
-    f.close()
-    gen = None
-    for line in lines:
-      if line.find('pmac-generation') != -1:
-        gen = line.split(':')[1]
-        break
-
-    if gen is None:
-        log.warning("Unable to find pmac-generation")
-
-    for type in pmacGen:
-      if gen.find(type) != -1:
-          return type
-
-    log.warning("Unknown Power Mac generation: %s" %(gen,))
-    return 0
-
-## Determine if the hardware is an iBook or PowerBook
-# @return 1 if so, 0 otherwise.
-def getPPCMacBook():
-    if not isPPC():
-        return 0
-    if getPPCMachine() != "PMac":
-        return 0
-
-    f = open('/proc/cpuinfo', 'r')
-    lines = f.readlines()
-    f.close()
-
-    for line in lines:
-      if not string.find(string.lower(line), 'book') == -1:
-        return 1
-    return 0
-
-cell = None
-## Determine if the hardware is the Cell platform.
-# @return True if so, False otherwise.
-def isCell():
-    global cell
-    if cell is not None:
-        return cell
-
-    cell = False
-    if not isPPC():
-        return cell
-
-    f = open('/proc/cpuinfo', 'r')
-    lines = f.readlines()
-    f.close()
-
-    for line in lines:
-      if not string.find(line, 'Cell') == -1:
-          cell = True
-
-    return cell
-
-mactel = None
-## Determine if the hardware is an Intel-based Apple Mac.
-# @return True if so, False otherwise.
-def isMactel():
-    global mactel
-    if mactel is not None:
-        return mactel
-
-    if not isX86():
-        mactel = False
-    elif not os.path.exists("/usr/sbin/dmidecode"):
-        mactel = False
-    else:
-        buf = execWithCapture("/usr/sbin/dmidecode",
-                              ["dmidecode", "-s", "system-manufacturer"])
-        if buf.lower().find("apple") != -1:
-            mactel = True
-        else:
-            mactel = False
-    return mactel
-
-efi = None
-## Determine if the hardware supports EFI.
-# @return True if so, False otherwise.
-def isEfi():
-    global efi
-    if efi is not None:
-        return efi
-
-    efi = False
-    # XXX need to make sure efivars is loaded...
-    if os.path.exists("/sys/firmware/efi"):
-        efi = True
-
-    return efi
-
-## Generate the /etc/rpm/macros file.
-# @param root The root of the filesystem to create the files in.
-def writeRpmPlatform(root="/"):
-    import rpmUtils.arch
-
-    if os.access("%s/etc/rpm/platform" %(root,), os.R_OK):
-        return
-    if not os.access("%s/etc/rpm" %(root,), os.X_OK):
-        os.mkdir("%s/etc/rpm" %(root,))
-
-    myarch = rpmUtils.arch.canonArch
-
-    # now allow an override with rpmarch=i586 on the command line (#101971)
-    if flags.targetarch != None:
-        myarch = flags.targetarch
-
-    # now make the current install believe it, too
-    rpmUtils.arch.canonArch = myarch
-
-    # FIXME: writing /etc/rpm/macros feels wrong somehow
-    # temporary workaround for #92285
-    if not (myarch.startswith("ppc64") or
-            myarch in ("s390x", "sparc64", "x86_64", "ia64")):
-        return
-    if os.access("%s/etc/rpm/macros" %(root,), os.R_OK):
-        if myarch.startswith("ppc64") or myarch == "sparc64":
-            f = open("%s/etc/rpm/macros" %(root,), 'r+')
-            lines = f.readlines()
-            addPrefer = True
-            for line in lines:
-                if line.startswith("%_prefer_color"):
-                    addPrefer = False
-            if addPrefer:    
-                f.write("%_prefer_color   1\n")
-            f.close()
-            return
-        else:
-            return
-
-    f = open("%s/etc/rpm/macros" %(root,), 'w+')
-    f.write("%_transaction_color   3\n")
-    if myarch.startswith("ppc64") or myarch == "sparc64":
-        f.write("%_prefer_color   1\n")
-
-    f.close()
-
-# Architecture checking functions
-
-def isX86(bits=None):
-    arch = os.uname()[4]
-
-    # x86 platforms include:
-    #     i*86
-    #     athlon*
-    #     x86_64
-    #     amd*
-    #     ia32e
-    if bits is None:
-        if (arch.startswith('i') and arch.endswith('86')) or \
-           arch.startswith('athlon') or arch.startswith('amd') or \
-           arch == 'x86_64' or arch == 'ia32e':
-            return True
-    elif bits == 32:
-        if arch.startswith('i') and arch.endswith('86'):
-            return True
-    elif bits == 64:
-        if arch.startswith('athlon') or arch.startswith('amd') or \
-           arch == 'x86_64' or arch == 'ia32e':
-            return True
-
-    return False
-
-def isPPC():
-    return os.uname()[4].startswith('ppc')
-
-def isS390():
-    return os.uname()[4].startswith('s390')
-
-def isIA64():
-    return os.uname()[4] == 'ia64'
-
-def isAlpha():
-    return os.uname()[4].startswith('alpha')
-
-def isSparc():
-    return os.uname()[4].startswith('sparc')
-
-def getArch():
-    if isX86(bits=32):
-        return 'i386'
-    elif isX86(bits=64):
-        return 'x86_64'
-    elif isPPC():
-        return 'ppc'
-    elif isAlpha():
-        return 'alpha'
-    elif isSparc():
-        return 'sparc'
-    else:
-        return os.uname()[4]
-
-def isConsoleOnVirtualTerminal():
-    # XXX PJFIX is there some way to ask the kernel this instead?
-    if isS390():
-        return False
-    return not flags.serial
-
-def strip_markup(text):
-    if text.find("<") == -1:
-        return text
-    r = ""
-    inTag = False
-    for c in text:
-        if c == ">" and inTag:
-            inTag = False
-            continue
-        elif c == "<" and not inTag:
-            inTag = True
-            continue
-        elif not inTag:
-            r += c
-    return r.encode("utf-8")
-
-def notify_kernel(path, action="change"):
-    """ Signal the kernel that the specified device has changed. """
-    log.debug("notifying kernel of '%s' event on device %s" % (action, path))
-    path = os.path.join(path, "uevent")
-    if not path.startswith("/sys/") or not os.access(path, os.W_OK):
-        log.debug("sysfs path '%s' invalid" % path)
-        raise ValueError("invalid sysfs path")
-
-    f = open(path, "a")
-    f.write("%s\n" % action)
-    f.close()
-
-def get_sysfs_path_by_name(dev_name, class_name="block"):
-    dev_name = os.path.basename(dev_name)
-    sysfs_class_dir = "/sys/class/%s" % class_name
-    dev_path = os.path.join(sysfs_class_dir, dev_name)
-    if os.path.exists(dev_path):
-        return dev_path
-
-def numeric_type(num):
-    """ Verify that a value is given as a numeric data type.
-
-        Return the number if the type is sensible or raise ValueError
-        if not.
-    """
-    if num is None:
-        num = 0
-    elif not (isinstance(num, int) or \
-              isinstance(num, long) or \
-              isinstance(num, float)):
-        raise ValueError("value (%s) must be either a number or None" % num)
-
-    return num
-
-def writeReiplMethod(reipl_path, reipl_type):
-    filename = "%s/reipl_type" % (reipl_path,)
-
-    try:
-        f = open(filename, "w")
-    except Exception, e:
-        message = _("Error: On open, cannot set reIPL method to %(reipl_type)s "
-                    "(%(filename)s: %(e)s)" % {'reipl_type': reipl_type,
-                                               'filename': filename,
-                                               'e': e})
-        log.warning(message)
-        raise Exception (message)
-
-    try:
-        f.write(reipl_type)
-        f.flush()
-    except Exception, e:
-        message = _("Error: On write, cannot set reIPL method to "
-                    "%(reipl_type)s (%(filename)s: %(e)s)" \
-                  % {'reipl_type': reipl_type, 'filename': filename, 'e': e})
-        log.warning(message)
-        raise Exception (message)
-
-    try:
-        f.close()
-    except Exception, e:
-        message = _("Error: On close, cannot set reIPL method to "
-                    "%(reipl_type)s (%(filename)s: %(e)s)" \
-                  % {'reipl_type': reipl_type, 'filename': filename, 'e': e})
-        log.warning(message)
-        raise Exception (message)
-
-def reIPLonCCW(iplsubdev, reipl_path):
-    device = "<unknown>"
-
-    try:
-        device = os.readlink("/sys/block/" + iplsubdev + "/device").split('/')[-1]
-
-        writeReiplMethod(reipl_path, 'ccw')
-
-        try:
-            f = open("%s/ccw/device" % (reipl_path,), "w")
-            f.write(device)
-            f.close()
-        except Exception, e:
-            message = _("Error: Could not set %(device)s as reIPL device "
-                        "(%(e)s)" % {'device': device, 'e': e})
-            log.warning(message)
-            raise Exception (message)
-
-        try:
-            f = open("%s/ccw/loadparm" % (reipl_path,), "w")
-            f.write("\n")
-            f.close()
-        except Exception, e:
-            message = _("Error: Could not reset loadparm (%s)" % (e,))
-            log.warning(message)
-            raise Exception (message)
-
-        try:
-            f = open("%s/ccw/parm" % (reipl_path,), "w")
-            f.write("\n")
-            f.close()
-        except Exception, e:
-            message = _("Warning: Could not reset parm (%s)" % (e,))
-            log.warning(message)
-            # do NOT raise an exception since this might not exist or not be writable
-
-        log.info("ccw reIPL using DASD %s" % (device,))
-
-    except Exception, e:
-        try:
-            message = e.args[0]
-        except:
-            message = e.__str__ ()
-        log.info("Caught exception %s", (message,))
-        return (message,
-                (_("After shutdown, please perform a manual IPL from DASD device %s to continue "
-                   "installation") % (device,)))
-
-    return None
-
-def reIPLonFCP(iplsubdev, reipl_path):
-    fcpvalue = { "device": "<unknown>", "wwpn": "<unknown>", "lun": "<unknown>" }
-
-    try:
-        syspath = "/sys/block/" + iplsubdev + "/device"
-
-        fcpprops = [ ("hba_id", "device"), ("wwpn", "wwpn"), ("fcp_lun", "lun") ]
-
-        # Read in values to change.
-        # This way, if we can't set FCP mode, we can tell the user what to manually reboot to.
-        for (syspath_property, reipl_property) in fcpprops:
-            try:
-                f = open(syspath + "/" + syspath_property, "r")
-                value = f.read().strip()
-                fcpvalue[reipl_property] = value
-                f.close()
-            except Exception, e:
-                message = _("Error: reading FCP property %(syspath_property)s "
-                            "for reIPL (%(e)s)" \
-                          % {'syspath_property': syspath_property, 'e': e})
-                log.warning(message)
-                raise Exception (message)
-
-        writeReiplMethod(reipl_path, 'fcp')
-
-        # Write out necessary parameters.
-        for (syspath_property, reipl_property) in fcpprops:
-            try:
-                f = open("%s/fcp/%s" % (reipl_path, reipl_property,), "w")
-                f.write(fcpvalue[reipl_property])
-                f.close()
-            except Exception, e:
-                message = _("Error: writing FCP property %(reipl_property)s "
-                            "for reIPL (%(e)s)" \
-                          % {'reipl_property': reipl_property, 'e': e})
-                log.warning(message)
-                raise Exception (message)
-
-        defaultprops = [ ("bootprog", "0"), ("br_lba", "0") ]
-
-        # Write out default parameters.
-        for (reipl_property, default_value) in defaultprops:
-            try:
-                f = open("%s/fcp/%s" % (reipl_path, reipl_property,), "w")
-                f.write (default_value)
-                f.close()
-            except Exception, e:
-                message = _("Error: writing default FCP property "
-                            "%(reipl_property)s for reIPL (%(e)s)" \
-                          % {'reipl_property': reipl_property, 'e': e})
-                log.warning(message)
-                raise Exception (message)
-
-        log.info("fcp reIPL using FCP %(device)s, WWPN %(wwpn)s, LUN %(lun)s" % (fcpvalue))
-
-    except Exception, e:
-        try:
-            message = e.args[0]
-        except:
-            message = e.__str__ ()
-        log.info("Caught exception %s", (message,))
-        return (message,
-                (_("After shutdown, please perform a manual IPL from FCP %(device)s with WWPN %(wwpn)s "
-                   "and LUN %(lun)s to continue installation") % (fcpvalue)))
-
-    return None
-
-
-def reIPLtrigger(anaconda):
-    if not isS390():
-        return
-    if anaconda.canReIPL:
-        log.info("reIPL configuration successful => reboot")
-        os.kill(os.getppid(), signal.SIGUSR2)
-    else:
-        log.info("reIPL configuration failed => halt")
-        os.kill(os.getppid(), signal.SIGUSR1)
-
-def reIPL(anaconda, loader_pid):
-    instruction = _("After shutdown, please perform a manual IPL from the device "
-                    "now containing /boot to continue installation")
-
-    reipl_path = "/sys/firmware/reipl"
-
-    try:
-        ipldev = anaconda.platform.bootDevice().disk.name
-    except:
-        ipldev = None
-
-    if ipldev is None:
-        message = _("Error determining boot device's disk name")
-        log.warning(message)
-        return (message, instruction)
-
-    message = (_("The mount point /boot or / is on a disk that we are not familiar with"), instruction)
-    if ipldev.startswith("dasd"):
-        message = reIPLonCCW(ipldev, reipl_path)
-    elif ipldev.startswith("sd"):
-        message = reIPLonFCP(ipldev, reipl_path)
-
-    if message is None:
-        anaconda.canReIPL = True
-    else:
-        anaconda.canReIPL = False
-        log.info(message)
-
-    reIPLtrigger(anaconda)
-
-    # the final return is either None if reipl configuration worked (=> reboot),
-    # or a two-item list with errorMessage and rebootInstr (=> shutdown)
-    return message
-
-def resetRpmDb(rootdir):
-    for rpmfile in glob.glob("%s/var/lib/rpm/__db.*" % rootdir):
-        try:
-            os.unlink(rpmfile)
-        except Exception, e:
-            log.debug("error %s removing file: %s" %(e,rpmfile))
-
-def parseNfsUrl(nfsurl):
-    options = ''
-    host = ''
-    path = ''
-    if nfsurl:
-        s = nfsurl.split(":")
-        s.pop(0)
-        if len(s) >= 3:
-            (options, host, path) = s[:3]
-        elif len(s) == 2:
-            (host, path) = s
-        else:
-            host = s[0]
-    return (options, host, path)
diff --git a/iw/DeviceSelector.py b/iw/DeviceSelector.py
deleted file mode 100644
index 33a7fe3..0000000
--- a/iw/DeviceSelector.py
+++ /dev/null
@@ -1,217 +0,0 @@
-#
-# Filtering UI for the simple path through the storage code.
-#
-# Copyright (C) 2009  Red Hat, Inc.
-# 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 as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# 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, see <http://www.gnu.org/licenses/>.
-#
-
-import gtk, gobject
-import gtk.glade
-import gui
-
-import gettext
-_ = lambda x: gettext.ldgettext("anaconda", x)
-
-# The column that holds a python object containing information about the
-# device in each row.  This value really shouldn't be overridden.
-OBJECT_COL = 0
-
-# These columns can be overridden with the active= and visible= parameters to
-# __init__.  active indicates which column tracks whether the row is checked
-# by default, and visible indicates which column tracks whether the row is
-# seen or not.
-VISIBLE_COL = 1
-ACTIVE_COL = 2
-
-# This should not be overridden.  It controls whether or not a row may be
-# deselected.  Rows with this column set will stay in selected or not
-# (whichever they were initialized to) permanently.
-IMMUTABLE_COL = 3
-
-class DeviceDisplayer(object):
-    def _column_toggled(self, menuItem, col):
-        # This is called when a selection is made in the column visibility drop
-        # down menu, and obviously makes a column visible (or not).
-        col.set_visible(not col.get_visible())
-
-    def __init__(self, store, model, view, active=ACTIVE_COL, visible=VISIBLE_COL):
-        self.store = store
-        self.model = model
-        self.view = view
-
-        self.menu = None
-
-        self.active = active
-        self.visible = visible
-
-    def addColumn(self, title, num, displayed=True):
-        cell = gtk.CellRendererText()
-        cell.set_property("yalign", 0)
-
-        col = gtk.TreeViewColumn(title, cell, text=num, active=self.active)
-        col.set_visible(displayed)
-        col.set_expand(True)
-        col.set_resizable(True)
-        self.view.append_column(col)
-
-        # This needs to be set on all columns or it will be impossible to sort
-        # by that column.
-        col.set_sort_column_id(num)
-
-        if self.menu:
-            # Add a new entry to the drop-down menu.
-            item = gtk.CheckMenuItem(title)
-            item.set_active(displayed)
-            item.connect("toggled", self._column_toggled, col)
-            item.show()
-            self.menu.append(item)
-
-    def createMenu(self):
-        self.menu = gtk.Menu()
-
-        # Add a blank column at the (current) end of the view.  This column
-        # exists only so we can have a header to click on and display the
-        # drop down allowing column configuration.
-        menuCol = gtk.TreeViewColumn("")
-        menuCol.set_clickable(True)
-        menuCol.set_sizing(gtk.TREE_VIEW_COLUMN_FIXED)
-        menuCol.set_fixed_width(30)
-        menuCol.connect("clicked", lambda col, menu: menu.popup(None, None, None, 0, 0),
-                        self.menu)
-
-        image = gui.readImageFromFile("filter-menu.png")
-        image.show_all()
-        menuCol.set_widget(image)
-
-        # Make sure the menu column gets added after all other columns so it
-        # will be on the far right edge.
-        self.view.connect("show", lambda x: self.view.append_column(menuCol))
-
-    def getStoreIter(self, row, model=None):
-        """Get an iter on the underlying store that maps to a row on the
-           provided model.  If model is None, use the default.
-        """
-        if not model:
-            model = self.model
-
-        iter = model.get_iter(row)
-        if not iter:
-            return None
-
-        while not self.store.iter_is_valid(iter):
-            if isinstance(model, gtk.TreeModelFilter):
-                iter = model.convert_iter_to_child_iter(iter)
-            elif isinstance(model, gtk.TreeModelSort):
-                iter = model.convert_iter_to_child_iter(None, iter)
-
-            model = model.get_model()
-
-        return iter
-
-    def getSelected(self):
-        """Return a list of all the items currently checked in the UI, or
-           an empty list if nothing is selected.
-        """
-        return filter(lambda row: row[self.active], self.store)
-
-    def getNVisible(self):
-        """Return the number of items currently visible in the UI."""
-        return len(filter(lambda row: row[self.visible], self.store))
-
-class DeviceSelector(DeviceDisplayer):
-    def createSelectionCol(self, title="", radioButton=False, toggledCB=None,
-                           membershipCB=None):
-        # Add a column full of checkboxes/radiobuttons in the first column of the view.
-        crt = gtk.CellRendererToggle()
-        crt.set_property("activatable", True)
-        crt.set_property("yalign", 0)
-        crt.set_radio(radioButton)
-
-        crt.connect("toggled", self._device_toggled, toggledCB, radioButton)
-
-        col = gtk.TreeViewColumn(title, crt, active=self.active)
-        col.set_alignment(0.75)
-
-        if not radioButton:
-            self.allButton = gtk.ToggleButton()
-            col.connect("clicked", lambda *args: self.allButton.set_active(not self.allButton.get_active()))
-
-            col.set_widget(self.allButton)
-            self.allButton.show_all()
-
-            self.allButton.connect("toggled", self._all_clicked, toggledCB, membershipCB)
-
-        self.view.append_column(col)
-        self.view.set_headers_clickable(True)
-        self._activated_id = self.view.connect("row-activated", self._row_activated, toggledCB, radioButton)
-
-    def _all_clicked(self, button, toggledCB=None, membershipCB=None):
-        # This is called when the Add/Remove all button is checked and does
-        # the obvious.
-        def _toggle_all(model, path, iter, set):
-            # Don't check the boxes of rows that aren't visible or aren't part
-            # of the currently displayed page.  We'd like the all button to
-            # only operate on the current page, after all.
-            if not model[path][self.visible] or model[path][IMMUTABLE_COL] or \
-                (membershipCB and not membershipCB(model[path][OBJECT_COL])):
-                return
-
-            # Don't try to set a row to active if it's already been checked.
-            # This prevents devices that have been checked before the all
-            # button was checked from getting double counted.
-            if model[path][self.active] == set:
-                return
-
-            model[path][self.active] = set
-
-            if toggledCB:
-                toggledCB(set, model[path][OBJECT_COL])
-
-        set = button.get_active()
-        self.store.foreach(_toggle_all, set)
-
-    def _row_activated(self, view, row, col, cb, isRadio):
-        # This is called when a row is double-clicked, or selected via space or
-        # enter.  We just want to do the same as if the checkbox were clicked.
-        self._device_toggled(None, row, cb, isRadio)
-
-    def _device_toggled(self, button, row, cb, isRadio):
-        # This is called when the checkbox for a device is clicked or unclicked.
-        iter = self.getStoreIter(row)
-        if not iter:
-            return
-
-        storeRow = self.store.get_path(iter)
-        if self.store[storeRow][IMMUTABLE_COL]:
-            return
-
-        if isRadio:
-            # This is lame, but there's no other way to do it.  First we have
-            # to uncheck everything in the store, then we check the one that
-            # was clicked on.
-            for r in self.store:
-                r[self.active] = False
-
-            self.store[storeRow][self.active] = True
-
-            if cb:
-                cb(True, self.store[storeRow][OBJECT_COL])
-        else:
-            is_checked = self.store[storeRow][self.active]
-            self.store[storeRow][self.active] = not is_checked
-
-            if cb:
-                cb(not is_checked, self.store[storeRow][OBJECT_COL])
diff --git a/iw/GroupSelector.py b/iw/GroupSelector.py
deleted file mode 100644
index 4d64e59..0000000
--- a/iw/GroupSelector.py
+++ /dev/null
@@ -1,620 +0,0 @@
-# Copyright 2005-2007 Red Hat, Inc.
-#
-# Jeremy Katz <katzj@xxxxxxxxxx>
-#
-# 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 only
-#
-# 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 Library 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
-import logging
-import gettext
-
-import gtk
-import gtk.glade
-import gtk.gdk as gdk
-import gobject
-
-import yum
-import yum.Errors
-try:
-    import repomd.mdErrors as mdErrors
-except ImportError: # yum 2.9.x
-    mdErrors = yum.Errors
-from yum.constants import *
-from compssort import *
-
-I18N_DOMAIN="anaconda"
-
-import rpm
-
-def sanitizeString(s, translate = True):
-    if len(s) == 0:
-        return s
-
-    if not translate:
-        i18ndomains = []
-    elif hasattr(rpm, "expandMacro"):
-        i18ndomains = rpm.expandMacro("%_i18ndomains").split(":")
-    else:
-        i18ndomains = ["redhat-dist"]
-        
-    # iterate over i18ndomains to find the translation
-    for d in i18ndomains:
-        r = gettext.dgettext(d, s)
-        if r != s:
-            s = r
-            break
-        
-    s = s.replace("\n\n", "\x00")
-    s = s.replace("\n", " ")
-    s = s.replace("\x00", "\n\n")
-    s = s.replace("&", "&amp;")
-    s = s.replace("<", "&lt;")
-    s = s.replace(">", "&gt;")
-    if type(s) != unicode:
-        try:
-            s = unicode(s, "utf-8")
-        except UnicodeDecodeError, e:
-            sys.stderr.write("Unable to convert %s to a unicode object: %s\n" % (s, e))
-            return ""
-    return s
-
-# given a package object, spit out a string reasonable for the list widgets
-def listEntryString(po):
-    desc = po.returnSimple('summary') or ''
-    pkgStr = "%s-%s-%s.%s" % (po.name, po.version, po.release, po.arch)
-    desc = "<b>%s</b> - %s" %(pkgStr, sanitizeString(desc))
-    return desc
-
-GLADE_FILE = "GroupSelector.glade"
-
-def _getgladefile(fn):
-    if os.path.exists(fn):
-        return fn
-    elif os.path.exists("data/%s" %(fn,)):
-        return "data/%s" %(fn,)
-    else:
-        return "/usr/share/pirut/ui/%s" %(fn,)
-
-t = gettext.translation(I18N_DOMAIN, "/usr/share/locale", fallback = True)
-_ = t.lgettext
-
-
-def _deselectPackage(ayum, group, pkg):
-    grpid = group.groupid
-    try:
-        pkgs = ayum.pkgSack.returnNewestByName(pkg)
-    except mdErrors.PackageSackError:
-        log = logging.getLogger("yum.verbose")
-        log.debug("no such package %s from group %s" % (pkg, grpid))
-    if pkgs:
-        pkgs = ayum.bestPackagesFromList(pkgs)
-    for po in pkgs:
-        txmbrs = ayum.tsInfo.getMembers(pkgtup = po.pkgtup)
-        for txmbr in txmbrs:
-            try:
-                txmbr.groups.remove(grpid)
-            except ValueError:
-                log = logging.getLogger("yum.verbose")                
-                log.debug("package %s was not marked in group %s" %(po, grpid))
-            if len(txmbr.groups) == 0:
-                ayum.tsInfo.remove(po.pkgtup)
-
-def _selectPackage(ayum, group, pkg):
-    grpid = group.groupid
-    try:
-        txmbrs = ayum.install(name = pkg)
-    except yum.Errors.InstallError, e:
-        log = logging.getLogger("yum.verbose")
-        log.info("No package named %s available to be installed: %s" %(pkg, e))
-    else:
-        map(lambda x: x.groups.append(grpid), txmbrs)
-
-def _catHasGroupWithPackages(cat, ayum):
-    grps = map(lambda x: ayum.comps.return_group(x),
-                   filter(lambda x: ayum.comps.has_group(x), cat.groups))
-    for g in grps:
-        if ayum._groupHasPackages(g):
-            return True
-    return False
-
-class OptionalPackageSelector:
-    def __init__(self, yumobj, group, parent = None, getgladefunc = None):
-        self.ayum = yumobj
-        self.group = group
-
-        if getgladefunc:
-            xmlfn = getgladefunc(GLADE_FILE)
-        else:
-            xmlfn = _getgladefile(GLADE_FILE)
-
-        self.xml = gtk.glade.XML(xmlfn, "groupDetailsDialog",
-                                 domain=I18N_DOMAIN)
-
-        self.window = self.xml.get_widget("groupDetailsDialog")
-        if parent:
-            self.window.set_transient_for(parent)
-        self.window.set_title(_("Packages in %s") %
-                               xmltrans(group.name, group.translated_name))
-        self.window.set_position(gtk.WIN_POS_CENTER_ON_PARENT)
-        self.window.set_size_request(600, 400)
-        self._createStore()
-        self._populate()
-
-    def __search_pkgs(self, model, col, key, i):
-        val = model.get_value(i, 2).returnSimple('name')
-        if val.lower().startswith(key.lower()):
-            return False
-        return True
-
-    def _createStore(self):
-        self.pkgstore = gtk.ListStore(gobject.TYPE_BOOLEAN,
-                                      gobject.TYPE_STRING,
-                                      gobject.TYPE_PYOBJECT)
-        tree = self.xml.get_widget("packageList")
-        tree.set_model(self.pkgstore)
-
-        column = gtk.TreeViewColumn(None, None)
-        cbr = gtk.CellRendererToggle()
-        cbr.connect ("toggled", self._pkgToggled)
-        column.pack_start(cbr, False)
-        column.add_attribute(cbr, 'active', 0)
-        tree.append_column(column)
-        
-        column = gtk.TreeViewColumn(None, None)
-        renderer = gtk.CellRendererText()
-        column.pack_start(renderer, True)
-        column.add_attribute(renderer, 'markup', 1)
-        tree.append_column(column)
-        tree.set_search_equal_func(self.__search_pkgs)
-        tree.connect("row-activated", self._rowToggle)
-
-        self.pkgstore.set_sort_column_id(1, gtk.SORT_ASCENDING)
-
-    def _rowToggle(self, tree, path, col):
-        self._pkgToggled(None, path)
-
-    def _pkgToggled(self, widget, path):
-        if type(path) == type(str):
-            i = self.pkgstore.get_iter_from_string(path)
-        else:
-            i = self.pkgstore.get_iter(path)
-        sel = self.pkgstore.get_value(i, 0)
-        pkg = self.pkgstore.get_value(i, 2).returnSimple('name')
-        if sel and not self.ayum.simpleDBInstalled(name = pkg):
-            _deselectPackage(self.ayum, self.group, pkg)
-        elif sel:
-            self.ayum.remove(name = pkg)
-        elif self.ayum.simpleDBInstalled(name = pkg):
-            txmbrs = self.ayum.tsInfo.matchNaevr(name = pkg)
-            for tx in txmbrs:
-                if tx.output_state == TS_ERASE:
-                    self.ayum.tsInfo.remove(tx.pkgtup)
-        else:
-            _selectPackage(self.ayum, self.group, pkg)
-        self.pkgstore.set_value(i, 0, not sel)
-            
-
-    def __getPackageObject(self, pkgname):
-        pos = self.ayum.pkgSack.searchNevra(name=pkgname)
-        if len(pos) > 0:
-            return pos[0]
-        return None
-
-    def _populate(self):
-        pkgs = self.group.default_packages.keys() + \
-               self.group.optional_packages.keys()
-        for pkg in pkgs:
-            po = self.__getPackageObject(pkg)
-            if not po:
-                continue
-
-            # Don't display obsolete packages in the UI
-            if self.ayum.up.checkForObsolete([po.pkgtup]).has_key(po.pkgtup):
-                continue
-
-            self.pkgstore.append([self.ayum.isPackageInstalled(pkg), listEntryString(po), po])
-
-    def run(self):
-        self.window.show_all()
-        return self.window.run()
-
-    def destroy(self):
-        return self.window.destroy()
-
-# the GroupSelector requires a YumBase object which also implements the
-# following additional methods:
-# * isPackageInstalled(p): is there a package named p installed or selected
-# * isGroupInstalled(grp): is there a group grp installed or selected
-class GroupSelector:
-    def __init__(self, yumobj, getgladefunc = None, framefunc = None):
-        self.ayum = yumobj
-
-        self.getgladefunc = getgladefunc
-        self.framefunc = framefunc
-        if getgladefunc:
-            xmlfn = getgladefunc(GLADE_FILE)
-        else:
-            xmlfn = _getgladefile(GLADE_FILE)
-
-        self.xml = gtk.glade.XML(xmlfn, "groupSelectionBox",
-                                 domain=I18N_DOMAIN)
-        self.vbox = self.xml.get_widget("groupSelectionBox")
-        self.xml.get_widget("detailsButton").set_sensitive(False)
-
-        self.menuxml = gtk.glade.XML(xmlfn, "groupPopupMenu",
-                                     domain=I18N_DOMAIN)
-        self.groupMenu = self.menuxml.get_widget("groupPopupMenu")
-
-        self._connectSignals()
-        self._createStores()
-        self.vbox.show()
-
-    def _connectSignals(self):
-        sigs = { "on_detailsButton_clicked": self._optionalPackagesDialog,
-                 "on_groupList_button_press": self._groupListButtonPress,
-                 "on_groupList_popup_menu": self._groupListPopup, }
-        self.xml.signal_autoconnect(sigs)
-
-        menusigs = { "on_select_activate": self._selectAllPackages,
-                     "on_selectgrp_activate": self._groupSelect,
-                     "on_deselectgrp_activate": self._groupDeselect,
-                     "on_deselect_activate": self._deselectAllPackages }
-        self.menuxml.signal_autoconnect(menusigs)
-
-    def _createStores(self):
-        self._createCategoryStore()
-        self._createGroupStore()
-
-        b = gtk.TextBuffer()
-        self.xml.get_widget("groupDescriptionTextView").set_buffer(b)
-
-    def _createCategoryStore(self):        
-        # display string, category object
-        self.catstore = gtk.TreeStore(gobject.TYPE_STRING,
-                                      gobject.TYPE_PYOBJECT)
-        tree = self.xml.get_widget("categoryList")
-        tree.set_model(self.catstore)
-
-        renderer = gtk.CellRendererText()
-        column = gtk.TreeViewColumn('Text', renderer, markup=0)
-        column.set_clickable(False)
-        tree.append_column(column)
-        tree.columns_autosize()
-        tree.set_enable_search(False)
-
-        selection = tree.get_selection()
-        selection.connect("changed", self._categorySelected)
-
-    def _createGroupStore(self):
-        # checkbox, display string, object
-        self.groupstore = gtk.TreeStore(gobject.TYPE_BOOLEAN,
-                                        gobject.TYPE_STRING,
-                                        gobject.TYPE_PYOBJECT,
-                                        gobject.TYPE_OBJECT)
-        tree = self.xml.get_widget("groupList")
-        tree.set_model(self.groupstore)
-
-        column = gtk.TreeViewColumn(None, None)
-        column.set_clickable(True)
-        pixr = gtk.CellRendererPixbuf()
-        pixr.set_property('stock-size', 1)
-        column.pack_start(pixr, False)
-        column.add_attribute(pixr, 'pixbuf', 3)
-        cbr = gtk.CellRendererToggle()
-        column.pack_start(cbr, False)
-        column.add_attribute(cbr, 'active', 0)
-        cbr.connect ("toggled", self._groupToggled)
-        tree.append_column(column)
-        
-        renderer = gtk.CellRendererText()
-        column = gtk.TreeViewColumn('Text', renderer, markup=1)
-        column.set_clickable(False)
-        tree.append_column(column)
-        tree.columns_autosize()
-        tree.set_enable_search(False)
-        tree.grab_focus()
-
-        selection = tree.get_selection()
-        selection.connect("changed", self._groupSelected)
-        selection.set_mode(gtk.SELECTION_MULTIPLE)
-
-    def _get_pix(self, fn):
-        imgsize = 24
-        pix = gtk.gdk.pixbuf_new_from_file(fn)
-        if pix.get_height() != imgsize or pix.get_width() != imgsize:
-            pix = pix.scale_simple(imgsize, imgsize,
-                                   gtk.gdk.INTERP_BILINEAR)
-        return pix
-
-    def _categorySelected(self, selection):
-        self.groupstore.clear()
-        (model, i) = selection.get_selected()
-        if not i:
-            return
-        cat = model.get_value(i, 1)
-
-        # fall back to the category pixbuf
-        fbpix = None
-        fn = "/usr/share/pixmaps/comps/%s.png" %(cat.categoryid,)
-        if os.access(fn, os.R_OK):
-            fbpix = self._get_pix(fn)
-        self._populateGroups(cat.groups, fbpix)
-
-    def _populateGroups(self, groups, defaultpix = None):
-        grps = map(lambda x: self.ayum.comps.return_group(x),
-                   filter(lambda x: self.ayum.comps.has_group(x), groups))
-        grps.sort(ui_comps_sort)
-        for grp in grps:
-            if not self.ayum._groupHasPackages(grp):
-                continue
-            s = "<span size=\"large\" weight=\"bold\">%s</span>" % xmltrans(grp.name, grp.translated_name)
-
-            fn = "/usr/share/pixmaps/comps/%s.png" % grp.groupid
-            if os.access(fn, os.R_OK):
-                pix = self._get_pix(fn)
-            elif defaultpix:
-                pix = defaultpix
-            else:
-                pix = None
-            self.groupstore.append(None,
-                                   [self.ayum.isGroupInstalled(grp),s,grp,pix])
-
-        tree = self.xml.get_widget("groupList")
-        gobject.idle_add(lambda x: x.flags() & gtk.REALIZED and x.scroll_to_point(0, 0), tree)
-        self.xml.get_widget("optionalLabel").set_text("")
-        self.xml.get_widget("detailsButton").set_sensitive(False)
-
-        # select the first group
-        i = self.groupstore.get_iter_first()
-        if i is not None:
-            sel = self.xml.get_widget("groupList").get_selection()
-            sel.select_iter(i)
-
-    def _groupSelected(self, selection):
-        if selection.count_selected_rows() != 1:
-            # if we have more groups (or no group) selected, then
-            # we can't show a description or allow selecting optional
-            self.__setGroupDescription(None)
-            return
-        (model, paths) = selection.get_selected_rows()
-        grp = model.get_value(model.get_iter(paths[0]), 2)
-        self.__setGroupDescription(grp)
-
-    def __setGroupDescription(self, grp):
-        b = self.xml.get_widget("groupDescriptionTextView").get_buffer()
-        b.set_text("")
-        if grp is None:
-            return
-        
-        if grp.description:
-            txt = xmltrans(grp.description, grp.translated_description)
-        else:
-            txt = xmltrans(grp.name, grp.translated_name)
-
-        inst = 0
-        cnt = 0
-        pkgs = grp.default_packages.keys() + grp.optional_packages.keys()
-        for p in pkgs:
-            if self.ayum.isPackageInstalled(p):
-                cnt += 1
-                inst += 1
-            elif self.ayum.pkgSack.searchNevra(name=p):
-                cnt += 1
-            else:
-                log = logging.getLogger("yum.verbose")
-                log.debug("no such package %s for %s" %(p, grp.groupid))
-
-        b.set_text(txt)
-        if cnt == 0 or not self.ayum.isGroupInstalled(grp):
-            self.xml.get_widget("detailsButton").set_sensitive(False)
-            self.xml.get_widget("optionalLabel").set_text("")
-        else:
-            self.xml.get_widget("detailsButton").set_sensitive(True)
-            txt = _("Optional packages selected: %(inst)d of %(cnt)d") \
-                    % {'inst': inst, 'cnt': cnt}
-            self.xml.get_widget("optionalLabel").set_markup(_("<i>%s</i>") %(txt,))
-
-    def _groupToggled(self, widget, path, sel = None, updateText = True):
-        if type(path) == type(str):
-            i = self.groupstore.get_iter_from_string(path)
-        else:
-            i = self.groupstore.get_iter(path)
-        if sel is None:
-            sel = not self.groupstore.get_value(i, 0)
-            
-        self.groupstore.set_value(i, 0, sel)
-        grp = self.groupstore.get_value(i, 2)
-
-        self.vbox.window.set_cursor(gdk.Cursor(gdk.WATCH))
-        
-        if sel:
-            self.ayum.selectGroup(grp.groupid)
-        else:
-            self.ayum.deselectGroup(grp.groupid)
-            # FIXME: this doesn't mark installed packages for removal.
-            # we probably want that behavior with s-c-p, but not anaconda
-
-        if updateText:
-            self.__setGroupDescription(grp)
-
-        self.vbox.window.set_cursor(None)
-
-    def populateCategories(self):
-        self.catstore.clear()
-        cats = self.ayum.comps.categories
-        cats.sort(ui_comps_sort)
-        for cat in cats:
-            if not _catHasGroupWithPackages(cat, self.ayum):
-                continue
-            s = "<span size=\"large\" weight=\"bold\">%s</span>" % xmltrans(cat.name, cat.translated_name)
-            self.catstore.append(None, [s, cat])
-
-        # select the first category
-        i = self.catstore.get_iter_first()
-        if i is not None:
-            sel = self.xml.get_widget("categoryList").get_selection()
-            sel.select_iter(i)
-
-    def _setupCatchallCategory(self):
-        # FIXME: this is a bad hack, but catch groups which aren't in
-        # a category yet are supposed to be user-visible somehow.
-        # conceivably should be handled by yum
-        grps = {}
-        for g in self.ayum.comps.groups:
-            if g.user_visible and self.ayum._groupHasPackages(g):
-                grps[g.groupid] = g
-
-        for cat in self.ayum.comps.categories:
-            for g in cat.groups:
-                if grps.has_key(g):
-                    del grps[g]
-
-        if len(grps.keys()) == 0:
-            return
-        c = yum.comps.Category()
-        c.name = _("Uncategorized")
-        c._groups = grps
-        c.categoryid = "uncategorized"
-
-        self.ayum.comps._categories[c.categoryid] = c
-
-    def doRefresh(self):
-        if len(self.ayum.comps.categories) == 0:
-            self.xml.get_widget("categorySW").hide()
-            self._populateGroups(map(lambda x: x.groupid,
-                                     self.ayum.comps.groups))
-        else:
-            self._setupCatchallCategory()
-            self.populateCategories()
-
-    def _getSelectedGroup(self):
-        """Return the selected group.
-        NOTE: this only ever returns one group."""
-        selection = self.xml.get_widget("groupList").get_selection()
-        (model, paths) = selection.get_selected_rows()
-        for p in paths:
-            return model.get_value(model.get_iter(p), 2)
-        return None
-    
-    def _optionalPackagesDialog(self, *args):
-        group = self._getSelectedGroup()
-        if group is None:
-            return
-
-        pwin = self.vbox.get_parent() # hack to find the parent window...
-        while not isinstance(pwin, gtk.Window):
-            pwin = pwin.get_parent()
-        d = OptionalPackageSelector(self.ayum, group, pwin, self.getgladefunc)
-        if self.framefunc:
-            self.framefunc(d.window)
-        rc = d.run()
-        d.destroy()
-        self.__setGroupDescription(group)
-
-    def _groupSelect(self, *args):
-        selection = self.xml.get_widget("groupList").get_selection()
-        if selection.count_selected_rows() == 0:
-            return
-
-        (model, paths) = selection.get_selected_rows()
-        for p in paths:
-            self._groupToggled(model, p, True, updateText=(len(paths) == 1))
-
-    def _groupDeselect(self, *args):
-        selection = self.xml.get_widget("groupList").get_selection()
-        if selection.count_selected_rows() == 0:
-            return
-
-        (model, paths) = selection.get_selected_rows()
-        for p in paths:
-            self._groupToggled(model, p, False, updateText=(len(paths) == 1))
-
-    def _selectAllPackages(self, *args):
-        selection = self.xml.get_widget("groupList").get_selection()
-        if selection.count_selected_rows() == 0:
-            return
-        (model, paths) = selection.get_selected_rows()
-
-        self.vbox.window.set_cursor(gdk.Cursor(gdk.WATCH))
-
-        for p in paths:
-            i = model.get_iter(p)
-            grp = model.get_value(i, 2)
-
-            # ensure the group is selected
-            self.ayum.selectGroup(grp.groupid)
-            model.set_value(i, 0, True)
-        
-            for pkg in grp.default_packages.keys() + \
-                    grp.optional_packages.keys():
-                if self.ayum.isPackageInstalled(pkg):
-                    continue
-                elif self.ayum.simpleDBInstalled(name = pkg):
-                    txmbrs = self.ayum.tsInfo.matchNaevr(name = pkg)
-                    for tx in txmbrs:
-                        if tx.output_state == TS_ERASE:
-                            self.ayum.tsInfo.remove(tx.pkgtup)
-                else:
-                    _selectPackage(self.ayum, grp, pkg)
-
-        if len(paths) == 1:
-            self.__setGroupDescription(grp)
-        self.vbox.window.set_cursor(None)
-
-    def _deselectAllPackages(self, *args):
-        selection = self.xml.get_widget("groupList").get_selection()
-        if selection.count_selected_rows() == 0:
-            return
-        (model, paths) = selection.get_selected_rows()
-        
-        for p in paths:
-            i = model.get_iter(p)
-            grp = model.get_value(i, 2)
-
-            for pkg in grp.default_packages.keys() + \
-                    grp.optional_packages.keys():
-                if not self.ayum.isPackageInstalled(pkg):
-                    continue
-                elif self.ayum.simpleDBInstalled(name=pkg):
-                    self.ayum.remove(name=pkg)
-                else:
-                    _deselectPackage(self.ayum, grp, pkg)
-        if len(paths) == 1:
-            self.__setGroupDescription(grp)
-
-    def __doGroupPopup(self, button, time):
-        menu = self.groupMenu
-        menu.popup(None, None, None, button, time)
-        menu.show_all()
-
-    def _groupListButtonPress(self, widget, event):
-        if event.button == 3:
-            x = int(event.x)
-            y = int(event.y)
-            pthinfo = widget.get_path_at_pos(x, y)
-            if pthinfo is not None:
-                sel = widget.get_selection()
-                if sel.count_selected_rows() == 1:
-                    path, col, cellx, celly = pthinfo                    
-                    widget.grab_focus()
-                    widget.set_cursor(path, col, 0)
-                self.__doGroupPopup(event.button, event.time)
-            return 1
-
-    def _groupListPopup(self, widget):
-        sel = widget.get_selection()
-        if sel.count_selected_rows() > 0:
-            self.__doGroupPopup(0, 0)
-        
-        
diff --git a/iw/Makefile.am b/iw/Makefile.am
deleted file mode 100644
index da0b579..0000000
--- a/iw/Makefile.am
+++ /dev/null
@@ -1,24 +0,0 @@
-# iw/Makefile.am for anaconda
-#
-# Copyright (C) 2009  Red Hat, Inc.
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU Lesser General Public License as published
-# by the Free Software Foundation; either version 2.1 of the License, or
-# (at your option) any later version.
-#
-# 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 Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public License
-# along with this program.  If not, see <http://www.gnu.org/licenses/>.
-#
-# Author: David Cantrell <dcantrell@xxxxxxxxxx>
-
-pkgpyexecdir = $(pyexecdir)/py$(PACKAGE_NAME)
-iwdir = $(pkgpyexecdir)/iw
-iw_PYTHON = *.py
-
-MAINTAINERCLEANFILES = Makefile.in
diff --git a/iw/account_gui.py b/iw/account_gui.py
deleted file mode 100644
index 7f3a964..0000000
--- a/iw/account_gui.py
+++ /dev/null
@@ -1,148 +0,0 @@
-#
-# account_gui.py: gui root password and crypt algorithm dialog
-#
-# Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005,  Red Hat Inc.
-#               2006, 2007, 2008
-# 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 as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# 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, see <http://www.gnu.org/licenses/>.
-#
-
-import gtk
-import string
-import gui
-from iw_gui import *
-from flags import flags
-from constants import *
-import cracklib
-import _isys
-
-import gettext
-_ = lambda x: gettext.ldgettext("anaconda", x)
-
-class AccountWindow (InstallWindow):
-    def getScreen(self, anaconda):
-        self.anaconda = anaconda
-        self.intf = anaconda.intf
-
-        (self.xml, self.align) = gui.getGladeWidget("account.glade",
-                                                    "account_align")
-        self.icon = self.xml.get_widget("icon")
-        self.capslock = self.xml.get_widget("capslock")
-        self.pwlabel = self.xml.get_widget("pwlabel")
-        self.pw = self.xml.get_widget("pw")
-        self.confirmlabel = self.xml.get_widget("confirmlabel")
-        self.confirm = self.xml.get_widget("confirm")
-
-        # load the icon
-        gui.readImageFromFile("root-password.png", image=self.icon)
-
-        # connect hotkeys
-        self.pwlabel.set_text_with_mnemonic(_("Root _Password:"))
-        self.pwlabel.set_mnemonic_widget(self.pw)
-        self.confirmlabel.set_text_with_mnemonic(_("_Confirm:"))
-        self.confirmlabel.set_mnemonic_widget(self.confirm)
-
-        # watch for Caps Lock so we can warn the user
-        self.intf.icw.window.connect("key-release-event",
-            lambda w, e: self.handleCapsLockRelease(w, e, self.capslock))
-
-        # we might have a root password already
-        if not self.anaconda.users.rootPassword['isCrypted']:
-            self.pw.set_text(self.anaconda.users.rootPassword['password'])
-            self.confirm.set_text(self.anaconda.users.rootPassword['password'])
-
-        # pressing Enter in confirm == clicking Next
-        vbox = self.xml.get_widget("account_box")
-        self.confirm.connect("activate", lambda widget,
-                             vbox=vbox: self.ics.setGrabNext(1))
-
-        # set initial caps lock label text
-        self.setCapsLockLabel()
-
-        return self.align
-
-    def focus(self):
-        self.pw.grab_focus()
-
-    def passwordError(self):
-        self.pw.set_text("")
-        self.confirm.set_text("")
-        self.pw.grab_focus()
-        raise gui.StayOnScreen
-
-    def handleCapsLockRelease(self, window, event, label):
-        if event.keyval == gtk.keysyms.Caps_Lock and \
-           event.state & gtk.gdk.LOCK_MASK:
-            self.setCapsLockLabel()
-
-    def setCapsLockLabel(self):
-        if _isys.isCapsLockEnabled():
-            self.capslock.set_text("<b>" + _("Caps Lock is on.") + "</b>")
-            self.capslock.set_use_markup(True)
-        else:
-            self.capslock.set_text("")
-
-    def getNext (self):
-        pw = self.pw.get_text()
-        confirm = self.confirm.get_text()
-
-        if not pw or not confirm:
-            self.intf.messageWindow(_("Error with Password"),
-                                    _("You must enter your root password "
-                                      "and confirm it by typing it a second "
-                                      "time to continue."),
-                                    custom_icon="error")
-            self.passwordError()
-
-        if pw != confirm:
-            self.intf.messageWindow(_("Error with Password"),
-                                    _("The passwords you entered were "
-                                      "different.  Please try again."),
-                                    custom_icon="error")
-            self.passwordError()
-
-        if len(pw) < 6:
-            self.intf.messageWindow(_("Error with Password"),
-                                    _("The root password must be at least "
-                                      "six characters long."),
-                                    custom_icon="error")
-            self.passwordError()
-
-        try:
-            cracklib.FascistCheck(pw)
-        except ValueError, e:
-            msg = gettext.ldgettext("cracklib", e)
-            ret = self.intf.messageWindow(_("Weak Password"),
-                                          _("You have provided a weak password: %s") % msg,
-                                          type="custom", custom_icon="error",
-                                          default=0,
-                                          custom_buttons=[_("Cancel"), _("Use Anyway")])
-            if ret == 0:
-                self.passwordError()
-
-        legal = string.digits + string.ascii_letters + string.punctuation + " "
-        for letter in pw:
-            if letter not in legal:
-                self.intf.messageWindow(_("Error with Password"),
-                                        _("Requested password contains "
-                                          "non-ASCII characters, which are "
-                                          "not allowed."),
-                                        custom_icon="error")
-                self.passwordError()
-
-        self.anaconda.users.rootPassword["password"] = self.pw.get_text()
-        self.anaconda.users.rootPassword["isCrypted"] = False
-
-        return None
diff --git a/iw/advanced_storage.py b/iw/advanced_storage.py
deleted file mode 100644
index 902d8ac..0000000
--- a/iw/advanced_storage.py
+++ /dev/null
@@ -1,256 +0,0 @@
-#
-# Copyright (C) 2009  Red Hat, Inc.  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 as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# 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, see <http://www.gnu.org/licenses/>.
-#
-
-import gettext
-_ = lambda x: gettext.ldgettext("anaconda", x)
-
-# UI methods for supporting adding advanced storage devices.
-import gobject
-import gtk
-import gtk.glade
-import gui
-import iutil
-import network
-import storage.fcoe
-import storage.iscsi
-from netconfig_dialog import NetworkConfigurator
-
-def addFcoeDrive(anaconda):
-    (dxml, dialog) = gui.getGladeWidget("fcoe-config.glade", "fcoeDialog")
-    combo = dxml.get_widget("fcoeNicCombo")
-    dcb_cb = dxml.get_widget("dcbCheckbutton")
-
-    # Populate the combo
-    cell = gtk.CellRendererText()
-    combo.pack_start(cell, True)
-    combo.set_attributes(cell, text = 0)
-    cell.set_property("wrap-width", 525)
-    combo.set_size_request(480, -1)
-    store = gtk.TreeStore(gobject.TYPE_STRING, gobject.TYPE_STRING)
-    combo.set_model(store)
-
-    netdevs = anaconda.network.available()
-    keys = netdevs.keys()
-    keys.sort()
-    selected_interface = None
-    for dev in keys:
-        # Skip NICs which are connected (iow in use for a net install)
-        if dev in network.getActiveNetDevs():
-            continue
-
-        i = store.append(None)
-        desc = netdevs[dev].get("DESC")
-        if desc:
-            desc = "%s - %s" %(dev, desc)
-        else:
-            desc = "%s" %(dev,)
-
-        mac = netdevs[dev].get("HWADDR")
-        if mac:
-            desc = "%s - %s" %(desc, mac)
-
-        if selected_interface is None:
-            selected_interface = i
-
-        store[i] = (desc, dev)
-
-    if selected_interface:
-        combo.set_active_iter(selected_interface)
-    else:
-        combo.set_active(0)
-
-    # Show the dialog
-    gui.addFrame(dialog)
-    dialog.show_all()
-    sg = gtk.SizeGroup(gtk.SIZE_GROUP_HORIZONTAL)
-    sg.add_widget(dxml.get_widget("fcoeNicCombo"))
-
-    while True:
-        rc = dialog.run()
-
-        if rc in [gtk.RESPONSE_CANCEL, gtk.RESPONSE_DELETE_EVENT]:
-            break
-
-        iter = combo.get_active_iter()
-        if iter is None:
-            anaconda.intf.messageWindow(_("Error"),
-                                        _("You must select a NIC to use."),
-                                        type="warning", custom_icon="error")
-            continue
-
-        try:
-            anaconda.storage.fcoe.addSan(store.get_value(iter, 1),
-                                         dcb=dcb_cb.get_active(),
-                                         intf=anaconda.intf)
-        except IOError as e:
-            anaconda.intf.messageWindow(_("Error"), str(e))
-            rc = gtk.RESPONSE_CANCEL
-
-        break
-
-    dialog.destroy()
-    return rc
-
-def addIscsiDrive(anaconda):
-    if not network.hasActiveNetDev():
-        net = NetworkConfigurator(anaconda.network)
-        ret = net.run()
-        net.destroy()
-        if ret != gtk.RESPONSE_OK:
-            return ret
-
-    (dxml, dialog) = gui.getGladeWidget("iscsi-config.glade", "iscsiDialog")
-    gui.addFrame(dialog)
-    dialog.show_all()
-    sg = gtk.SizeGroup(gtk.SIZE_GROUP_HORIZONTAL)
-    for w in ["iscsiAddrEntry", "iscsiInitiatorEntry", "userEntry",
-              "passEntry", "userinEntry", "passinEntry"]:
-        sg.add_widget(dxml.get_widget(w))
-
-    # get the initiator name if it exists and don't allow changing
-    # once set
-    e = dxml.get_widget("iscsiInitiatorEntry")
-    e.set_text(anaconda.storage.iscsi.initiator)
-    if anaconda.storage.iscsi.initiatorSet:
-        e.set_sensitive(False)
-
-    while True:
-        rc = dialog.run()
-        if rc in [gtk.RESPONSE_CANCEL, gtk.RESPONSE_DELETE_EVENT]:
-            break
-
-        initiator = e.get_text().strip()
-        if len(initiator) == 0:
-            anaconda.intf.messageWindow(_("Invalid Initiator Name"),
-                                        _("You must provide an initiator name."))
-            continue
-
-        anaconda.storage.iscsi.initiator = initiator
-
-        target = dxml.get_widget("iscsiAddrEntry").get_text().strip()
-        user = dxml.get_widget("userEntry").get_text().strip()
-        pw = dxml.get_widget("passEntry").get_text().strip()
-        user_in = dxml.get_widget("userinEntry").get_text().strip()
-        pw_in = dxml.get_widget("passinEntry").get_text().strip()
-
-        try:
-            count = len(target.split(":"))
-            idx = target.rfind("]:")
-            # Check for IPV6 [IPV6-ip]:port
-            if idx != -1:
-                ip = target[1:idx]
-                port = target[idx+2:]
-            # Check for IPV4 aaa.bbb.ccc.ddd:port
-            elif count == 2:
-                idx = target.rfind(":")
-                ip = target[:idx]
-                port = target[idx+1:]
-            else:
-                ip = target
-                port = "3260"
-
-            network.sanityCheckIPString(ip)
-        except (network.IPMissing, network.IPError) as msg:
-            anaconda.intf.messageWindow(_("Error with Data"), msg)
-            continue
-
-        try:
-            anaconda.storage.iscsi.addTarget(ip, port, user, pw,
-                                             user_in, pw_in,
-                                             anaconda.intf)
-        except ValueError as e:
-            anaconda.intf.messageWindow(_("Error"), str(e))
-            continue
-        except IOError as e:
-            anaconda.intf.messageWindow(_("Error"), str(e))
-            rc = gtk.RESPONSE_CANCEL
-
-        break
-
-    dialog.destroy()
-    return rc
-
-def addZfcpDrive(anaconda):
-    (dxml, dialog) = gui.getGladeWidget("zfcp-config.glade", "zfcpDialog")
-    gui.addFrame(dialog)
-    dialog.show_all()
-    sg = gtk.SizeGroup(gtk.SIZE_GROUP_HORIZONTAL)
-    for w in ["devnumEntry", "wwpnEntry", "fcplunEntry"]:
-        sg.add_widget(dxml.get_widget(w))
-
-    while True:
-        rc = dialog.run()
-        if rc != gtk.RESPONSE_APPLY:
-            break
-
-        devnum = dxml.get_widget("devnumEntry").get_text().strip()
-        wwpn = dxml.get_widget("wwpnEntry").get_text().strip()
-        fcplun = dxml.get_widget("fcplunEntry").get_text().strip()
-
-        try:
-            anaconda.storage.zfcp.addFCP(devnum, wwpn, fcplun)
-        except ValueError as e:
-            anaconda.intf.messageWindow(_("Error"), str(e))
-            continue
-
-        break
-
-    dialog.destroy()
-    return rc
-
-def addDrive(anaconda):
-    (dxml, dialog) = gui.getGladeWidget("adddrive.glade", "addDriveDialog")
-    gui.addFrame(dialog)
-    dialog.show_all()
-    if not iutil.isS390():
-        dxml.get_widget("zfcpRadio").hide()
-        dxml.get_widget("zfcpRadio").set_group(None)
-
-    if not storage.iscsi.has_iscsi():
-        dxml.get_widget("iscsiRadio").set_sensitive(False)
-        dxml.get_widget("iscsiRadio").set_active(False)
-
-    if not storage.fcoe.has_fcoe():
-        dxml.get_widget("fcoeRadio").set_sensitive(False)
-        dxml.get_widget("fcoeRadio").set_active(False)
-
-    #figure out what advanced devices we have available and set sensible default
-    group = dxml.get_widget("iscsiRadio").get_group()
-    for button in group:
-        if button is not None and button.get_property("sensitive"):
-            button.set_active(True)
-            break
-
-    rc = dialog.run()
-    dialog.hide()
-
-    if rc in [gtk.RESPONSE_CANCEL, gtk.RESPONSE_DELETE_EVENT]:
-        return False
-
-    if dxml.get_widget("iscsiRadio").get_active() and storage.iscsi.has_iscsi():
-        rc = addIscsiDrive(anaconda)
-    elif dxml.get_widget("fcoeRadio").get_active() and storage.fcoe.has_fcoe():
-        rc = addFcoeDrive(anaconda)
-    elif dxml.get_widget("zfcpRadio") is not None and dxml.get_widget("zfcpRadio").get_active():
-        rc = addZfcpDrive(anaconda)
-
-    dialog.destroy()
-
-    if rc in [gtk.RESPONSE_CANCEL, gtk.RESPONSE_DELETE_EVENT]:
-        return False
-    else:
-        return True
diff --git a/iw/autopart_type.py b/iw/autopart_type.py
deleted file mode 100644
index 2ba1075..0000000
--- a/iw/autopart_type.py
+++ /dev/null
@@ -1,284 +0,0 @@
-#
-# autopart_type.py: Allows the user to choose how they want to partition
-#
-# Copyright (C) 2005, 2006  Red Hat, Inc.  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 as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# 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, see <http://www.gnu.org/licenses/>.
-#
-# Author(s): Jeremy Katz <katzj@xxxxxxxxxx>
-#
-
-import gtk
-import gobject
-import math
-
-from constants import *
-import gui
-from partition_ui_helpers_gui import *
-from pixmapRadioButtonGroup_gui import pixmapRadioButtonGroup
-
-from iw_gui import *
-from flags import flags
-from storage.deviceaction import *
-
-import gettext
-_ = lambda x: gettext.ldgettext("anaconda", x)
-
-def whichToShrink(storage, intf):
-    def getActive(combo):
-        act = combo.get_active_iter()
-        return combo.get_model().get_value(act, 1)
-
-    def comboCB(combo, shrinkSB):
-        # partition to resize changed, let's update our spinbutton
-        newSize = shrinkSB.get_value_as_int()
-
-        part = getActive(combo)
-        reqlower = long(math.ceil(part.format.minSize))
-        requpper = long(math.floor(part.format.currentSize))
-
-        adj = shrinkSB.get_adjustment()
-        adj.lower = reqlower
-        adj.upper = requpper
-        adj.set_value(reqlower)
-
-
-    (dxml, dialog) = gui.getGladeWidget("autopart.glade", "shrinkDialog")
-
-    store = gtk.TreeStore(gobject.TYPE_STRING, gobject.TYPE_PYOBJECT)
-    combo = dxml.get_widget("shrinkPartCombo")
-    combo.set_model(store)
-    crt = gtk.CellRendererText()
-    combo.pack_start(crt, True)
-    combo.set_attributes(crt, text = 0)
-    combo.connect("changed", comboCB, dxml.get_widget("shrinkSB"))
-
-    biggest = -1
-    for part in storage.partitions:
-        if not part.exists:
-            continue
-
-        entry = None
-        if part.resizable and part.format.resizable:
-            entry = ("%s (%s, %d MB)" % (part.name,
-                                         part.format.name,
-                                         math.floor(part.format.size)),
-                     part)
-
-        if entry:
-            i = store.append(None)
-            store[i] = entry
-            combo.set_active_iter(i)
-
-            if biggest == -1:
-                biggest = i
-            else:
-                current = store.get_value(biggest, 1)
-                if part.format.targetSize > current.format.targetSize:
-                    biggest = i
-
-    if biggest > -1:
-        combo.set_active_iter(biggest)
-
-    if len(store) == 0:
-        dialog.destroy()
-        intf.messageWindow(_("Error"),
-                           _("No partitions are available to resize.  Only "
-                             "physical partitions with specific filesystems "
-                             "can be resized."),
-                             type="warning", custom_icon="error")
-        return (gtk.RESPONSE_CANCEL, [])
-
-    gui.addFrame(dialog)
-    dialog.show_all()
-    runResize = True
-
-    while runResize:
-        rc = dialog.run()
-        if rc != gtk.RESPONSE_OK:
-            dialog.destroy()
-            return (rc, [])
-
-        request = getActive(combo)
-        newSize = dxml.get_widget("shrinkSB").get_value_as_int()
-        actions = []
-
-        try:
-            actions.append(ActionResizeFormat(request, newSize))
-        except ValueError as e:
-            intf.messageWindow(_("Resize FileSystem Error"),
-                               _("%(device)s: %(msg)s")
-                                 % {'device': request.format.device,
-                                    'msg': e.message},
-                               type="warning", custom_icon="error")
-            continue
-
-        try:
-            actions.append(ActionResizeDevice(request, newSize))
-        except ValueError as e:
-            intf.messageWindow(_("Resize Device Error"),
-                               _("%(name)s: %(msg)s")
-                                 % {'name': request.name, 'msg': e.message},
-                               type="warning", custom_icon="error")
-            continue
-
-        runResize = False
-
-    dialog.destroy()
-    return (rc, actions)
-
-class PartitionTypeWindow(InstallWindow):
-    def __init__(self, ics):
-        InstallWindow.__init__(self, ics)
-        ics.setTitle("Automatic Partitioning")
-        ics.setNextEnabled(True)
-
-    def getNext(self):
-        if self.storage.checkNoDisks():
-            raise gui.StayOnScreen
-
-        if self.buttonGroup.getCurrent() == "custom":
-            self.dispatch.skipStep("autopartitionexecute", skip = 1)
-            self.dispatch.skipStep("partition", skip = 0)
-            self.dispatch.skipStep("bootloader", skip = 0)
-
-            self.storage.clearPartType = CLEARPART_TYPE_NONE
-        else:
-            if self.buttonGroup.getCurrent() == "shrink":
-                (rc, actions) = whichToShrink(self.storage, self.intf)
-                if rc == gtk.RESPONSE_OK:
-                    for action in actions:
-                        self.storage.devicetree.registerAction(action)
-                else:
-                    raise gui.StayOnScreen
-
-                # we're not going to delete any partitions in the resize case
-                self.storage.clearPartType = CLEARPART_TYPE_NONE
-            elif self.buttonGroup.getCurrent() == "all":
-                self.storage.clearPartType = CLEARPART_TYPE_ALL
-            elif self.buttonGroup.getCurrent() == "replace":
-                self.storage.clearPartType = CLEARPART_TYPE_LINUX
-            elif self.buttonGroup.getCurrent() == "freespace":
-                self.storage.clearPartType = CLEARPART_TYPE_NONE
-
-            self.dispatch.skipStep("autopartitionexecute", skip = 0)
-
-            if self.encryptButton.get_active():
-                self.storage.encryptedAutoPart = True
-            else:
-                self.storage.encryptionPassphrase = ""
-                self.storage.retrofitPassphrase = False
-                self.storage.encryptedAutoPart = False
-
-            self.storage.doAutoPart = True
-
-            if self.reviewButton.get_active():
-                self.dispatch.skipStep("partition", skip = 0)
-                self.dispatch.skipStep("bootloader", skip = 0)
-            else:
-                self.dispatch.skipStep("partition")
-                self.dispatch.skipStep("bootloader")
-                self.dispatch.skipStep("bootloaderadvanced")
-
-        return None
-
-    def typeChanged(self, *args):
-        if self.buttonGroup.getCurrent() == "custom":
-            if not self.prevrev:
-                self.prevrev = self.reviewButton.get_active()
-
-            self.reviewButton.set_active(True)
-            self.reviewButton.set_sensitive(False)
-            self.encryptButton.set_sensitive(False)
-        else:
-            if self.prevrev:
-                self.reviewButton.set_active(self.prevrev)
-                self.prevrev = None
-
-            self.reviewButton.set_sensitive(True)
-            self.encryptButton.set_sensitive(True)
-
-    def getScreen(self, anaconda):
-        self.anaconda = anaconda
-        self.storage = anaconda.storage
-        self.intf = anaconda.intf
-        self.dispatch = anaconda.dispatch
-
-        (self.xml, vbox) = gui.getGladeWidget("autopart.glade", "parttypeTable")
-        self.encryptButton = self.xml.get_widget("encryptButton")
-        self.reviewButton = self.xml.get_widget("reviewButton")
-        self.table = self.xml.get_widget("parttypeTable")
-
-        self.prevrev = None
-        self.reviewButton.set_active(not self.dispatch.stepInSkipList("partition"))
-        self.encryptButton.set_active(self.storage.encryptedAutoPart)
-
-        self.buttonGroup = pixmapRadioButtonGroup()
-        self.buttonGroup.addEntry("all", _("Use All Space"),
-                                  pixmap=gui.readImageFromFile("partscheme-all.png"),
-                                  descr=_("Removes all partitions on the selected "
-                                          "device(s).  This includes partitions "
-                                          "created by other operating systems.\n\n"
-                                          "<b>Tip:</b> This option will remove "
-                                          "data from the selected device(s).  Make "
-                                          "sure you have backups."))
-        self.buttonGroup.addEntry("replace", _("Replace Existing Linux System(s)"),
-                                  pixmap=gui.readImageFromFile("partscheme-replace.png"),
-                                  descr=_("Removes all Linux partitions on the "
-                                          "selected device(s). This does "
-                                          "not remove other partitions you may have "
-                                          "on your storage device(s) (such as VFAT or "
-                                          "FAT32).\n\n"
-                                          "<b>Tip:</b> This option will remove "
-                                          "data from the selected device(s).  Make "
-                                          "sure you have backups."))
-        self.buttonGroup.addEntry("shrink", _("Shrink Current System"),
-                                  pixmap=gui.readImageFromFile("partscheme-shrink.png"),
-                                  descr=_("Shrinks existing partitions to create free "
-                                          "space for the default layout."))
-        self.buttonGroup.addEntry("freespace", _("Use Free Space"),
-                                  pixmap=gui.readImageFromFile("partscheme-freespace.png"),
-                                  descr=_("Retains your current data and partitions and "
-                                          "uses only the unpartitioned space on the "
-                                          "selected device(s), assuming you have enough "
-                                          "free space available."))
-        self.buttonGroup.addEntry("custom", _("Create Custom Layout"),
-                                  pixmap=gui.readImageFromFile("partscheme-custom.png"),
-                                  descr=_("Manually create your own custom layout on "
-                                          "the selected device(s) using our partitioning "
-                                          "tool."))
-
-        self.buttonGroup.setToggleCallback(self.typeChanged)
-
-        widget = self.buttonGroup.render()
-        self.table.attach(widget, 0, 1, 1, 2)
-
-        # if not set in ks, use UI default
-        if self.storage.clearPartType is None or self.storage.clearPartType == CLEARPART_TYPE_LINUX:
-            self.buttonGroup.setCurrent("replace")
-        elif self.storage.clearPartType == CLEARPART_TYPE_NONE:
-            self.buttonGroup.setCurrent("freespace")
-        elif self.storage.clearPartType == CLEARPART_TYPE_ALL:
-            self.buttonGroup.setCurrent("all")
-
-        if self.buttonGroup.getCurrent() == "custom":
-            # make sure reviewButton is active and not sensitive
-            if self.prevrev == None:
-                self.prevrev = self.reviewButton.get_active()
-
-            self.reviewButton.set_active(True)
-            self.reviewButton.set_sensitive(False)
-            self.encryptButton.set_sensitive(False)
-
-        return vbox
diff --git a/iw/blpasswidget.py b/iw/blpasswidget.py
deleted file mode 100644
index c6e6881..0000000
--- a/iw/blpasswidget.py
+++ /dev/null
@@ -1,164 +0,0 @@
-#
-# blpasswidget.py - widget for setting of a boot loader password
-#
-# Copyright (C) 2001, 2002  Red Hat, Inc.  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 as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# 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, see <http://www.gnu.org/licenses/>.
-#
-# Author(s): Jeremy Katz <katzj@xxxxxxxxxx>
-#
-
-import gtk
-import gui
-from constants import *
-
-import gettext
-_ = lambda x: gettext.ldgettext("anaconda", x)
-
-class BootloaderPasswordWidget:
-    def __init__(self, anaconda, parent):
-        self.parent = parent
-        self.intf = anaconda.intf
-        
-        if anaconda.bootloader.getPassword():
-            usePass = 1
-            self.password = anaconda.bootloader.getPassword()
-        else:
-            usePass = 0
-            self.password = None
-        
-        vbox = gtk.VBox(False, 6)
-
-        # password widgets + callback
-        self.usePassCb = gtk.CheckButton(_("_Use a boot loader password"))
-        self.usePassCb.set_tooltip_text(_("A boot loader password prevents users from changing kernel options, increasing security."))
-        self.passButton = gtk.Button("No password")
-        if usePass:
-            self.usePassCb.set_active(True)
-            self.passButton.set_sensitive(True)
-        else:
-            self.usePassCb.set_active(False)
-            self.passButton.set_sensitive(False)
-        self.usePassCb.connect("toggled", self.passCallback)
-        self.passButton.connect("clicked", self.passButtonCallback)
-        self.setPassLabel()
-            
-        box = gtk.HBox(False, 12)
-        box.pack_start(self.usePassCb, False)
-        box.pack_start(self.passButton, False)
-        vbox.pack_start(box, False)
-
-        self.widget = vbox
-
-    def getWidget(self):
-        return self.widget
-
-    def getPassword(self):
-        # XXX should we handle the only having a crypted password case?
-        if self.usePassCb.get_active() and self.password:
-            return self.password
-        else:
-            return None
-
-    # set the label on the button for the bootloader password
-    def setPassLabel(self):
-        self.passButton.set_label(_("Change _password"))        
-        if not self.usePassCb.get_active() or not self.password:
-            self.passButton.set_sensitive(False)
-        else:
-            self.passButton.set_sensitive(True)
-
-    # callback for when the password checkbox is clicked
-    def passCallback(self, widget, *args):
-        if not widget.get_active():
-            self.passButton.set_sensitive(False)
-            self.setPassLabel()
-        else:
-            if self.passwordWindow() == 2:
-                widget.set_active(0)
-            self.setPassLabel()
-
-    # callback for when the password button is clicked
-    def passButtonCallback(self, widget, *args):
-        self.passwordWindow()
-        self.setPassLabel()
-
-    # get the bootloader password
-    def passwordWindow(self, *args):
-        dialog = gtk.Dialog(_("Enter Boot Loader Password"), self.parent)
-        dialog.add_button('gtk-cancel', gtk.RESPONSE_CANCEL)
-        dialog.add_button('gtk-ok', 1)
-        dialog.set_position(gtk.WIN_POS_CENTER)
-        gui.addFrame(dialog)
-        
-        label = gui.WrappingLabel(_("Enter a boot loader password and then confirm it.  (Note that your BIOS keymap may be different than the actual keymap you are used to.)"))
-        label.set_alignment(0.0, 0.0)
-        dialog.vbox.pack_start(label)
-
-        table = gtk.Table(2, 2)
-        table.set_row_spacings(5)
-        table.set_col_spacings(5)
-        label = gui.MnemonicLabel(_("_Password:"))
-        table.attach(label, 0, 1, 2, 3, gtk.FILL, 0, 10)
-        pwEntry = gtk.Entry (16)
-        pwEntry.set_visibility (False)
-        label.set_mnemonic_widget(pwEntry)
-        table.attach(pwEntry, 1, 2, 2, 3, gtk.FILL, 0, 10)
-        label = gui.MnemonicLabel(_("Con_firm:"))        
-        table.attach(label, 0, 1, 3, 4, gtk.FILL, 0, 10) 
-        confirmEntry = gtk.Entry (16)
-        confirmEntry.set_visibility (False)
-        label.set_mnemonic_widget(confirmEntry)
-        table.attach(confirmEntry, 1, 2, 3, 4, gtk.FILL, 0, 10)
-        dialog.vbox.pack_start(table)
-
-        # set the default
-        if self.password:
-            pwEntry.set_text(self.password)
-            confirmEntry.set_text(self.password)
-
-        dialog.show_all()
-
-        while 1:
-            rc = dialog.run()
-            if rc in [gtk.RESPONSE_CANCEL, gtk.RESPONSE_DELETE_EVENT]:
-                break
-
-            if pwEntry.get_text() != confirmEntry.get_text():
-                self.intf.messageWindow(_("Passwords don't match"),
-                                        _("Passwords do not match"),
-                                        type='warning')
-                continue
-
-            thePass = pwEntry.get_text()
-            if not thePass:
-                continue
-            if len(thePass) < 6:
-                ret = self.intf.messageWindow(_("Warning"),
-                                    _("Your boot loader password is shorter than "
-                                      "six characters.  We recommend a longer "
-                                      "boot loader password."
-                                      "\n\n"
-                                      "Would you like to continue with this "
-                                      "password?"),
-                                             type = "yesno")
-                if ret == 0:
-                    continue
-
-            self.password = thePass
-            break
-
-        dialog.destroy()
-        return rc
-
diff --git a/iw/bootloader_main_gui.py b/iw/bootloader_main_gui.py
deleted file mode 100644
index 05588b6..0000000
--- a/iw/bootloader_main_gui.py
+++ /dev/null
@@ -1,244 +0,0 @@
-#
-# bootloader_main_gui.py: gui bootloader configuration dialog
-#
-# Copyright (C) 2001, 2002  Red Hat, Inc.  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 as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# 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, see <http://www.gnu.org/licenses/>.
-#
-# Author(s): Jeremy Katz <katzj@xxxxxxxxxx>
-#
-
-import gtk
-import gobject
-import gui
-from iw_gui import *
-from constants import *
-
-import gettext
-_ = lambda x: gettext.ldgettext("anaconda", x)
-
-from osbootwidget import OSBootWidget
-from blpasswidget import BootloaderPasswordWidget
-
-
-class MainBootloaderWindow(InstallWindow):
-    windowTitle = N_("Boot Loader Configuration")
-
-    def __init__(self, ics):
-        InstallWindow.__init__(self, ics)
-        self.parent = ics.getICW().window
-
-
-    def getPrev(self):
-        pass
-
-
-    def getNext(self):
-        # go ahead and set the device even if we already knew it
-        # since that won't change anything
-        self.bl.setDevice(self.bldev)
-
-        self.bl.drivelist = self.driveorder
-
-        if not self.grubCB.get_active():
-            # if we're not installing a boot loader, don't show the second
-            # screen and don't worry about other options
-            self.dispatch.skipStep("instbootloader", skip = 1)
-
-            # kind of a hack...
-            self.bl.defaultDevice = None
-            return
-        else:
-            self.dispatch.skipStep("instbootloader", skip = 0)
-            self.bl.setUseGrub(1)
-
-        # set the password
-        self.bl.setPassword(self.blpass.getPassword(), isCrypted = 0)
-
-        # set the bootloader images based on what's in our list
-        self.oslist.setBootloaderImages()
-
-    def bootloaderChanged(self, *args):
-        active = self.grubCB.get_active()
-
-        for widget in [ self.oslist.getWidget(), self.blpass.getWidget(), self.deviceButton ]:
-            widget.set_sensitive(active)
-
-
-    def _deviceChange(self, b, anaconda, *args):
-        def __driveChange(combo, dxml, choices):
-            if not choices.has_key("mbr"):
-                return
-
-            iter = combo.get_active_iter()
-            if not iter:
-                return
-
-            first = combo.get_model()[iter][1]
-            desc = choices["mbr"][1]
-            dxml.get_widget("mbrRadio").set_label("%s - /dev/%s" %(_(desc), first))
-            dxml.get_widget("mbrRadio").set_data("bootDevice", first)
-
-        def __genStore(combo, disks, active):
-            model = gtk.TreeStore(gobject.TYPE_STRING, gobject.TYPE_STRING)
-            combo.set_model(model)
-            cell = gtk.CellRendererText()
-            combo.pack_start(cell, True)
-            combo.set_attributes(cell, text = 0)
-
-            for disk in disks:
-                i = model.append(None)
-                model[i] = ("%s %8.0f MB %s" %(disk.name, disk.size,
-                                               disk.description),
-                            "%s" %(disk.name,))
-                if disk.name == active:
-                    combo.set_active_iter(i)
-
-            return model
-
-        (dxml, dialog) = gui.getGladeWidget("blwhere.glade",
-                                            "blwhereDialog")
-        gui.addFrame(dialog)
-        dialog.set_transient_for(self.parent)
-        dialog.show()
-
-        choices = anaconda.platform.bootloaderChoices(self.bl)
-        for t in ("mbr", "boot"):
-            if not choices.has_key(t):
-                continue
-            (device, desc) = choices[t]
-            w = dxml.get_widget("%sRadio" %(t,))
-            w.set_label("%s - /dev/%s" %(_(desc), device))
-            w.show()
-            if self.bldev == device:
-                w.set_active(True)
-            else:
-                w.set_active(False)
-            w.set_data("bootDevice", device)
-
-        for i in range(1, 5):
-            if len(self.driveorder) < i:
-                break
-            combo = dxml.get_widget("bd%dCombo" %(i,))
-            lbl = dxml.get_widget("bd%dLabel" %(i,))
-            combo.show()
-            lbl.show()
-            partitioned = anaconda.storage.partitioned
-            disks = anaconda.storage.disks
-            bl_disks = [d for d in disks if d in partitioned]
-            m = __genStore(combo, bl_disks, self.driveorder[i - 1])
-
-        dxml.get_widget("bd1Combo").connect("changed", __driveChange, dxml, choices)
-        __driveChange(dxml.get_widget("bd1Combo"), dxml, choices)
-
-        while 1:
-            rc = dialog.run()
-            if rc in [gtk.RESPONSE_CANCEL, gtk.RESPONSE_DELETE_EVENT]:
-                break
-
-            # set the boot device based on what they chose
-            if dxml.get_widget("bootRadio").get_active():
-                self.bldev = dxml.get_widget("bootRadio").get_data("bootDevice")
-            elif dxml.get_widget("mbrRadio").get_active():
-                self.bldev = dxml.get_widget("mbrRadio").get_data("bootDevice")
-            else:
-                raise RuntimeError, "No radio button selected!"
-
-            # and adjust the boot order
-            neworder = []
-            for i in range(1, 5):
-                if len(self.driveorder) < i:
-                    break
-
-                combo = dxml.get_widget("bd%dCombo" %(i,))
-                iter = combo.get_active_iter()
-                if not iter:
-                    continue
-
-                act = combo.get_model()[iter][1]
-                if act not in neworder:
-                    neworder.append(act)
-            for d in self.driveorder:
-                if d not in neworder:
-                    neworder.append(d)
-            self.driveorder = neworder
-
-            break
-
-        dialog.destroy()
-        self.grubCB.set_label(_("_Install boot loader on /dev/%s.") %
-                              (self.bldev,))
-        return rc
-
-    def _setBLCBText(self):
-        self.grubCB.set_label(_("_Install boot loader on /dev/%s.") %
-                              (self.bldev,))
-
-
-    def getScreen(self, anaconda):
-        self.dispatch = anaconda.dispatch
-        self.bl = anaconda.bootloader
-        self.intf = anaconda.intf
-
-        self.driveorder = self.bl.drivelist
-        if len(self.driveorder) == 0:
-            partitioned = anaconda.storage.partitioned
-            disks = anaconda.storage.disks
-            self.driveorder = [d.name for d in disks if d in partitioned]
-
-        if self.bl.getPassword():
-            self.usePass = 1
-            self.password = self.bl.getPassword()
-        else:
-            self.usePass = 0
-            self.password = None
-
-        thebox = gtk.VBox (False, 12)
-        thebox.set_border_width(18)
-
-        # make sure we get a valid device to say we're installing to
-        if self.bl.getDevice() is not None:
-            self.bldev = self.bl.getDevice()
-        else:
-            # we don't know what it is yet... if mbr is possible, we want
-            # it, else we want the boot dev
-            choices = anaconda.platform.bootloaderChoices(self.bl)
-            if choices.has_key('mbr'):
-                self.bldev = choices['mbr'][0]
-            else:
-                self.bldev = choices['boot'][0]
-
-        hb = gtk.HBox(False, 12)
-        self.grubCB = gtk.CheckButton(_("_Install boot loader on /dev/%s.") %
-                                      (self.bldev,))
-        self.grubCB.set_active(not self.dispatch.stepInSkipList("instbootloader"))
-        self.grubCB.connect("toggled", self.bootloaderChanged)
-        hb.pack_start(self.grubCB, False)
-
-        self.deviceButton = gtk.Button(_("_Change device"))
-        self.deviceButton.connect("clicked", self._deviceChange, anaconda)
-        hb.pack_start(self.deviceButton, False)
-
-        thebox.pack_start(hb, False)
-
-        # control whether or not there's a boot loader password and what it is
-        self.blpass = BootloaderPasswordWidget(anaconda, self.parent)
-        thebox.pack_start(self.blpass.getWidget(), False)
-
-        # configure the systems available to boot from the boot loader
-        self.oslist = OSBootWidget(anaconda, self.parent)
-        thebox.pack_end(self.oslist.getWidget(), True)
-
-        self.bootloaderChanged()
-        return thebox
diff --git a/iw/checklist.py b/iw/checklist.py
deleted file mode 100644
index 50026a1..0000000
--- a/iw/checklist.py
+++ /dev/null
@@ -1,225 +0,0 @@
-#
-# checklist.py: A class (derived from GtkTreeView) that provides a list of
-#               checkbox / text string pairs
-#
-# Copyright (C) 2000, 2001  Red Hat, Inc.  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 as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# 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, see <http://www.gnu.org/licenses/>.
-#
-# Author(s): Brent Fox <bfox@xxxxxxxxxx>
-#            Jeremy Katz <katzj@xxxxxxxxxx>
-#
-
-import gtk
-import gobject
-
-class CheckList (gtk.TreeView):
-    """A class (derived from gtk.TreeView) that provides a list of
-    checkbox / text string pairs"""
-
-    # override this to make your own columns if necessary
-    def create_columns(self, columns):
-        # add the string columns to the tree view widget
-        for i in range(1, columns + 1):
-            renderer = gtk.CellRendererText()
-            column = gtk.TreeViewColumn('Text', renderer, text=i,
-                                        **self.sensitivity_args)
-            column.set_clickable(False)
-            self.append_column(column)
-
-    # XXX need to handle the multicolumn case better still....
-    def __init__ (self, columns = 1, custom_store=None, sensitivity=False):
-	if custom_store is None:
-	    self.store = gtk.TreeStore(gobject.TYPE_BOOLEAN,
-				       gobject.TYPE_STRING,
-				       gobject.TYPE_STRING)
-	else:
-	    self.store = custom_store
-	    
-        gtk.TreeView.__init__ (self, self.store)
-        
-        # XXX we only handle two text columns right now
-        if custom_store is None and columns > 2:
-            raise RuntimeError, "CheckList supports a maximum of 2 columns"
-	
-        self.columns = columns
-
-        # sensitivity_col is an optional hidden boolean column that controls
-        # the sensitive property of all of the CellRenderers in its row.
-        #
-        # To enable this functionality the last column in the TreeStore
-        # must be boolean and you must pass a value of True for the
-        # 'sensitivity' keyword argument to this class' constructor.
-        self.sensitivity_col = None
-        self.sensitivity_args = {}
-        last_col = self.store.get_n_columns() - 1
-        if sensitivity and \
-           self.store.get_column_type(last_col) == gobject.TYPE_BOOLEAN:
-            self.sensitivity_col = last_col
-            self.sensitivity_args = {"sensitive": self.sensitivity_col}
-
-        self.checkboxrenderer = gtk.CellRendererToggle()
-        column = gtk.TreeViewColumn('', self.checkboxrenderer, active=0,
-                                    **self.sensitivity_args)
-#        column.set_sizing(gtk.TREE_VIEW_COLUMN_FIXED)
-#        column.set_fixed_width(40)
-        column.set_clickable(True)
-        self.checkboxrenderer.connect ("toggled", self.toggled_item)        
-        self.append_column(column)
-
-	self.create_columns(columns)
-
-        self.set_rules_hint(False)
-        self.set_headers_visible(False)
-        self.columns_autosize()
-        self.set_enable_search(False)
-
-        # keep track of the number of rows we have so we can
-        # iterate over them all
-        self.num_rows = 0
-
-        self.tiptext = {}
-        self.props.has_tooltip = True
-        self.connect("query-tooltip", self._tipQuery)
-
-    def _tipQuery(self, widget, x, y, kbd, tip, *data):
-        (tx, ty) = widget.convert_widget_to_bin_window_coords(x, y)
-        r = widget.get_path_at_pos(tx, ty)
-        if not r:
-            return False
-        path = r[0]
-        if not self.tiptext.has_key(path):
-            return False
-        tip.set_text(self.tiptext[path])
-        return True
-
-    def append_row (self, textList, init_value, tooltipText = None):
-        """Add a row to the list.
-        text: text to display in the row
-        init_value: initial state of the indicator
-        tooltipText: the text that will appear when the mouse is over the row."""
-
-        iter = self.store.append(None)
-        self.store.set_value(iter, 0, init_value)
-        if self.sensitivity_col is not None:
-            self.store.set_value(iter, self.sensitivity_col, True)
-
-        # add the text for the number of columns we have
-        i = 1
-        for text in textList[:self.columns]:
-            self.store.set_value(iter, i, textList[i - 1])
-            i = i + 1
-
-        if tooltipText:
-            self.tiptext[self.store.get_path(iter)] = tooltipText
-
-        self.num_rows = self.num_rows + 1
-
-
-    def toggled_item(self, data, row):
-        """Set a function to be called when the value of a row is toggled.
-        The  function will be called with two arguments, the clicked item
-        in the row and a string for which row was clicked."""
-        
-        iter = self.store.get_iter((int(row),))
-        val = self.store.get_value(iter, 0)
-        self.store.set_value(iter, 0, not val)
-
-
-    def clear (self):
-        "Remove all rows"
-        self.store.clear()
-        self.num_rows = 0
-
-
-    def get_active(self, row):
-        """Return FALSE or TRUE as to whether or not the row is toggled
-        similar to GtkToggleButtons"""
-
-        iter = self.store.get_iter((row,))
-        return self.store.get_value(iter, 0)
-
-
-    def set_active(self, row, is_active):
-        "Set row to be is_active, similar to GtkToggleButton"
-
-        iter = self.store.get_iter((row,))
-        self.store.set_value(iter, 0, is_active)
-
-
-    def get_text(self, row, column):
-        "Get the text from row and column"
-
-        iter = self.store.get_iter((row,))
-        return self.store.get_value(iter, column)
-
-
-    def set_column_title(self, column, title):
-        "Set the title of column to title"
-
-        col = self.get_column(column)
-        if col:
-            col.set_title(title)
-
-
-    def set_column_min_width(self, column, min):
-        "Set the minimum width of column to min"
-
-        col = self.get_column(column)
-        if col:
-            col.set_min_width(min)
-
-
-    def set_column_clickable(self, column, clickable):
-        "Set the column to be clickable"
-
-        col = self.get_column(column)
-        if col:
-            col.set_clickable(clickable)
-            
-
-    def set_column_sizing(self, column, sizing):
-        "Set the column to use the given sizing method"
-
-        col = self.get_column(column)
-        if col:
-            col.set_sizing(sizing)
-
-    def set_column_sort_id(self, column, id):
-        "Set the sort id of column to id"
-
-        col = self.get_column(column)
-        if col:
-            col.set_sort_column_id(id)
-
-def main():
-    win = gtk.Window()
-    cl = CheckList(1)
-    for i in range(1, 10):
-        cl.append_row("%s" %(i,), False, "foo: %d" %(i,))
-
-    sw = gtk.ScrolledWindow()
-    sw.set_policy (gtk.POLICY_NEVER, gtk.POLICY_AUTOMATIC)
-    sw.add (cl)
-    sw.set_shadow_type(gtk.SHADOW_IN)
-    cl.set_headers_visible(True)
-
-    win.add(sw)
-    win.set_size_request(250, 250)
-    win.show_all()
-
-    gtk.main()
-
-if __name__ == "__main__":
-    main()
diff --git a/iw/cleardisks_gui.py b/iw/cleardisks_gui.py
deleted file mode 100644
index 0fee708..0000000
--- a/iw/cleardisks_gui.py
+++ /dev/null
@@ -1,240 +0,0 @@
-#
-# Select which disks to clear and which ones to just mount.
-#
-# Copyright (C) 2009  Red Hat, Inc.
-# 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 as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# 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, see <http://www.gnu.org/licenses/>.
-#
-
-import gtk, gobject
-import gui
-from DeviceSelector import *
-from constants import *
-import isys
-from iw_gui import *
-from storage.udev import *
-
-import gettext
-_ = lambda x: gettext.ldgettext("anaconda", x)
-
-class ClearDisksWindow (InstallWindow):
-    windowTitle = N_("Clear Disks Selector")
-
-    def getNext (self):
-        # All the rows that are visible in the right hand side should be cleared.
-        cleardisks = []
-        for row in self.store:
-            if row[self.rightVisible]:
-                cleardisks.append(row[OBJECT_COL].name)
-
-        if len(cleardisks) == 0:
-            self.anaconda.intf.messageWindow(_("Error"),
-                                             _("You must select at least one "
-                                               "drive to be used for installation."),
-                                             custom_icon="error")
-            raise gui.StayOnScreen
-
-        # The selected row is the disk to boot from.
-        selected = self.rightDS.getSelected()
-
-        if len(selected) == 0:
-            self.anaconda.intf.messageWindow(_("Error"),
-                                             _("You must select one drive to "
-                                               "boot from."),
-                                             custom_icon="error")
-            raise gui.StayOnScreen
-
-        bootDisk = selected[0][OBJECT_COL].name
-
-        cleardisks.sort(self.anaconda.storage.compareDisks)
-
-        self.anaconda.storage.clearPartDisks = cleardisks
-        self.anaconda.bootloader.updateDriveList([bootDisk])
-
-    def getScreen (self, anaconda):
-        # We can't just use exclusiveDisks here because of kickstart.  First,
-        # the kickstart file could have used ignoredisk --drives= in which case
-        # exclusiveDisks would be empty.  Second, ignoredisk is entirely
-        # optional in which case neither list would be populated.  Luckily,
-        # storage.disks takes isIgnored into account and that handles both these
-        # issues.
-        disks = filter(lambda d: not d.format.hidden, anaconda.storage.disks)
-
-        # Skip this screen as well if there's only one disk to use.
-        if len(disks) == 1:
-            anaconda.storage.clearPartDisks = [disks[0].name]
-            anaconda.bootloader.drivelist = [disks[0].name]
-            return None
-
-        (xml, self.vbox) = gui.getGladeWidget("cleardisks.glade", "vbox")
-        self.leftScroll = xml.get_widget("leftScroll")
-        self.rightScroll = xml.get_widget("rightScroll")
-        self.addButton = xml.get_widget("addButton")
-        self.removeButton = xml.get_widget("removeButton")
-        self.installTargetImage = xml.get_widget("installTargetImage")
-        self.installTargetTip = xml.get_widget("installTargetTip")
-
-        self.anaconda = anaconda
-
-        self.leftVisible = 1
-        self.leftActive = 2
-        self.rightVisible = 4
-        self.rightActive = 5
-
-        # One store for both views.  First the obejct, then a visible/active for
-        # the left hand side, then a visible/active for the right hand side, then
-        # all the other stuff.
-        #
-        # NOTE: the third boolean is a placeholder.  DeviceSelector uses the third
-        # slot in the store to determine whether the row is immutable or not.  We
-        # just need to put False in there for everything.
-        self.store = gtk.TreeStore(gobject.TYPE_PYOBJECT,
-                                   gobject.TYPE_BOOLEAN, gobject.TYPE_BOOLEAN,
-                                   gobject.TYPE_BOOLEAN,
-                                   gobject.TYPE_BOOLEAN, gobject.TYPE_BOOLEAN,
-                                   gobject.TYPE_STRING, gobject.TYPE_STRING,
-                                   gobject.TYPE_STRING, gobject.TYPE_STRING,
-                                   gobject.TYPE_STRING)
-        self.store.set_sort_column_id(6, gtk.SORT_ASCENDING)
-
-        # The left view shows all the drives that will just be mounted, but
-        # can still be moved to the right hand side.
-        self.leftFilteredModel = self.store.filter_new()
-        self.leftSortedModel = gtk.TreeModelSort(self.leftFilteredModel)
-        self.leftTreeView = gtk.TreeView(self.leftSortedModel)
-
-        self.leftFilteredModel.set_visible_func(lambda model, iter, view: model.get_value(iter, self.leftVisible), self.leftTreeView)
-
-        self.leftScroll.add(self.leftTreeView)
-
-        self.leftDS = DeviceSelector(self.store, self.leftSortedModel,
-                                     self.leftTreeView, visible=self.leftVisible,
-                                     active=self.leftActive)
-        self.leftDS.createMenu()
-        self.leftDS.addColumn(_("Model"), 6)
-        self.leftDS.addColumn(_("Capacity"), 7)
-        self.leftDS.addColumn(_("Vendor"), 8)
-        self.leftDS.addColumn(_("Interconnect"), 9, displayed=False)
-        self.leftDS.addColumn(_("Serial Number"), 10, displayed=False)
-
-        # The right view show all the drives that will be wiped during install.
-        self.rightFilteredModel = self.store.filter_new()
-        self.rightSortedModel = gtk.TreeModelSort(self.rightFilteredModel)
-        self.rightTreeView = gtk.TreeView(self.rightSortedModel)
-
-        self.rightFilteredModel.set_visible_func(lambda model, iter, view: model.get_value(iter, self.rightVisible), self.rightTreeView)
-
-        self.rightScroll.add(self.rightTreeView)
-
-        self.rightDS = DeviceSelector(self.store, self.rightSortedModel,
-                                      self.rightTreeView, visible=self.rightVisible,
-                                      active=self.rightActive)
-        self.rightDS.createSelectionCol(title=_("Boot\nLoader"), radioButton=True)
-        self.rightDS.addColumn(_("Model"), 6)
-        self.rightDS.addColumn(_("Capacity"), 7)
-
-        # Store the first disk (according to our detected BIOS order) for
-        # auto boot device selection
-        names = map(lambda d: d.name, disks)
-        self.bootDisk = sorted(names, self.anaconda.storage.compareDisks)[0]
-
-        # The device filtering UI set up exclusiveDisks as a list of the names
-        # of all the disks we should use later on.  Now we need to go get those,
-        # look up some more information in the devicetree, and set up the
-        # selector.
-        for d in disks:
-            rightVisible = d.name in self.anaconda.storage.clearPartDisks
-            rightActive = rightVisible and \
-                          d.name in self.anaconda.bootloader.drivelist[:1]
-            leftVisible = not rightVisible
-            self.store.append(None, (d,
-                                     leftVisible, True, False,
-                                     rightVisible, rightActive,
-                                     d.model,
-                                     str(int(d.size)) + " MB",
-                                     d.vendor, "", d.serial))
-
-        self.addButton.connect("clicked", self._add_clicked)
-        self.removeButton.connect("clicked", self._remove_clicked)
-
-        # Also allow moving devices back and forth with double click, enter, etc.
-        self.leftTreeView.connect("row-activated", self._add_clicked)
-        self.rightTreeView.disconnect(self.rightDS._activated_id)
-        self.rightTreeView.connect("row-activated", self._remove_clicked)
-
-        # And let the user select multiple devices at a time.
-        self.leftTreeView.get_selection().set_mode(gtk.SELECTION_MULTIPLE)
-        self.rightTreeView.get_selection().set_mode(gtk.SELECTION_MULTIPLE)
-
-        if self.anaconda.storage.clearPartType == CLEARPART_TYPE_LINUX:
-            self.installTargetTip.set_markup(_("<b>Tip:</b> All Linux filesystems on the install target devices will be reformatted and wiped of any data.  Make sure you have backups."))
-        elif self.anaconda.storage.clearPartType == CLEARPART_TYPE_ALL:
-            self.installTargetTip.set_markup(_("<b>Tip:</b> The install target devices will be reformatted and wiped of any data.  Make sure you have backups."))
-        else:
-            self.installTargetTip.set_markup(_("<b>Tip:</b> Your filesystems on the install target devices will not be reformatted unless you choose to do so during customization."))
-
-        return self.vbox
-
-    def _autoSelectBootDisk(self):
-        if self.rightDS.getSelected():
-            return
-
-        for row in self.store:
-            if row[OBJECT_COL].name == self.bootDisk and row[self.rightVisible]:
-                row[self.rightActive] = True
-
-    def _add_clicked(self, widget, *args, **kwargs):
-        (sortedModel, pathlist) = self.leftTreeView.get_selection().get_selected_rows()
-
-        if not pathlist:
-            return
-
-        for path in reversed(pathlist):
-            sortedIter = sortedModel.get_iter(path)
-            if not sortedIter:
-                continue
-
-            filteredIter = self.leftSortedModel.convert_iter_to_child_iter(None, sortedIter)
-            iter = self.leftFilteredModel.convert_iter_to_child_iter(filteredIter)
-
-            self.store.set_value(iter, self.leftVisible, False)
-            self.store.set_value(iter, self.rightVisible, True)
-            self.store.set_value(iter, self.rightActive, False)
-
-        self._autoSelectBootDisk()
-        self.leftFilteredModel.refilter()
-        self.rightFilteredModel.refilter()
-
-    def _remove_clicked(self, widget, *args, **kwargs):
-        (sortedModel, pathlist) = self.rightTreeView.get_selection().get_selected_rows()
-
-        if not pathlist:
-            return
-
-        for path in reversed(pathlist):
-            sortedIter = sortedModel.get_iter(path)
-            if not sortedIter:
-                continue
-
-            filteredIter = self.rightSortedModel.convert_iter_to_child_iter(None, sortedIter)
-            iter = self.rightFilteredModel.convert_iter_to_child_iter(filteredIter)
-
-            self.store.set_value(iter, self.leftVisible, True)
-            self.store.set_value(iter, self.rightVisible, False)
-            self.store.set_value(iter, self.rightActive, False)
-
-        self._autoSelectBootDisk()
-        self.leftFilteredModel.refilter()
-        self.rightFilteredModel.refilter()
diff --git a/iw/congrats_gui.py b/iw/congrats_gui.py
deleted file mode 100644
index 3027568..0000000
--- a/iw/congrats_gui.py
+++ /dev/null
@@ -1,103 +0,0 @@
-#
-# congrats_gui.py: install/upgrade complete screen.
-#
-# Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006  Red Hat, Inc.
-# 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 as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# 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, see <http://www.gnu.org/licenses/>.
-#
-
-import gtk
-import gui
-from iw_gui import *
-from constants import *
-import os
-import platform
-
-import gettext
-_ = lambda x: gettext.ldgettext("anaconda", x)
-
-class CongratulationWindow (InstallWindow):		
-
-    windowTitle = N_("Congratulations")
-
-    def __init__ (self, ics):
-	InstallWindow.__init__(self, ics)
-
-        ics.setPrevEnabled(False)
-
-        # force buttonbar on in case release notes viewer is running
-        ics.cw.mainxml.get_widget("buttonBar").set_sensitive(True)
-
-        self.rebootButton = ics.cw.mainxml.get_widget("rebootButton")
-
-        # this mucks around a bit, but it's the weird case and it's
-        # better than adding a lot of complication to the normal
-	ics.cw.mainxml.get_widget("nextButton").hide()
-        if os.path.exists(os.environ.get("LIVE_BLOCK", "/dev/mapper/live-osimg-min")):
-            ics.cw.mainxml.get_widget("closeButton").show()
-            ics.cw.mainxml.get_widget("closeButton").grab_focus()
-        else:
-            self.rebootButton.show()
-            self.rebootButton.grab_focus()
-            ics.cw.mainxml.get_widget("rebootButton").show()
-            ics.cw.mainxml.get_widget("rebootButton").grab_focus()
-
-    def getNext(self):
-	# XXX - copy any screenshots over
-	gui.copyScreenshots()
-
-    # CongratulationWindow tag=NA
-    def getScreen (self, anaconda):
-        hbox = gtk.HBox (False, 5)
-        
-        pix = gui.readImageFromFile ("done.png")
-        if pix:
-            a = gtk.Alignment ()
-            a.add (pix)
-            a.set (0.5, 0.5, 1.0, 1.0)
-	    a.set_size_request(200, -1)
-            hbox.pack_start (a, False, False, 36)
-
-        if isinstance(anaconda.platform, platform.S390):
-            txt = _("Congratulations, your %s installation is complete.\n\n") % (productName,)
-
-            if not anaconda.canReIPL:
-                self.rebootButton.set_label(_("Shutdown"))
-
-                txt = txt + _("Please shutdown to use the installed system.\n")
-            else:
-                txt = txt + _("Please reboot to use the installed system.\n")
-
-            if not anaconda.reIPLMessage is None:
-                txt = txt + "\n" + anaconda.reIPLMessage + "\n\n"
-
-            txt = txt + _("Note that updates may be available to ensure the proper "
-                          "functioning of your system and installation of these "
-                          "updates is recommended after the reboot.")
-        else:
-            txt = _("Congratulations, your %s installation is complete.\n\n"
-                    "Please reboot to use the installed system.  "
-                    "Note that updates may be available to ensure the proper "
-                    "functioning of your system and installation of these "
-                    "updates is recommended after the reboot.") %(productName,)
-
-	label = gui.WrappingLabel(txt)
-        label.set_size_request(250, -1)
-
-        hbox.pack_start (label, True, True)
-
-        gtk.gdk.beep()
-        return hbox
-
diff --git a/iw/datacombo.py b/iw/datacombo.py
deleted file mode 100644
index 9b6a092..0000000
--- a/iw/datacombo.py
+++ /dev/null
@@ -1,99 +0,0 @@
-#
-# datacombo.py: A class (derived from GtkComboBox) that provides
-#               the ability to store data and show text in a GtkComboBox easily
-#
-# Copyright (C) 2004  Red Hat, Inc.  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 as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# 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, see <http://www.gnu.org/licenses/>.
-#
-# Author(s): Jeremy Katz <katzj@xxxxxxxxxx>
-#
-
-import gtk
-import gobject
-
-class DataComboBox(gtk.ComboBox):
-    """A class derived from gtk.ComboBox to allow setting a user visible
-    string and (not-visible) data string"""
-
-    def __init__(self, store = None):
-        if store is None:
-            self.store = gtk.TreeStore(gobject.TYPE_STRING, gobject.TYPE_STRING)
-        else:
-            self.store = store
-        gtk.ComboBox.__init__(self, self.store)
-
-        cell = gtk.CellRendererText()
-        self.pack_start(cell, True)
-        self.set_attributes(cell, text = 0)
-
-    def append(self, text, data):
-        iter = self.store.append(None)
-        self.store[iter] = (text, data)
-
-    def get_active_value(self, col = 1):
-        row = self.get_active()
-        return self.get_stored_data(row, col)
-
-    def get_stored_data(self, row, col = 1):
-        if row < 0:
-            return None
-        iter = self.store.get_iter(row)
-        val = self.store.get_value(iter, col)
-        return val
-
-    def get_text(self, row):
-        return self.get_stored_data(row, col = 0)
-
-    def set_active_text(self, t):
-        """set_active_text(string) ->  Sets the active row to whereever t is.
-           returns True if set_active is run, False otherwise.
-        """
-        retval = False
-        n = 0
-        i = self.store.get_iter(n)
-        while i is not None:
-            if self.store.get_value(i, 0) == t:
-                self.set_active(n)
-                retval = True
-                break
-            i = self.store.iter_next(i)
-            n += 1
-
-        return retval
-
-    def clear(self):
-        self.store.clear()
-
-if __name__ == "__main__":
-    def mycb(widget, *args):
-        idx = widget.get_active()
-        print(idx, widget.get_stored_data(idx), widget.get_text(idx))
-        
-    win = gtk.Window()
-
-    cb = DataComboBox()
-    cb.append("/dev/hda5", "hda5")
-    cb.append("/dev/hda6", "hda6")
-    cb.append("/dev/hda7", "hda7")
-    cb.append("/dev/hda8", "hda8")
-    cb.set_active_text("/dev/hda7")
-
-    cb.connect('changed', mycb)
-    
-    win.add(cb)
-    win.show_all()
-
-    gtk.main()
-
diff --git a/iw/examine_gui.py b/iw/examine_gui.py
deleted file mode 100644
index e40ebf8..0000000
--- a/iw/examine_gui.py
+++ /dev/null
@@ -1,163 +0,0 @@
-#
-# examine_gui.py: dialog to allow selection of a RHL installation to upgrade
-#
-# Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006  Red Hat, Inc.
-# 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 as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# 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, see <http://www.gnu.org/licenses/>.
-#
-
-import gtk
-import gui
-from iw_gui import *
-from pixmapRadioButtonGroup_gui import pixmapRadioButtonGroup
-from constants import *
-import upgrade
-from flags import flags
-
-import gettext
-_ = lambda x: gettext.ldgettext("anaconda", x)
-
-UPGRADE_STR = "upgrade"
-REINSTALL_STR = "reinstall"
-
-seenExamineScreen = False
-
-class UpgradeExamineWindow (InstallWindow):
-
-    windowTitle = N_("Upgrade Examine")
-
-    def getNext (self):
-        if self.doupgrade:
-            upgrade.setSteps(self.anaconda)
-            self.anaconda.upgrade = True
-
-	    rootfs = self.parts[self.upgradecombo.get_active()]
-            self.anaconda.upgradeRoot = [(rootfs[0], rootfs[1])]
-            self.anaconda.rootParts = self.parts
-
-            self.anaconda.dispatch.skipStep("installtype", skip = 1)
-            self.anaconda.upgrade = True
-        else:
-            self.anaconda.dispatch.skipStep("installtype", skip = 0)
-            self.anaconda.upgrade = False
-	
-        return None
-
-    def createUpgradeOption(self):
-	r = pixmapRadioButtonGroup()
-	r.addEntry(REINSTALL_STR, _("Fresh Installation"),
-		   pixmap=gui.readImageFromFile("install.png"),
-                   descr=_("Choose this option to install a fresh copy of %s "
-                           "on your system.  Existing software and data may "
-                           "be overwritten depending on your configuration "
-                           "choices.") % productName)
-
-	r.addEntry(UPGRADE_STR, _("Upgrade an Existing Installation"),
-		   pixmap=gui.readImageFromFile("upgrade.png"),
-                   descr=_("Choose this option if you would like to upgrade "
-                           "your existing %s system.  This option will "
-                           "preserve the existing data on your storage "
-                           "device(s).") % productName)
-
-	return r
-
-    def upgradeOptionsSetSensitivity(self, state):
-	self.uplabel.set_sensitive(state)
-	self.upgradecombo.set_sensitive(state)
-
-    def optionToggled(self, widget, name):
-	if name == UPGRADE_STR:
-	    self.upgradeOptionsSetSensitivity(widget.get_active())
-	    self.doupgrade = widget.get_active()
-
-    #UpgradeExamineWindow tag = "upgrade"
-    def getScreen (self, anaconda):
-        global seenExamineScreen
-        self.anaconda = anaconda
-
-        if not seenExamineScreen:
-	    # this is the first time we've entered this screen
-	    self.doupgrade = self.anaconda.dispatch.stepInSkipList("installtype")
-            seenExamineScreen = True
-	else:
-	    self.doupgrade = self.anaconda.upgrade
-
-        # we might get here after storage reset that obsoleted
-        # root device objects we had found
-        if not self.anaconda.rootParts:
-            self.anaconda.rootParts = upgrade.findExistingRoots(self.anaconda,
-                                                                flags.cmdline.has_key("upgradeany"))
-            upgrade.setUpgradeRoot(self.anaconda)
-
-        self.parts = self.anaconda.rootParts
-
-        vbox = gtk.VBox (False, 12)
-	vbox.set_border_width (8)
-
-        introLabel = gtk.Label(_("At least one existing installation has been "
-                                 "detected on your system.  What would you "
-                                 "like to do?"))
-        introLabel.set_alignment(0, 0)
-        vbox.pack_start(introLabel, False, False)
-
-	r = self.createUpgradeOption()
-        self.r = r
-
-	b = self.r.render()
-	if self.doupgrade:
-	    self.r.setCurrent(UPGRADE_STR)
-	else:
-	    self.r.setCurrent(REINSTALL_STR)
-
-	self.r.setToggleCallback(self.optionToggled)
-        vbox.pack_start(b, False)
-        self.root = self.parts[0]
-
-	uplabelstr = _("<b>Which %s installation would you like to upgrade?</b>") % productName
-	self.uplabel = gtk.Label(uplabelstr)
-        self.uplabel.set_use_markup(True)
-        self.uplabel.set_alignment(0, 0)
-        model = gtk.ListStore(str)
-	self.upgradecombo = gtk.ComboBox(model)
-
-        cell = gtk.CellRendererText()
-        self.upgradecombo.pack_start(cell, True)
-        self.upgradecombo.set_attributes(cell, markup=0)
-
-	for (dev, desc) in self.parts:
-            iter = model.append()
-	    if (desc is None) or len(desc) < 1:
-		desc = _("Unknown Linux system")
-            model[iter][0] = "<small>%s <i>(installed on %s)</i></small>" %(desc, dev.path)
-
-	# hack hack hackity hack
-        alignment = gtk.Alignment(xalign=0.25)
-        alignmentBox = gtk.VBox(False, 6)
-        alignmentBox.pack_start(self.uplabel, False, False)
-        alignmentBox.pack_start(self.upgradecombo, False, False)
-        alignment.add(alignmentBox)
-        vbox.pack_start(alignment, True, True)
-
-	# set default
-	idx = 0
-	for p in self.parts:
-	    if self.anaconda.upgradeRoot[0][0] == p[0]:
-	        self.upgradecombo.set_active(idx)
-	        break
-	    idx = idx + 1
-
-	self.upgradeOptionsSetSensitivity(self.doupgrade)
-
-        return vbox
diff --git a/iw/filter_gui.py b/iw/filter_gui.py
deleted file mode 100644
index a267ce2..0000000
--- a/iw/filter_gui.py
+++ /dev/null
@@ -1,764 +0,0 @@
-#
-# Storage filtering UI
-#
-# Copyright (C) 2009  Red Hat, Inc.
-# 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 as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# 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, see <http://www.gnu.org/licenses/>.
-#
-
-import block
-import collections
-import gtk, gobject
-import gtk.glade
-import gui
-import parted
-import _ped
-from DeviceSelector import *
-from baseudev import *
-from constants import *
-from iw_gui import *
-from storage.devices import devicePathToName
-from storage.udev import *
-from storage.devicelibs.mpath import *
-from flags import flags
-import storage.iscsi
-import storage.fcoe
-import storage.zfcp
-import storage.dasd
-
-import gettext
-_ = lambda x: gettext.ldgettext("anaconda", x)
-
-DEVICE_COL = 4
-MODEL_COL = 5
-CAPACITY_COL = 6
-VENDOR_COL = 7
-INTERCONNECT_COL = 8
-SERIAL_COL = 9
-ID_COL = 10
-PATHS_COL = 11
-PORT_COL = 12
-TARGET_COL = 13
-LUN_COL = 14
-
-# This is kind of a magic class that is used for populating the device store.
-# It mostly acts like a list except for some funny behavior on adding/getting.
-# You must add udev dicts to this list, but when you go to examine the list
-# (by pulling items out, checking membership, etc.) you are comparing based
-# on names.
-#
-# The only reason to have this is to prevent needing two lists in a variety
-# of places throughout FilterWindow.
-class NameCache(collections.MutableSequence):
-    def __init__(self, iterable):
-        self._lst = list(iterable)
-
-    def __contains__(self, item):
-        return item["name"] in iter(self)
-
-    def __delitem__(self, index):
-        return self._lst.__delitem__(index)
-
-    def __getitem__(self, index):
-        return self._lst.__getitem__(index)["name"]
-
-    def __iter__(self):
-        for d in self._lst:
-            yield d["name"]
-
-    def __len__(self):
-        return len(self._lst)
-
-    def __setitem__(self, index, value):
-        return self._lst.__setitem__(index, value)
-
-    def insert(self, index, value):
-        return self._lst.insert(index, value)
-
-# These are global because they need to be accessible across all Callback
-# objects as the same values, and from the AdvancedFilterWindow object to add
-# and remove devices when populating scrolled windows.
-totalDevices = 0
-selectedDevices = 0
-totalSize = 0
-selectedSize = 0
-
-# These are global so they can be accessed from all Callback objects.  The
-# basic callback defines its membership as anything that doesn't pass the
-# is* methods.
-def isCCISS(info):
-    return udev_device_is_cciss(info)
-
-def isRAID(info):
-    if flags.dmraid:
-        return udev_device_is_biosraid(info)
-
-    return False
-
-def isMultipath(info):
-    return udev_device_is_multipath_member(info)
-
-def isOther(info):
-    return udev_device_is_iscsi(info) or udev_device_is_fcoe(info)
-
-class Callbacks(object):
-    def __init__(self, xml):
-        self.model = None
-        self.xml = xml
-
-        self.sizeLabel = self.xml.get_widget("sizeLabel")
-        self.sizeLabel.connect("realize", self.update)
-
-    def addToUI(self, tuple):
-        pass
-
-    def deviceToggled(self, set, device):
-        global selectedDevices, totalDevices
-        global selectedSize, totalSize
-
-        if set:
-            selectedDevices += 1
-            selectedSize += device["XXX_SIZE"]
-        else:
-            selectedDevices -= 1
-            selectedSize -= device["XXX_SIZE"]
-
-        self.update()
-
-    def isMember(self, info):
-        return info and not isRAID(info) and not isCCISS(info) and \
-               not isMultipath(info) and not isOther(info)
-
-    def update(self, *args, **kwargs):
-        global selectedDevices, totalDevices
-        global selectedSize, totalSize
-
-        self.sizeLabel.set_markup(_("Selected devices: %s (%s MB) out of %s (%s MB).") % (selectedDevices, selectedSize, totalDevices, totalSize))
-
-    def visible(self, model, iter, view):
-        # Most basic visibility function - does the model say this row
-        # should be visible?  Subclasses can define their own more specific
-        # visibility function, though they should also take a look at this
-        # one to see what the model says.
-        return self.isMember(model.get_value(iter, OBJECT_COL)) and \
-               model.get_value(iter, VISIBLE_COL)
-
-class RAIDCallbacks(Callbacks):
-    def isMember(self, info):
-        return info and (isRAID(info) or isCCISS(info))
-
-class FilteredCallbacks(Callbacks):
-    def __init__(self, *args, **kwargs):
-        Callbacks.__init__(self, *args, **kwargs)
-
-        # Are we even applying the filtering UI?  This is False when
-        # whateverFilterBy is empty, True the rest of the time.
-        self.filtering = False
-
-    def reset(self):
-        self.notebook.set_current_page(0)
-        self.filtering = False
-
-    def set(self, num):
-        self.notebook.set_current_page(num)
-        self.filtering = True
-
-class MPathCallbacks(FilteredCallbacks):
-    def __init__(self, *args, **kwargs):
-        FilteredCallbacks.__init__(self, *args, **kwargs)
-
-        self._vendors = []
-        self._interconnects = []
-
-        self.filterBy = self.xml.get_widget("mpathFilterBy")
-        self.notebook = self.xml.get_widget("mpathNotebook")
-
-        self.vendorEntry = self.xml.get_widget("mpathVendorEntry")
-        self.interconnectEntry = self.xml.get_widget("mpathInterconnectEntry")
-        self.IDEntry = self.xml.get_widget("mpathIDEntry")
-
-        self.mpathFilterHBox = self.xml.get_widget("mpathFilterHBox")
-        self.mpathFilterHBox.connect("realize", self._populateUI)
-
-        self.vendorEntry.connect("changed", lambda entry: self.model.get_model().refilter())
-        self.interconnectEntry.connect("changed", lambda entry: self.model.get_model().refilter())
-        self.IDEntry.connect("changed", lambda entry: self.model.get_model().refilter())
-
-    def addToUI(self, tuple):
-        if not tuple[VENDOR_COL] in self._vendors:
-            self._vendors.append(tuple[VENDOR_COL])
-
-        if not tuple[INTERCONNECT_COL] in self._interconnects:
-            self._interconnects.append(tuple[INTERCONNECT_COL])
-
-    def isMember(self, info):
-        return info and isMultipath(info)
-
-    def visible(self, model, iter, view):
-        if not FilteredCallbacks.visible(self, model, iter, view):
-            return False
-
-        if self.filtering:
-            if self.notebook.get_current_page() == 0:
-                return self._visible_by_interconnect(model, iter, view)
-            elif self.notebook.get_current_page() == 1:
-                return self._visible_by_vendor(model, iter, view)
-            elif self.notebook.get_current_page() == 2:
-                return self._visible_by_wwid(model, iter, view)
-
-        return True
-
-    def _populateUI(self, widget):
-        cell = gtk.CellRendererText()
-
-        self._vendors.sort()
-        self.vendorEntry.set_model(gtk.ListStore(gobject.TYPE_STRING))
-        self.vendorEntry.pack_start(cell)
-        self.vendorEntry.add_attribute(cell, 'text', 0)
-
-        for v in self._vendors:
-            self.vendorEntry.append_text(v)
-
-        self.vendorEntry.show_all()
-
-        self._interconnects.sort()
-        self.interconnectEntry.set_model(gtk.ListStore(gobject.TYPE_STRING))
-        self.interconnectEntry.pack_start(cell)
-        self.interconnectEntry.add_attribute(cell, 'text', 0)
-
-        for i in self._interconnects:
-            self.interconnectEntry.append_text(i)
-
-        self.interconnectEntry.show_all()
-
-    def _visible_by_vendor(self, model, iter, view):
-        entered = self.vendorEntry.get_child().get_text()
-        return model.get_value(iter, VENDOR_COL).find(entered) != -1
-
-    def _visible_by_interconnect(self, model, iter, view):
-        entered = self.interconnectEntry.get_child().get_text()
-        return model.get_value(iter, INTERCONNECT_COL).find(entered) != -1
-
-    def _visible_by_wwid(self, model, iter, view):
-        # FIXME:  make this support globs, etc.
-        entered = self.IDEntry.get_text()
-
-        return entered != "" and model.get_value(iter, ID_COL).find(entered) != -1
-
-class OtherCallbacks(MPathCallbacks):
-    def __init__(self, *args, **kwargs):
-        FilteredCallbacks.__init__(self, *args, **kwargs)
-
-        self._vendors = []
-        self._interconnects = []
-
-        self.filterBy = self.xml.get_widget("otherFilterBy")
-        self.notebook = self.xml.get_widget("otherNotebook")
-
-        self.vendorEntry = self.xml.get_widget("otherVendorEntry")
-        self.interconnectEntry = self.xml.get_widget("otherInterconnectEntry")
-        self.IDEntry = self.xml.get_widget("otherIDEntry")
-
-        self.otherFilterHBox = self.xml.get_widget("otherFilterHBox")
-        self.otherFilterHBox.connect("realize", self._populateUI)
-
-        self.vendorEntry.connect("changed", lambda entry: self.model.get_model().refilter())
-        self.interconnectEntry.connect("changed", lambda entry: self.model.get_model().refilter())
-        self.IDEntry.connect("changed", lambda entry: self.model.get_model().refilter())
-
-    def isMember(self, info):
-        return info and isOther(info)
-
-class SearchCallbacks(FilteredCallbacks):
-    def __init__(self, *args, **kwargs):
-        FilteredCallbacks.__init__(self, *args, **kwargs)
-
-        self._ports = []
-        self._targets = []
-        self._luns = []
-
-        self.filterBy = self.xml.get_widget("searchFilterBy")
-        self.notebook = self.xml.get_widget("searchNotebook")
-
-        self.portEntry = self.xml.get_widget("searchPortEntry")
-        self.targetEntry = self.xml.get_widget("searchTargetEntry")
-        self.LUNEntry = self.xml.get_widget("searchLUNEntry")
-        self.IDEntry = self.xml.get_widget("searchIDEntry")
-
-        # When these entries are changed, we need to redo the filtering.
-        # If we don't do filter-as-you-type, we'd need a Search/Clear button.
-        self.portEntry.connect("changed", lambda entry: self.model.get_model().refilter())
-        self.targetEntry.connect("changed", lambda entry: self.model.get_model().refilter())
-        self.LUNEntry.connect("changed", lambda entry: self.model.get_model().refilter())
-        self.IDEntry.connect("changed", lambda entry: self.model.get_model().refilter())
-
-    def isMember(self, info):
-        return True
-
-    def visible(self, model, iter, view):
-        if not model.get_value(iter, VISIBLE_COL):
-            return False
-
-        if self.filtering:
-            if self.notebook.get_current_page() == 0:
-                return self._visible_by_ptl(model, iter, view)
-            else:
-                return self._visible_by_wwid(model, iter, view)
-
-        return True
-
-    def _visible_by_ptl(self, model, iter, view):
-        rowPort = model.get_value(iter, PORT_COL)
-        rowTarget = model.get_value(iter, TARGET_COL)
-        rowLUN = model.get_value(iter, LUN_COL)
-
-        enteredPort = self.portEntry.get_text()
-        enteredTarget = self.targetEntry.get_text()
-        enteredLUN = self.LUNEntry.get_text()
-
-        return (not enteredPort or enteredPort and enteredPort == rowPort) and \
-               (not enteredTarget or enteredTarget and enteredTarget == rowTarget) and \
-               (not enteredLUN or enteredLUN and enteredLUN == rowLUN)
-
-    def _visible_by_wwid(self, model, iter, view):
-        # FIXME:  make this support globs, etc.
-        entered = self.IDEntry.get_text()
-
-        return entered != "" and model.get_value(iter, ID_COL).find(entered) != -1
-
-class NotebookPage(object):
-    def __init__(self, store, name, xml, cb):
-        # Every page needs a ScrolledWindow to display the results in.
-        self.scroll = xml.get_widget("%sScroll" % name)
-
-        self.filteredModel = store.filter_new()
-        self.sortedModel = gtk.TreeModelSort(self.filteredModel)
-        self.treeView = gtk.TreeView(self.sortedModel)
-
-        self.scroll.add(self.treeView)
-
-        self.cb = cb
-        self.cb.model = self.sortedModel
-
-        self.ds = DeviceSelector(store, self.sortedModel, self.treeView,
-                                 visible=VISIBLE_COL, active=ACTIVE_COL)
-        self.ds.createMenu()
-        self.ds.createSelectionCol(toggledCB=self.cb.deviceToggled,
-                                   membershipCB=self.cb.isMember)
-
-        self.filteredModel.set_visible_func(self.cb.visible, self.treeView)
-
-        # Not every NotebookPage will have a filter box - just those that do
-        # some sort of filtering (obviously).
-        self.filterBox = xml.get_widget("%sFilterHBox" % name)
-
-        if self.filterBox:
-            self.filterBy = xml.get_widget("%sFilterBy" % name)
-            self.filterBy.connect("changed", self._filter_by_changed)
-
-            # However if the page has a filter box, then it must also have a
-            # notebook with an easily discoverable name.
-            self.notebook = xml.get_widget("%sNotebook" % name)
-
-    def _filter_by_changed(self, combo):
-        active = combo.get_active()
-
-        if active == -1:
-            self.cb.reset()
-        else:
-            self.cb.set(active)
-
-        self.filteredModel.refilter()
-
-    def getNVisible(self):
-        retval = 0
-        iter = self.filteredModel.get_iter_first()
-
-        while iter:
-            if self.cb.visible(self.filteredModel, iter, self.treeView):
-                retval += 1
-
-            iter = self.filteredModel.iter_next(iter)
-
-        return retval
-
-class FilterWindow(InstallWindow):
-    windowTitle = N_("Device Filter")
-
-    def getNext(self):
-        # All pages use the same store, so we only need to use the first one.
-        # However, we do need to make sure all paths from multipath devices
-        # are in the list.
-        selected = set()
-        for dev in self.pages[0].ds.getSelected():
-            selected.add(udev_device_get_name(dev[OBJECT_COL]))
-
-        if len(selected) == 0:
-            self.anaconda.intf.messageWindow(_("Error"),
-                                             _("You must select at least one "
-                                               "drive to be used for installation."),
-                                             custom_icon="error")
-            raise gui.StayOnScreen
-
-        self.anaconda.storage.exclusiveDisks = list(selected)
-
-    def _add_advanced_clicked(self, button):
-        from advanced_storage import addDrive
-
-        if not addDrive(self.anaconda):
-            return
-
-        udev_trigger(subsystem="block", action="change")
-        new_disks = filter(udev_device_is_disk, udev_get_block_devices())
-        (new_singlepaths, new_mpaths, new_partitions) = identifyMultipaths(new_disks)
-        (new_raids, new_nonraids) = self.split_list(lambda d: isRAID(d) and not isCCISS(d),
-                                                    new_singlepaths)
-
-        nonraids = filter(lambda d: d not in self._cachedDevices, new_nonraids)
-        mpaths = filter(lambda d: d not in self._cachedMPaths, new_mpaths)
-        raids = filter(lambda d: d not in self._cachedRaidDevices, new_raids)
-
-        self.populate(nonraids, mpaths, raids, activeByDefault=True)
-
-        # Make sure to update the size label at the bottom.
-        self.pages[0].cb.update()
-
-        self._cachedDevices.extend(nonraids)
-        self._cachedMPaths.extend(mpaths)
-        self._cachedRaidDevices.extend(raids)
-
-    def _makeBasic(self):
-        np = NotebookPage(self.store, "basic", self.xml, Callbacks(self.xml))
-
-        np.ds.addColumn(_("Model"), MODEL_COL)
-        np.ds.addColumn(_("Capacity"), CAPACITY_COL)
-        np.ds.addColumn(_("Vendor"), VENDOR_COL)
-        np.ds.addColumn(_("Interconnect"), INTERCONNECT_COL)
-        np.ds.addColumn(_("Serial Number"), SERIAL_COL)
-        np.ds.addColumn(_("Device"), DEVICE_COL, displayed=False)
-        return np
-
-    def _makeRAID(self):
-        np = NotebookPage(self.store, "raid", self.xml, RAIDCallbacks(self.xml))
-
-        np.ds.addColumn(_("Model"), MODEL_COL)
-        np.ds.addColumn(_("Capacity"), CAPACITY_COL)
-        np.ds.addColumn(_("Device"), DEVICE_COL, displayed=False)
-        return np
-
-    def _makeMPath(self):
-        np = NotebookPage(self.store, "mpath", self.xml, MPathCallbacks(self.xml))
-
-        np.ds.addColumn(_("Identifier"), ID_COL)
-        np.ds.addColumn(_("Capacity"), CAPACITY_COL)
-        np.ds.addColumn(_("Vendor"), VENDOR_COL)
-        np.ds.addColumn(_("Interconnect"), INTERCONNECT_COL)
-        np.ds.addColumn(_("Paths"), PATHS_COL)
-        np.ds.addColumn(_("Device"), DEVICE_COL, displayed=False)
-        return np
-
-    def _makeOther(self):
-        np = NotebookPage(self.store, "other", self.xml, OtherCallbacks(self.xml))
-
-        np.ds.addColumn(_("Identifier"), ID_COL)
-        np.ds.addColumn(_("Capacity"), CAPACITY_COL)
-        np.ds.addColumn(_("Vendor"), VENDOR_COL)
-        np.ds.addColumn(_("Interconnect"), INTERCONNECT_COL)
-        np.ds.addColumn(_("Serial Number"), SERIAL_COL, displayed=False)
-        np.ds.addColumn(_("Device"), DEVICE_COL, displayed=False)
-        return np
-
-    def _makeSearch(self):
-        np = NotebookPage(self.store, "search", self.xml, SearchCallbacks(self.xml))
-
-        np.ds.addColumn(_("Model"), MODEL_COL)
-        np.ds.addColumn(_("Capacity"), CAPACITY_COL, displayed=False)
-        np.ds.addColumn(_("Vendor"), VENDOR_COL)
-        np.ds.addColumn(_("Interconnect"), INTERCONNECT_COL, displayed=False)
-        np.ds.addColumn(_("Serial Number"), SERIAL_COL, displayed=False)
-        np.ds.addColumn(_("Identifier"), ID_COL)
-        np.ds.addColumn(_("Port"), PORT_COL)
-        np.ds.addColumn(_("Target"), TARGET_COL)
-        np.ds.addColumn(_("LUN"), LUN_COL)
-        np.ds.addColumn(_("Device"), DEVICE_COL, displayed=False)
-        return np
-
-    def _page_switched(self, notebook, useless, page_num):
-        # When the page is switched, we need to change what is visible so the
-        # Select All button only selects/deselected things on the current page.
-        # Unfortunately, the only way to do this is iterate over all rows and
-        # check for membership.
-        for line in self.store:
-            line[VISIBLE_COL] = self.pages[page_num].cb.isMember(line[OBJECT_COL])
-
-    def _show_buttons(self, *args, **kwargs):
-        if self.anaconda.simpleFilter:
-            self.buttonBox.hide()
-            self.buttonBox.set_no_show_all(True)
-        else:
-            self.buttonBox.show_all()
-
-    def getScreen(self, anaconda):
-        (self.xml, self.vbox) = gui.getGladeWidget("filter.glade", "vbox")
-        self.buttonBox = self.xml.get_widget("buttonBox")
-        self.notebook = self.xml.get_widget("notebook")
-        self.addAdvanced = self.xml.get_widget("addAdvancedButton")
-
-        self.buttonBox.connect("realize", self._show_buttons)
-        self.notebook.connect("switch-page", self._page_switched)
-        self.addAdvanced.connect("clicked", self._add_advanced_clicked)
-
-        self.pages = []
-
-        self.anaconda = anaconda
-
-        # One common store that all the views on all the notebook tabs share.
-        # Yes, this means a whole lot of columns that are going to be empty or
-        # unused much of the time.  Oh well.
-
-        # Object,
-        # visible, active (checked), immutable,
-        # device, model, capacity, vendor, interconnect, serial number, wwid
-        # paths, port, target, lun
-        self.store = gtk.TreeStore(gobject.TYPE_PYOBJECT,
-                                   gobject.TYPE_BOOLEAN, gobject.TYPE_BOOLEAN,
-                                   gobject.TYPE_BOOLEAN,
-                                   gobject.TYPE_STRING, gobject.TYPE_STRING,
-                                   gobject.TYPE_STRING, gobject.TYPE_STRING,
-                                   gobject.TYPE_STRING, gobject.TYPE_STRING,
-                                   gobject.TYPE_STRING, gobject.TYPE_STRING,
-                                   gobject.TYPE_STRING, gobject.TYPE_STRING,
-                                   gobject.TYPE_STRING)
-        self.store.set_sort_column_id(MODEL_COL, gtk.SORT_ASCENDING)
-
-        udev_trigger(subsystem="block", action="change")
-        # So that drives onlined by these show up in the filter UI
-        storage.iscsi.iscsi().startup(anaconda.intf)
-        storage.fcoe.fcoe().startup(anaconda.intf)
-        storage.zfcp.ZFCP().startup()
-        storage.dasd.DASD().startup(anaconda.intf,
-                                    anaconda.storage.exclusiveDisks,
-                                    anaconda.storage.zeroMbr)
-        disks = filter(udev_device_is_disk, udev_get_block_devices())
-        (singlepaths, mpaths, partitions) = identifyMultipaths(disks)
-
-        # The device list could be really long, so we really only want to
-        # iterate over it the bare minimum of times.  Dividing this list up
-        # now means fewer elements to iterate over later.
-        (raids, nonraids) = self.split_list(lambda d: isRAID(d) and not isCCISS(d),
-                                            singlepaths)
-
-        if anaconda.simpleFilter:
-            # In the typical use case, the user likely only has one drive and
-            # there's no point showing either the filtering UI or the
-            # cleardisks UI.  Unfortunately, that means we need to duplicate
-            # some of the getNext method.
-            if len(singlepaths) == 1:
-                anaconda.storage.exclusiveDisks = [udev_device_get_name(singlepaths[0])]
-                return None
-
-            self.pages = [self._makeBasic()]
-            self.notebook.set_show_border(False)
-            self.notebook.set_show_tabs(False)
-        else:
-            self.pages = [self._makeBasic(), self._makeRAID(),
-                          self._makeMPath(), self._makeOther(),
-                          self._makeSearch()]
-
-        self.populate(nonraids, mpaths, raids)
-
-        # If the "Add Advanced" button is ever clicked, we need to have a list
-        # of what devices previously existed so we know what's new.  Then we
-        # can just add the new devices to the UI.  This is going to be slow,
-        # but the user has to click a button to get to the slow part.
-        self._cachedDevices = NameCache(singlepaths)
-        self._cachedMPaths = NameCache(mpaths)
-        self._cachedRaidDevices = NameCache(raids)
-
-        # Switch to the first notebook page that displays any devices.
-        i = 0
-        for pg in self.pages:
-            if pg.getNVisible():
-                self.notebook.set_current_page(i)
-                break
-
-            i += 1
-
-        return self.vbox
-
-    def populate(self, nonraids, mpaths, raids, activeByDefault=False):
-        def _addTuple(tuple):
-            global totalDevices, totalSize
-            global selectedDevices, selectedSize
-            added = False
-
-            self.store.append(None, tuple)
-
-            for pg in self.pages:
-                if pg.cb.isMember(tuple[0]):
-                    added = True
-                    pg.cb.addToUI(tuple)
-
-            # Only update the size label if this device was added to any pages.
-            # This prevents situations where we're only displaying the basic
-            # filter that has one disk, but there are several advanced disks
-            # in the store that cannot be seen.
-            if added:
-                totalDevices += 1
-                totalSize += tuple[0]["XXX_SIZE"]
-
-                if tuple[ACTIVE_COL]:
-                    selectedDevices += 1
-                    selectedSize += tuple[0]["XXX_SIZE"]
-
-        def _isProtected(info):
-            protectedNames = map(udev_resolve_devspec, self.anaconda.protected)
-
-            sysfs_path = udev_device_get_sysfs_path(info)
-            for protected in protectedNames:
-                _p = "/sys/%s/%s" % (sysfs_path, protected)
-                if os.path.exists(os.path.normpath(_p)):
-                    return True
-
-            return False
-
-        def _active(info):
-            if _isProtected(info) or activeByDefault:
-                return True
-
-            name = udev_device_get_name(info)
-
-            if self.anaconda.storage.exclusiveDisks and \
-               name in self.anaconda.storage.exclusiveDisks:
-                return True
-            elif self.anaconda.storage.ignoredDisks and \
-                name not in self.anaconda.storage.ignoredDisks:
-                return True
-            else:
-                return False
-
-        for d in nonraids:
-            name = udev_device_get_name(d)
-
-            # We aren't guaranteed to be able to get a device.  In
-            # particular, built-in USB flash readers show up as devices but
-            # do not always have any media present, so parted won't be able
-            # to find a device.
-            try:
-                partedDevice = parted.Device(path="/dev/" + name)
-            except (_ped.IOException, _ped.DeviceException):
-                continue
-            d["XXX_SIZE"] = int(partedDevice.getSize())
-            # cciss controllers, without any sets defined, show up as a 0 size
-            # blockdev, ignore these
-            if d["XXX_SIZE"] == 0:
-                continue
-
-            # This isn't so great, but iSCSI and s390 devices have an ID_PATH
-            # that contains a lot of useful identifying info, so that should be
-            # displayed instead of a blank WWID.
-            if udev_device_is_iscsi(d) or udev_device_is_dasd(d) or udev_device_is_zfcp(d):
-                ident = udev_device_get_path(d)
-            else:
-                ident = udev_device_get_wwid(d)
-
-            tuple = (d, True, _active(d), _isProtected(d), name,
-                     partedDevice.model, str(d["XXX_SIZE"]) + " MB",
-                     udev_device_get_vendor(d), udev_device_get_bus(d),
-                     udev_device_get_serial(d), ident, "", "", "", "")
-            _addTuple(tuple)
-
-        if raids and flags.dmraid:
-            used_raidmembers = []
-            for rs in block.getRaidSets():
-                # dmraid does everything in sectors
-                size = (rs.rs.sectors * 512) / (1024.0 * 1024.0)
-                fstype = ""
-
-                # get_members also returns subsets with layered raids, we only
-                # want the devices
-                members = filter(lambda m: isinstance(m, block.device.RaidDev),
-                                 list(rs.get_members()))
-                members = map(lambda m: m.get_devpath(), members)
-                for d in raids:
-                    if udev_device_get_name(d) in members:
-                        fstype = udev_device_get_format(d)
-                        sysfs_path = udev_device_get_sysfs_path(d)
-                        break
-
-                # Skip this set if none of its members are in the raids list
-                if not fstype:
-                    continue
-
-                used_raidmembers.extend(members)
-
-                # biosraid devices don't really get udev data, at least not in a
-                # a way that's useful to the filtering UI.  So we need to fake
-                # that data now so we have something to put into the store.
-                data = {"XXX_SIZE": size, "ID_FS_TYPE": fstype,
-                        "DM_NAME": rs.name, "name": rs.name,
-                        "sysfs_path": sysfs_path}
-
-                model = "BIOS RAID set (%s)" % rs.rs.set_type
-                tuple = (data, True, _active(data), _isProtected(data), rs.name,
-                         model, str(size) + " MB", "", "", "", "", "", "", "", "")
-                _addTuple(tuple)
-
-            unused_raidmembers = []
-            for d in raids:
-                if udev_device_get_name(d) not in used_raidmembers:
-                    unused_raidmembers.append(udev_device_get_name(d))
-
-            self.anaconda.intf.unusedRaidMembersWarning(unused_raidmembers)
-
-        for mpath in mpaths:
-            # We only need to grab information from the first device in the set.
-            name = udev_device_get_name(mpath[0])
-
-            try:
-                partedDevice = parted.Device(path="/dev/" + name)
-            except (_ped.IOException, _ped.DeviceException):
-                continue
-            mpath[0]["XXX_SIZE"] = int(partedDevice.getSize())
-            model = partedDevice.model
-
-            # However, we do need all the paths making up this multipath set.
-            paths = "\n".join(map(udev_device_get_name, mpath))
-
-            # We use a copy here, so as to not modify the original udev info
-            # dict as that would break NameCache matching
-            data = mpath[0].copy()
-            data["name"] = udev_device_get_multipath_name(mpath[0])
-            tuple = (data, True, _active(data), _isProtected(data),
-                     udev_device_get_multipath_name(mpath[0]), model,
-                     str(mpath[0]["XXX_SIZE"]) + " MB",
-                     udev_device_get_vendor(mpath[0]),
-                     udev_device_get_bus(mpath[0]),
-                     udev_device_get_serial(mpath[0]),
-                     udev_device_get_wwid(mpath[0]),
-                     paths, "", "", "")
-            _addTuple(tuple)
-
-    def split_list(self, pred, lst):
-        pos = []
-        neg = []
-
-        for ele in lst:
-            if pred(ele):
-                pos.append(ele)
-            else:
-                neg.append(ele)
-
-        return (pos, neg)
diff --git a/iw/filter_type.py b/iw/filter_type.py
deleted file mode 100644
index 3c691bd..0000000
--- a/iw/filter_type.py
+++ /dev/null
@@ -1,80 +0,0 @@
-#
-# Copyright (C) 2009  Red Hat, Inc.  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 as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# 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, see <http://www.gnu.org/licenses/>.
-#
-# Author(s): Chris Lumens <clumens@xxxxxxxxxx>
-#
-
-import gtk
-import gobject
-import math
-
-from constants import *
-import gui
-from partition_ui_helpers_gui import *
-from pixmapRadioButtonGroup_gui import pixmapRadioButtonGroup
-
-from iw_gui import *
-from flags import flags
-from storage.deviceaction import *
-
-import gettext
-_ = lambda x: gettext.ldgettext("anaconda", x)
-
-class FilterTypeWindow(InstallWindow):
-    def __init__(self, ics):
-        InstallWindow.__init__(self, ics)
-        ics.setTitle("Filter Type")
-        ics.setNextEnabled(True)
-
-    def getNext(self):
-        if self.buttonGroup.getCurrent() == "simple":
-            self.anaconda.simpleFilter = True
-        else:
-            self.anaconda.simpleFilter = False
-
-        return None
-
-    def getScreen(self, anaconda):
-        self.anaconda = anaconda
-        self.intf = anaconda.intf
-
-        vbox = gtk.VBox()
-        label = gtk.Label(_("What type of devices will your installation "
-                            "involve?"))
-        label.set_alignment(0.0, 0.0)
-        vbox.pack_start(label, expand=False, fill=False)
-
-        self.buttonGroup = pixmapRadioButtonGroup()
-        self.buttonGroup.addEntry("simple", _("Basic Storage Devices"),
-                                  descr=_("Installs or upgrades to typical types "
-                                          "of storage devices.  If you're not sure "
-                                          "which option is right for you, this is "
-                                          "probably it."))
-        self.buttonGroup.addEntry("complex", _("Specialized Storage Devices"),
-                                  descr=_("Installs or upgrades to devices such as "
-                                          "Storage Area Networks (SANs) or mainframe "
-                                          "attached disks (DASD), usually in an "
-                                          "enterprise environment"))
-
-        widget = self.buttonGroup.render()
-        vbox.pack_start(widget, expand=True, fill=True)
-
-        if self.anaconda.simpleFilter == True:
-            self.buttonGroup.setCurrent("simple")
-        else:
-            self.buttonGroup.setCurrent("complex")
-
-        return vbox
diff --git a/iw/iw_gui.py b/iw/iw_gui.py
deleted file mode 100644
index 997a239..0000000
--- a/iw/iw_gui.py
+++ /dev/null
@@ -1,53 +0,0 @@
-#
-# iw_gui.py: install window base class
-#
-# Copyright (C) 2000, 2001, 2002  Red Hat, Inc.  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 as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# 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, see <http://www.gnu.org/licenses/>.
-#
-
-from constants import *
-import gettext
-_ = lambda x: gettext.ldgettext("anaconda", x)
-
-class InstallWindow:
-
-    windowTitle = None
-
-    def __init__ (self,ics):
-        self.ics = ics
-
-	if self.windowTitle:
-	    ics.setTitle (_(self.windowTitle))
-
-    def getNext (self):
-	return None
-
-    def renderCallback(self):
-	return None
-
-    def getPrev (self):
-	return None
-
-    def getScreen (self):
-        pass
-
-    def getICS (self):
-        return self.ics
-
-    def fixUp (self):
-        pass
-
-    def focus(self):
-        pass
diff --git a/iw/kbd_gui.py b/iw/kbd_gui.py
deleted file mode 100644
index 95fc106..0000000
--- a/iw/kbd_gui.py
+++ /dev/null
@@ -1,39 +0,0 @@
-#
-# keyboard_gui.py:  Shim around system-config-keyboard
-# Brrrraaaaaiiiinnnns...
-#
-# Copyright (C) 2006, 2007  Red Hat, Inc.  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 as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# 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, see <http://www.gnu.org/licenses/>.
-#
-
-from iw_gui import *
-import sys
-
-sys.path.append("/usr/share/system-config-keyboard")
-
-from keyboard_gui import childWindow as installKeyboardWindow
-
-class KeyboardWindow(InstallWindow, installKeyboardWindow):
-    def __init__(self, ics):
-        InstallWindow.__init__(self, ics)
-        installKeyboardWindow.__init__(self)
-
-    def getNext(self):
-        installKeyboardWindow.getNext(self)
-
-    def getScreen(self, anaconda):
-        default = anaconda.instLanguage.getDefaultKeyboard(anaconda.rootPath)
-        anaconda.keyboard.set(default)
-        return installKeyboardWindow.getScreen(self, default, anaconda.keyboard)
diff --git a/iw/language_gui.py b/iw/language_gui.py
deleted file mode 100644
index 952f8a8..0000000
--- a/iw/language_gui.py
+++ /dev/null
@@ -1,134 +0,0 @@
-#
-# langauge_gui.py: installtime language selection.
-#
-# Copyright (C) 2000, 2001, 2002  Red Hat, Inc.  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 as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# 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, see <http://www.gnu.org/licenses/>.
-#
-
-import gobject
-import gtk
-import gui
-from iw_gui import *
-from constants import *
-
-import gettext
-_ = lambda x: gettext.ldgettext("anaconda", x)
-
-from gui import setupTreeViewFixupIdleHandler, StayOnScreen
-
-class LanguageWindow (InstallWindow):
-
-    windowTitle = N_("Language Selection")
-
-    def __init__ (self, ics):
-	InstallWindow.__init__ (self, ics)
-
-    def getNext (self):
-        anaconda = self.ics.getICW().anaconda
-
-        (model, iter) = self.listView.get_selection().get_selected()
-        if not iter:
-            raise StayOnScreen
-
-	choice = self.listStore.get_value(iter, 1)
-        self.lang = self.instLang.getLangByName(choice)
-
-        if self.lang in self.instLang.getCurrentLangSearchList():
-            return None
-
-        self.instLang.instLang = self.lang
-        self.instLang.systemLang = self.lang
-        anaconda.timezone.setTimezoneInfo(anaconda.instLanguage.getDefaultTimeZone(anaconda.rootPath))
-	self.ics.getICW().setLanguage()
-
-        return None
-
-    def listScroll(self, widget, *args):
-        # recenter the list
-        (model, iter) = self.listView.get_selection().get_selected()
-        if iter is None:
-            return
-
-        path = self.listStore.get_path(iter)
-        col = self.listView.get_column(0)
-        self.listView.scroll_to_cell(path, col, True, 0.5, 0.5)
-	self.listView.set_cursor(path, col, False)
-
-    # LanguageWindow tag="lang"
-    def getScreen (self, anaconda):
-        self.running = 0
-        mainBox = gtk.VBox (False, 10)
-
-        hbox = gtk.HBox(False, 5)
-        pix = gui.readImageFromFile ("config-language.png")
-        if pix:
-            a = gtk.Alignment ()
-            a.add (pix)
-            hbox.pack_start (a, False)
-
-        label = gtk.Label (_("What language would you like to use during the "
-                         "installation process?"))
-        label.set_line_wrap (True)
-        label.set_size_request(350, -1)
-        hbox.pack_start(label, False)
-
-	self.instLang = anaconda.instLanguage
-
-        self.listStore = gtk.ListStore(gobject.TYPE_STRING,
-                                       gobject.TYPE_STRING,
-                                       gobject.TYPE_STRING)
-
-        for locale in self.instLang.available():
-            iter = self.listStore.append()
-            nick = self.instLang.getLangByName(locale)
-            lang = '%s (<span lang="%s">%s</span>)' % (
-                _(locale), "%s" % (nick.split('.')[0],),
-                self.instLang.getNativeLangName(locale))
-            self.listStore.set_value(iter, 0, lang)
-            self.listStore.set_value(iter, 1, locale)
-            self.listStore.set_value(iter, 2, _(locale))
-
-        self.listStore.set_sort_column_id(2, gtk.SORT_ASCENDING)
-
-        self.listView = gtk.TreeView(self.listStore)
-        col = gtk.TreeViewColumn(None, gtk.CellRendererText(), markup=0)
-        self.listView.append_column(col)
-        self.listView.set_property("headers-visible", False)
-
-        current = self.instLang.getLangName(self.instLang.instLang)
-        iter = self.listStore.get_iter_first()
-        while iter:
-            if self.listStore.get_value(iter, 1) == current:
-                selection = self.listView.get_selection()
-                selection.unselect_all()
-                selection.select_iter(iter)
-                break
-            iter = self.listStore.iter_next(iter)
-        self.listView.connect("size-allocate", self.listScroll)
-
-        sw = gtk.ScrolledWindow ()
-        sw.set_border_width (5)
-        sw.set_shadow_type(gtk.SHADOW_IN)
-        sw.set_policy (gtk.POLICY_NEVER, gtk.POLICY_AUTOMATIC)
-        sw.add (self.listView)
-
-	setupTreeViewFixupIdleHandler(self.listView, self.listStore)
-
-        mainBox.pack_start (hbox, False, False, 10)
-        mainBox.pack_start (sw, True, True)
-
-        self.running = 1
-
-        return mainBox
diff --git a/iw/lvm_dialog_gui.py b/iw/lvm_dialog_gui.py
deleted file mode 100644
index 2474627..0000000
--- a/iw/lvm_dialog_gui.py
+++ /dev/null
@@ -1,1466 +0,0 @@
-#
-# lvm_dialog_gui.py: dialog for editing a volume group request
-#
-# Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007  Red Hat, Inc.
-# 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 as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# 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, see <http://www.gnu.org/licenses/>.
-#
-# Author(s): Michael Fulbright <msf@xxxxxxxxxx>
-#
-
-import copy
-
-import gobject
-import gtk
-import datacombo
-
-import gui
-from partition_ui_helpers_gui import *
-from constants import *
-from storage.devices import *
-from storage.deviceaction import *
-
-import gettext
-_ = lambda x: gettext.ldgettext("anaconda", x)
-P_ = lambda x, y, z: gettext.ldngettext("anaconda", x, y, z)
-
-import logging
-log = logging.getLogger("anaconda")
-
-class VolumeGroupEditor:
-
-    def getTempVG(self):
-        pvs = [copy.deepcopy(pv) for pv in self.pvs]
-        vg = LVMVolumeGroupDevice('tmp-%s' % self.vg.name,
-                                  parents=pvs, peSize=self.peSize)
-        for lv in self.lvs.values():
-            _l = LVMLogicalVolumeDevice(lv['name'], vg, format=lv['format'],
-                                   size=lv['size'], exists=lv['exists'],
-                                   stripes=lv['stripes'],
-                                   logSize=lv['logSize'],
-                                   snapshotSpace=lv['snapshotSpace'])
-            _l.originalFormat = lv['originalFormat']
-
-        return vg
-
-    def numAvailableLVSlots(self):
-	return max(0, lvm.MAX_LV_SLOTS - len(self.lvs))
-
-    def computeSpaceValues(self):
-        vg = self.getTempVG()
-        vgsize = vg.size
-        vgfree = vg.freeSpace
-        vgused = vgsize - vgfree
-	return (vgsize, vgused, vgfree)
-
-    def getPVWastedRatio(self, newpe):
-        """ given a new pe value, return percentage of smallest PV wasted
-
-        newpe - (int) new value of PE, in KB
-        """
-        pvlist = self.getSelectedPhysicalVolumes()
-
-	waste = 0.0
-	for pv in pvlist:
-	    waste = max(waste, (long(pv.size*1024) % newpe)/(pv.size*1024.0))
-
-	return waste
-
-    def getSmallestPVSize(self):
-        """ finds the smallest PV and returns its size in MB
-        """
-	first = 1
-        pvlist = self.getSelectedPhysicalVolumes()
-	for pv in pvlist:
-            try:
-                pesize = int(self.peCombo.get_active_value()) / 1024.0
-            except:
-                pesize = self.vg.peSize
-
-            # FIXME: move this logic into a property of LVMVolumeGroupDevice
-            pvsize = max(0, lvm.clampSize(pv.size, pesize) - pesize)
-	    if first:
-		minpvsize = pvsize
-		first = 0
-	    else:
-		minpvsize = min(pvsize, minpvsize)
-
-	return minpvsize
-
-
-    def reclampLV(self, newpe):
-        """ given a new pe value, set logical volume sizes accordingly
-
-        newpe - (int) new value of PE, in MB
-        """
-
-        pvlist = self.getSelectedPhysicalVolumes()
-        availSpaceMB = self.computeVGSize(pvlist, newpe)
-
-        # see if total space is enough
-        used = 0
-        resize = False
-        for lv in self.lvs.values():
-            # total space required by an lv may be greater than lv size.
-            vg_space = lv['size'] * lv['stripes'] + lv['logSize'] \
-                        + lv['snapshotSpace']
-            clamped_vg_space = lvm.clampSize(vg_space, newpe, roundup=1)
-            used += clamped_vg_space
-            if lv['size'] != lvm.clampSize(lv['size'], newpe, roundup=1):
-                resize = True
-
-        if used > availSpaceMB:
-            self.intf.messageWindow(_("Not enough space"),
-                                    _("The physical extent size cannot be "
-                                      "changed because otherwise the space "
-                                      "required by the currently defined "
-                                      "logical volumes will be increased "
-                                      "to more than the available space."),
-				    custom_icon="error")
-            return 0
-
-	if resize:
-	    rc = self.intf.messageWindow(_("Confirm Physical Extent Change"),
-					 _("This change in the value of the "
-					   "physical extent will require the "
-					   "sizes of the current logical "
-					   "volume requests to be rounded "
-					   "up in size to an integer multiple "
-					   "of the "
-					   "physical extent.\n\nThis change "
-					   "will take effect immediately."),
-					 type="custom", custom_icon="question",
-					 custom_buttons=["gtk-cancel", _("C_ontinue")])
-	    if not rc:
-		return 0
-
-        for lv in self.lvs.values():
-            lv['size'] = lvm.clampSize(lv['size'], newpe, roundup=1)
-
-        return 1
-            
-    def peChangeCB(self, widget, *args):
-        """ handle changes in the Physical Extent option menu
-
-        widget - menu item which was activated
-        peOption - the Option menu containing the items. The data value for
-                   "lastval" is the previous PE value.
-        """
-
-        curval = int(widget.get_active_value())
-        # this one's in MB so we can stop with all this dividing by 1024
-        curpe = curval / 1024.0
-        lastval = widget.get_data("lastpe")
-	lastidx = widget.get_data("lastidx")
-
-	# see if PE is too large compared to smallest PV
-	maxpvsize = self.getSmallestPVSize()
-	if curpe > maxpvsize:
-            self.intf.messageWindow(_("Not enough space"),
-                                    _("The physical extent size cannot be "
-                                      "changed because the value selected "
-				      "(%(curpe)10.2f MB) is larger than the "
-				      "smallest physical volume "
-				      "(%(maxpvsize)10.2f MB) in the volume "
-				      "group.") % {'curpe': curpe,
-				                   'maxpvsize': maxpvsize},
-                                      custom_icon="error")
-	    widget.set_active(lastidx)
-            return 0
-
-	# see if new PE will make any PV useless due to overhead
-	if lvm.clampSize(maxpvsize, curpe) < curpe:
-            self.intf.messageWindow(_("Not enough space"),
-                                    _("The physical extent size cannot be "
-                                      "changed because the value selected "
-				      "(%(curpe)10.2f MB) is too large "
-				      "compared to the size of the "
-				      "smallest physical volume "
-				      "(%(maxpvsize)10.2f MB) in the "
-				      "volume group.")
-				    % {'curpe': curpe, 'maxpvsize': maxpvsize},
-                                    custom_icon="error")
-	    widget.set_active(lastidx)
-            return 0
-	    
-
-	if self.getPVWastedRatio(curpe) > 0.10:
-	    rc = self.intf.messageWindow(_("Too small"),
-					 _("This change in the value of the "
-					   "physical extent will waste "
-					   "substantial space on one or more "
-					   "of the physical volumes in the "
-					   "volume group."),
-					 type="custom", custom_icon="error",
-					   custom_buttons=["gtk-cancel", _("C_ontinue")])
-	    if not rc:
-		widget.set_active(lastidx)
-		return 0
-
-	# now see if we need to fixup effect PV and LV sizes based on PE
-        if curval > lastval:
-            rc = self.reclampLV(curpe)
-            if not rc:
-		widget.set_active(lastidx)
-		return 0
-            else:
-                self.updateLogVolStore()
-	else:
-	    maxlv = lvm.getMaxLVSize()
-	    for lv in self.lvs.values():
-		if lv['size'] > maxlv:
-		    self.intf.messageWindow(_("Not enough space"),
-					    _("The physical extent size "
-					      "cannot be changed because the "
-					      "resulting maximum logical "
-					      "volume size (%10.2f MB) is "
-					      "smaller "
-					      "than one or more of the "
-					      "currently defined logical "
-					      "volumes.") % (maxlv,),
-					    custom_icon="error")
-		    widget.set_active(lastidx)
-		    return 0
-            
-        widget.set_data("lastpe", curval)
-	widget.set_data("lastidx", widget.get_active())
-
-        # now actually set the VG's extent size
-        self.peSize = curpe
-        self.updateAllowedLvmPartitionsList()
-	self.updateVGSpaceLabels()
-
-    def prettyFormatPESize(self, val):
-        """ Pretty print for PE size in KB """
-        if val < 1024:
-            return "%s KB" % (val,)
-        elif val < 1024*1024:
-            return "%s MB" % (val/1024,)
-        else:
-            return "%s GB" % (val/1024/1024,)
-
-    def createPEOptionMenu(self, default=4096):
-        peCombo = datacombo.DataComboBox()
-
-        actualPE = []
-        for curpe in lvm.getPossiblePhysicalExtents(floor=1024):
-            # don't show PE over 128M, unless it's the default
-            if curpe > 131072 and curpe != default:
-                continue
-
-            actualPE.append(curpe)
-            val = self.prettyFormatPESize(curpe)
-
-            peCombo.append(val, curpe)
-
-        # First try to set the combo's active value to the default we're
-        # passed.  If that doesn't work, just set it to the first one to
-        # prevent TypeErrors everywhere.
-        try:
-            peCombo.set_active(actualPE.index(default))
-        except ValueError:
-            peCombo.set_active(0)
-
-        peCombo.set_data("lastidx", peCombo.get_active())
-        peCombo.connect("changed", self.peChangeCB)
-        peCombo.set_data("lastpe", default)
-
-	return peCombo
-
-    def clickCB(self, row, data):
-	model = self.lvmlist.get_model()
-	pvlist = self.getSelectedPhysicalVolumes()
-
-	# get the selected row
-	iter = model.get_iter((string.atoi(data),))
-
-	# we invert val because we get called before checklist
-	# changes the toggle state
-	val      = not model.get_value(iter, 0)
-	partname = model.get_value(iter, 1)
-        pv = self.storage.devicetree.getDeviceByName(partname)
-        if val:
-            self.pvs.append(pv)
-        else:
-            self.pvs.remove(pv)
-            try:
-                vg = self.getTempVG()
-            except DeviceError as e:
-                self.intf.messageWindow(_("Not enough space"),
-                                    _("You cannot remove this physical "
-                                      "volume because otherwise the "
-                                      "volume group will be too small to "
-                                      "hold the currently defined logical "
-                                      "volumes."), custom_icon="error")
-                self.pvs.append(pv)
-                return False
-
-	self.updateVGSpaceLabels()
-	return True
-
-    def createAllowedLvmPartitionsList(self):
-	store = gtk.TreeStore(gobject.TYPE_BOOLEAN,
-			      gobject.TYPE_STRING,
-			      gobject.TYPE_STRING)
-	partlist = WideCheckList(2, store, self.clickCB)
-
-	sw = gtk.ScrolledWindow()
-	sw.add(partlist)
-	sw.set_policy(gtk.POLICY_NEVER, gtk.POLICY_AUTOMATIC)
-	sw.set_shadow_type(gtk.SHADOW_IN)
-
-        origpvs = self.pvs[:]
-	for device in self.availlvmparts:
-	    # clip size to current PE
-	    pesize = int(self.peCombo.get_active_value()) / 1024.0
-	    size = lvm.clampSize(device.size, pesize)
-	    size_string = "%10.2f MB" % size
-            include = True
-            selected = False
-
-            # now see if the pv is in use either by a vg in the tree or by
-            # the vg we are editing now
-            if device in origpvs:
-                selected = True
-                include = True
-            else:
-                for vg in self.storage.vgs:
-                    if vg.name == self.vg.name:
-                        continue
-
-                    if device in vg.pvs:
-                        include = False
-                        break
-
-                if include and not origpvs:
-                    selected = True
-
-            if include:
-                partlist.append_row((device.name, size_string), selected)
-                if selected and device not in self.pvs:
-                    self.pvs.append(device)
-
-	return (partlist, sw)
-
-    def updateAllowedLvmPartitionsList(self):
-	""" update sizes in pv list """
-	row = 0
-	for part in self.availlvmparts:
-	    size = part.size
-
-	    # clip size to current PE
-	    pesize = int(self.peCombo.get_active_value()) / 1024.0
-	    size = lvm.clampSize(size, pesize)
-	    partsize = "%10.2f MB" % size
-
-	    iter = self.lvmlist.store.get_iter((int(row),))
-	    self.lvmlist.store.set_value(iter, 2, partsize)
-	    row = row + 1
-	
-    def getCurrentLogicalVolume(self):
-	selection = self.logvollist.get_selection()
-	(model, iter) = selection.get_selected()
-	return iter
-
-    def editLogicalVolume(self, lv, isNew = 0):
-        # Mixing logical code and gtk code is confusing to me.  So I am going
-        # to do the logic first and then create all the gtk crap!
-        #
-        # lv -- whatever self.logvolstore.get_value returns
-
-        #newfstypelabel = None # File system type label & combo
-        #newfstypeCombo = None
-        newfslabellabel = None # File system Label label & combo
-        newfslableCombo = None
-        #lvnamelabel = None # Logical Volume name label & entry
-        #lvnameentry = None
-        #lvsizelabel = None # Logical Volume size label & entry
-        #lvsizeentry = None
-        maxsizelabel = None # Maximum size label
-        #mountCombo = None # Mount Point Combo Box
-        #tstr = None # String that appears on top of the window
-        tempvg = self.getTempVG()  # copy of self.vg
-        templv = None
-        cpefsos = None # lambda function that represents
-                       # createPreExistFSOptionSection
-
-        # Define the string
-        if isNew:
-            tstr = _("Make Logical Volume")
-        else:
-            tstr = _("Edit Logical Volume: %s") % lv['name']
-
-        # Create the mountCombo.  This is the box where the mountpoint will
-        # appear.  Note that if the format is swap or Raiddevice, the mount
-        # point is none-sense.
-        templuks = None
-        templv = self.getLVByName(lv['name'], vg=tempvg)
-        usedev = templv
-        if templv.format.type == "luks":
-            templuks = LUKSDevice("luks-%s" % lv['name'],
-                                  parents=[templv],
-                                  format=self.luks[lv['name']],
-                                  exists=templv.format.exists)
-            usedev = templuks
-
-        if lv['format'].type == "luks":
-            format = self.luks[lv['name']]
-        else:
-            format = lv['format']
-
-        if lv['exists']:
-            _origlv = self.getLVByName(lv['name'])
-            originalFormat = _origlv.originalFormat
-            if originalFormat.type == "luks":
-                try:
-                    _origluks = self.storage.devicetree.getChildren(_origlv)[0]
-                except IndexError:
-                    pass
-                else:
-                    originalFormat = _origluks.originalFormat
-
-        mountCombo = createMountPointCombo(usedev, excludeMountPoints=["/boot"])
-
-
-        # Stuff appears differently when the lv exists and when the lv is new.
-        # here we make that difference.  Except for newfslabelCombo,  and
-        # maxsizelabel all vars will have a value != None.
-        if not lv['exists']:
-            # File system type lables & combo
-            newfstypelabel = createAlignedLabel(_("_File System Type:"))
-            newfstypeCombo = createFSTypeMenu(format, fstypechangeCB,mountCombo,
-                    ignorefs = ["mdmember", "lvmpv", "efi", "prepboot", "appleboot"])
-            newfstypelabel.set_mnemonic_widget(newfstypeCombo)
-
-            # Logical Volume name label & entry
-            lvnamelabel = createAlignedLabel(_("_Logical Volume Name:"))
-            lvnameentry = gtk.Entry(32)
-            lvnamelabel.set_mnemonic_widget(lvnameentry)
-            if lv['name']:
-                lvnameentry.set_text(lv['name'])
-            else:
-                lvnameentry.set_text(self.storage.createSuggestedLVName(self.getTempVG()))
-
-            # Logical Volume size label & entry
-            lvsizelabel = createAlignedLabel(_("_Size (MB):"))
-            lvsizeentry = gtk.Entry(16)
-            lvsizelabel.set_mnemonic_widget(lvsizeentry)
-            lvsizeentry.set_text("%Ld" % lv['size'])
-
-            # Maximum size label
-            max_grow = tempvg.freeSpace / lv['stripes']
-            maxsizelabel = createAlignedLabel(_("(Max size is %s MB)") %
-                                              min(lvm.getMaxLVSize(),
-                                                  lv['size'] + max_grow))
-
-            # Encrypt Check Box button.
-            self.lukscb = gtk.CheckButton(_("_Encrypt"))
-            self.lukscb.set_data("formatstate", 1)
-            if lv['format'].type == "luks":
-                self.lukscb.set_active(1)
-            else:
-                self.lukscb.set_active(0)
-
-        else:
-            # File system type lable & combo
-            newfstypelabel = createAlignedLabel(_("Original File System Type:"))
-            newfstypeCombo = gtk.Label(originalFormat.name)
-
-            # File system label label & combo
-            if getattr(originalFormat, "label", None):
-                newfslabellabel = createAlignedLabel(_("Original File System "
-                                                      "Label:"))
-                newfslableCombo = gtk.Label(originalFormat.label)
-
-            # Logical Volume name label & entry
-            lvnamelabel = createAlignedLabel(_("Logical Volume Name:"))
-            lvnameentry = gtk.Label(lv['name'])
-
-            # Logical Volume size label & entry
-            lvsizelabel = createAlignedLabel(_("Size (MB):"))
-            lvsizeentry = gtk.Label(str(lv['size']))
-
-            # Create the File System Format Section
-            self.fsoptionsDict = {}
-            # We are going to lambda the createPreExistFSOptionSection so we can call
-            # it latter with two arguments, row and mainttable.
-            cpefsos = lambda table, row: createPreExistFSOptionSection(templv,
-                    maintable, row, mountCombo, self.storage,
-                    ignorefs = ["software RAID", "physical volume (LVM)", "vfat"],
-                    luksdev=templuks)
-
-
-        # Here is where the gtk crap begins.
-        dialog = gtk.Dialog(tstr, self.parent)
-        gui.addFrame(dialog)
-        dialog.add_button('gtk-cancel', gtk.RESPONSE_CANCEL)
-        dialog.add_button('gtk-ok', 1)
-        dialog.set_position(gtk.WIN_POS_CENTER)
-
-        # Initialize main table
-        maintable = gtk.Table()
-        maintable.set_row_spacings(5)
-        maintable.set_col_spacings(5)
-        row = 0
-
-        # Add the mountCombo that we previously created
-        lbl = createAlignedLabel(_("_Mount Point:"))
-        maintable.attach(lbl, 0, 1, row,row+1)
-        lbl.set_mnemonic_widget(mountCombo)
-        maintable.attach(mountCombo, 1, 2, row, row + 1)
-        row += 1
-
-        # Add the filesystem combo labels.
-        maintable.attach(newfstypelabel, 0, 1, row, row + 1)
-        maintable.attach(newfstypeCombo, 1, 2, row, row + 1)
-        row += 1
-
-        # If there is a File system lable, add it.
-        if newfslabellabel is not None and newfslableCombo is not None:
-            maintable.attach(newfslabellabel, 0, 1, row, row + 1)
-            maintable.attach(newfslableCombo, 1, 2, row, row + 1)
-            row += 1
-
-        # Add the logical volume name
-        maintable.attach(lvnamelabel, 0, 1, row, row + 1)
-        maintable.attach(lvnameentry, 1, 2, row, row + 1)
-        row += 1
-
-        # Add the logical volume size
-        maintable.attach(lvsizelabel, 0, 1, row, row + 1)
-        maintable.attach(lvsizeentry, 1, 2, row, row + 1)
-        row += 1
-
-        # If there is a maxsize, add it.
-        if maxsizelabel is not None:
-            maintable.attach(maxsizelabel, 1, 2, row, row + 1)
-
-        # If we have the createPreExistFSOptionSection lamda function it means
-        # that we have a preexisting lv and we must call the lambda function
-        # to create the Pre exsisting FS option section.
-        if cpefsos is not None:
-            (row, self.fsoptionsDict) = cpefsos(maintable, row)
-
-        # checkbutton for encryption using dm-crypt/LUKS
-        # FIXME: Here we could not decouple the gtk stuff from the logic because
-        #        of the createPreExistFSOptionSection function call.  We must
-        #        decouple that function.
-        if not lv['exists']:
-            maintable.attach(self.lukscb, 0, 2, row, row + 1)
-            row = row + 1
-        else:
-            self.lukscb = self.fsoptionsDict.get("lukscb")
-
-        dialog.vbox.pack_start(maintable)
-        dialog.show_all()
-        # Here ends the gtk crap
-
-        while 1:
-            rc = dialog.run()
-            if rc in [gtk.RESPONSE_CANCEL, gtk.RESPONSE_DELETE_EVENT]:
-                if isNew:
-                    del self.lvs[lv['name']]
-                dialog.destroy()
-                return
-
-            actions = []
-            targetSize = None
-            migrate = None
-            format = None
-            newluks = None
-
-            if templv.format.type == "luks":
-                format = self.luks[lv['name']]
-            else:
-                format = templv.format
-
-            if not templv.exists:
-                fmt_class = newfstypeCombo.get_active_value()
-            else:
-                # existing lv
-                fmt_class = self.fsoptionsDict["fstypeCombo"].get_active_value()
-
-            mountpoint = mountCombo.get_children()[0].get_text().strip()
-            if mountpoint == _("<Not Applicable>"):
-                mountpoint = ""
-
-            # validate logical volume name
-            lvname = lvnameentry.get_text().strip()
-            if not templv.exists:
-                err = sanityCheckLogicalVolumeName(lvname)
-                if err:
-                    self.intf.messageWindow(_("Illegal Logical Volume Name"),
-                                            err, custom_icon="error")
-                    continue
-
-            # check that the name is not already in use
-            used = 0
-            for _lv in self.lvs.values():
-                if _lv == lv:
-                    continue
-
-                if _lv['name'] == lvname:
-                    used = 1
-                    break
-
-            if used:
-                self.intf.messageWindow(_("Illegal logical volume name"),
-                                        _("The logical volume name \"%s\" is "
-                                          "already in use. Please pick "
-                                          "another.") % (lvname,), custom_icon="error")
-                continue
-
-            # test mount point
-            # check in pending logical volume requests
-            # these may not have been put in master list of requests
-            # yet if we have not hit 'OK' for the volume group creation
-            if fmt_class().mountable and mountpoint:
-                used = False
-                curmntpt = getattr(format, "mountpoint", None)
-
-                for _lv in self.lvs.values():
-                    if _lv['format'].type == "luks":
-                        _format = self.luks[_lv['name']]
-                    else:
-                        _format = _lv['format']
-
-                    if not _format.mountable or curmntpt and \
-                       _format.mountpoint == curmntpt:
-                        continue
-
-                    if _format.mountpoint == mountpoint:
-                        used = True
-                        break
-
-                if not used:
-                    # we checked this VG's LVs above; now check the rest of
-                    # the devices in the tree
-                    mountdevs = self.lvs.values()
-                    full_name = "%s-%s" % (self.vg.name, lv['name'])
-                    for (mp,d) in self.storage.mountpoints.iteritems():
-                        if (d.type != "lvmlv" or d.vg.id != self.vg.id) and \
-                           mp == mountpoint and \
-                           not (isinstance(d, LUKSDevice) and
-                                full_name in [dev.name for dev in d.parents]):
-                            used = True
-                            break
-
-                if used:
-                    self.intf.messageWindow(_("Mount point in use"),
-                                            _("The mount point \"%s\" is in "
-                                              "use. Please pick another.") %
-                                            (mountpoint,),
-                                            custom_icon="error")
-                    continue
-
-            # check that size specification is numeric and positive
-            if not templv.exists:
-                badsize = 0
-                try:
-                    size = long(lvsizeentry.get_text())
-                except:
-                    badsize = 1
-
-                if badsize or size <= 0:
-                    self.intf.messageWindow(_("Illegal size"),
-                                            _("The requested size as entered is "
-                                              "not a valid number greater "
-                                              "than 0."), custom_icon="error")
-                    continue
-            else:
-                size = templv.size
-
-            # check that size specification is within limits
-            pesize = int(self.peCombo.get_active_value()) / 1024.0
-            size = lvm.clampSize(size, pesize, roundup=True)
-            maxlv = lvm.getMaxLVSize()
-            if size > maxlv:
-                self.intf.messageWindow(_("Not enough space"),
-                                        _("The current requested size "
-                                          "(%(size)10.2f MB) is larger than "
-                                          "the maximum logical volume size "
-                                          "(%(maxlv)10.2f MB). "
-                                          "To increase this limit you can "
-                                          "create more Physical Volumes from "
-                                          "unpartitioned disk space and "
-                                          "add them to this Volume Group.")
-                                          % {'size': size, 'maxlv': maxlv},
-                                        custom_icon="error")
-                continue
-
-            # Ok -- now we've done all the checks to validate the
-            # user-specified parameters. Time to set up the device...
-            origname = templv.lvname
-            if not templv.exists:
-                templv._name = lvname
-                try:
-                    templv.size = size
-                except ValueError:
-                    self.intf.messageWindow(_("Not enough space"),
-                                            _("The size entered for this "
-                                              "logical volume (%(size)d MB) "
-                                              "combined with the size of the "
-                                              "other logical volume(s) "
-                                              "exceeds the size of the "
-                                              "volume group (%(tempvgsize)d "
-                                              "MB). Please make the volume "
-                                              "group larger or make the "
-                                              "logical volume smaller.")
-                                              % {'size': size,
-                                                 'tempvgsize': tempvg.size},
-                                            custom_icon="error")
-                    continue
-
-                format = fmt_class(mountpoint=mountpoint)
-                if self.lukscb and self.lukscb.get_active():
-                    if templv.format.type != "luks":
-                        newluks = format
-                        format = getFormat("luks",
-                                       passphrase=self.storage.encryptionPassphrase)
-                    else:
-                        newluks = format
-                        format = templv.format
-
-                templv.format = format
-            else:
-                # existing lv
-                if self.fsoptionsDict.has_key("formatcb") and \
-                   self.fsoptionsDict["formatcb"].get_active():
-                    format = fmt_class(mountpoint=mountpoint)
-                    if self.lukscb and self.lukscb.get_active() and \
-                       templv.format.type != "luks":
-                        newluks = format
-                        format = getFormat("luks",
-                                           device=templv.path,
-                                           passphrase=self.storage.encryptionPassphrase)
-                    elif self.lukscb and self.lukscb.get_active():
-                        newluks = format
-                        format = templv.format
-
-                    templv.format = format
-                elif self.fsoptionsDict.has_key("formatcb") and \
-                     not self.fsoptionsDict["formatcb"].get_active():
-                    templv.format = templv.originalFormat
-                    format = templv.format
-
-                if format.mountable:
-                    format.mountpoint = mountpoint
-
-                if self.fsoptionsDict.has_key("migratecb") and \
-                   self.fsoptionsDict["migratecb"].get_active():
-                    format.migrate = True
-
-                if self.fsoptionsDict.has_key("resizecb") and self.fsoptionsDict["resizecb"].get_active():
-                    targetSize = self.fsoptionsDict["resizesb"].get_value_as_int()
-                    templv.targetSize = targetSize
-
-            if format.exists and format.mountable and format.mountpoint:
-                tempdev = StorageDevice('tmp', format=format)
-                if self.storage.formatByDefault(tempdev) and \
-                   not queryNoFormatPreExisting(self.intf):
-                    continue
-
-            # everything ok
-            break
-
-        if templv.format.type == "luks":
-            if newluks:
-                self.luks[templv.lvname] = newluks
-
-            if self.luks.has_key(origname) and origname != templv.lvname:
-                self.luks[templv.lvname] = self.luks[origname]
-                del self.luks[templv.lvname]
-        elif templv.format.type != "luks" and self.luks.has_key(origname):
-            del self.luks[origname]
-
-        self.lvs[templv.lvname] = {'name': templv.lvname,
-                                   'size': templv.size,
-                                   'format': templv.format,
-                                   'originalFormat': templv.originalFormat,
-                                   'stripes': templv.stripes,
-                                   'logSize': templv.logSize,
-                                   'snapshotSpace': templv.snapshotSpace,
-                                   'exists': templv.exists}
-        if self.lvs.has_key(origname) and origname != templv.lvname:
-            del self.lvs[origname]
-
-        self.updateLogVolStore()
-        self.updateVGSpaceLabels()
-        dialog.destroy()
-        return
-
-    def editCurrentLogicalVolume(self):
-	iter = self.getCurrentLogicalVolume()
-
-	if iter is None:
-	    return
-	
-	logvolname = self.logvolstore.get_value(iter, 0)
-	lv = self.lvs[logvolname]
-	self.editLogicalVolume(lv)
-
-    def addLogicalVolumeCB(self, widget):
-        if self.numAvailableLVSlots() < 1:
-            self.intf.messageWindow(_("No free slots"),
-                P_("You cannot create more than %d logical volume "
-                   "per volume group.",
-                   "You cannot create more than %d logical volumes "
-                   "per volume group.", lvm.MAX_LV_SLOTS)
-                % (lvm.MAX_LV_SLOTS,),
-                custom_icon="error")
-            return
-
-        (total, used, free) = self.computeSpaceValues()
-	if free <= 0:
-	    self.intf.messageWindow(_("No free space"),
-				    _("There is no room left in the "
-				      "volume group to create new logical "
-				      "volumes. "
-				      "To add a logical volume you must "
-				      "reduce the size of one or more of "
-				      "the currently existing "
-				      "logical volumes"), custom_icon="error")
-	    return
-
-        tempvg = self.getTempVG()
-        name = self.storage.createSuggestedLVName(tempvg)
-        format = getFormat(self.storage.defaultFSType)
-        self.lvs[name] = {'name': name,
-                          'size': free,
-                          'format': format,
-                          'originalFormat': format,
-                          'stripes': 1,
-                          'logSize': 0,
-                          'snapshotSpace': 0,
-                          'exists': False}
-        self.editLogicalVolume(self.lvs[name], isNew = 1)
-        return
-
-    def editLogicalVolumeCB(self, widget):
-	self.editCurrentLogicalVolume()
-	return
-
-    def delLogicalVolumeCB(self, widget):
-	iter = self.getCurrentLogicalVolume()
-	if iter is None:
-	    return
-	
-	logvolname = self.logvolstore.get_value(iter, 0)
-	if logvolname is None:
-	    return
-
-	rc = self.intf.messageWindow(_("Confirm Delete"),
-				_("Are you sure you want to delete the "
-				"logical volume \"%s\"?") % (logvolname,),
-				type = "custom", custom_buttons=["gtk-cancel", _("_Delete")], custom_icon="warning")
-	if not rc:
-	    return
-
-        del self.lvs[logvolname]
-        self.logvolstore.remove(iter)
-        self.updateVGSpaceLabels()
-        return
-    
-    def logvolActivateCb(self, view, path, col):
-	self.editCurrentLogicalVolume()
-
-    def getSelectedPhysicalVolumes(self):
-        model = self.lvmlist.get_model()
-        pv = []
-        next = model.get_iter_first()
-        currow = 0
-        while next is not None:
-	    iter = next
-	    val      = model.get_value(iter, 0)
-	    partname = model.get_value(iter, 1)
-	    
-	    if val:
-		dev = self.storage.devicetree.getDeviceByName(partname)
-                pv.append(dev)
-
-	    next = model.iter_next(iter)
-	    currow = currow + 1
-
-	return pv
-
-    def computeVGSize(self, pvlist, curpe):
-	availSpaceMB = 0L
-	for pv in pvlist:
-            # have to clamp pvsize to multiple of PE
-            # XXX why the subtraction? fudging metadata?
-	    pvsize = lvm.clampSize(pv.size, curpe) - (curpe/1024)
-
-	    availSpaceMB = availSpaceMB + pvsize
-
-        log.info("computeVGSize: vgsize is %s" % (availSpaceMB,))
-	return availSpaceMB
-
-    def updateLogVolStore(self):
-        self.logvolstore.clear()
-        for lv in self.lvs.values():
-            iter = self.logvolstore.append()
-            if lv['format'].type == "luks":
-                format = self.luks[lv['name']]
-            else:
-                format = lv['format']
-
-            mntpt = getattr(format, "mountpoint", "")
-            if lv['name']:
-                self.logvolstore.set_value(iter, 0, lv['name'])
-                
-            if format.type and format.mountable:
-                self.logvolstore.set_value(iter, 1, mntpt)
-	    else:
-		self.logvolstore.set_value(iter, 1, "N/A")
-
-            self.logvolstore.set_value(iter, 2, "%Ld" % lv['size'])
-
-    def updateVGSpaceLabels(self):
-        (total, used, free) = self.computeSpaceValues()
-
-	self.totalSpaceLabel.set_text("%10.2f MB" % (total,))
-	self.usedSpaceLabel.set_text("%10.2f MB" % (used,))
-
-	if total > 0:
-	    usedpercent = (100.0*used)/total
-	else:
-	    usedpercent = 0.0
-	    
-	self.usedPercentLabel.set_text("(%4.1f %%)" % (usedpercent,))
-
-	self.freeSpaceLabel.set_text("%10.2f MB" % (free,))
-	if total > 0:
-	    freepercent = (100.0*free)/total
-	else:
-	    freepercent = 0.0
-
-	self.freePercentLabel.set_text("(%4.1f %%)" % (freepercent,))
-
-#
-# run the VG editor we created
-#
-    def run(self):
-	if self.dialog is None:
-	    return []
-	
-	while 1:
-	    rc = self.dialog.run()
-
-	    if rc in [gtk.RESPONSE_CANCEL, gtk.RESPONSE_DELETE_EVENT]:
-		self.destroy()
-		return []
-
-	    pvlist = self.getSelectedPhysicalVolumes()
-
-	    # check volume name
-	    volname = self.volnameEntry.get_text().strip()
-	    err = sanityCheckVolumeGroupName(volname)
-	    if err:
-		self.intf.messageWindow(_("Invalid Volume Group Name"), err,
-					custom_icon="error")
-		continue
-
-	    origvname = self.vg.name
-
-	    if origvname != volname:
-                # maybe we should see if _any_ device has this name
-		if volname in [vg.name for vg in self.storage.vgs]:
-		    self.intf.messageWindow(_("Name in use"),
-					    _("The volume group name \"%s\" is "
-					      "already in use. Please pick "
-					      "another." % (volname,)),
-					    custom_icon="error")
-		    continue
-
-	    # get physical extent
-	    pesize = int(self.peCombo.get_active_value()) / 1024.0
-
-	    # everything ok
-	    break
-        return self.convertToActions()
-
-    def convertToActions(self):
-        # here we have to figure out what all was done and convert it to
-        # devices and actions
-        #
-        # set up the vg with the right pvs
-        # set up the lvs
-        #  set up the lvs' formats
-        #
-        log.debug("finished editing vg")
-        log.debug("pvs: %s" % [p.name for p in self.pvs])
-        log.debug("luks: %s" % self.luks.keys())
-        volname = self.volnameEntry.get_text().strip()
-        pesize = int(self.peCombo.get_active_value()) / 1024.0
-        for lv in self.lvs.itervalues():
-            log.debug("lv %s" % lv)
-            _luks = self.luks.get(lv['name'])
-            if _luks:
-                log.debug("  luks: %s" % _luks)
-
-        actions = []
-        origlvs = self.vg.lvs
-        if not self.vg.exists:
-            log.debug("non-existing vg -- setting up lvs, pvs, name, pesize")
-            # remove all of the lvs
-            for lv in self.vg.lvs:
-                self.vg._removeLogVol(lv)
-
-            # set up the pvs
-            for pv in self.vg.pvs:
-                if pv not in self.pvs:
-                    self.vg._removePV(pv)
-            for pv in self.pvs:
-                if pv not in self.vg.pvs:
-                    self.vg._addPV(pv)
-
-            self.vg.name = volname
-            self.vg.peSize = pesize
-
-            if self.isNew:
-                actions = [ActionCreateDevice(self.vg)]
-
-        # Schedule destruction of all non-existing lvs, their formats,
-        # luks devices, &c. Also destroy devices that have been removed.
-        for lv in origlvs:
-            log.debug("old lv %s..." % lv.lvname)
-            if not lv.exists or lv.lvname not in self.lvs or \
-               (not self.lvs[lv.lvname]['exists'] and lv.exists):
-                log.debug("removing lv %s" % lv.lvname)
-                if lv.format.type == "luks":
-                    try:
-                        _luksdev = self.storage.devicetree.getChildren(lv)[0]
-                    except IndexError:
-                        pass
-                    else:
-                        if _luksdev.format.type:
-                            actions.append(ActionDestroyFormat(_luksdev))
-
-                        actions.append(ActionDestroyDevice(_luksdev))
-
-                if lv.format.type:
-                    actions.append(ActionDestroyFormat(lv))
-
-                if lv in self.vg.lvs:
-                    self.vg._removeLogVol(lv)
-
-                actions.append(ActionDestroyDevice(lv))
-
-        # schedule creation of all new lvs, their formats, luks devices, &c
-        tempvg = self.getTempVG()
-        for lv in tempvg.lvs:
-            log.debug("new lv %s" % lv)
-            if not lv.exists:
-                log.debug("creating lv %s" % lv.lvname)
-                # create the device
-                newlv = LVMLogicalVolumeDevice(lv.lvname,
-                                               self.vg,
-                                               size=lv.size)
-                actions.append(ActionCreateDevice(newlv))
-
-                # create the format
-                mountpoint = getattr(lv.format, "mountpoint", None)
-                format = getFormat(lv.format.type,
-                                   mountpoint=mountpoint,
-                                   device=newlv.path)
-                actions.append(ActionCreateFormat(newlv, format))
-
-                if lv.format.type == "luks":
-                    # create the luks device
-                    newluks = LUKSDevice("luks-%s" % newlv.name,
-                                         parents=[newlv])
-                    actions.append(ActionCreateDevice(newluks))
-
-                    # create the luks format
-                    oldfmt = self.luks[lv.lvname]
-                    mountpoint = getattr(oldfmt, "mountpoint", None)
-                    format = getFormat(oldfmt.type,
-                                       mountpoint=mountpoint,
-                                       device=newluks.path)
-                    actions.append(ActionCreateFormat(newluks, format))
-            else:
-                log.debug("lv %s already exists" % lv.lvname)
-                # this lv is preexisting. check for resize and reformat.
-                # first, get the real/original lv
-                origlv = self.getLVByName(lv.lvname)
-                if lv.resizable and lv.targetSize != origlv.size:
-                    actions.append(ActionResizeDevice(origlv, lv.targetSize))
-
-                if lv.format.exists:
-                    log.debug("format already exists")
-                    if lv.format.type == "luks":
-                        # see if the luks device already exists
-                        try:
-                            usedev = self.storage.devicetree.getChildren(origlv)[0]
-                        except IndexError:
-                            # the luks device does not exist, meaning we
-                            # do not have a key for it
-                            continue
-
-                        format = self.luks[lv.lvname]
-                        if not format.exists:
-                            actions.append(ActionCreateFormat(usedev, format))
-                    else:
-                        usedev = origlv
-                        format = lv.format
-
-                    # no formatting action requested, meaning we should
-                    # cancel all format create/destroy actions
-                    if format == usedev.originalFormat:
-                        devicetree = self.storage.devicetree
-                        cancel = []
-                        if origlv.originalFormat.type == "luks":
-                            path = "/dev/mapper/luks-%s" % origlv.originalFormat.uuid
-                            cancel.extend(devicetree.findActions(path=path))
-
-                        cancel.extend(devicetree.findActions(type="create",
-                                                             object="format",
-                                                             devid=origlv.id))
-                        cancel.extend(devicetree.findActions(type="destroy",
-                                                             object="format",
-                                                             devid=origlv.id))
-                        for action in cancel:
-                            devicetree.cancelAction(action)
-
-                        # even though we cancelled a bunch of actions, it's
-                        # pretty much impossible to be sure we cancelled them
-                        # in the correct order. make sure things are back to
-                        # their original state.
-                        if origlv.format.type == "luks":
-                            try:
-                                usedev = devicetree.getChildren(origlv)[0]
-                            except IndexError:
-                                usedev = origlv
-                            else:
-                                usedev.format = usedev.originalFormat
-                        else:
-                            usedev = origlv
-
-                    if hasattr(format, "mountpoint"):
-                        usedev.format.mountpoint = format.mountpoint
-
-                    if format.migratable and format.migrate and \
-                       not usedev.format.migrate:
-                        usedev.format.migrate = format.migrate
-                        actions.append(ActionMigrateFormat(usedev))
-
-                    # check the lv's format also, explicitly, in case it is
-                    # encrypted. in this case we must check them both.
-                    if format.resizable and lv.format.resizable and \
-                            lv.targetSize != format.targetSize and \
-                            usedev.format.exists:
-                        log.debug("resizing format on %s to %d" % (usedev.lvname, lv.targetSize))
-                        actions.append(ActionResizeFormat(usedev, lv.targetSize))
-                elif lv.format.type:
-                    log.debug("new format: %s" % lv.format.type)
-                    # destroy old format and any associated luks devices
-                    if origlv.format.type:
-                        if origlv.format.type == "luks":
-                            # destroy the luks device and its format
-                            try:
-                                _luksdev = self.storage.devicetree.getChildren(origlv)[0]
-                            except IndexError:
-                                pass
-                            else:
-                                if _luksdev.format.type:
-                                    # this is probably unnecessary
-                                    actions.append(ActionDestroyFormat(_luksdev))
-
-                                actions.append(ActionDestroyDevice(_luksdev))
-
-                        actions.append(ActionDestroyFormat(origlv))
-
-                    # create the format
-                    mountpoint = getattr(lv.format, "mountpoint", None)
-                    format = getFormat(lv.format.type,
-                                       mountpoint=mountpoint,
-                                       device=origlv.path)
-                    actions.append(ActionCreateFormat(origlv, format))
-
-                    if lv.format.type == "luks":
-                        # create the luks device
-                        newluks = LUKSDevice("luks-%s" % origlv.name,
-                                             parents=[origlv])
-                        actions.append(ActionCreateDevice(newluks))
-
-                        # create the luks format
-                        tmpfmt = self.luks[lv.lvname]
-                        mountpoint = getattr(tmpfmt, "mountpoint", None)
-                        format = getFormat(tmpfmt.type,
-                                           mountpoint=mountpoint,
-                                           device=newluks.path)
-                        actions.append(ActionCreateFormat(newluks, format))
-                else:
-                    log.debug("no format!?")
-
-	return actions
-
-    def destroy(self):
-	if self.dialog:
-	    self.dialog.destroy()
-	self.dialog = None
-
-    def getLVByName(self, name, vg=None):
-        if vg is None:
-            vg = self.vg
-
-        for lv in vg.lvs:
-            if lv.lvname == name or lv.name == name:
-                return lv
-
-    def __init__(self, anaconda, intf, parent, vg, isNew = 0):
-        self.storage = anaconda.storage
-
-        # the vg instance we were passed
-        self.vg = vg
-        self.peSize = vg.peSize
-        self.pvs = self.vg.pvs[:]
-
-        # a dict of dicts
-        #  keys are lv names
-        #  values are dicts representing the lvs
-        #   name, size, format instance, exists
-        self.lvs = {}
-
-        # a dict of luks devices
-        #  keys are lv names
-        #  values are formats of the mapped devices
-        self.luks = {}
-
-        self.isNew = isNew
-        self.intf = intf
-        self.parent = parent
-        self.actions = []
-
-        for lv in self.vg.lvs:
-            self.lvs[lv.lvname] = {"name": lv.lvname,
-                                   "size": lv.size,
-                                   "format": copy.copy(lv.format),
-                                   "originalFormat": lv.originalFormat,
-                                   "stripes": lv.stripes,
-                                   "logSize": lv.logSize,
-                                   "snapshotSpace": lv.snapshotSpace,
-                                   "exists": lv.exists}
-
-            if lv.format.type == "luks":
-                try:
-                    self.luks[lv.lvname] = self.storage.devicetree.getChildren(lv)[0].format
-                except IndexError:
-                    self.luks[lv.lvname] = lv.format
-
-        self.availlvmparts = self.storage.unusedPVs(vg=vg)
-
-        # if no PV exist, raise an error message and return
-        if len(self.availlvmparts) < 1:
-	    self.intf.messageWindow(_("Not enough physical volumes"),
-			       _("At least one unused physical "
-				 "volume partition is "
-				 "needed to create an LVM Volume Group.\n\n"
-				 "Create a partition or RAID array "
-				 "of type \"physical volume (LVM)\" and then "
-				 "select the \"LVM\" option again."),
-				    custom_icon="error")
-	    self.dialog = None
-            return
-
-	if isNew:
-	    tstr = _("Make LVM Volume Group")
-	else:
-	    try:
-		tstr = _("Edit LVM Volume Group: %s") % (vg.name,)
-	    except AttributeError:
-		tstr = _("Edit LVM Volume Group")
-	    
-        dialog = gtk.Dialog(tstr, self.parent)
-        gui.addFrame(dialog)
-        dialog.add_button('gtk-cancel', gtk.RESPONSE_CANCEL)
-        dialog.add_button('gtk-ok', 1)
-
-        dialog.set_position(gtk.WIN_POS_CENTER)
-
-        maintable = gtk.Table()
-        maintable.set_row_spacings(5)
-        maintable.set_col_spacings(5)
-        row = 0
-
-        # volume group name
-        if not vg.exists:
-            lbl = createAlignedLabel(_("_Volume Group Name:"))
-            self.volnameEntry = gtk.Entry(16)
-            lbl.set_mnemonic_widget(self.volnameEntry)
-            if not self.isNew:
-                self.volnameEntry.set_text(self.vg.name)
-            else:
-                self.volnameEntry.set_text(self.storage.createSuggestedVGName(anaconda.network))
-        else:
-            lbl = createAlignedLabel(_("Volume Group Name:"))
-            self.volnameEntry = gtk.Label(self.vg.name)
-	    
-	maintable.attach(lbl, 0, 1, row, row + 1,
-                         gtk.EXPAND|gtk.FILL, gtk.SHRINK)
-        maintable.attach(self.volnameEntry, 1, 2, row, row + 1, gtk.EXPAND|gtk.FILL, gtk.SHRINK)
-	row = row + 1
-
-        lbl = createAlignedLabel(_("_Physical Extent:"))
-        self.peCombo = self.createPEOptionMenu(self.vg.peSize * 1024)
-        lbl.set_mnemonic_widget(self.peCombo)
-        if vg.exists:
-            self.peCombo.set_sensitive(False)
-
-        maintable.attach(lbl, 0, 1, row, row + 1,
-                         gtk.EXPAND|gtk.FILL, gtk.SHRINK)
-        maintable.attach(self.peCombo, 1, 2, row, row + 1, gtk.EXPAND|gtk.FILL, gtk.SHRINK)
-        row = row + 1
-
-        (self.lvmlist, sw) = self.createAllowedLvmPartitionsList()
-        if vg.exists:
-            self.lvmlist.set_sensitive(False)
-        self.lvmlist.set_size_request(275, 80)
-        lbl = createAlignedLabel(_("Physical Volumes to _Use:"))
-        lbl.set_mnemonic_widget(self.lvmlist)
-        maintable.attach(lbl, 0, 1, row, row + 1)
-        maintable.attach(sw, 1, 2, row, row + 1)
-        row = row + 1
-
-        maintable.attach(createAlignedLabel(_("Used Space:")), 0, 1, row,
-			 row + 1, gtk.EXPAND|gtk.FILL, gtk.SHRINK)
-	lbox = gtk.HBox()
-	self.usedSpaceLabel = gtk.Label("")
-	labelalign = gtk.Alignment()
-	labelalign.set(1.0, 0.5, 0.0, 0.0)
-	labelalign.add(self.usedSpaceLabel)
-	lbox.pack_start(labelalign, False, False)
-	self.usedPercentLabel = gtk.Label("")
-	labelalign = gtk.Alignment()
-	labelalign.set(1.0, 0.5, 0.0, 0.0)
-	labelalign.add(self.usedPercentLabel)
-	lbox.pack_start(labelalign, False, False, padding=10)
-        maintable.attach(lbox, 1, 2, row, row + 1, gtk.EXPAND|gtk.FILL, gtk.SHRINK)
-	maintable.set_row_spacing(row, 0)
-        row = row + 1
-
-        maintable.attach(createAlignedLabel(_("Free Space:")), 0, 1, row,
-			 row + 1, gtk.EXPAND|gtk.FILL, gtk.SHRINK)
-	lbox = gtk.HBox()
-	self.freeSpaceLabel = gtk.Label("")
-	labelalign = gtk.Alignment()
-	labelalign.set(1.0, 0.5, 0.0, 0.0)
-	labelalign.add(self.freeSpaceLabel)
-	lbox.pack_start(labelalign, False, False)
-	self.freePercentLabel = gtk.Label("")
-	labelalign = gtk.Alignment()
-	labelalign.set(1.0, 0.5, 0.0, 0.0)
-	labelalign.add(self.freePercentLabel)
-	lbox.pack_start(labelalign, False, False, padding=10)
-
-        maintable.attach(lbox, 1, 2, row, row + 1, gtk.EXPAND|gtk.FILL, gtk.SHRINK)
-	maintable.set_row_spacing(row, 0)
-        row = row + 1
-
-        maintable.attach(createAlignedLabel(_("Total Space:")), 0, 1, row,
-			 row + 1, gtk.EXPAND|gtk.FILL, gtk.SHRINK)
-	self.totalSpaceLabel = gtk.Label("")
-	labelalign = gtk.Alignment()
-	labelalign.set(0.0, 0.5, 0.0, 0.0)
-	labelalign.add(self.totalSpaceLabel)
-        maintable.attach(labelalign, 1, 2, row, row + 1, gtk.EXPAND|gtk.FILL, gtk.SHRINK)
-	maintable.set_row_spacing(row, 5)
-        row = row + 1
-
-	# populate list of logical volumes
-        lvtable = gtk.Table()
-        lvtable.set_row_spacings(5)
-        lvtable.set_col_spacings(5)
-	self.logvolstore = gtk.ListStore(gobject.TYPE_STRING,
-				      gobject.TYPE_STRING,
-				      gobject.TYPE_STRING)
-	
-	if self.vg.lvs:
-	    for lv in self.vg.lvs:
-		iter = self.logvolstore.append()
-		self.logvolstore.set_value(iter, 0, lv.lvname)
-                if lv.format.type == "luks":
-                    try:
-                        format = self.storage.devicetree.getChildren(lv)[0].format
-                    except IndexError:
-                        format = lv.format
-                else:
-                    format = lv.format
-
-                if getattr(format, "mountpoint", None):
-		    self.logvolstore.set_value(iter, 1,
-                                               format.mountpoint)
-		else:
-		    self.logvolstore.set_value(iter, 1, "")
-		self.logvolstore.set_value(iter, 2, "%Ld" % lv.size)
-
-	self.logvollist = gtk.TreeView(self.logvolstore)
-        col = gtk.TreeViewColumn(_("Logical Volume Name"),
-				 gtk.CellRendererText(), text=0)
-        self.logvollist.append_column(col)
-        col = gtk.TreeViewColumn(_("Mount Point"),
-				 gtk.CellRendererText(), text=1)
-        self.logvollist.append_column(col)
-        col = gtk.TreeViewColumn(_("Size (MB)"),
-				 gtk.CellRendererText(), text=2)
-        self.logvollist.append_column(col)
-        self.logvollist.connect('row-activated', self.logvolActivateCb)
-
-        sw = gtk.ScrolledWindow()
-        sw.add(self.logvollist)
-        sw.set_size_request(100, 100)
-        sw.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
-	sw.set_shadow_type(gtk.SHADOW_IN)
-        lvtable.attach(sw, 0, 1, 0, 1)
-
-	# button box of options
-	lvbbox = gtk.VBox()
-        add = gtk.Button(_("_Add"))
-        add.connect("clicked", self.addLogicalVolumeCB)
-	lvbbox.pack_start(add)
-        edit = gtk.Button(_("_Edit"))
-        edit.connect("clicked", self.editLogicalVolumeCB)
-	lvbbox.pack_start(edit)
-        delete = gtk.Button(_("_Delete"))
-        delete.connect("clicked", self.delLogicalVolumeCB)
-	lvbbox.pack_start(delete)
-
-	lvalign = gtk.Alignment()
-	lvalign.set(0.5, 0.0, 0.0, 0.0)
-	lvalign.add(lvbbox)
-        lvtable.attach(lvalign, 1, 2, 0, 1, gtk.SHRINK, gtk.SHRINK)
-
-	# pack all logical volumne stuff in a frame
-	lvtable.set_border_width(12)
-        l = gtk.Label()
-        l.set_markup_with_mnemonic("<b>%s</b>" %(_("_Logical Volumes"),))
-        l.set_mnemonic_widget(self.logvollist)
-	frame = gtk.Frame()
-        frame.set_label_widget(l)
-	frame.add(lvtable)
-        frame.set_shadow_type(gtk.SHADOW_NONE)
-
-#	dialog.vbox.pack_start(frame)
-	maintable.attach(frame, 0, 2, row, row+1)
-	row = row + 1
-	
-        dialog.vbox.pack_start(maintable)
-	dialog.set_size_request(550, 450)
-        dialog.show_all()
-
-	# set space labels to correct values
-	self.updateVGSpaceLabels()
-
-	self.dialog = dialog
diff --git a/iw/netconfig_dialog.py b/iw/netconfig_dialog.py
deleted file mode 100644
index 336cf0e..0000000
--- a/iw/netconfig_dialog.py
+++ /dev/null
@@ -1,329 +0,0 @@
-#
-# netconfig_dialog.py: Configure a network interface now.
-#
-# Copyright (C) 2006  Red Hat, Inc.  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 as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# 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, see <http://www.gnu.org/licenses/>.
-#
-# Author(s): Jeremy Katz <katzj@xxxxxxxxxx>
-#
-
-import gtk
-import gobject
-import gui
-
-from constants import *
-import gettext
-_ = lambda x: gettext.ldgettext("anaconda", x)
-
-import network
-import isys
-
-class NetworkConfigurator:
-    def __init__(self, network):
-        (xml, w) = gui.getGladeWidget("netconfig.glade", "NetworkConfigWindow")
-
-        self.window = w
-        self.network = network
-        self.xml = xml
-        self.rc = gtk.RESPONSE_CANCEL
-
-        self._setSizeGroup()
-        self._connectSignals()
-        self._populateNetdevs()
-
-        self.xml.get_widget("ipv4Checkbutton").set_active(True)
-        self.xml.get_widget("ipv6Checkbutton").set_active(False)
-
-    def _connectSignals(self):
-        sigs = { "on_ipv4Checkbutton_toggled": self._ipv4Toggled,
-                 "on_ipv6Checkbutton_toggled": self._ipv6Toggled,
-                 "on_dhcpCheckbutton_toggled": self._dhcpToggled,
-                 "on_interfaceCombo_changed": self._netdevChanged,
-                 "on_cancelButton_clicked": self._cancel,
-                 "on_okButton_clicked": self._ok }
-        self.xml.signal_autoconnect(sigs)
-
-    def _setSizeGroup(self): # too bad we can't do this in the glade file
-        sg = gtk.SizeGroup(gtk.SIZE_GROUP_HORIZONTAL)
-        for w in ("nameserverLabel", "gatewayLabel", "ipv6Label",
-                  "ipv4Label", "interfaceLabel"):
-            sg.add_widget(self.xml.get_widget(w))
-
-    def _netdevChanged(self, combo):
-        active = combo.get_active_iter()
-        val = combo.get_model().get_value(active, 1)
-        netdev = self.network.available()[val]
-
-        bootproto = netdev.get("BOOTPROTO")
-        if not bootproto or bootproto == "dhcp" or bootproto == "ibft":
-            self.xml.get_widget("dhcpCheckbutton").set_active(True)
-        else:
-            self.xml.get_widget("dhcpCheckbutton").set_active(False)
-
-            # FIXME: need to set ipv6 here too once we have that
-            try:
-                if netdev.get('IPADDR'):
-                    self.xml.get_widget("ipv4Address").set_text(netdev.get('IPADDR'))
-            except:
-                pass
-
-            try:
-                if netdev.get('NETMASK'):
-                    self.xml.get_widget("ipv4Netmask").set_text(netdev.get('NETMASK'))
-            except:
-                pass
-
-            try:
-                if self.network.gateway:
-                    self.xml.get_widget("gatewayEntry").set_text(self.network.gateway)
-            except:
-                pass
-
-            try:
-                if self.network.primaryNS:
-                    self.xml.get_widget("nameserverEntry").set_text(self.network.primaryNS)
-            except:
-                pass
-
-    def _ipv4Toggled(self, cb):
-        if self.xml.get_widget("dhcpCheckbutton").get_active():
-            return
-        if cb.get_active():
-            self.xml.get_widget("ipv4Box").set_sensitive(True)
-        else:
-            self.xml.get_widget("ipv4Box").set_sensitive(False)
-
-    def _ipv6Toggled(self, cb):
-        if self.xml.get_widget("dhcpCheckbutton").get_active():
-            return
-        if cb.get_active():
-            self.xml.get_widget("ipv6Box").set_sensitive(True)
-        else:
-            self.xml.get_widget("ipv6Box").set_sensitive(False)
-
-    def _dhcpToggled(self, cb):
-        boxes = ("ipv4Box", "ipv6Box", "nameserverBox", "gatewayBox")
-        if not cb.get_active():
-            map(lambda x: self.xml.get_widget(x).set_sensitive(True), boxes)
-            self.xml.get_widget("ipv4Box").set_sensitive(self.xml.get_widget("ipv4Checkbutton").get_active())
-            self.xml.get_widget("ipv6Box").set_sensitive(self.xml.get_widget("ipv6Checkbutton").get_active())
-        else:
-            map(lambda x: self.xml.get_widget(x).set_sensitive(False), boxes)
-
-    def _populateNetdevs(self):
-        combo = self.xml.get_widget("interfaceCombo")
-
-        cell = gtk.CellRendererText()
-        combo.pack_start(cell, True)
-        combo.set_attributes(cell, text = 0)
-        cell.set_property("wrap-width", 525)
-        combo.set_size_request(480, -1)
-
-        store = gtk.TreeStore(gobject.TYPE_STRING, gobject.TYPE_STRING)
-        combo.set_model(store)
-
-        netdevs = self.network.available()
-        devs = netdevs.keys()
-        devs.sort()
-        ksdevice = self.network.getKSDevice()
-        if ksdevice:
-            ksdevice = ksdevice.get('DEVICE')
-        selected_interface = None
-
-        for dev in devs:
-            i = store.append(None)
-            hwaddr = netdevs[dev].get("HWADDR")
-
-            if hwaddr:
-                desc = "%s - %s" %(dev, hwaddr,)
-            else:
-                desc = "%s" %(dev,)
-
-            if selected_interface is None:
-                selected_interface = i
-
-            if ksdevice and ksdevice == dev:
-                selected_interface = i
-
-            store[i] = (desc, dev)
-
-        if selected_interface:
-            combo.set_active_iter(selected_interface)
-        else:
-            combo.set_active(0)
-
-    def run(self):
-        gui.addFrame(self.window)
-        busycursor = gui.getBusyCursorStatus()
-        gui.setCursorToNormal()
-
-        self.window.show()
-        while True:
-            rc = self.window.run()
-            if rc in [gtk.RESPONSE_CANCEL, gtk.RESPONSE_DELETE_EVENT]:
-                self._cancel()
-                break
-            if self._ok():
-                break
-
-        # restore busy cursor
-        if busycursor:
-            gui.setCursorToBusy()
-        return self.rc
-
-    def destroy(self):
-        self.window.destroy()
-
-    def _handleIPError(self, field, errmsg):
-        d = gtk.MessageDialog(None, 0, gtk.MESSAGE_ERROR,
-                              gtk.BUTTONS_OK,
-                                _("An error occurred converting the value "
-                                  "entered for \"%(field)s\":\n%(errmsg)s")
-                                % {'field': field, 'errmsg': errmsg})
-        d.set_title(_("Error With Data"))
-        d.set_position(gtk.WIN_POS_CENTER)
-        gui.addFrame(d)
-        d.run()
-        d.destroy()
-
-    def _handleIPMissing(self, field):
-        d = gtk.MessageDialog(None, 0, gtk.MESSAGE_ERROR, gtk.BUTTONS_OK,
-                         _("A value is required for the field %s.") % (field,))
-        d.set_title(_("Error With Data"))
-        d.set_position(gtk.WIN_POS_CENTER)
-        gui.addFrame(d)
-        d.run()
-        d.destroy()
-
-    def _handleNetworkError(self, field):
-        d = gtk.MessageDialog(None, 0, gtk.MESSAGE_ERROR,
-                              gtk.BUTTONS_OK,
-                              _("An error occurred trying to bring up the "
-                                "%s network interface.") % (field,))
-        d.set_title(_("Error Configuring Network"))
-        d.set_position(gtk.WIN_POS_CENTER)
-        gui.addFrame(d)
-        d.run()
-        d.destroy()
-
-    def _cancel(self, *args):
-        self.rc = gtk.RESPONSE_CANCEL
-
-    def _ok(self, *args):
-        self.rc = gtk.RESPONSE_OK
-        haveNet = False
-        combo = self.xml.get_widget("interfaceCombo")
-        active = combo.get_active_iter()
-        val = combo.get_model().get_value(active, 1)
-        for v, dev in self.network.available().items():
-            if v == val:
-                dev.set(('ONBOOT', 'yes'))
-                netdev = dev
-            else:
-                dev.set(('ONBOOT', 'no'))
-
-        # FIXME: need to do input validation
-        if self.xml.get_widget("dhcpCheckbutton").get_active():
-            netdev.set(('BOOTPROTO', 'dhcp'))
-            self.window.hide()
-            w = gui.WaitWindow(_("Dynamic IP Address"),
-                               _("Sending request for IP address information "
-                                 "for %s") % (netdev.get('DEVICE'),))
-            haveNet = self.network.bringUp(devices=[netdev])
-            w.pop()
-        else:
-            netdev.set(('BOOTPROTO', 'static'))
-            ipv4addr = self.xml.get_widget("ipv4Address").get_text()
-            ipv4nm = self.xml.get_widget("ipv4Netmask").get_text()
-            gateway = self.xml.get_widget("gatewayEntry").get_text()
-            ns = self.xml.get_widget("nameserverEntry").get_text()
-
-            try:
-                network.sanityCheckIPString(ipv4addr)
-                netdev.set(('IPADDR', ipv4addr))
-            except network.IPMissing, msg:
-                self._handleIPMissing(_("IP Address"))
-                return False
-            except network.IPError, msg:
-                self._handleIPError(_("IP Address"), msg)
-                return False
-
-            if ipv4nm.find('.') == -1:
-                # user provided a CIDR prefix
-                try:
-                    if int(ipv4nm) > 32 or int(ipv4nm) < 0:
-                        msg = _("IPv4 CIDR prefix must be between 0 and 32.")
-                        self._handleIPError(_("IPv4 Network Mask"), msg)
-                        return False
-                    else:
-                        ipv4nm = isys.prefix2netmask(int(ipv4nm))
-                        netdev.set(('NETMASK', ipv4nm))
-                except:
-                    self._handleIPMissing(_("IPv4 Network Mask"))
-                    return False
-            else:
-                # user provided a dotted-quad netmask
-                try:
-                    network.sanityCheckIPString(ipv4nm)
-                    netdev.set(('NETMASK', ipv4nm))
-                except network.IPMissing, msg:
-                    self._handleIPMissing(_("IPv4 Network Mask"))
-                    return False
-                except network.IPError, msg:
-                    self._handleIPError(_("IPv4 Network Mask"), msg)
-                    return False
-
-            try:
-                if gateway:
-                    network.sanityCheckIPString(gateway)
-                    netdev.set(('GATEWAY', gateway))
-            except network.IPMissing, msg:
-                pass
-            except network.IPError, msg:
-                self._handleIPError(_("Gateway"), msg)
-                return False
-
-            try:
-                if ns:
-                    network.sanityCheckIPString(ns)
-                    netdev.set(('DNS1', ns))
-            except network.IPMissing, msg:
-                pass
-            except network.IPError, msg:
-                self._handleIPError(_("Nameserver"), msg)
-                return False
-
-            try:
-                haveNet = self.network.bringUp(devices=[netdev])
-            except Exception, e:
-                import logging
-                log = logging.getLogger("anaconda")
-                log.error("Error configuring network device: %s" %(e,))
-                self._handleIPError(_("Error configuring network device:"), e)
-                return False
-
-        if not haveNet:
-            self._handleNetworkError(netdev.get('DEVICE'))
-            return False
-
-        return True
-
-def main():
-    net = network.Network()
-    d = NetworkConfigurator(net)
-    ret = d.run()
-
-if __name__ == "__main__":
-    main()
diff --git a/iw/network_gui.py b/iw/network_gui.py
deleted file mode 100644
index 4d8e5da..0000000
--- a/iw/network_gui.py
+++ /dev/null
@@ -1,106 +0,0 @@
-#
-# network_gui.py: Network configuration dialog
-#
-# Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006,  Red Hat, Inc.
-#               2007, 2008, 2009
-#
-# 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; either version 2 of the License, or
-# (at your option) any later version.
-#
-# 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, see <http://www.gnu.org/licenses/>.
-#
-# Author(s): Michael Fulbright <msf@xxxxxxxxxx>
-#            David Cantrell <dcantrell@xxxxxxxxxx>
-#
-
-import string
-from iw_gui import *
-import gui
-import network
-import iutil
-import gobject
-import subprocess
-
-from constants import *
-import gettext
-_ = lambda x: gettext.ldgettext("anaconda", x)
-
-class NetworkWindow(InstallWindow):
-    def getScreen(self, anaconda):
-        self.intf = anaconda.intf
-        self.anaconda = anaconda
-        self.hostname = network.getDefaultHostname(anaconda)
-
-        # load the UI
-        (self.xml, self.align) = gui.getGladeWidget("network.glade",
-                                                    "network_align")
-        self.icon = self.xml.get_widget("icon")
-        self.hostnameEntry = self.xml.get_widget("hostnameEntry")
-        self.hostnameEntry.set_text(self.hostname)
-
-        self.xml.get_widget("netconfButton").connect("clicked", self._NMConfig)
-
-        # pressing Enter in confirm == clicking Next
-        self.hostnameEntry.connect("activate",
-                                   lambda w: self.ics.setGrabNext(1))
-
-        # load the icon
-        gui.readImageFromFile("network.png", image=self.icon)
-
-        return self.align
-
-    def focus(self):
-        self.hostnameEntry.grab_focus()
-
-    def hostnameError(self):
-        self.hostnameEntry.grab_focus()
-        raise gui.StayOnScreen
-
-    def getNext(self):
-        hostname = string.strip(self.hostnameEntry.get_text())
-        herrors = network.sanityCheckHostname(hostname)
-
-        if not hostname:
-            self.intf.messageWindow(_("Error with Hostname"),
-                                    _("You must enter a valid hostname for this "
-                                      "computer."), custom_icon="error")
-            self.hostnameError()
-
-        if herrors is not None:
-            self.intf.messageWindow(_("Error with Hostname"),
-                                    _("The hostname \"%(hostname)s\" is not "
-                                      "valid for the following reason:\n\n"
-                                      "%(herrors)s")
-                                    % {'hostname': hostname,
-                                       'herrors': herrors},
-                                    custom_icon="error")
-            self.hostnameError()
-
-        self.anaconda.network.hostname = hostname
-        return None
-
-    def _NMExited(self, pid, condition, data):
-        self.intf.icw.window.set_sensitive(True)
-
-    def _NMConfig(self, *args):
-
-        self.intf.icw.window.set_sensitive(False)
-        cmd = ["/usr/bin/nm-connection-editor"]
-        out = open("/dev/tty5", "w")
-        try:
-            proc = subprocess.Popen(cmd, stdout=out, stderr=out)
-        except Exception as e:
-            self.intf.icw.window.set_sensitive(True)
-            import logging
-            log = logging.getLogger("anaconda")
-            log.error("Could not start nm-connection-editor: %s" % e)
-        else:
-            gobject.child_watch_add(proc.pid, self._NMExited, data=None, priority=gobject.PRIORITY_DEFAULT)
diff --git a/iw/osbootwidget.py b/iw/osbootwidget.py
deleted file mode 100644
index 8c89d43..0000000
--- a/iw/osbootwidget.py
+++ /dev/null
@@ -1,397 +0,0 @@
-#
-# osbootwidget.py: gui bootloader list of operating systems to boot
-#
-# Copyright (C) 2001, 2002  Red Hat, Inc.  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 as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# 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, see <http://www.gnu.org/licenses/>.
-#
-# Author(s): Jeremy Katz <katzj@xxxxxxxxxx>
-#
-
-import gtk
-import gobject
-import iutil
-import parted
-import gui
-import datacombo
-from constants import *
-from storage.devices import devicePathToName
-
-import gettext
-_ = lambda x: gettext.ldgettext("anaconda", x)
-
-class OSBootWidget:
-    """Widget to display OSes to boot and allow adding new ones."""
-    
-    def __init__(self, anaconda, parent, blname = None):
-        self.bl = anaconda.bootloader
-        self.storage = anaconda.storage
-        self.parent = parent
-        self.intf = anaconda.intf
-        if blname is not None:
-            self.blname = blname
-        else:
-            self.blname = "GRUB"
-
-        self.setIllegalChars()
-        
-        self.vbox = gtk.VBox(False, 5)
-        label = gtk.Label("<b>" + _("Boot loader operating system list") + "</b>")
-	label.set_alignment(0.0, 0.0)
-        label.set_property("use-markup", True)
-        self.vbox.pack_start(label, False)
-
-        box = gtk.HBox (False, 5)
-        sw = gtk.ScrolledWindow()
-        sw.set_shadow_type(gtk.SHADOW_ETCHED_IN)
-        sw.set_policy(gtk.POLICY_NEVER, gtk.POLICY_AUTOMATIC)
-        sw.set_size_request(300, 100)
-        box.pack_start(sw, True)
-
-
-        self.osStore = gtk.ListStore(gobject.TYPE_BOOLEAN, gobject.TYPE_STRING,
-                                     gobject.TYPE_STRING, gobject.TYPE_BOOLEAN)
-        self.osTreeView = gtk.TreeView(self.osStore)
-        theColumns = [ _("Default"), _("Label"), _("Device") ]
-
-        self.checkboxrenderer = gtk.CellRendererToggle()
-        column = gtk.TreeViewColumn(theColumns[0], self.checkboxrenderer,
-                                    active = 0)
-        column.set_sizing(gtk.TREE_VIEW_COLUMN_AUTOSIZE)
-        self.checkboxrenderer.connect("toggled", self.toggledDefault)
-        self.checkboxrenderer.set_radio(True)
-        self.osTreeView.append_column(column)
-
-        for columnTitle in theColumns[1:]:
-            renderer = gtk.CellRendererText()
-            column = gtk.TreeViewColumn(columnTitle, renderer,
-                                        text = theColumns.index(columnTitle))
-            column.set_clickable(False)
-            self.osTreeView.append_column(column)
-
-        self.osTreeView.set_headers_visible(True)
-        self.osTreeView.columns_autosize()
-        self.osTreeView.set_size_request(100, 100)
-        sw.add(self.osTreeView)
-        self.osTreeView.connect('row-activated', self.osTreeActivateCb)
-
-        self.imagelist = self.bl.images.getImages()
-        self.defaultDev = self.bl.images.getDefault()
-        self.fillOSList()
-
-        buttonbar = gtk.VButtonBox()
-        buttonbar.set_layout(gtk.BUTTONBOX_START)
-        buttonbar.set_border_width(5)
-        add = gtk.Button(_("_Add"))
-        buttonbar.pack_start(add, False)
-        add.connect("clicked", self.addEntry)
-
-        edit = gtk.Button(_("_Edit"))
-        buttonbar.pack_start(edit, False)
-        edit.connect("clicked", self.editEntry)
-
-        delete = gtk.Button(_("_Delete"))
-        buttonbar.pack_start(delete, False)
-        delete.connect("clicked", self.deleteEntry)
-        box.pack_start(buttonbar, False)
-
-        self.vbox.pack_start(box, False)
-
-        self.widget = self.vbox
-
-    def setIllegalChars(self):
-        # illegal characters for boot loader labels
-        if self.blname == "GRUB":
-            self.illegalChars = [ "$", "=" ]
-        else:
-            self.illegalChars = [ "$", "=", " " ]
-
-    def changeBootLoader(self, blname):
-        if blname is not None:
-            self.blname = blname
-        else:
-            self.blname = "GRUB"
-        self.setIllegalChars()
-        self.fillOSList()
-
-    # adds/edits a new "other" os to the boot loader config
-    def editOther(self, oldDevice, oldLabel, isDefault, isRoot = 0):
-        dialog = gtk.Dialog(_("Image"), self.parent)
-        dialog.add_button('gtk-cancel', gtk.RESPONSE_CANCEL)
-        dialog.add_button('gtk-ok', 1)
-        dialog.set_position(gtk.WIN_POS_CENTER)
-        gui.addFrame(dialog)
-
-        dialog.vbox.pack_start(gui.WrappingLabel(
-            _("Enter a label for the boot loader menu to display. The "
-	      "device (or hard drive and partition number) is the device "
-	      "from which it boots.")))
-
-        table = gtk.Table(2, 5)
-        table.set_row_spacings(5)
-        table.set_col_spacings(5)
-
-        label = gui.MnemonicLabel(_("_Label"))
-        table.attach(label, 0, 1, 1, 2, gtk.FILL, 0, 10)
-        labelEntry = gtk.Entry(32)
-        label.set_mnemonic_widget(labelEntry)
-        table.attach(labelEntry, 1, 2, 1, 2, gtk.FILL, 0, 10)
-        if oldLabel:
-            labelEntry.set_text(oldLabel)
-
-        label = gui.MnemonicLabel(_("_Device"))
-        table.attach(label, 0, 1, 2, 3, gtk.FILL, 0, 10)
-        if not isRoot:
-            parts = []
-
-            for part in self.storage.partitions:
-                if part.partedPartition.getFlag(parted.PARTITION_LVM) or \
-                   part.partedPartition.getFlag(parted.PARTITION_RAID) or \
-                   not part.partedPartition.active:
-                    continue
-
-                parts.append(part)
-
-            deviceCombo = datacombo.DataComboBox()
-            defindex = 0
-            i = 0
-            for part in parts:
-                deviceCombo.append(part.path, part.name)
-                if oldDevice and oldDevice == part.name:
-                    defindex = i
-                i = i + 1
-
-
-            deviceCombo.set_active(defindex)
-            
-            table.attach(deviceCombo, 1, 2, 2, 3, gtk.FILL, 0, 10)
-            label.set_mnemonic_widget(deviceCombo)
-        else:
-            table.attach(gtk.Label(oldDevice), 1, 2, 2, 3, gtk.FILL, 0, 10)
-
-        default = gtk.CheckButton(_("Default Boot _Target"))
-        table.attach(default, 0, 2, 3, 4, gtk.FILL, 0, 10)
-        if isDefault != 0:
-            default.set_active(True)
-
-        if self.numentries == 1 and oldDevice != None:
-            default.set_sensitive(False)
-        else:
-            default.set_sensitive(True)
-        
-        dialog.vbox.pack_start(table)
-        dialog.show_all()
-
-        while 1:
-            rc = dialog.run()
-
-            # cancel
-            if rc in [gtk.RESPONSE_CANCEL, gtk.RESPONSE_DELETE_EVENT]:
-                break
-
-            label = labelEntry.get_text()
-
-            if not isRoot:
-                dev = deviceCombo.get_active_value()
-            else:
-                dev = oldDevice
-
-            if not label:
-                self.intf.messageWindow(_("Error"),
-                                        _("You must specify a label for the "
-                                          "entry"),
-                                        type="warning")
-                continue
-
-            foundBad = 0
-            for char in self.illegalChars:
-                if char in label:
-                    self.intf.messageWindow(_("Error"),
-                                            _("Boot label contains illegal "
-                                              "characters"),
-                                            type="warning")
-                    foundBad = 1
-                    break
-            if foundBad:
-                continue
-
-            # verify that the label hasn't been used
-            foundBad = 0
-            for key in self.imagelist.keys():
-                if dev == key:
-                    continue
-                if self.blname == "GRUB":
-                    thisLabel = self.imagelist[key][1]
-                else:
-                    thisLabel = self.imagelist[key][0]
-
-                # if the label is the same as it used to be, they must
-                # have changed the device which is fine
-                if thisLabel == oldLabel:
-                    continue
-
-                if thisLabel == label:
-                    self.intf.messageWindow(_("Duplicate Label"),
-                                            _("This label is already in "
-                                              "use for another boot entry."),
-                                            type="warning")
-                    foundBad = 1
-                    break
-            if foundBad:
-                continue
-
-            # XXX need to do some sort of validation of the device?
-
-            # they could be duplicating a device, which we don't handle
-            if dev in self.imagelist.keys() and (not oldDevice or
-                                                 dev != oldDevice):
-                self.intf.messageWindow(_("Duplicate Device"),
-                                        _("This device is already being "
-                                          "used for another boot entry."),
-                                        type="warning")
-                continue
-
-            # if we're editing a previous, get what the old info was for
-            # labels.  otherwise, make it something safe for grub and the
-            # device name for lilo for lack of any better ideas
-            if oldDevice:
-                (oldshort, oldlong, oldisroot) = self.imagelist[oldDevice]
-            else:
-                (oldshort, oldlong, oldisroot) = (dev, label, None)
-                
-            # if we're editing and the device has changed, delete the old
-            if oldDevice and dev != oldDevice:
-                del self.imagelist[oldDevice]
-                
-            # go ahead and add it
-            if self.blname == "GRUB":
-                self.imagelist[dev] = (oldshort, label, isRoot)
-            else:
-                self.imagelist[dev] = (label, oldlong, isRoot)
-
-            if default.get_active():
-                self.defaultDev = dev
-
-            # refill the os list store
-            self.fillOSList()
-            break
-        
-        dialog.destroy()
-
-    def getSelected(self):
-        selection = self.osTreeView.get_selection()
-        (model, iter) = selection.get_selected()
-        if not iter:
-            return None
-
-        dev = devicePathToName(model.get_value(iter, 2))
-        label = model.get_value(iter, 1)
-        isRoot = model.get_value(iter, 3)
-        isDefault = model.get_value(iter, 0)
-        return (dev, label, isDefault, isRoot)
-
-
-    def addEntry(self, widget, *args):
-        self.editOther(None, None, 0)
-
-    def deleteEntry(self, widget, *args):
-        rc = self.getSelected()
-        if not rc:
-            return
-        (dev, label, isDefault, isRoot) = rc
-        if not isRoot:
-            del self.imagelist[dev]
-            if isDefault:
-                keys = self.imagelist.keys()
-                keys.sort()
-                self.defaultDev = keys[0]
-                
-            self.fillOSList()
-        else:
-            self.intf.messageWindow(_("Cannot Delete"),
-                                    _("This boot target cannot be deleted "
-				      "because it is for the %s "
-				      "system you are about to install.")
-                                    %(productName,),
-                                      type="warning")
-
-    def editEntry(self, widget, *args):
-        rc = self.getSelected()
-        if not rc:
-            return
-        (dev, label, isDefault, isRoot) = rc
-        self.editOther(dev, label, isDefault, isRoot)
-
-    # the default os was changed in the treeview
-    def toggledDefault(self, data, row):
-        iter = self.osStore.get_iter((int(row),))
-        dev = self.osStore.get_value(iter, 2)
-        self.defaultDev = devicePathToName(dev)
-        self.fillOSList()
-
-    # fill in the os list tree view
-    def fillOSList(self):
-        self.osStore.clear()
-        
-        keys = self.imagelist.keys()
-        keys.sort()
-
-        for dev in keys:
-            (label, longlabel, fstype) = self.imagelist[dev]
-            device = self.storage.devicetree.getDeviceByName(dev)
-            if self.blname == "GRUB":
-                theLabel = longlabel
-            else:
-                theLabel = label
-
-            # if the label is empty, remove from the image list and don't
-            # worry about it
-            if not theLabel:
-                del self.imagelist[dev]
-                continue
-
-	    isRoot = 0
-            rootDev = self.storage.rootDevice
-            if rootDev and rootDev.name == dev:
-		isRoot = 1
-
-            devPath = getattr(device, "path", "/dev/%s" % dev)
-            iter = self.osStore.append()
-            self.osStore.set_value(iter, 1, theLabel)
-            self.osStore.set_value(iter, 2, devPath)
-            self.osStore.set_value(iter, 3, isRoot)
-            if self.defaultDev == dev:
-                self.osStore.set_value(iter, 0, True)
-            else:
-                self.osStore.set_value(iter, 0, False)
-
-        self.numentries = len(keys)
-
-    def osTreeActivateCb(self, view, path, col):
-        self.editEntry(view)
-        
-        
-    def getWidget(self):
-        return self.widget
-
-    # FIXME: I really shouldn't have such intimate knowledge of
-    # the bootloader object
-    def setBootloaderImages(self):
-        "Apply the changes from our list into the self.bl object"
-        # make a copy of our image list to shove into the bl struct
-        self.bl.images.images = {}
-        for key in self.imagelist.keys():
-            self.bl.images.images[key] = self.imagelist[key]
-        self.bl.images.setDefault(self.defaultDev)
-        
diff --git a/iw/package_gui.py b/iw/package_gui.py
deleted file mode 100644
index 4e6bfbe..0000000
--- a/iw/package_gui.py
+++ /dev/null
@@ -1,39 +0,0 @@
-#
-# package_gui.py: package group selection screen
-#
-# Copyright (C) 2005  Red Hat, Inc.  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 as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# 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, see <http://www.gnu.org/licenses/>.
-#
-# Author(s): Jeremy Katz <katzj@xxxxxxxxxx>
-#
-
-# FIXME: group selection isn't currently backend independent
-from GroupSelector import GroupSelector
-
-import gui
-from iw_gui import *
-
-from constants import *
-import gettext
-_ = lambda x: gettext.ldgettext("anaconda", x)
-
-class GroupSelectionWindow (InstallWindow):
-    def getScreen(self, anaconda):
-        self.backend = anaconda.backend
-        self.intf = anaconda.intf
-        self.grpsel = GroupSelector(self.backend.ayum, gui.findGladeFile,
-                                    gui.addFrame)
-        self.grpsel.doRefresh()
-        return self.grpsel.vbox
diff --git a/iw/partition_dialog_gui.py b/iw/partition_dialog_gui.py
deleted file mode 100644
index 9279636..0000000
--- a/iw/partition_dialog_gui.py
+++ /dev/null
@@ -1,534 +0,0 @@
-#
-# partition_dialog_gui.py: dialog for editting a partition request
-#
-# Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007  Red Hat, Inc.
-# 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 as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# 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, see <http://www.gnu.org/licenses/>.
-#
-# Author(s): Michael Fulbright <msf@xxxxxxxxxx>
-#
-
-import copy
-
-import gobject
-import gtk
-
-import gui
-from storage.devices import PartitionDevice, LUKSDevice
-from storage.deviceaction import *
-from partition_ui_helpers_gui import *
-from constants import *
-
-import gettext
-_ = lambda x: gettext.ldgettext("anaconda", x)
-
-class PartitionEditor:
-    def sizespinchangedCB(self, widget, fillmaxszsb):
-	size = widget.get_value_as_int()
-	maxsize = fillmaxszsb.get_value_as_int()
-        if size < 1:
-            widget.set_value(1)
-            size = 1
-	if size > maxsize:
-	    fillmaxszsb.set_value(size)
-
-	# ugly got to be better way
-	adj = fillmaxszsb.get_adjustment()
-	adj.clamp_page(size, adj.upper)
-	fillmaxszsb.set_adjustment(adj)
-
-    def fillmaxszCB(self, widget, spin):
-	spin.set_sensitive(widget.get_active())
-
-    # pass in CB defined above because of two scope limitation of python!
-    def createSizeOptionsFrame(self, request, fillmaxszCB):
-	frame = gtk.Frame(_("Additional Size Options"))
-	sizeoptiontable = gtk.Table()
-	sizeoptiontable.set_row_spacings(5)
-	sizeoptiontable.set_border_width(4)
-
-	fixedrb     = gtk.RadioButton(label=_("_Fixed size"))
-	fillmaxszrb = gtk.RadioButton(group=fixedrb,
-				      label=_("Fill all space _up "
-					      "to (MB):"))
-	maxsizeAdj = gtk.Adjustment(value = 1, lower = 1,
-				    upper = MAX_PART_SIZE, step_incr = 1)
-	fillmaxszsb = gtk.SpinButton(maxsizeAdj, digits = 0)
-	fillmaxszsb.set_property('numeric', True)
-	fillunlimrb = gtk.RadioButton(group=fixedrb,
-				     label=_("Fill to maximum _allowable "
-					     "size"))
-
-	fillmaxszrb.connect("toggled", fillmaxszCB, fillmaxszsb)
-
-	# default to fixed, turn off max size spinbutton
-	fillmaxszsb.set_sensitive(0)
-	if request.req_grow:
-	    if request.req_max_size:
-		fillmaxszrb.set_active(1)
-		fillmaxszsb.set_sensitive(1)
-		fillmaxszsb.set_value(request.req_max_size)
-	    else:
-		fillunlimrb.set_active(1)
-	else:
-	    fixedrb.set_active(1)
-
-	sizeoptiontable.attach(fixedrb, 0, 1, 0, 1)
-	sizeoptiontable.attach(fillmaxszrb, 0, 1, 1, 2)
-	sizeoptiontable.attach(fillmaxszsb, 1, 2, 1, 2)
-	sizeoptiontable.attach(fillunlimrb, 0, 1, 2, 3)
-
-	frame.add(sizeoptiontable)
-
-	return (frame, fixedrb, fillmaxszrb, fillmaxszsb)
-
-
-    def run(self):
-	if self.dialog is None:
-	    return []
-
-        while 1:
-            rc = self.dialog.run()
-            actions = []
-            luksdev = None
-	    
-            # user hit cancel, do nothing
-            if rc in [gtk.RESPONSE_CANCEL, gtk.RESPONSE_DELETE_EVENT]:
-                self.destroy()
-                return []
-
-            mountpoint = self.mountCombo.get_children()[0].get_text()
-            if mountpoint == _("<Not Applicable>"):
-                mountpoint = ""
-
-            if mountpoint:
-                used = False
-                for (mp, dev) in self.storage.mountpoints.iteritems():
-                    if mp == mountpoint and \
-                       dev.id != self.origrequest.id and \
-                       not (self.origrequest.format.type == "luks" and
-                            self.origrequest in dev.parents):
-                        used = True
-                        break
-
-                if used:
-                    self.intf.messageWindow(_("Mount point in use"),
-                                            _("The mount point \"%s\" is in "
-                                              "use. Please pick another.") %
-                                            (mountpoint,),
-                                            custom_icon="error")
-                    continue
-
-            if not self.origrequest.exists:
-                # read out UI into a partition specification
-                fmt_class = self.newfstypeCombo.get_active_value()
-                # there's nothing about origrequest we care about
-                #request = copy.copy(self.origrequest)
-
-                if self.primonlycheckbutton.get_active():
-                    primary = True
-                else:
-                    primary = None
-
-                if self.fixedrb.get_active():
-                    grow = None
-                else:
-                    grow = True
-
-                self.sizespin.update()
-
-                if self.fillmaxszrb.get_active():
-                    self.fillmaxszsb.update()
-                    maxsize = self.fillmaxszsb.get_value_as_int()
-                else:
-                    maxsize = 0
-
-                allowdrives = []
-                model = self.driveview.get_model()
-                iter = model.get_iter_first()
-                while iter:
-                    val   = model.get_value(iter, 0)
-                    drive = model.get_value(iter, 1)
-
-                    if val:
-                        allowdrives.append(drive)
-
-                    iter = model.iter_next(iter)
-
-                if len(allowdrives) == len(self.storage.partitioned):
-                    allowdrives = None
-
-                size = self.sizespin.get_value_as_int()
-                disks = []
-                if allowdrives:
-                    for drive in allowdrives:
-                        for disk in self.storage.partitioned:
-                            if disk.name == drive:
-                                disks.append(disk)
-
-                format = fmt_class(mountpoint=mountpoint)
-                weight = self.anaconda.platform.weight(mountpoint=mountpoint,
-                                                       fstype=format.type)
-                if self.isNew:
-                    request = self.storage.newPartition(size=size,
-                                                        grow=grow,
-                                                        maxsize=maxsize,
-                                                        primary=primary,
-                                                        format=format,
-                                                        parents=disks,
-                                                        weight=weight)
-                else:
-                    request = self.origrequest
-                    request.weight = weight
-
-                if self.lukscb and self.lukscb.get_active() and \
-                   request.format.type != "luks":
-                    luksformat = format
-                    format = getFormat("luks",
-                                       passphrase=self.storage.encryptionPassphrase)
-                    luksdev = LUKSDevice("luks%d" % self.storage.nextID,
-                                         format=luksformat,
-                                         parents=request)
-                elif self.lukscb and not self.lukscb.get_active() and \
-                     self.origrequest.format.type == "luks":
-                    # destroy the luks format and the mapped device
-                    try:
-                        luksdev = self.storage.devicetree.getChildren(self.origrequest)[0]
-                    except IndexError:
-                        pass
-                    else:
-                        actions.append(ActionDestroyFormat(luksdev))
-                        actions.append(ActionDestroyDevice(luksdev))
-                        luksdev = None
-
-                    actions.append(ActionDestroyFormat(request))
-
-                if self.isNew:
-                    # we're all set, so create the actions
-                    actions.append(ActionCreateDevice(request))
-                else:
-                    request.req_size = size
-                    request.req_base_size = size
-                    request.req_grow = grow
-                    request.req_max_size = maxsize
-                    request.req_primary = primary
-                    request.req_disks = disks
-
-                actions.append(ActionCreateFormat(request, format))
-                if luksdev:
-                    actions.append(ActionCreateDevice(luksdev))
-                    actions.append(ActionCreateFormat(luksdev))
-            else:
-                # preexisting partition
-                request = self.origrequest
-                if request.format.type == "luks":
-                    try:
-                        usedev = self.storage.devicetree.getChildren(request)[0]
-                    except IndexError:
-                        usedev = request
-                else:
-                    usedev = request
-
-                origformat = usedev.format
-                devicetree = self.anaconda.storage.devicetree
-
-                if self.fsoptionsDict.has_key("formatcb"):
-                    if self.fsoptionsDict["formatcb"].get_active():
-                        fmt_class = self.fsoptionsDict["fstypeCombo"].get_active_value()
-
-                        # carry over exists, migrate, size, and device
-                        # necessary for partition editor UI
-                        format = fmt_class(mountpoint=mountpoint,
-                                           device=usedev.path)
-
-                        luksdev = None
-                        if self.fsoptionsDict.has_key("lukscb") and \
-                           self.fsoptionsDict["lukscb"].get_active() and \
-                           (request.format.type != "luks" or
-                            (request.format.exists and
-                             not request.format.hasKey)):
-                            luksdev = LUKSDevice("luks%d" % self.storage.nextID,
-                                                 format=format,
-                                                 parents=request)
-                            format = getFormat("luks",
-                                               device=self.origrequest.path,
-                                               passphrase=self.storage.encryptionPassphrase)
-                        elif self.fsoptionsDict.has_key("lukscb") and \
-                             not self.fsoptionsDict["lukscb"].get_active() and \
-                             request.format.type == "luks":
-                            # user elected to format the device w/o encryption
-                            try:
-                                luksdev = self.storage.devicetree.getChildren(request)[0]
-                            except IndexError:
-                                pass
-                            else:
-                                actions.append(ActionDestroyFormat(luksdev))
-                                actions.append(ActionDestroyDevice(luksdev))
-                                luksdev = None
-
-                            actions.append(ActionDestroyFormat(request))
-                            # we set the new format's device while under the
-                            # impression that the device was going to be
-                            # encrypted, so we need to remedy that now
-                            format.device = request.path
-                            usedev = request
-
-                        actions.append(ActionCreateFormat(usedev, format))
-                        if luksdev:
-                            actions.append(ActionCreateDevice(luksdev))
-                            actions.append(ActionCreateFormat(luksdev))
-                    elif not self.fsoptionsDict["formatcb"].get_active():
-                        # if the format checkbutton is inactive, cancel all
-                        # actions on this device that create or destroy
-                        # formats
-                        cancel = []
-                        if request.originalFormat.type == "luks":
-                            path = "/dev/mapper/luks-%s" % request.originalFormat.uuid
-                            cancel.extend(devicetree.findActions(path=path))
-
-                        cancel.extend(devicetree.findActions(type="destroy",
-                                                             object="format",
-                                                             devid=request.id))
-                        cancel.extend(devicetree.findActions(type="create",
-                                                             object="format",
-                                                             devid=request.id))
-                        cancel.reverse()
-                        for action in cancel:
-                            devicetree.cancelAction(action)
-
-                        # even though we cancelled a bunch of actions, it's
-                        # pretty much impossible to be sure we cancelled them
-                        # in the correct order. make sure things are back to
-                        # their original state.
-                        request.format = request.originalFormat
-                        if request.format.type == "luks":
-                            try:
-                                usedev = devicetree.getChildren(request)[0]
-                            except IndexError:
-                                usedev = request
-                            else:
-                                usedev.format = usedev.originalFormat
-                        else:
-                            usedev = request
-
-                        if usedev.format.mountable:
-                            usedev.format.mountpoint = mountpoint
-                elif self.origrequest.protected and usedev.format.mountable:
-                    # users can set a mountpoint for protected partitions
-                    usedev.format.mountpoint = mountpoint
-
-                request.weight = self.anaconda.platform.weight(mountpoint=mountpoint,
-                                                               fstype=request.format.type)
-
-                if self.fsoptionsDict.has_key("migratecb") and \
-                   self.fsoptionsDict["migratecb"].get_active():
-                    actions.append(ActionMigrateFormat(usedev))
-
-                if self.fsoptionsDict.has_key("resizecb") and \
-                   self.fsoptionsDict["resizecb"].get_active():
-                    size = self.fsoptionsDict["resizesb"].get_value_as_int()
-
-                    try:
-                        actions.append(ActionResizeDevice(request, size))
-                        if request.format.type and request.format.exists:
-                            actions.append(ActionResizeFormat(request, size))
-                    except ValueError:
-                        pass
-
-                if request.format.exists and \
-                   getattr(request, "mountpoint", None) and \
-                   self.storage.formatByDefault(request):
-                    if not queryNoFormatPreExisting(self.intf):
-                        continue
-
-            # everything ok, fall out of loop
-	    break
-
-	return actions
-
-    def destroy(self):
-	if self.dialog:
-	    self.dialog.destroy()
-	self.dialog = None
-
-
-    def __init__(self, anaconda, parent, origrequest, isNew = 0,
-                 restrictfs = None):
-        self.anaconda = anaconda
-	self.storage = self.anaconda.storage
-	self.intf = self.anaconda.intf
-	self.origrequest = origrequest
-	self.isNew = isNew
-	self.parent = parent
-
-	if isNew:
-	    tstr = _("Add Partition")
-	else:
-	    tstr = _("Edit Partition: %s") % (origrequest.path,)
-	    
-        self.dialog = gtk.Dialog(tstr, self.parent)
-        gui.addFrame(self.dialog)
-        self.dialog.add_button('gtk-cancel', gtk.RESPONSE_CANCEL)
-        self.dialog.add_button('gtk-ok', 1)
-        self.dialog.set_position(gtk.WIN_POS_CENTER)
-        
-        maintable = gtk.Table()
-        maintable.set_row_spacings(5)
-        maintable.set_col_spacings(5)
-        row = 0
-
-        # if this is a luks device we need to grab info from two devices
-        # to make it seem like one device. wee!
-        if self.origrequest.format.type == "luks":
-            try:
-                luksdev = self.storage.devicetree.getChildren(self.origrequest)[0]
-            except IndexError:
-                usereq = self.origrequest
-                luksdev = None
-            else:
-                usereq = luksdev
-        else:
-            luksdev = None
-            usereq = self.origrequest
-
-        # Mount Point entry
-	lbl = createAlignedLabel(_("_Mount Point:"))
-        maintable.attach(lbl, 0, 1, row, row + 1)
-        self.mountCombo = createMountPointCombo(usereq)
-	lbl.set_mnemonic_widget(self.mountCombo)
-        maintable.attach(self.mountCombo, 1, 2, row, row + 1)
-        row = row + 1
-
-        # Partition Type
-        if not self.origrequest.exists:
-	    lbl = createAlignedLabel(_("File System _Type:"))
-            maintable.attach(lbl, 0, 1, row, row + 1)
-
-            self.newfstypeCombo = createFSTypeMenu(usereq.format,
-                                                   fstypechangeCB,
-                                                   self.mountCombo,
-                                                   availablefstypes = restrictfs)
-	    lbl.set_mnemonic_widget(self.newfstypeCombo)
-            maintable.attach(self.newfstypeCombo, 1, 2, row, row + 1)
-        else:
-            self.newfstypeCombo = None
-            
-        row = row + 1
-
-        # allowable drives
-        if not self.origrequest.exists:
-            lbl = createAlignedLabel(_("Allowable _Drives:"))
-            maintable.attach(lbl, 0, 1, row, row + 1)
-
-            req_disk_names = [d.name for d in self.origrequest.req_disks]
-            self.driveview = createAllowedDrivesList(self.storage.partitioned,
-                                                     req_disk_names,
-                                                     disallowDrives=[self.anaconda.updateSrc])
-            lbl.set_mnemonic_widget(self.driveview)
-            sw = gtk.ScrolledWindow()
-            sw.add(self.driveview)
-            sw.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
-            sw.set_shadow_type(gtk.SHADOW_IN)
-            maintable.attach(sw, 1, 2, row, row + 1)
-            self.driveview.set_size_request(375, 80)
-
-            row = row + 1
-
-        # original fs type and label
-        if self.origrequest.exists:
-            maintable.attach(createAlignedLabel(_("Original File System Type:")),
-                             0, 1, row, row + 1)
-            self.fstypeCombo = gtk.Label(usereq.originalFormat.name)
-
-            maintable.attach(self.fstypeCombo, 1, 2, row, row + 1)
-            row += 1
-
-            if getattr(usereq.originalFormat, "label", None):
-                maintable.attach(createAlignedLabel(_("Original File System "
-                                                      "Label:")),
-                                 0, 1, row, row + 1)
-                fslabel = gtk.Label(usereq.originalFormat.label)
-                maintable.attach(fslabel, 1, 2, row, row + 1)
-                row = row + 1
-
-        # size
-        if not self.origrequest.exists:
-            # Size specification
-            lbl = createAlignedLabel(_("_Size (MB):"))
-            maintable.attach(lbl, 0, 1, row, row + 1)
-            sizeAdj = gtk.Adjustment(value = 1, lower = 1,
-                                     upper = MAX_PART_SIZE, step_incr = 1)
-            self.sizespin = gtk.SpinButton(sizeAdj, digits = 0)
-            self.sizespin.set_property('numeric', True)
-
-            if self.origrequest.req_size:
-                self.sizespin.set_value(self.origrequest.req_size)
-
-            lbl.set_mnemonic_widget(self.sizespin)
-            maintable.attach(self.sizespin, 1, 2, row, row + 1)
-        else:
-            self.sizespin = None
-            
-        row = row + 1
-
-        # format/migrate options for pre-existing partitions, as long as they
-        # aren't protected (we'd still like to be able to mount them, though)
-	self.fsoptionsDict = {}
-        if self.origrequest.exists and \
-           not self.origrequest.protected:
-	    (row, self.fsoptionsDict) = createPreExistFSOptionSection(self.origrequest, maintable, row, self.mountCombo, self.storage, luksdev=luksdev)
-
-        # size options
-        if not self.origrequest.exists:
-            (sizeframe, self.fixedrb, self.fillmaxszrb,
-             self.fillmaxszsb) = self.createSizeOptionsFrame(self.origrequest,
-                                                        self.fillmaxszCB)
-            self.sizespin.connect("value-changed", self.sizespinchangedCB,
-                                  self.fillmaxszsb)
-
-            maintable.attach(sizeframe, 0, 2, row, row + 1)
-            row = row + 1
-        else:
-            self.sizeoptiontable = None
-
-        # create only as primary
-        if not self.origrequest.exists:
-            self.primonlycheckbutton = gtk.CheckButton(_("Force to be a _primary "
-                                                    "partition"))
-            self.primonlycheckbutton.set_active(0)
-            if self.origrequest.req_primary:
-                self.primonlycheckbutton.set_active(1)
-
-            # only show if we have something other than primary
-            if self.storage.extendedPartitionsSupported():
-                maintable.attach(self.primonlycheckbutton, 0, 2, row, row+1)
-                row = row + 1
-
-        # checkbutton for encryption using dm-crypt/LUKS
-        if not self.origrequest.exists:
-            self.lukscb = gtk.CheckButton(_("_Encrypt"))
-            self.lukscb.set_data("formatstate", 1)
-
-            if self.origrequest.format.type == "luks":
-                self.lukscb.set_active(1)
-            else:
-                self.lukscb.set_active(0)
-            maintable.attach(self.lukscb, 0, 2, row, row + 1)
-            row = row + 1
-
-        # put main table into dialog
-        self.dialog.vbox.pack_start(maintable)
-        self.dialog.show_all()
-
diff --git a/iw/partition_gui.py b/iw/partition_gui.py
deleted file mode 100644
index 9496e4e..0000000
--- a/iw/partition_gui.py
+++ /dev/null
@@ -1,1835 +0,0 @@
-#
-# partition_gui.py: allows the user to choose how to partition their disks
-#
-# Copyright (C) 2001, 2002  Red Hat, Inc.  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 as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# 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, see <http://www.gnu.org/licenses/>.
-#
-# Author(s): Matt Wilson <msw@xxxxxxxxxx>
-#            Michael Fulbright <msf@xxxxxxxxxx>
-#
-
-import gobject
-import gtk
-import gtk.glade
-try:
-    import gnomecanvas
-except ImportError:
-    import gnome.canvas as gnomecanvas
-import pango
-import gui
-import parted
-import string
-import types
-import copy
-
-import storage
-from iw_gui import *
-from flags import flags
-
-import datacombo
-import lvm_dialog_gui as l_d_g
-import raid_dialog_gui as r_d_g
-import partition_dialog_gui as p_d_g
-
-from partIntfHelpers import *
-from constants import *
-from partition_ui_helpers_gui import *
-from storage.partitioning import doPartitioning
-from storage.partitioning import hasFreeDiskSpace
-from storage.devicelibs import lvm
-from storage.devices import devicePathToName, PartitionDevice
-
-import gettext
-_ = lambda x: gettext.ldgettext("anaconda", x)
-P_ = lambda x, y, z: gettext.ldngettext("anaconda", x, y, z)
-
-import logging
-log = logging.getLogger("anaconda")
-
-STRIPE_HEIGHT = 35.0
-LOGICAL_INSET = 3.0
-TREE_SPACING = 2
-
-# XXX hack but will work for now
-if gtk.gdk.screen_width() > 640:
-    CANVAS_WIDTH = 490
-else:
-    CANVAS_WIDTH = 390
-CANVAS_HEIGHT = 200
-
-MODE_ADD = 1
-MODE_EDIT = 2
-
-class Slice:
-    """Class representing a slice of a stripe.
-
-    parent -- the stripe that the slice belongs too.
-    text -- what will appear in the slice
-    type -- either SLICE or SUBSLICE
-    xoffset -- start percentage
-    xlength -- a length percentage
-    dcCB -- function that is called on a double click.
-    cCB -- function that is called when one click (selected)
-    sel_col -- color when selected
-    unsel_col -- color when unselected
-    obj -- some python object that is related to this slice.
-    selected -- initial state of slice.
-    """
-    SLICE = 0
-    SUBSLICE = 1
-    CONTAINERSLICE = 2
-
-    def __init__(self, parent, text, type, xoffset, xlength, dcCB=lambda: None,
-            cCB=lambda x: None, sel_col="cornsilk1", unsel_col="white",
-            obj = None, selected = False):
-        self.text = text
-        self.type = type
-        self.xoffset = xoffset
-        self.xlength = xlength
-        self.parent = parent
-        self.dcCB = dcCB
-        self.cCB = cCB
-        self.sel_col = sel_col
-        self.unsel_col = unsel_col
-        self.obj = obj
-        self.selected = selected
-
-    def eventHandler(self, widget, event):
-        if event.type == gtk.gdk.BUTTON_PRESS:
-            if event.button == 1:
-                self.select()
-                self.cCB(self.obj)
-        elif event.type == gtk.gdk._2BUTTON_PRESS:
-            #self.select()
-            self.dcCB()
-
-        return True
-
-    def putOnCanvas(self):
-        pgroup = self.parent.getGroup()
-        self.group = pgroup.add(gnomecanvas.CanvasGroup)
-        self.box = self.group.add(gnomecanvas.CanvasRect)
-        self.group.connect("event", self.eventHandler)
-        canvas_text = self.group.add(gnomecanvas.CanvasText,
-                                    font="sans", size_points=8)
-
-        xoffset = self.xoffset * CANVAS_WIDTH
-        xlength = self.xlength * CANVAS_WIDTH
-
-        if self.type == Slice.SUBSLICE:
-            yoffset = 0.0 + LOGICAL_INSET
-            yheight = STRIPE_HEIGHT - (LOGICAL_INSET * 2)
-            texty = 0.0
-        else:
-            yoffset = 0.0
-            yheight = STRIPE_HEIGHT
-            texty = LOGICAL_INSET
-
-        if self.selected:
-            fill_color = self.sel_col
-        else:
-            fill_color = self.unsel_col
-
-        self.group.set(x=xoffset, y=yoffset)
-        self.box.set(x1=0.0, y1=0.0, x2=xlength,
-                     y2=yheight, fill_color=fill_color,
-                     outline_color='black', width_units=1.0)
-        canvas_text.set(x=2.0, y=texty + 2.0, text=self.text,
-                            fill_color='black',
-                            anchor=gtk.ANCHOR_NW, clip=True,
-                            clip_width=xlength-1, clip_height=yheight-1)
-
-    def shutDown(self):
-        self.parent = None
-        if self.group:
-            self.group.destroy()
-            self.group = None
-
-    def select(self):
-        for slice in self.parent.slices:
-            slice.deselect()
-        self.selected = True
-
-        if self.group and self.box:
-            if self.type != Slice.CONTAINERSLICE:
-                self.group.raise_to_top()
-            self.box.set(outline_color="red")
-            self.box.set(fill_color=self.sel_col)
-
-    def deselect(self):
-        self.selected = False
-        if self.box:
-            self.box.set(outline_color="black", fill_color=self.unsel_col)
-
-class Stripe(object):
-    """
-    canvas -- the canvas where everything goes
-    text -- the text that will appear on top of the stripe
-    yoff -- its the position in the y axis where this stripe should be drawn
-    dcCB -- function that should be called on a double click
-    obj -- some python object that is related to this stripe
-
-    """
-    def __init__(self, canvas, text, dcCB, obj = None):
-        self.canvas_text = None
-        self.canvas = canvas
-        self.text = text
-        self.group = None
-        self._slices = []
-        self.dcCB = dcCB
-        self.selected = None
-        self.obj = obj
-
-    def putOnCanvas(self, yoff):
-        """
-        returns the yposition after drawhing this stripe.
-
-        """
-        # We set the text for the stripe.
-        self.canvas_text = self.canvas.root().add(gnomecanvas.CanvasText,
-                x=0.0, y=yoff, font="sans", size_points=9)
-        self.canvas_text.set(text=self.text, fill_color='black',
-                anchor=gtk.ANCHOR_NW, weight=pango.WEIGHT_BOLD)
-
-        (xxx1, yyy1, xxx2, yyy2) =  self.canvas_text.get_bounds()
-        textheight = yyy2 - yyy1 + 2
-        self.group = self.canvas.root().add(gnomecanvas.CanvasGroup,
-                                       x=0, y=yoff+textheight)
-
-        self.group.add(gnomecanvas.CanvasRect, x1=0.0, y1=0.0, x2=CANVAS_WIDTH,
-                  y2=STRIPE_HEIGHT, fill_color='green',
-                  outline_color='grey71', width_units=1.0)
-        self.group.lower_to_bottom()
-
-        # We paint all the container slices first.  So the contained slices
-        # actually show up.
-        for slice in [s for s in self.slices if s.type == Slice.CONTAINERSLICE]:
-            slice.putOnCanvas()
-        # After painting the containers we paint the rest.
-        for slice in [s for s in self.slices if s.type != Slice.CONTAINERSLICE]:
-            slice.putOnCanvas()
-
-        # 10 is a separator space.
-        return yoff + STRIPE_HEIGHT+textheight+10
-
-    def shutDown(self):
-        for slice in self.slices:
-            slice.shutDown()
-        self._slices = []
-
-        if self.canvas_text:
-            self.canvas_text.destroy()
-
-        if self.group:
-            self.group.destroy()
-            self.group = None
-
-    def getGroup(self):
-        return self.group
-
-    @property
-    def slices(self):
-        return self._slices
-
-    def addSlice(self, new_slice):
-        # check to see if they overlap.
-        for slice in self.slices:
-            # Container slices and subslices can overlap.
-            if new_slice.type+slice.type == Slice.CONTAINERSLICE+Slice.SUBSLICE:
-                continue
-
-            if new_slice.xoffset > slice.xoffset \
-                    and new_slice.xoffset < slice.xoffset + slice.xlength:
-                # there is a colission, we cannot add.
-                return
-
-        self._slices.append(new_slice)
-
-    def getSelectedSlice(self):
-        for slice in self.slices:
-            if slice.selected:
-                return slice
-        return None
-
-class StripeGraph:
-    """ This class will only handle one stripe."""
-
-    __canvas = None
-    def __init__(self):
-        self.stripe = None
-        self.next_ypos = 0.0
-
-    def __del__(self):
-        self.shutDown()
-
-    def shutDown(self):
-        if self.stripe:
-            self.stripe.shutDown()
-            self.stripe = None
-
-        self.next_ypos = 0.0
-
-    @classmethod
-    def getCanvas(cls):
-        if not StripeGraph.__canvas:
-            StripeGraph.__canvas = gnomecanvas.Canvas()
-        return StripeGraph.__canvas
-
-    def setDisplayed(self, obj):
-        # Check to see if we already have the correct obj displayed.
-        if self.getDisplayed() and self.getDisplayed().obj == obj:
-            return
-
-        if self.stripe:
-            self.stripe.shutDown()
-
-        self.stripe = self._createStripe(obj)
-        self.stripe.putOnCanvas(0)
-
-        # Trying to center the picture.
-        apply(self.getCanvas().set_scroll_region, self.getCanvas().root().get_bounds())
-
-    def getDisplayed(self):
-        return self.stripe
-
-    def selectSliceFromObj(self, obj):
-        """Search for obj in the slices """
-        stripe = self.getDisplayed()
-        if not stripe:
-            return
-
-        for slice in stripe.slices:
-            # There is a part object in each slice.
-            if not slice.obj:
-                continue
-
-            if obj == slice.obj and not slice.selected:
-                slice.select()
-                break
-
-    def _createStripe(self, obj):
-        #This method needs to be overridden
-        pass
-
-    def getSelectedSlice(self):
-        return self.stripe.getSelectedSlice()
-
-
-class DiskStripeGraph(StripeGraph):
-    """Handles the creation of a bar view for the 'normal' devies.
-
-    storage -- the storage object
-
-    cCB -- call back function used when the user clicks on a slice. This function
-           is passed a device object when its executed.
-    dcCB -- call back function used when the user double clicks on a slice.
-    drive -- drive to display
-    """
-    def __init__(self, storage, drive=None, cCB=lambda x:None, dcCB=lambda:None):
-        StripeGraph.__init__(self)
-        self.storage = storage
-        self.cCB = cCB
-        self.dcCB = dcCB
-       # Define the default colors per partition type.
-        self.part_type_colors = \
-                {"sel_logical": "cornsilk1", "unsel_logical": "white",
-                 "sel_extended": "cornsilk1", "unsel_extended": "white",
-                 "sel_normal": "cornsilk1", "unsel_normal": "white",
-                 "sel_freespace": "grey88", "unsel_freespace": "grey88"}
-        if drive:
-            self.setDisplayed(drive)
-
-    def _createStripe(self, drive):
-        # Create the stripe
-        drivetext = _("Drive %(drive)s (%(size)-0.f MB) (Model: %(model)s)") \
-                    % {'drive': drive.path,
-                       'size': drive.size,
-                       'model': drive.model}
-        stripe = Stripe(self.getCanvas(), drivetext, self.dcCB, obj = drive)
-
-        # Free Extended Calculation
-        # Free slice/partition in the extended partition "free space".  If there
-        # is space between the last logical partition and the ending of the
-        # extended partition we create a "free space" in the extended part.
-        # Create the slices.
-
-        # These offsets are where the partition/slices end. 0<offset<1
-        last_logical_offset = None
-        last_extended_offset = None
-
-        for part in drive.format.partedDisk.getFreeSpacePartitions() \
-                + [d for d in drive.format.partitions]:
-            if part.getSize(unit="MB") <= 1.0:
-                continue
-
-            # Create the start and length for the slice.
-            xoffset = (float(part.geometry.start)
-                        / float(drive.partedDevice.length))
-            xlength = (float(part.geometry.length)
-                        / float(drive.partedDevice.length))
-
-            if part.type == parted.PARTITION_LOGICAL:
-                partstr = "%s\n%.0f MB" % (part.path, float(part.getSize()))
-                stype = Slice.SUBSLICE
-                unsel_col = self.part_type_colors["unsel_logical"]
-                sel_col = self.part_type_colors["sel_logical"]
-
-                # Free Extended Calculation
-                if last_logical_offset == None:
-                    last_logical_offset = xoffset + xlength
-                elif last_logical_offset < xoffset + xlength:
-                    last_logical_offset = xoffset + xlength
-
-            elif part.type == parted.PARTITION_FREESPACE:
-                partstr = "%s\n%.0f MB" % (_("Free"), float(part.getSize()))
-                stype = Slice.SLICE
-                unsel_col = self.part_type_colors["unsel_freespace"]
-                sel_col = self.part_type_colors["sel_freespace"]
-
-            elif part.type == parted.PARTITION_EXTENDED:
-                partstr = ""
-                stype = Slice.CONTAINERSLICE
-                unsel_col = self.part_type_colors["unsel_extended"]
-                sel_col = self.part_type_colors["sel_extended"]
-
-                # Free Extended Calculation
-                last_extended_offset = xoffset + xlength
-
-            elif part.type == parted.PARTITION_NORMAL:
-                partstr = "%s\n%.0f MB" % (part.path, float(part.getSize()))
-                stype = Slice.SLICE
-                unsel_col = self.part_type_colors["unsel_normal"]
-                sel_col = self.part_type_colors["sel_normal"]
-
-            else:
-                # We don't really want to draw anything in this case.
-                continue
-
-            # We need to use the self.storage objects not the partedDisk ones.
-            # The free space has not storage object.
-            if part.type != parted.PARTITION_FREESPACE:
-                partName = devicePathToName(part.getDeviceNodeName())
-                o_part = self.storage.devicetree.getDeviceByName(partName)
-            else:
-                o_part = None
-
-            slice = Slice(stripe, partstr, stype, xoffset, xlength,
-                    dcCB = self.dcCB, cCB = self.cCB, sel_col = sel_col,
-                    unsel_col = unsel_col, obj = o_part)
-            stripe.addSlice(slice)
-
-        # Free Extended Calculation
-        if (last_logical_offset != None and last_extended_offset != None) \
-                and last_logical_offset < last_extended_offset:
-            # We must create a "free extended" slice
-            stype = Slice.SUBSLICE
-            unsel_col = self.part_type_colors["unsel_freespace"]
-            sel_col = self.part_type_colors["sel_freespace"]
-            xoffset = last_logical_offset
-            xlength = last_extended_offset - last_logical_offset
-            slcstr = "%s\n%.0f MB" % (_("Free"), float(drive.size * xlength))
-
-            slice = Slice(stripe, slcstr, stype, xoffset, xlength,
-                    dcCB = self.dcCB, cCB = self.cCB, sel_col=sel_col,
-                    unsel_col=unsel_col)
-            stripe.addSlice(slice)
-
-        return stripe
-
-class LVMStripeGraph(StripeGraph):
-    """
-    storage -- the storage object
-
-    cCB -- call back function used when the user clicks on a slice. This function
-           is passed a device object when its executed.
-    dcCB -- call back function used when the user double clicks on a slice.
-    vg -- volume group to display
-    """
-    def __init__(self, storage, vg=None, cCB=lambda x:None, dcCB=lambda:None):
-        StripeGraph.__init__(self)
-        self.storage = storage
-        self.cCB = cCB
-        self.dcCB = dcCB
-       # Define the default colors per partition type.
-        self.part_type_colors = \
-                {"sel_lv": "cornsilk1", "unsel_lv": "white",
-                 "sel_freespace": "grey88", "unsel_freespace": "grey88"}
-        if vg:
-            self.setDisplayed(vg)
-
-    def _createStripe(self, vg):
-        # Create the stripe
-        vgtext = _("LVM Volume Group %s (%-0.f MB)") % (vg.name, vg.size)
-        stripe = Stripe(self.getCanvas(), vgtext, self.dcCB, obj = vg)
-
-        # Create the slices.
-        # Since se don't have a start and length like in the partitions, we
-        # put all the LVs next to each other and put the free space at the end.
-        curr_offset = float(0)
-        for lv in vg.lvs:
-            lvstr = "%s\n%.0f MB" % (lv.name, float(lv.size))
-            stype = Slice.SLICE
-            sel_col = self.part_type_colors["sel_lv"]
-            unsel_col = self.part_type_colors["unsel_lv"]
-
-            #xoffset = float(curr_offset) / float(vg.size)
-            xoffset = curr_offset
-            xlength = float(lv.size) / float(vg.size)
-
-            slice = Slice(stripe, lvstr, stype, xoffset, xlength,
-                    dcCB = self.dcCB, cCB = self.cCB, sel_col = sel_col,
-                    unsel_col = unsel_col, obj = lv)
-            stripe.addSlice(slice)
-
-            curr_offset += xlength
-
-        # We add the free space if there is any space left.
-        if curr_offset < 1:
-            #freestr = _("Free")
-            stype = Slice.SLICE
-            sel_col = self.part_type_colors["sel_freespace"]
-            unsel_col = self.part_type_colors["unsel_freespace"]
-
-            xoffset = curr_offset
-            xlength = float(1 - curr_offset)
-
-            # with the xlength we give an approximate size
-            freestr = "%s\n%.0f MB" % (_("Free"), float(vg.size*xlength))
-
-            # We append no object.
-            slice = Slice(stripe, freestr, stype, xoffset, xlength,
-                    dcCB = self.dcCB, cCB = self.cCB, sel_col = sel_col,
-                    unsel_col = unsel_col)
-
-            stripe.addSlice(slice)
-
-        return stripe
-
-class MDRaidArrayStripeGraph(StripeGraph):
-    """
-    storage -- the storage object
-
-    cCB -- call back function used when the user clicks on a slice. This function
-           is passed a device object when its executed.
-    dcCB -- call back function used when the user double clicks on a slice.
-    md -- RAID device to display.
-    """
-    def __init__(self, storage, md=None, cCB=lambda x:None, dcCB=lambda:None):
-        StripeGraph.__init__(self)
-        self.storage = storage
-        self.cCB = cCB
-        self.dcCB = dcCB
-        self.part_type_colors = \
-                {"sel_md": "cornsilk1", "unsel_md": "white"}
-        if md:
-            self.setDisplayed(md)
-
-    def _createStripe(self, md):
-        mdtext = _("MD RAID ARRAY %s (%-0.f MB)") % (md.path, md.size)
-        stripe = Stripe(self.getCanvas(), mdtext, self.dcCB, obj = md)
-
-        # Since we can't really create subslices with md devices we will only
-        # show the md device size in the bar.
-        mdstr = "%s\n%.0f MB" % (md.path, float(md.size))
-        stype = Slice.SLICE
-        sel_col = self.part_type_colors["sel_md"]
-        unsel_col = self.part_type_colors["unsel_md"]
-        xoffset = 0
-        xlength = 1
-
-        slice = Slice(stripe, mdstr, stype, xoffset, xlength,
-                dcCB = self.dcCB, cCB = self.cCB, sel_col = sel_col,
-                unsel_col = unsel_col, obj = md)
-        stripe.addSlice(slice)
-
-        return stripe
-
-class MessageGraph:
-    def __init__(self, canvas, message):
-        self.canvas = canvas
-        self.message = message
-        self.canvas_text = None
-
-    def display(self):
-        if self.canvas_text != None:
-            # This means that its already displayed.
-            return
-
-        self.canvas_text = self.canvas.root().add(gnomecanvas.CanvasText,
-                x=0.0, y=20, font="sans", size_points=16)
-        self.canvas_text.set(text=self.message, fill_color='black',
-                anchor=gtk.ANCHOR_CENTER, weight=pango.WEIGHT_BOLD)
-
-        # Trying to center the picture.
-        apply(self.canvas.set_scroll_region, self.canvas.root().get_bounds())
-
-    def destroy(self):
-        if self.canvas_text:
-            self.canvas_text.destroy()
-            self.canvas_text = None
-
-class DiskTreeModelHelper:
-    def __init__(self, model, columns, iter):
-        self.model = model
-        self.iter = iter
-        self.columns = columns
-
-    def __getitem__(self, key):
-        if type(key) == types.StringType:
-            key = self.columns[key]
-        try:
-            return self.model.get_value(self.iter, key)
-        except:
-            return None
-
-    def __setitem__(self, key, value):
-        if type(key) == types.StringType:
-            key = self.columns[key]
-        self.model.set_value(self.iter, key, value)
-
-class DiskTreeModel(gtk.TreeStore):
-    isLeaf = -3
-    isFormattable = -2
-    
-    # format: column header, type, x alignment, hide?, visibleKey
-    titles = ((N_("Device"), gobject.TYPE_STRING, 0.0, 0, 0),
-              (N_("Label"), gobject.TYPE_STRING, 0.0, 1, 0),
-              (N_("Size (MB)"), gobject.TYPE_STRING, 1.0, 0, 0),
-              (N_("Mount Point"), gobject.TYPE_STRING, 0.0, 0, isLeaf),
-              (N_("Type"), gobject.TYPE_STRING, 0.0, 0, 0),
-              (N_("Format"), gobject.TYPE_OBJECT, 0.5, 0, isFormattable),
-              ("", gobject.TYPE_STRING, 0.0, 0, 0),
-              # the following must be the last two
-              ("IsLeaf", gobject.TYPE_BOOLEAN, 0.0, 1, 0),
-              ("IsFormattable", gobject.TYPE_BOOLEAN, 0.0, 1, 0),
-              ("PyObject", gobject.TYPE_PYOBJECT, 0.0, 1, 0))
-    
-    def __init__(self):
-	self.hiddenPartitions = []
-        self.titleSlot = {}
-        i = 0
-        types = [self]
-        self.columns = []
-        for title, kind, alignment, hide, key in self.titles:
-            self.titleSlot[title] = i
-            types.append(kind)
-            if hide:
-                i += 1
-                continue
-            elif kind == gobject.TYPE_OBJECT:
-                renderer = gtk.CellRendererPixbuf()
-                propertyMapping = {'pixbuf': i}
-            elif kind == gobject.TYPE_BOOLEAN:
-                renderer = gtk.CellRendererToggle()
-                propertyMapping = {'active': i}
-            elif (kind == gobject.TYPE_STRING or
-                  kind == gobject.TYPE_INT):
-                renderer = gtk.CellRendererText()
-                propertyMapping = {'markup': i}
-
-            # wire in the cells that we want only visible on leaf nodes to
-            # the special leaf node column.
-            if key < 0:
-                propertyMapping['visible'] = len(self.titles) + key
-                
-            renderer.set_property('xalign', alignment)
-	    if title == "Mount Point":
-		title = _("Mount Point/\nRAID/Volume")
-	    elif title == "Size (MB)":
-		title = _("Size\n(MB)")
-            elif title != "":
-                title = _(title)
-            col = apply(gtk.TreeViewColumn, (title, renderer),
-                        propertyMapping)
-	    col.set_alignment(0.5)
-	    if kind == gobject.TYPE_STRING or kind == gobject.TYPE_INT:
-		col.set_property('sizing', gtk.TREE_VIEW_COLUMN_AUTOSIZE)
-            self.columns.append(col)
-            i += 1
-
-        apply(gtk.TreeStore.__init__, types)
-
-        self.view = gtk.TreeView(self)
-        # append all of the columns
-        map(self.view.append_column, self.columns)
-
-    def getTreeView(self):
-        return self.view
-
-    def selectRowFromObj(self, obj, iter=None):
-        """Find the row in the tree containing obj and select it.
-
-        obj -- the object that we are searching
-        iter -- an iter from the tree. If None, get the first one.
-
-        Returns the iter where obj was found.  None otherwise.
-        """
-        retval = None
-        r_obj = None
-        #FIXME: watch out for hidden rows.
-
-        if not iter:
-            iter = self.get_iter_first()
-
-        while iter:
-            # r_obj -> (row object)
-            r_obj = self[iter]["PyObject"]
-
-            if obj and r_obj == obj:
-                # We have fond our object, select this row and break.
-                selection = self.view.get_selection()
-                if selection is not None:
-                    selection.unselect_all()
-                    selection.select_iter(iter)
-
-                # Make sure the tree view shows what we have selected.
-                path = self.get_path(iter)
-                col = self.view.get_column(0)
-                self.view.set_cursor(path, col, False)
-                self.view.scroll_to_cell(path, col, True, 0.5, 0.5)
-                retval = iter
-                break
-
-            if self.iter_has_child(iter):
-                # Call recursively if row has children.
-                rv = self.selectRowFromObj(obj, iter=self.iter_children(iter))
-                if rv != None:
-                    retval = rv
-                    break
-
-            iter = self.iter_next(iter)
-
-        return iter
-
-    def getCurrentDevice(self):
-        """ Return the device representing the current selection,
-            None otherwise.
-        """
-        selection = self.view.get_selection()
-        model, iter = selection.get_selected()
-        if not iter:
-            return None
-
-        return model[iter]['PyObject']
-
-    def getCurrentDeviceParent(self):
-        """ Return the parent of the selected row.  Returns an iter.
-            None if there is no parent.
-        """
-        selection = self.view.get_selection()
-        model, iter = selection.get_selected()
-        if not iter:
-            return None
-
-        return model.iter_parent(iter)
-
-    def resetSelection(self):
-        pass
-
-    def clear(self):
-        selection = self.view.get_selection()
-        if selection is not None:
-            selection.unselect_all()
-        gtk.TreeStore.clear(self)
-
-    def __getitem__(self, iter):
-        if type(iter) == gtk.TreeIter:
-            return DiskTreeModelHelper(self, self.titleSlot, iter)
-        raise KeyError, iter
-
-
-class PartitionWindow(InstallWindow):
-    def __init__(self, ics):
-	InstallWindow.__init__(self, ics)
-        ics.setTitle(_("Partitioning"))
-        ics.setNextEnabled(True)
-        self.parent = ics.getICW().window
-
-    def quit(self):
-        pass
-
-    def presentPartitioningComments(self,title, labelstr1, labelstr2, comments,
-				    type="ok", custom_buttons=None):
-
-        if flags.autostep:
-            return 1
-
-        win = gtk.Dialog(title)
-        gui.addFrame(win)
-        
-        if type == "ok":
-            win.add_button('gtk-ok', 1)
-	    defaultchoice = 0
-        elif type == "yesno":
-            win.add_button('gtk-no', 2)
-            win.add_button('gtk-yes', 1)
-	    defaultchoice = 1
-	elif type == "continue":
-            win.add_button('gtk-cancel', 0)
-            win.add_button(_("Continue"), 1)
-	    defaultchoice = 1
-	elif type == "custom":
-	    rid=0
-
-	    for button in custom_buttons:
-		widget = win.add_button(button, rid)
-		rid = rid + 1
-
-            defaultchoice = rid - 1
-	    
-        image = gtk.Image()
-        image.set_from_stock('gtk-dialog-warning', gtk.ICON_SIZE_DIALOG)
-        hbox = gtk.HBox(False, 9)
-	al=gtk.Alignment(0.0, 0.0)
-	al.add(image)
-        hbox.pack_start(al, False)
-
-        buffer = gtk.TextBuffer(None)
-        buffer.set_text(comments)
-        text = gtk.TextView()
-        text.set_buffer(buffer)
-        text.set_property("editable", False)
-        text.set_property("cursor_visible", False)
-        text.set_wrap_mode(gtk.WRAP_WORD)
-        
-        sw = gtk.ScrolledWindow()
-        sw.add(text)
-	sw.set_size_request(400, 200)
-        sw.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
-        sw.set_shadow_type(gtk.SHADOW_IN)
-        
-        info1 = gtk.Label(labelstr1)
-        info1.set_line_wrap(True)
-        info1.set_size_request(400, -1)
-
-        info2 = gtk.Label(labelstr2)
-        info2.set_line_wrap(True)
-        info2.set_size_request(400, -1)
-        
-        vbox = gtk.VBox(False, 9)
-
-	al=gtk.Alignment(0.0, 0.0)
-	al.add(info1)
-        vbox.pack_start(al, False)
-	
-        vbox.pack_start(sw, True, True)
-
-	al=gtk.Alignment(0.0, 0.0)
-	al.add(info2)
-        vbox.pack_start(al, True)
-	
-        hbox.pack_start(vbox, True, True)
-
-        win.vbox.pack_start(hbox)
-        win.set_position(gtk.WIN_POS_CENTER)
-        win.set_default_response(defaultchoice)
-        win.show_all()
-        rc = win.run()
-        win.destroy()
-        return rc
-        
-    def getNext(self):
-        (errors, warnings) = self.storage.sanityCheck()
-        if errors:
-            labelstr1 =  _("The partitioning scheme you requested "
-                           "caused the following critical errors.")
-            labelstr2 = _("You must correct these errors before "
-                          "you continue your installation of "
-                          "%s.") % (productName,)
-
-            commentstr = string.join(errors, "\n\n")
-            
-            self.presentPartitioningComments(_("Partitioning Errors"),
-                                             labelstr1, labelstr2,
-                                             commentstr, type="ok")
-            raise gui.StayOnScreen
-        
-        if warnings:
-            # "storage configuration"
-            labelstr1 = _("The partitioning scheme you requested "
-                          "generated the following warnings.")
-            labelstr2 = _("Would you like to continue with "
-                         "your requested partitioning "
-                         "scheme?")
-            
-            commentstr = string.join(warnings, "\n\n")
-            rc = self.presentPartitioningComments(_("Partitioning Warnings"),
-                                                  labelstr1, labelstr2,
-                                                  commentstr,
-						  type="yesno")
-            if rc != 1:
-                raise gui.StayOnScreen
-
-        formatWarnings = getPreExistFormatWarnings(self.storage)
-        if formatWarnings:
-            labelstr1 = _("The following pre-existing devices have been "
-                          "selected to be formatted, destroying all data.")
-
-#            labelstr2 = _("Select 'Yes' to continue and format these "
-#                          "partitions, or 'No' to go back and change these "
-#                          "settings.")
-            labelstr2 = ""
-            commentstr = ""
-            for (dev, type, mntpt) in formatWarnings:
-                commentstr = commentstr + \
-                        "%s         %s         %s\n" % (dev,type,mntpt)
-
-            rc = self.presentPartitioningComments(_("Format Warnings"),
-                                                  labelstr1, labelstr2,
-                                                  commentstr,
-						  type="custom",
-						  custom_buttons=["gtk-cancel",
-								  _("_Format")])
-            if rc != 1:
-                raise gui.StayOnScreen
-
-        self.stripeGraph.shutDown()
-        self.tree.clear()
-        del self.parent
-        return None
-
-    def getPrev(self):
-        self.stripeGraph.shutDown()
-        # temporarily unset storage.clearPartType so that all devices will be
-        # found during storage reset
-        clearPartType = self.storage.clearPartType
-        self.storage.clearPartType = None
-        self.storage.reset()
-        self.storage.clearPartType = clearPartType
-        self.tree.clear()
-        del self.parent
-        return None
-
-    def addDevice(self, device, treeiter):
-        if device.format.hidden:
-            return
-
-        if device.format.type == "luks":
-            # we'll want to grab format info from the mapped
-            # device, not the encrypted one
-            try:
-                dm_dev = self.storage.devicetree.getChildren(device)[0]
-            except IndexError:
-                format = device.format
-            else:
-                format = dm_dev.format
-        else:
-            format = device.format
-
-        # icon for the format column
-        if device.format.type == "luks" and not device.format.exists:
-            # we're creating the LUKS header
-            format_icon = self.lock_pixbuf
-        elif not format.exists:
-            # we're creating a format on the device
-            format_icon = self.checkmark_pixbuf
-        else:
-            format_icon = None
-
-        # mount point string
-        if format.type == "lvmpv":
-            vg = None
-            for _vg in self.storage.vgs:
-                if _vg.dependsOn(device):
-                    vg = _vg
-                    break
-
-            mnt_str = getattr(vg, "name", "")
-        elif format.type == "mdmember":
-            array = None
-            for _array in self.storage.mdarrays:
-                if _array.dependsOn(device):
-                    array = _array
-                    break
-
-            mnt_str = getattr(array, "name", "")
-        else:
-            mnt_str = getattr(format, "mountpoint", "")
-            if mnt_str is None:
-                mnt_str = ""
-
-        # device name
-        name_str = getattr(device, "lvname", device.name)
-
-        # label
-        label_str = getattr(format, "label", "")
-        if label_str is None:
-            label_str = ""
-
-        self.tree[treeiter]['Device'] = name_str
-        self.tree[treeiter]['Size (MB)'] = "%Ld" % device.size
-        self.tree[treeiter]['PyObject'] = device
-        self.tree[treeiter]['IsFormattable'] = format.formattable
-        self.tree[treeiter]['Format'] = format_icon
-        self.tree[treeiter]['Mount Point'] = mnt_str
-        self.tree[treeiter]['IsLeaf'] = True
-        self.tree[treeiter]['Type'] = format.name
-        self.tree[treeiter]['Label'] = label_str
-
-    def populate(self, initial = 0):
-        self.tree.resetSelection()
-
-        # first do LVM
-        vgs = self.storage.vgs
-        if vgs:
-	    lvmparent = self.tree.append(None)
-	    self.tree[lvmparent]['Device'] = _("LVM Volume Groups")
-            for vg in vgs:
-                vgparent = self.tree.append(lvmparent)
-                self.addDevice(vg, vgparent)
-                self.tree[vgparent]['Type'] = ""
-                for lv in vg.lvs:
-                    iter = self.tree.append(vgparent)
-                    self.addDevice(lv, iter)
-
-                # We add a row for the VG free space.
-                if vg.freeSpace > 0:
-                    iter = self.tree.append(vgparent)
-                    self.tree[iter]['Device'] = _("Free")
-                    self.tree[iter]['Size (MB)'] = vg.freeSpace
-                    self.tree[iter]['PyObject'] = None
-                    self.tree[iter]['Mount Point'] = ""
-                    self.tree[iter]['IsLeaf'] = True
-
-        # handle RAID next
-        mdarrays = self.storage.mdarrays
-        if mdarrays:
-	    raidparent = self.tree.append(None)
-	    self.tree[raidparent]['Device'] = _("RAID Devices")
-            for array in mdarrays:
-                iter = self.tree.append(raidparent)
-                self.addDevice(array, iter)
-                name = "%s <span size=\"small\" color=\"gray\">(%s)</span>" % \
-                            (array.name, array.path)
-                self.tree[iter]['Device'] = name
-
-        # now normal partitions
-        disks = self.storage.partitioned
-        drvparent = self.tree.append(None)
-        self.tree[drvparent]['Device'] = _("Hard Drives")
-        for disk in disks:
-            # add a parent node to the tree
-            parent = self.tree.append(drvparent)
-
-            self.tree[parent]['PyObject'] = disk
-            if disk.partitioned:
-                part = disk.format.firstPartition
-                extendedParent = None
-                while part:
-                    if part.type & parted.PARTITION_METADATA:
-                        part = part.nextPartition()
-                        continue
-
-                    partName = devicePathToName(part.getDeviceNodeName())
-                    device = self.storage.devicetree.getDeviceByName(partName)
-                    if not device and not part.type & parted.PARTITION_FREESPACE:
-                        log.debug("can't find partition %s in device"
-                                           " tree" % partName)
-
-                    # ignore the tiny < 1 MB free space partitions (#119479)
-                    if part.getSize(unit="MB") <= 1.0 and \
-                       part.type & parted.PARTITION_FREESPACE:
-                        if not part.active or not device.bootable:
-                            part = part.nextPartition()
-                            continue
-
-                    if device and device.isExtended:
-                        if extendedParent:
-                            raise RuntimeError, ("can't handle more than "
-                                                 "one extended partition per disk")
-                        extendedParent = self.tree.append(parent)
-                        iter = extendedParent
-                    elif device and device.isLogical:
-                        if not extendedParent:
-                            raise RuntimeError, ("crossed logical partition "
-                                                 "before extended")
-                        iter = self.tree.append(extendedParent)
-                    else:
-                        iter = self.tree.append(parent)
-
-                    if device and not device.isExtended:
-                        self.addDevice(device, iter)
-                    else:
-                        # either extended or freespace
-                        if part.type & parted.PARTITION_FREESPACE:
-                            devstring = _("Free")
-                            ptype = ""
-                        else:
-                            devstring = device.name
-                            ptype = _("Extended")
-
-                        self.tree[iter]['Device'] = devstring
-                        self.tree[iter]['Type'] = ptype
-                        size = part.getSize(unit="MB")
-                        if size < 1.0:
-                            sizestr = "< 1"
-                        else:
-                            sizestr = "%Ld" % (size)
-                        self.tree[iter]['Size (MB)'] = sizestr
-                        self.tree[iter]['PyObject'] = device
-
-                    part = part.nextPartition()
-            else:
-                # whole-disk formatting
-                self.addDevice(disk, parent)
-
-            # Insert a '\n' when device string is too long.  Usually when it
-            # contains '/dev/mapper'.  First column should be around 20 chars.
-            if len(disk.name) + len(disk.path) > 20:
-                separator = "\n"
-            else:
-                separator= " "
-            self.tree[parent]['Device'] = \
-                    "%s%s<span size=\"small\" color=\"gray\">(%s)</span>" \
-                    % (disk.name, separator, disk.path)
-
-        self.treeView.expand_all()
-        self.messageGraph.display()
-
-    def barviewActivateCB(self):
-        """ Should be called when we double click on a slice"""
-        # This is a bit of a hack to make the double click on free space work.
-        # This function is useful when the selected slice is a free space,
-        # in any other case it calls self.treeActiveCB.
-
-        # We first see if the double click was from a free space or from another
-        # slice.
-        sel_slice = self.stripeGraph.getSelectedSlice()
-
-        if sel_slice == None:
-            # This really should not happen. Do nothing.
-            return
-
-        # The selected slice is a free slice if the object contained in it is
-        # None.
-        if sel_slice.obj != None:
-            # This is not a free slice, we should call treeActivateCB
-            return self.treeActivateCB()
-        else:
-            # Display a create window according to the stripe object.
-            # Get the device from the stripe.obj
-            disp_stripe = self.stripeGraph.getDisplayed()
-            if disp_stripe == None:
-                # this should not happen
-                return
-
-            # Display a create dialog.
-            stripe_dev = disp_stripe.obj
-            if stripe_dev.partitioned:
-                tempformat = self.storage.defaultFSType
-                device = self.storage.newPartition(fmt_type=tempformat)
-                self.editPartition(device, isNew = True)
-
-            elif isinstance(stripe_dev, storage.LVMVolumeGroupDevice):
-                self.editLVMLogicalVolume(vg = stripe_dev)
-                return
-
-    def treeActivateCB(self, *args):
-        curr_dev = self.tree.getCurrentDevice()
-        if isinstance(curr_dev, storage.PartitionDevice) \
-                or isinstance(curr_dev, storage.LVMLogicalVolumeDevice) \
-                or isinstance(curr_dev, storage.LVMVolumeGroupDevice) \
-                or isinstance(curr_dev, storage.MDRaidArrayDevice):
-            self.editCB()
-
-        elif curr_dev == None:
-            # Its probably a free space
-            iparent = self.tree.getCurrentDeviceParent()
-            if iparent == None:
-                # it was not free space, it is a root row.
-                return
-
-            # We execute a create function given the type of parent that was
-            # found.
-            # FIXME: This code might repeat itself.  might be a good idea to
-            # put it in a function.
-            curr_parent = self.tree[iparent]["PyObject"]
-            if curr_parent.partitioned:
-                tempformat = self.storage.defaultFSType
-                device = self.storage.newPartition(fmt_type=tempformat)
-                self.editPartition(device, isNew = True)
-
-            elif isinstance(curr_parent, storage.LVMVolumeGroupDevice):
-                self.editLVMLogicalVolume(vg = curr_parent)
-                return
-
-    def treeSelectCB(self, selection, *args):
-        # The edit and create buttons will be enabled if the user has chosen
-        # something editable and/or deletable.
-        self.deleteButton.set_sensitive(False)
-        self.editButton.set_sensitive(False)
-
-        # I have no idea why this iter might be None.  Its best to return
-        # without any action.
-        model, iter = selection.get_selected()
-        if not iter:
-            return
-
-        # If we return because there is no parent, make sure we show the user
-        # the infoGraph and no stripeGraph.  The 'create' and 'delete' buttons
-        # will be deactivated.
-        iparent = model.iter_parent(iter)
-        if not iparent:
-            self.stripeGraph.shutDown()
-            self.messageGraph.display()
-            return # This is a root row.
-
-        # We destroy the message first.  We will make sure to repaint it later
-        # if no stipe is displayed.  Can't destroy it at the end of this func
-        # because it uncenters the created stripe, if any.
-        self.messageGraph.destroy()
-
-        device = model[iter]['PyObject']
-
-        # See if we need to change what is in the canvas. In all possibilities
-        # we must make sure we have the correct StripeGraph class.
-        if not device:
-            # This is free space.
-            parent = self.tree[iparent]["PyObject"]
-            if parent.partitioned:
-                if not isinstance(self.stripeGraph, DiskStripeGraph):
-                    self.stripeGraph.shutDown()
-                    self.stripeGraph = DiskStripeGraph(self.storage,
-                            drive = parent, cCB = self.tree.selectRowFromObj,
-                            dcCB = self.barviewActivateCB)
-                self.stripeGraph.setDisplayed(parent)
-
-            elif isinstance(parent, storage.LVMVolumeGroupDevice):
-                if not isinstance(self.stripeGraph, LVMStripeGraph):
-                    self.stripeGraph.shutDown()
-                    self.stripeGraph = LVMStripeGraph(self.storage,
-                            vg = parent, cCB = self.tree.selectRowFromObj,
-                            dcCB = self.barviewActivateCB)
-                self.stripeGraph.setDisplayed(parent)
-
-        elif device.partitioned:
-            if not isinstance(self.stripeGraph, DiskStripeGraph):
-                self.stripeGraph.shutDown()
-                self.stripeGraph = DiskStripeGraph(self.storage,
-                        drive = device,
-                        cCB = self.tree.selectRowFromObj,
-                        dcCB = self.barviewActivateCB)
-            self.stripeGraph.setDisplayed(device)
-            # this is deletable but not editable.
-            self.deleteButton.set_sensitive(True)
-
-        elif isinstance(device, storage.PartitionDevice):
-            if not isinstance(self.stripeGraph, DiskStripeGraph):
-                self.stripeGraph.shutDown()
-                self.stripeGraph = DiskStripeGraph(self.storage,
-                        drive = device.parents[0],
-                        cCB = self.tree.selectRowFromObj,
-                        dcCB = self.barviewActivateCB)
-            self.stripeGraph.setDisplayed(device.parents[0])
-            self.stripeGraph.selectSliceFromObj(device)
-            self.deleteButton.set_sensitive(True)
-            self.editButton.set_sensitive(True)
-
-        elif isinstance(device, storage.LVMVolumeGroupDevice):
-            if not isinstance(self.stripeGraph, LVMStripeGraph):
-                self.stripeGraph.shutDown()
-                self.stripeGraph = LVMStripeGraph(self.storage, vg = device,
-                        cCB = self.tree.selectRowFromObj,
-                        dcCB = self.barviewActivateCB)
-            self.stripeGraph.setDisplayed(device)
-            self.deleteButton.set_sensitive(True)
-            self.editButton.set_sensitive(True)
-
-        elif isinstance(device, storage.LVMLogicalVolumeDevice):
-            if not isinstance(self.stripeGraph, LVMStripeGraph):
-                self.stripeGraph.shutDown()
-                self.stripeGraph = LVMStripeGraph(self.storage, vg = device.vg,
-                        cCB = self.tree.selectRowFromObj,
-                        dcCB = self.barviewActivateCB)
-            self.stripeGraph.setDisplayed(device.vg)
-            self.stripeGraph.selectSliceFromObj(device)
-            self.deleteButton.set_sensitive(True)
-            self.editButton.set_sensitive(True)
-
-        elif isinstance(device, storage.MDRaidArrayDevice):
-            if not isinstance(self.stripeGraph, MDRaidArrayStripeGraph):
-                self.stripeGraph.shutDown()
-                self.stripeGraph = MDRaidArrayStripeGraph(self.storage,
-                        md = device,
-                        cCB = self.tree.selectRowFromObj,
-                        dcCB = self.barviewActivateCB)
-            self.stripeGraph.setDisplayed(device)
-            self.deleteButton.set_sensitive(True)
-            self.editButton.set_sensitive(True)
-
-        else:
-            # This means that the user selected something that is not showable
-            # in the bar view.  Just show the information message.
-            self.stripeGraph.shutDown()
-            self.messageGraph.display()
-            self.deleteButton.set_sensitive(False)
-            self.editButton.set_sensitive(False)
-
-    def deleteCB(self, widget):
-        """ Right now we can say that if the device is partitioned we
-            want to delete all of the devices it contains. At some point
-            we will want to support creation and removal of partitionable
-            devices. This will need some work when that time comes.
-        """
-        device = self.tree.getCurrentDevice()
-        if device.partitioned:
-            if doClearPartitionedDevice(self.intf,
-                                        self.storage,
-                                        device):
-                self.refresh()
-        elif doDeleteDevice(self.intf,
-                            self.storage,
-                            device):
-            if isinstance(device, storage.devices.PartitionDevice):
-                justRedraw = False
-            else:
-                justRedraw = True
-                if device.type == "lvmlv" and device in device.vg.lvs:
-                    device.vg._removeLogVol(device)
-
-            self.refresh(justRedraw=justRedraw)
-
-    def createCB(self, *args):
-        # First we must decide what parts of the create_storage_dialog
-        # we will activate.
-
-        # For the Partition checkboxes.
-        # If we see that there is free space in the "Hard Drive" list, then we
-        # must activate all the partition radio buttons (RAID partition,
-        # LVM partition and Standard partition).  We will have only one var to
-        # control all three activations (Since they all depend on the same
-        # thing)
-        activate_create_partition = False
-        free_part_available = hasFreeDiskSpace(self.storage)
-        if free_part_available:
-            activate_create_partition = True
-
-        # We activate the create Volume Group radio button if there is a free
-        # partition with a Physical Volume format.
-        activate_create_vg = False
-        availpvs = len(self.storage.unusedPVs())
-        if (lvm.has_lvm()
-                and getFormat("lvmpv").supported
-                and availpvs > 0):
-            activate_create_vg = True
-
-        # We activate the create RAID dev if there are partitions that have
-        # raid format and are not related to any raid dev.
-        activate_create_raid_dev = False
-        availraidparts = len(self.storage.unusedMDMembers())
-        availminors = self.storage.unusedMDMinors
-        if (len(availminors) > 0
-                and getFormat("software RAID").supported
-                and availraidparts > 1):
-            activate_create_raid_dev = True
-
-        # Must check if all the possibilities are False.  In this case tell the
-        # user that he can't create anything and the reasons.
-        if (not activate_create_partition
-                and not activate_create_vg
-                and not activate_create_raid_dev):
-            self.intf.messageWindow(_("Cannot perform any creation action"),
-                        _("Note that the creation action requires one of the "
-                        "following:\n\n"
-                        "* Free space in one of the Hard Drives.\n"
-                        "* At least two free Software RAID partitions.\n"
-                        "* At least one free physical volume (LVM) partition.\n"
-                        "* At least one Volume Group with free space."),
-                        custom_icon="warning")
-            return
-
-        # We will activate the create lv button when we have a VG to put the
-        # LVs on.
-        activate_create_lv = False
-        vgs_with_free_space = []
-        for vg in self.storage.vgs:
-            if vg.freeSpace > 0:
-                vgs_with_free_space.append(vg)
-        if len(vgs_with_free_space) > 0:
-            activate_create_lv = True
-
-        # GTK crap starts here.
-        create_storage_xml = gtk.glade.XML(
-                gui.findGladeFile("create-storage.glade"), domain="anaconda")
-        self.dialog = create_storage_xml.get_widget("create_storage_dialog")
-
-        # Activate the partition radio buttons if needed.
-        # sp_rb -> standard partition
-        sp_rb = create_storage_xml.get_widget("create_storage_rb_standard_part")
-        # lp_rb -> lvm partition (physical volume)
-        lp_rb = create_storage_xml.get_widget("create_storage_rb_lvm_part")
-        # rp_rb -> RAID partition
-        rp_rb = create_storage_xml.get_widget("create_storage_rb_raid_part")
-        if activate_create_partition:
-            sp_rb.set_sensitive(True)
-            lp_rb.set_sensitive(True)
-            rp_rb.set_sensitive(True)
-
-        # Activate the Volume Group radio buttons if needed.
-        # vg_rb -> Volume Group
-        vg_rb = create_storage_xml.get_widget("create_storage_rb_lvm_vg")
-        if activate_create_vg:
-            vg_rb.set_sensitive(True)
-
-        # Activate the Logical Volume radio button if needed.
-        # We must also take care to control the combo box.
-        lv_rb = create_storage_xml.get_widget("create_storage_rb_lvm_lv")
-        if activate_create_lv:
-            # The combobox will be visible if the radio button is active.
-            # The combobox will be sensitive when the radio button is active.
-            def toggle_vg_cb_CB(button, vg_cb, selected_dev):
-                if button.get_active():
-                    vg_cb.set_sensitive(True)
-
-                    # We set the VG to whatever the user has chosen in the tree
-                    # view. We will fall back on the first item on the list if
-                    # there is no chosen VG.
-                    if selected_dev and selected_dev.name \
-                            and vg_cb.set_active_text(selected_dev.name):
-                        # if set_active is True, we don't need to do anything else
-                        pass
-                    else:
-                        vg_cb.set_active_text(vgs_with_free_space[0].name)
-
-                else:
-                    vg_cb.set_sensitive(False)
-
-            vg_cb_st = gtk.TreeStore(gobject.TYPE_STRING, gobject.TYPE_PYOBJECT)
-            vg_cb = datacombo.DataComboBox(store = vg_cb_st)
-            vg_cb.set_sensitive(False)
-
-            for vg in vgs_with_free_space:
-                # FIXME: the name length might be a problem.
-                vg_cb.append(vg.name, vg)
-            lv_hb = create_storage_xml.get_widget("create_storage_hb_lvm_lv")
-            lv_hb.pack_start(vg_cb)
-
-            lv_rb.set_sensitive(True)
-            selected_dev = self.tree.getCurrentDevice()
-            lv_rb.connect("toggled", toggle_vg_cb_CB, vg_cb, selected_dev)
-
-        # Activate the RAID dev if needed.
-        # rd_rb -> RAID device
-        rd_rb = create_storage_xml.get_widget("create_storage_rb_raid_dev")
-        if activate_create_raid_dev:
-            rd_rb.set_sensitive(True)
-
-        # Before drawing lets select the first radio button that is sensitive:
-        # How can I get sensitivity from gtk.radiobutton?
-        if activate_create_partition:
-            sp_rb.set_active(True)
-            sp_rb.grab_focus()
-        elif activate_create_vg:
-            vg_rb.set_active(True)
-            vg_rb.grab_focus()
-        elif activate_create_raid_dev:
-            rd_rb.set_active(True)
-            rd_rb.grab_focus()
-
-        gui.addFrame(self.dialog)
-        self.dialog.show_all()
-
-        # Lets work the information messages with CB
-        # The RAID info message
-        rinfo_button = create_storage_xml.get_widget("create_storage_info_raid")
-        whatis_r = _("Software RAID allows you to combine several disks into "
-                    "a larger RAID device.  A RAID device can be configured "
-                    "to provide additional speed and reliability compared "
-                    "to using an individual drive.  For more information on "
-                    "using RAID devices please consult the %s "
-                    "documentation.\n") % (productName,)
-        whatneed_r = _("To use RAID you must first create at least two "
-                "partitions of type 'software RAID'.  Then you can create a "
-                "RAID device that can be formatted and mounted.\n\n")
-        whathave_r = P_(
-                "You currently have %d software RAID partition free to use.",
-                "You currently have %d software RAID partitions free to use.",
-                availraidparts) % (availraidparts,)
-        rinfo_message = "%s\n%s%s" % (whatis_r, whatneed_r, whathave_r)
-        rinfo_cb = lambda x : self.intf.messageWindow(_("About RAID"),
-                                rinfo_message, custom_icon="information")
-        rinfo_button.connect("clicked", rinfo_cb)
-
-        # The LVM info message
-        lvminfo_button = create_storage_xml.get_widget("create_storage_info_lvm")
-        whatis_lvm = _("Logical Volume Manager (LVM) is a 3 level construct. "
-                "The first level is made up of disks or partitions formatted with "
-                "LVM metadata called Physical Volumes (PV).  A Volume Group "
-                "(VG) sits on top of one or more PVs. The VG, in turn, is the "
-                "base to create one or more Logical Volumes (LV).  Note that a "
-                "VG can be an aggregate of PVs from multiple physical disks.  For "
-                "more information on using LVM please consult the %s "
-                "documentation\n") % (productName, )
-        whatneed_lvm = _("To create a PV you need a partition with "
-                "free space.  To create a VG you need a PV that is not "
-                "part of any existing VG.  To create an LV you need a VG with "
-                "free space.\n\n")
-        whathave_lvm = P_("You currently have %d available PV free to use.\n",
-                            "You currently have %d available PVs free to use.\n",
-                            availpvs) % (availpvs, )
-        if free_part_available:
-            whathave_lvm = whathave_lvm + _("You currently have free space to "
-                    "create PVs.")
-        lvminfo_message = "%s\n%s%s" % (whatis_lvm, whatneed_lvm, whathave_lvm)
-        lvminfo_cb = lambda x : self.intf.messageWindow(_("About LVM"),
-                                    lvminfo_message, custom_icon="information")
-        lvminfo_button.connect("clicked", lvminfo_cb)
-
-        dialog_rc = self.dialog.run()
-
-        # If Cancel was pressed
-        if dialog_rc == 0:
-            self.dialog.destroy()
-            return
-
-        # If Create was pressed  Make sure we do a dialog.destroy before
-        # calling any other screen.  We don't want the create dialog to show
-        # in the back when we pop up other screens.
-        if dialog_rc != 1:
-            log.error("I received a dialog_rc != 1 (%d) witch should not "
-                    "happen" % dialog_rc)
-            self.dialog.destroy()
-            return
-
-        self.dialog.destroy()
-        if rp_rb.get_active():
-            member = self.storage.newPartition(fmt_type="mdmember")
-            self.editPartition(member, isNew = True, restrictfs=["mdmember"])
-            return
-
-        elif rd_rb.get_active():
-            array = self.storage.newMDArray(fmt_type=self.storage.defaultFSType)
-            self.editRaidArray(array, isNew = True)
-            return
-
-        elif lp_rb.get_active():
-            member = self.storage.newPartition(fmt_type="lvmpv")
-            self.editPartition(member, isNew = True, restrictfs=["lvmpv"])
-            return
-
-        elif vg_rb.get_active():
-            tempvg = self.storage.newVG()
-            self.editLVMVolumeGroup(tempvg, isNew = True)
-            return
-
-        elif lv_rb.get_active():
-            selected_vg = vg_cb.get_active_value()
-            self.editLVMLogicalVolume(vg = selected_vg)
-            return
-
-        elif sp_rb.get_active():
-            tempformat = self.storage.defaultFSType
-            device = self.storage.newPartition(fmt_type=tempformat)
-            self.editPartition(device, isNew = True)
-            return
-
-    def resetCB(self, *args):
-        if not confirmResetPartitionState(self.intf):
-            return
-
-        self.stripeGraph.shutDown()
-        self.storage.reset()
-        self.tree.clear()
-        self.populate()
-
-    def refresh(self, justRedraw=None):
-        log.debug("refresh: justRedraw=%s" % justRedraw)
-        self.stripeGraph.shutDown()
-        self.tree.clear()
-
-        if justRedraw:
-            rc = 0
-        else:
-            try:
-                doPartitioning(self.storage)
-                rc = 0
-            except PartitioningError, msg:
-                self.intf.messageWindow(_("Error Partitioning"),
-                       _("Could not allocate requested partitions: %s.") % (msg),
-                                        custom_icon="error")
-                rc = -1
-            except PartitioningWarning, msg:
-                # XXX somebody other than me should make this look better
-                # XXX this doesn't handle the 'delete /boot partition spec' case
-                #     (it says 'add anyway')
-                dialog = gtk.MessageDialog(self.parent, 0, gtk.MESSAGE_WARNING,
-                                           gtk.BUTTONS_NONE,
-                                           _("Warning: %s.") % (msg))
-                gui.addFrame(dialog)
-                button = gtk.Button(_("_Modify Partition"))
-                dialog.add_action_widget(button, 1)
-                button = gtk.Button(_("_Continue"))
-                dialog.add_action_widget(button, 2)
-                dialog.set_position(gtk.WIN_POS_CENTER)
-
-                dialog.show_all()
-                rc = dialog.run()
-                dialog.destroy()
-                
-                if rc == 1:
-                    rc = -1
-                else:
-                    rc = 0
-                    all_devices = self.storage.devicetree.devices
-                    bootDevs = [d for d in all_devices if d.bootable]
-                    #if reqs:
-                    #    for req in reqs:
-                    #        req.ignoreBootConstraints = 1
-
-	if not rc == -1:
-	    self.populate()
-
-        return rc
-
-    def editCB(self, *args):
-        device = self.tree.getCurrentDevice()
-        reason = self.storage.deviceImmutable(device, ignoreProtected=True)
-        if reason:
-            self.intf.messageWindow(_("Unable To Edit"),
-                                    _("You cannot edit this device:\n\n%s")
-                                    % reason,
-                                    custom_icon="error")
-            return
-
-        if device.type == "mdarray":
-            self.editRaidArray(device)
-        elif device.type == "lvmvg":
-            self.editLVMVolumeGroup(device)
-        elif device.type == "lvmlv":
-            self.editLVMLogicalVolume(lv = device)
-        elif isinstance(device, storage.devices.PartitionDevice):
-            self.editPartition(device)
-
-    # isNew implies that this request has never been successfully used before
-    def editRaidArray(self, raiddev, isNew = False):
-        # r_d_g -> raid_dialog_gui
-        raideditor = r_d_g.RaidEditor(self.storage, self.intf, self.parent,
-                raiddev, isNew)
-
-        while True:
-            actions = raideditor.run()
-
-            for action in actions:
-                # FIXME: this needs to handle exceptions
-                self.storage.devicetree.registerAction(action)
-
-	    if self.refresh(justRedraw=True):
-                actions.reverse()
-                for action in actions:
-                    self.storage.devicetree.cancelAction(action)
-                    if self.refresh():
-                        raise RuntimeError, ("Returning partitions to state "
-                                             "prior to RAID edit failed")
-                continue
-	    else:
-		break
-
-	raideditor.destroy()		
-
-
-    def editPartition(self, device, isNew = False, restrictfs = None):
-        # p_d_g -> partition_dialog_gui
-        parteditor = p_d_g.PartitionEditor(self.anaconda, self.parent, device,
-                isNew = isNew, restrictfs = restrictfs)
-
-        while True:
-            orig_device = copy.copy(device)
-            actions = parteditor.run()
-
-            for action in actions:
-                # XXX we should handle exceptions here
-                self.anaconda.storage.devicetree.registerAction(action)
-
-            if self.refresh(justRedraw=not actions):
-                # autopart failed -- cancel the actions and try to get
-                # back to previous state
-                actions.reverse()
-                for action in actions:
-                    self.anaconda.storage.devicetree.cancelAction(action)
-
-                # FIXME: proper action/device management would be better
-                if not isNew:
-                    device.req_size = orig_device.req_size
-                    device.req_base_size = orig_device.req_base_size
-                    device.req_grow = orig_device.req_grow
-                    device.req_max_size = orig_device.req_max_size
-                    device.req_primary = orig_device.req_primary
-                    device.req_disks = orig_device.req_disks
-
-                if self.refresh():
-                    # this worked before and doesn't now...
-                    raise RuntimeError, ("Returning partitions to state "
-                                         "prior to edit failed")
-            else:
-		break
-
-	parteditor.destroy()
-	return 1
-
-    def editLVMVolumeGroup(self, device, isNew = False):
-        # l_d_g -> lvm_dialog_gui
-        vgeditor = l_d_g.VolumeGroupEditor(self.anaconda, self.intf, self.parent,
-                device, isNew)
-
-        while True:
-            actions = vgeditor.run()
-
-            for action in actions:
-                # FIXME: handle exceptions
-                self.storage.devicetree.registerAction(action)
-
-	    if self.refresh(justRedraw=True):
-                actions.reverse()
-                for action in actions:
-                    self.storage.devicetree.cancelAction(action)
-
-                if self.refresh():
-                    raise RuntimeError, ("Returning partitions to state "
-                                         "prior to edit failed")
-		continue
-	    else:
-		break
-
-	vgeditor.destroy()
-
-    def editLVMLogicalVolume (self, lv = None, vg = None):
-        """Will be consistent with the state of things and use this funciton
-        for creating and editing LVs.
-
-        lv -- the logical volume to edit.  If this is set there is no need
-              for the other two arguments.
-        vg -- the volume group where the new lv is going to be created. This
-              will only be relevant when we are createing an LV.
-        """
-
-        if lv != None:
-            # l_d_g -> lvm_dialog_gui
-            vgeditor = l_d_g.VolumeGroupEditor(self.anaconda, self.intf, self.parent,
-                    lv.vg, isNew = False)
-            lv = vgeditor.lvs[lv.lvname]
-            isNew = False
-
-        elif vg != None:
-            # l_d_g -> lvm_dialog_gui
-            vgeditor = l_d_g.VolumeGroupEditor(self.anaconda, self.intf, self.parent,
-                    vg, isNew = False)
-            tempvg = vgeditor.getTempVG()
-            name = self.storage.createSuggestedLVName(tempvg)
-            format = getFormat(self.storage.defaultFSType)
-            vgeditor.lvs[name] = {'name': name,
-                              'size': vg.freeSpace,
-                              'format': format,
-                              'originalFormat': format,
-                              'stripes': 1,
-                              'logSize': 0,
-                              'snapshotSpace': 0,
-                              'exists': False}
-            lv = vgeditor.lvs[name]
-            isNew = True
-
-        else:
-            # This is non-sense.
-            return
-
-
-        while True:
-            vgeditor.editLogicalVolume(lv, isNew = isNew)
-            actions = vgeditor.convertToActions()
-
-            for action in actions:
-                # FIXME: handle exceptions
-                self.storage.devicetree.registerAction(action)
-
-            if self.refresh(justRedraw=True):
-                actions.reverse()
-                for action in actions:
-                    self.storage.devicetree.cancelAction(action)
-
-                if self.refresh():
-                    raise RuntimeError, ("Returning partitions to state "
-                                         "prior to edit failed")
-                continue
-            else:
-                break
-
-        vgeditor.destroy()
-
-    def getScreen(self, anaconda):
-        self.anaconda = anaconda
-        self.storage = anaconda.storage
-        self.intf = anaconda.intf
-        self.checkmark_pixbuf = gui.getPixbuf("checkMark.png")
-        self.lock_pixbuf = gui.getPixbuf("gnome-lock.png")
-
-        checkForSwapNoMatch(anaconda)
-
-        # Beginning of the GTK stuff.
-        # create the operational buttons
-        buttonBox = gtk.HButtonBox()
-        buttonBox.set_spacing(6)
-        buttonBox.set_layout(gtk.BUTTONBOX_END)
-
-        ops = ((_("_Create"), self.createCB),
-               (_("_Edit"), self.editCB),
-               (_("_Delete"), self.deleteCB),
-               (_("Re_set"), self.resetCB))
-
-        for label, cb in ops:
-            button = gtk.Button(label)
-            buttonBox.add (button)
-            button.connect ("clicked", cb)
-
-            # We need these to control their sensitivity.
-            if label == _("_Edit"):
-                self.editButton = button
-                self.editButton.set_sensitive(False)
-            elif label == _("_Delete"):
-                self.deleteButton = button
-                self.deleteButton.set_sensitive(False)
-
-        # Create the disk tree (Fills the tree and the Bar View)
-        self.tree = DiskTreeModel()
-        self.treeView = self.tree.getTreeView()
-        self.treeView.connect('row-activated', self.treeActivateCB)
-        self.treeViewSelection = self.treeView.get_selection()
-        self.treeViewSelection.connect("changed", self.treeSelectCB)
-        self.stripeGraph = StripeGraph()
-        self.messageGraph = MessageGraph(self.stripeGraph.getCanvas(),
-                _("Please Select A Device"))
-        self.populate(initial = 1)
-
-        # Create the top scroll window
-        # We don't actually need a *scroll* window but nuthing else worked.
-        hadj = gtk.Adjustment(step_incr = 5.0)
-        vadj = gtk.Adjustment(step_incr = 5.0)
-        swt = gtk.ScrolledWindow(hadjustment = hadj, vadjustment = vadj)
-        swt.add(self.stripeGraph.getCanvas())
-        swt.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
-        swt.set_shadow_type(gtk.SHADOW_IN)
-
-        # Create the bottom scroll window
-        swb = gtk.ScrolledWindow()
-        swb.add(self.treeView)
-        swb.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
-        swb.set_shadow_type(gtk.SHADOW_IN)
-
-        # Create main vertical box and add everything.
-        MVbox = gtk.VBox(False, 5)
-        MVbox.pack_start(swt, False, False)
-        MVbox.pack_start(swb, True)
-        MVbox.pack_start(buttonBox, False, False)
-        MVbox.pack_start(gtk.HSeparator(), False)
-
-        return MVbox
diff --git a/iw/partition_ui_helpers_gui.py b/iw/partition_ui_helpers_gui.py
deleted file mode 100644
index f38adea..0000000
--- a/iw/partition_ui_helpers_gui.py
+++ /dev/null
@@ -1,445 +0,0 @@
-#
-# partition_ui_helpers_gui.py: convenience functions for partition_gui.py
-#                              and friends.
-#
-# Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007  Red Hat, Inc.
-# 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 as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# 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, see <http://www.gnu.org/licenses/>.
-#
-# Author(s): Michael Fulbright <msf@xxxxxxxxxx>
-#
-
-import gobject
-import gtk
-import checklist
-import datacombo
-import iutil
-
-from constants import *
-from partIntfHelpers import *
-from storage.formats import *
-
-import gettext
-_ = lambda x: gettext.ldgettext("anaconda", x)
-
-FLAG_FORMAT = 1
-FLAG_MIGRATE = 2
-
-class WideCheckList(checklist.CheckList):
-    def toggled_item(self, data, row):
-
-	rc = True
-	if self.clickCB:
-	    rc = self.clickCB(data, row)
-
-	if rc:
-	    checklist.CheckList.toggled_item(self, data, row)
-
-    
-    def __init__(self, columns, store, clickCB=None, sensitivity=False):
-        checklist.CheckList.__init__(self, columns=columns,
-                                     custom_store=store,
-                                     sensitivity=sensitivity)
-
-        # make checkbox column wider
-        column = self.get_column(columns)
-        self.set_expander_column(column)
-        column = self.get_column(0)
-        column.set_sizing(gtk.TREE_VIEW_COLUMN_FIXED)
-        column.set_fixed_width(25)
-
-	self.clickCB = clickCB
-
-def createAlignedLabel(text):
-    label = gtk.Label(text)
-    label.set_alignment(0.0, 0.5)
-    label.set_property("use-underline", True)
-
-    return label
-
-defaultMountPoints = ['/', '/boot', '/home', '/tmp', '/usr',
-                      '/var', '/usr/local', '/opt']
-
-if iutil.isS390():
-    # Many s390 have 2G DASDs, we recomment putting /usr/share on its own DASD
-    defaultMountPoints.insert(5, '/usr/share')
-
-if iutil.isEfi():
-    defaultMountPoints.insert(2, '/boot/efi')
-
-def createMountPointCombo(request, excludeMountPoints=[]):
-    mountCombo = gtk.combo_box_entry_new_text()
-
-    mntptlist = []
-    label = getattr(request.format, "label", None)
-    if request.exists and label and label.startswith("/"):
-        mntptlist.append(label)
-        idx = 0
-
-    for p in defaultMountPoints:
-        if p in excludeMountPoints:
-            continue
-
-        if not p in mntptlist and (p[0] == "/"):
-            mntptlist.append(p)
-
-    map(mountCombo.append_text, mntptlist)
-
-    if (request.format.type or request.format.migrate) and \
-       request.format.mountable:
-        mountpoint = request.format.mountpoint
-        mountCombo.set_sensitive(1)
-        if mountpoint:
-            mountCombo.get_children()[0].set_text(mountpoint)
-        else:
-            mountCombo.get_children()[0].set_text("")
-    else:
-        mountCombo.get_children()[0].set_text(_("<Not Applicable>"))
-        mountCombo.set_sensitive(0)
-
-    mountCombo.set_data("saved_mntpt", None)
-
-    return mountCombo
-
-def setMntPtComboStateFromType(fmt_class, mountCombo):
-    prevmountable = mountCombo.get_data("prevmountable")
-    mountpoint = mountCombo.get_data("saved_mntpt")
-
-    format = fmt_class()
-    if prevmountable and format.mountable:
-        return
-
-    if format.mountable:
-        mountCombo.set_sensitive(1)
-        if mountpoint != None:
-            mountCombo.get_children()[0].set_text(mountpoint)
-        else:
-            mountCombo.get_children()[0].set_text("")
-    else:
-        if mountCombo.get_children()[0].get_text() != _("<Not Applicable>"):
-            mountCombo.set_data("saved_mntpt", mountCombo.get_children()[0].get_text())
-        mountCombo.get_children()[0].set_text(_("<Not Applicable>"))
-        mountCombo.set_sensitive(0)
-
-    mountCombo.set_data("prevmountable", format.mountable)
-
-def fstypechangeCB(widget, mountCombo):
-    fstype = widget.get_active_value()
-    setMntPtComboStateFromType(fstype, mountCombo)
-
-def createAllowedDrivesStore(disks, reqdrives, drivelist, selectDrives=True,
-                             disallowDrives=[]):
-    drivelist.clear()
-    for disk in disks:
-        selected = 0
-
-        if selectDrives:
-            if reqdrives:
-                if disk.name in reqdrives:
-                    selected = 1
-            else:
-                if disk.name not in disallowDrives:
-                    selected = 1
-
-        sizestr = "%8.0f MB" % disk.size
-        drivelist.append_row((disk.name,
-                              sizestr,
-                              disk.description),
-                             selected)
-
-    if len(disks) < 2:
-        drivelist.set_sensitive(False)
-    else:
-        drivelist.set_sensitive(True)
-
-def createAllowedDrivesList(disks, reqdrives, selectDrives=True, disallowDrives=[]):
-    store = gtk.TreeStore(gobject.TYPE_BOOLEAN,
-                          gobject.TYPE_STRING,
-                          gobject.TYPE_STRING,
-                          gobject.TYPE_STRING,
-                          gobject.TYPE_BOOLEAN)
-    drivelist = WideCheckList(3, store, sensitivity=True)
-    createAllowedDrivesStore(disks, reqdrives, drivelist, selectDrives=selectDrives,
-                             disallowDrives=disallowDrives)
-
-    return drivelist
-    
-    
-
-# pass in callback for when fs changes because of python scope issues
-def createFSTypeMenu(format, fstypechangeCB, mountCombo,
-                     availablefstypes = None, ignorefs = None):
-    store = gtk.TreeStore(gobject.TYPE_STRING, gobject.TYPE_PYOBJECT)
-    fstypecombo = datacombo.DataComboBox(store)
-    
-    if availablefstypes:
-        names = availablefstypes
-    else:
-        names = device_formats.keys()
-    if format and format.supported and format.formattable:
-        default = format.type
-    else:
-        default = get_default_filesystem_type()
-        
-    names.sort()
-    defindex = 0
-    i = 0
-    for name in names:
-        # we could avoid instantiating them all if we made a static class
-        # method that does what the supported property does
-        format = device_formats[name]()
-        if not format.supported:
-            continue
-
-        if ignorefs and name in ignorefs:
-            continue
-        
-        if format.formattable:
-            fstypecombo.append(format.name, device_formats[name])
-            if default == name:
-                defindex = i
-                defismountable = format.mountable
-            i = i + 1
-
-    fstypecombo.set_active(defindex)
-
-    if fstypechangeCB and mountCombo:
-        fstypecombo.connect("changed", fstypechangeCB, mountCombo)
-
-    if mountCombo:
-        mountCombo.set_data("prevmountable",
-                            fstypecombo.get_active_value()().mountable)
-        mountCombo.connect("changed", mountptchangeCB, fstypecombo)
-
-    return fstypecombo
-
-def mountptchangeCB(widget, fstypecombo):
-    if iutil.isEfi() and widget.get_children()[0].get_text() == "/boot/efi":
-        fstypecombo.set_active_text(getFormat("efi").name)
-    if widget.get_children()[0].get_text() == "/boot":
-        fstypecombo.set_active_text(get_default_filesystem_type(boot=True))
-
-def resizeOptionCB(widget, data):
-    (formatcb, resizesb) = data
-    formatcb.set_sensitive(not widget.get_active())
-    resizesb.set_sensitive(widget.get_active())
-
-def formatOptionResizeCB(widget, data):
-    (resizecb, resizesb, fmt) = data
-
-    if widget.get_active():
-        lower = 1
-    else:
-        lower = resizesb.get_data("reqlower")
-
-    adj = resizesb.get_adjustment()
-    adj.lower = lower
-    resizesb.set_adjustment(adj)
-
-    if resizesb.get_value_as_int() < lower:
-        resizesb.set_value(adj.lower)
-
-    resizecb.set_sensitive(not widget.get_active())
-    resizesb.set_sensitive(resizecb.get_active())
-
-def formatMigrateOptionCB(widget, data):
-    (sensitive,) = widget.get_properties('sensitive')
-    if not sensitive:
-        return
-
-    (combowidget, mntptcombo, fs, lukscb, othercombo, othercb, flag) = data
-    combowidget.set_sensitive(widget.get_active())
-
-    if othercb is not None:
-        othercb.set_sensitive(not widget.get_active())
-        othercb.set_active(False)
-
-        if othercombo is not None:
-            othercombo.set_sensitive(othercb.get_active())
-
-    if lukscb is not None:
-        lukscb.set_data("formatstate", widget.get_active())
-        if not widget.get_active():
-            # set "Encrypt" checkbutton to match partition's initial state
-            lukscb.set_active(lukscb.get_data("encrypted"))
-            lukscb.set_sensitive(False)
-        else:
-            lukscb.set_sensitive(True)
-
-    # inject event for fstype menu
-    if widget.get_active():
-        fstype = combowidget.get_active_value()
-        setMntPtComboStateFromType(fstype, mntptcombo)
-        combowidget.grab_focus()
-    else:
-        if isinstance(fs, type(fs)):
-            fs = type(fs)
-
-        setMntPtComboStateFromType(fs, mntptcombo)
-
-
-def createPreExistFSOptionSection(origrequest, maintable, row, mountCombo,
-                                  partitions, ignorefs=[], luksdev=None):
-    """ createPreExistFSOptionSection: given inputs for a preexisting partition,
-        create a section that will provide format and migrate options
-
-        Returns the value of row after packing into the maintable,
-        and a dictionary consistenting of:
-           formatcb      - checkbutton for 'format as new fs'
-           fstype        - part of format fstype menu
-           fstypeMenu    - part of format fstype menu
-           migratecb     - checkbutton for migrate fs
-           migfstypeMenu - menu for migrate fs types
-           lukscb        - checkbutton for 'encrypt using LUKS/dm-crypt'
-           resizecb      - checkbutton for 'resize fs'
-           resizesb      - spinbutton with resize target
-    """
-    rc = {}
-
-    if luksdev:
-        origfs = luksdev.format
-    else:
-        origfs = origrequest.format
-
-    if origfs.formattable or not origfs.type:
-        formatcb = gtk.CheckButton(label=_("_Format as:"))
-        maintable.attach(formatcb, 0, 1, row, row + 1)
-        formatcb.set_active(origfs.formattable and not origfs.exists)
-        rc["formatcb"] = formatcb
-
-        fstypeCombo = createFSTypeMenu(origfs, fstypechangeCB,
-                                       mountCombo, ignorefs=ignorefs)
-        fstypeCombo.set_sensitive(formatcb.get_active())
-        maintable.attach(fstypeCombo, 1, 2, row, row + 1)
-        row += 1
-        rc["fstypeCombo"] = fstypeCombo
-    else:
-        formatcb = None
-        fstypeCombo = None
-
-    if formatcb and not formatcb.get_active() and not origfs.migrate:
-        mountCombo.set_data("prevmountable", origfs.mountable)
-
-    # this gets added to the table a bit later on
-    lukscb = gtk.CheckButton(_("_Encrypt"))
-
-    if origfs.migratable and origfs.exists:
-        migratecb = gtk.CheckButton(label=_("Mi_grate filesystem to:"))
-        if formatcb is not None:
-            migratecb.set_active(origfs.migrate and (not formatcb.get_active()))
-        else:
-            migratecb.set_active(origfs.migrate)
-
-        migtypes = [origfs.migrationTarget]
-
-        maintable.attach(migratecb, 0, 1, row, row + 1)
-        migfstypeCombo = createFSTypeMenu(origfs,
-                                          None, None,
-                                          availablefstypes = migtypes)
-        migfstypeCombo.set_sensitive(migratecb.get_active())
-        maintable.attach(migfstypeCombo, 1, 2, row, row + 1)
-        row = row + 1
-        rc["migratecb"] = migratecb
-        rc["migfstypeCombo"] = migfstypeCombo
-        migratecb.connect("toggled", formatMigrateOptionCB,
-                          (migfstypeCombo, mountCombo, origfs, None,
-                           fstypeCombo, formatcb, FLAG_MIGRATE))
-    else:
-        migratecb = None
-        migfstypeCombo = None
-
-    if formatcb:
-        formatcb.connect("toggled", formatMigrateOptionCB,
-                         (fstypeCombo, mountCombo, origfs, lukscb,
-                          migfstypeCombo, migratecb, FLAG_FORMAT))
-
-    if origrequest.resizable and origfs.exists:
-        resizecb = gtk.CheckButton(label=_("_Resize"))
-        resizecb.set_active(origfs.resizable and \
-                            (origfs.currentSize != origfs.targetSize) and \
-                            (origfs.currentSize != 0))
-        rc["resizecb"] = resizecb
-        maintable.attach(resizecb, 0, 1, row, row + 1)
-
-        if origrequest.targetSize is not None:
-            value = origrequest.targetSize
-        else:
-            value = origrequest.size
-
-        reqlower = 1
-        requpper = origrequest.maxSize
-
-        if origfs.exists:
-            reqlower = origrequest.minSize
-
-            if origrequest.type == "partition":
-                geomsize = origrequest.partedPartition.geometry.getSize(unit="MB")
-                if (geomsize != 0) and (requpper > geomsize):
-                    requpper = geomsize
-
-        adj = gtk.Adjustment(value = value, lower = reqlower,
-                             upper = requpper, step_incr = 1)
-        resizesb = gtk.SpinButton(adj, digits = 0)
-        resizesb.set_property('numeric', True)
-        resizesb.set_data("requpper", requpper)
-        resizesb.set_data("reqlower", reqlower)
-        rc["resizesb"] = resizesb
-        maintable.attach(resizesb, 1, 2, row, row + 1)
-        resizecb.connect('toggled', resizeOptionCB, (formatcb, resizesb))
-        resizeOptionCB(resizecb, (formatcb, resizesb))
-        row = row + 1
-
-        if formatcb:
-            formatcb.connect("toggled", formatOptionResizeCB,
-                             (resizecb, resizesb, origfs))
-
-    if luksdev:
-        lukscb.set_active(1)
-
-    if origrequest.originalFormat.type == "luks":
-        lukscb.set_data("encrypted", 1)
-    else:
-        lukscb.set_data("encrypted", 0)
-
-    if formatcb:
-        lukscb.set_sensitive(formatcb.get_active())
-        lukscb.set_data("formatstate", formatcb.get_active())
-    else:
-        lukscb.set_sensitive(0)
-        lukscb.set_data("formatstate", 0)
-
-    rc["lukscb"] = lukscb
-    maintable.attach(lukscb, 0, 2, row, row + 1)
-    row = row + 1
-
-    return (row, rc)
-
-# do tests we just want in UI for now, not kickstart
-def doUIRAIDLVMChecks(request, storage):
-    fstype = request.format.name
-    numdrives = len(storage.partitioned)
-    
-##     if fstype and fstype.getName() == "physical volume (LVM)":
-## 	if request.grow:
-## 	    return (_("Partitions of type '%s' must be of fixed size, and "
-## 		     "cannot be marked to fill to use available space.")) % (fstype.getName(),)
-
-    if fstype in ["physical volume (LVM)", "software RAID"]:
-	if numdrives > 1 and (not request.req_disks or len(request.req_disks) > 1):
-	    return (_("Partitions of type '%s' must be constrained to "
-		      "a single drive.  To do this, select the "
-		      "drive in the 'Allowable Drives' checklist.")) % (fstype.getName(),)
-    
-    return None
diff --git a/iw/pixmapRadioButtonGroup_gui.py b/iw/pixmapRadioButtonGroup_gui.py
deleted file mode 100644
index 0ded4e2..0000000
--- a/iw/pixmapRadioButtonGroup_gui.py
+++ /dev/null
@@ -1,248 +0,0 @@
-#
-# pixmapRadioButtonGroup_gui.py: general purpose radio button group with pixmaps
-#                                and descriptions
-#
-# Copyright (C) 2000, 2001, 2002  Red Hat, Inc.  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 as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# 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, see <http://www.gnu.org/licenses/>.
-#
-
-import gtk
-from constants import *
-
-class pixmapRadioButtonGroup:
-
-    def toggled (self, widget):
-	if self.togglecb is not None:
-
-	    name = None
-	    for b in self.buttonToEntry.keys():
-		if b == widget:
-		    name = self.buttonToEntry[b]
-	    
-	    self.togglecb(widget, name)
-	    
-#        if not widget.get_active ():
-#	    return
-
-    #
-    # expects a gtk pixmap for pixmap
-    #
-    def pixRadioButton (self, group, labelstr, pixmap, description=None):
-        pix = pixmap
-
-	hbox = gtk.HBox (False, 18)
-	if pix != None:
-	    hbox.pack_start (pix, True, True, 0)
-
-	label = gtk.Label("")
-	label.set_line_wrap(True)
-	label.set_markup("<b>"+labelstr+"</b>")
-	label.set_alignment (0.0, 0.5)
-	if description is not None:
-	    label.set_markup ("<b>%s</b>\n<small>%s</small>" %(labelstr,
-                                                               description))
-	    label.set_line_wrap(True)
-	    if  gtk.gdk.screen_width() > 640:
-		wraplen = 600
-	    else:
-		wraplen = 250
-		
-	    label.set_size_request(wraplen, -1)
-	label.set_use_markup (True)
-	label.set_use_underline(True)
-	    
-	hbox.pack_start (label, True, True, 0)
-	button = gtk.RadioButton (group)
-	button.add (hbox)
-	label.set_mnemonic_widget(button)
-        return button
-
-    # add a entry to end of list
-    # (label and descr should already be passed through _())
-    def addEntry(self, name, label, pixmap=None, descr=None, userdata=None):
-	node = {}
-	node["name"] = name
-	node["label"] = label
-	node["descr"] = descr
-	node["pixmap"] = pixmap
-	node["userdata"] = userdata
-	self.entries.append(node)
-
-    #
-    # finds entry matching name and makes it current
-    #
-    # MUST call AFTER calling render, since widgets are not created yet otherwise
-    #
-    def setCurrent(self, name):
-	for b in self.buttonToEntry.keys():
-	    if self.buttonToEntry[b] == name:
-		b.set_active(1)
-
-	
-
-    #
-    # returns name of current selection
-    #
-    # MUST call AFTER calling render, since widgets are not created yet otherwise
-    #
-    def getCurrent(self):
-	for b in self.buttonToEntry.keys():
-	    if b.get_active():
-		return self.buttonToEntry[b]
-
-
-    #
-    # MUST call AFTER calling render, since widgets are not created yet otherwise
-    #
-    def packWidgetInEntry(self, name, widget):
-	# find button for name
-	for b in self.buttonToEntry.keys():
-	    if self.buttonToEntry[b] == name:
-		# now find box for button
-		for (button, box, buttons) in self.topLevelButtonList:
-		    if button == b:
-			box.pack_end(widget)
-			return
-
-    def setToggleCallback(self, cb):
-	self.togglecb = cb
-	    
-    # render resulting list, returns a box you can pack
-    #
-    # call this after adding all parents and nodes
-    def render(self):
-
-	radioGroup = None
-	buttons = []
-	for item in self.entries:
-	    box = gtk.VBox (False, 6)
-	    name = item["name"]
-	    label = item["label"]
-	    pixmap = item["pixmap"]
-	    descr = item["descr"]
-	    radioGroup = self.pixRadioButton(radioGroup, label, pixmap,
-					     description=descr)
-	    buttons.append(radioGroup)
-	    self.buttonToEntry[radioGroup] = name
-
-	    self.topLevelButtonList.append((radioGroup, box, buttons))
-	    radioGroup.connect("toggled", self.toggled)
-
-	finalVBox = gtk.VBox(False, 6)
-	finalVBox.set_border_width (5)
-
-	for (button, box, buttons) in self.topLevelButtonList:
-	    vbox = gtk.VBox (False, 6)
-	    finalVBox.pack_start(vbox, False, False)
-	    vbox.pack_start (button, False, False)
-	    
-	    if box:
-		tmphbox = gtk.HBox(False)
-
-		crackhbox = gtk.HBox(False)
-		crackhbox.set_size_request(50, -1)
-
-		tmphbox.pack_start(crackhbox, False, False)
-		tmphbox.pack_start(box, True, True)
-		vbox.pack_start(tmphbox, False, False)
-		
-        return finalVBox
-    
-    
-    # InstallPathWindow tag="instpath"
-    def __init__(self):
-	self.entries = []
-	self.topLevelButtonList = []
-	self.buttonToEntry = {}
-	self.togglecb = None
-
-
-if __name__ == "__main__":
-    def readPixmap(fn):
-	pixbuf = gtk.gdk.pixbuf_new_from_file(fn)
-
-	source = gtk.IconSource()
-	source.set_pixbuf(pixbuf)
-	source.set_size(gtk.ICON_SIZE_DIALOG)
-	source.set_size_wildcarded(False)
-	iconset = gtk.IconSet()
-	iconset.add_source(source)
-	p = gtk.image_new_from_icon_set(iconset, gtk.ICON_SIZE_DIALOG)
-
-	return p
-
-    def nowquit(widget):
-	global r
-
-	print("selection -> %s" % (r.getCurrent(),))
-
-	gtk.mainquit()
-	
-    win = gtk.Window()
-    win.connect('destroy', nowquit)
-
-
-    if 0:
-	opts = ['8.0 - /dev/hda1', '7.1 - /dev/hda5']
-    else:
-	opts = ['8.0 - /dev/hda1']
-
-    label = "The following installed system will be upgraded:"
-    upgradeoption = gtk.OptionMenu()
-    upgradeoptionmenu = gtk.Menu()
-    for lev in opts:
-	item = gtk.MenuItem(lev)
-	item.show()        
-	upgradeoptionmenu.add(item)
-
-    upboxtmp = gtk.VBox(False, 5)
-    l = gtk.Label(label)
-    l.set_alignment(0.0, 0.0)
-    upboxtmp.pack_start(l)
-    upboxtmp.pack_start(upgradeoption)
-    upgradeoption.set_menu(upgradeoptionmenu)
-
-    upgradeoption.set_sensitive(0)
-    
-    # hack indent it
-    upbox = gtk.HBox(False)
-
-    crackhbox = gtk.HBox(False)
-    crackhbox.set_size_request(80, -1)
-
-    upbox.pack_start(crackhbox, False, False)
-    upbox.pack_start(upboxtmp, True, True)
-
-    r = pixmapRadioButtonGroup()
-    r.addEntry("upgrade", "_Upgrade Existing Installation", pixmap=readPixmap("/usr/share/anaconda/pixmaps/upgrade.png"),  descr="Choose this option if you would like to upgrade your existing %s system.  This option will preserve the data on your drive" % (productName,), userdata="data")
-
-    r.addEntry("install", "_Reinstall %s" %(productName,), pixmap=readPixmap("../pixmaps/install.png"),
-	       descr="Choose this option to reinstall your system.  Depending on how you partition your system, your previous data may be lost.", userdata="data2")
-    b = r.render()
-    r.setCurrent("Don't Upgrade")
-
-    r.packWidgetInEntry("Upgrade Existing Installation", upbox)
-
-    vbox = gtk.VBox()
-    vbox.pack_start(b, False, False)
-    
-    button = gtk.Button("Quit")
-    button.connect("pressed", nowquit)
-    vbox.pack_start(button, False, False)
-    
-    win.add(vbox)
-    win.show_all()
-
-    gtk.main()
diff --git a/iw/progress_gui.py b/iw/progress_gui.py
deleted file mode 100644
index a72b526..0000000
--- a/iw/progress_gui.py
+++ /dev/null
@@ -1,150 +0,0 @@
-#
-# progress_gui.py: install/upgrade progress window setup.
-#
-# Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007  Red Hat, Inc.
-# 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 as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# 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, see <http://www.gnu.org/licenses/>.
-#
-
-import os
-import glob
-
-import gtk
-import pango
-
-import gui
-from flags import flags
-from iw_gui import *
-from constants import *
-import language
-
-import logging
-log = logging.getLogger("anaconda")
-
-class InstallProgressWindow (InstallWindow):
-    windowTitle = N_("Installing Packages")
-
-    def __init__ (self, ics):
-	InstallWindow.__init__ (self, ics)
-        ics.setPrevEnabled (False)
-        ics.setNextEnabled (False)
-
-        self._updateChange = 0.01
-        self._showPercentage = False
-
-    def processEvents(self):
-        gui.processEvents()
-
-    def get_fraction(self):
-        return self.progress.get_fraction()
-    def set_fraction(self, pct):
-        cur = self.get_fraction()
-        if pct - cur > self._updateChange:
-            self.progress.set_fraction(pct)
-            if self._showPercentage:
-                self.progress.set_text("%d %%" %(pct * 100,))
-            self.processEvents()
-
-    def set_label(self, txt):
-        # handle txt strings that contain '&' and '&amp;'
-        # we convert everything to '&' first, then take them all to '&amp;'
-        # so we avoid things like &amp;&amp;
-        # we have to use '&amp;' for the set_markup() method
-        txt = txt.replace('&amp;', '&')
-        txt = txt.replace('&', '&amp;')
-        self.infolabel.set_markup(txt)
-        self.infolabel.set_ellipsize(pango.ELLIPSIZE_END)
-        self.processEvents()
-
-    def set_text(self, txt):
-        if self._showPercentage:
-            log.debug("Setting progress text with showPercentage set")
-            return
-        self.progress.set_text(txt)
-        self.processEvents()
-
-    def renderCallback(self):
-        self.intf.icw.nextClicked()
-
-    def setShowPercentage(self, val):
-        if val not in (True, False):
-            raise ValueError, "Invalid value passed to setShowPercentage"
-        self._showPercentage = val
-
-    def _getRnotes(self):
-        langs = []
-        pixmaps = []
-        if (os.environ.has_key('LANG')):
-            langs = language.expandLangs(os.environ['LANG'])
-        langs.append('')
-
-        pixmaps = []
-        paths = ("/tmp/product/pixmaps/rnotes/%s/*.png",
-                 "/usr/share/anaconda/pixmaps/rnotes/%s/*.png")
-        for p in paths:
-            for lang in langs:
-                path = p % lang
-                pixmaps = glob.glob(path)
-                if len(pixmaps) > 0:
-                    break
-
-        if len(pixmaps) > 0:
-            files = pixmaps
-        else:
-            files = ["progress_first.png"]
-
-        return files
-        
-
-    def getScreen (self, anaconda):
-	self.intf = anaconda.intf
-	if anaconda.dir == DISPATCH_BACK:
-	    self.intf.icw.prevClicked()
-	    return
-
-        self.pixmaps = self._getRnotes()
-
-	# Create vbox to contain components of UI
-        vbox = gtk.VBox (False, 12)
-
-        # Create rnote area
-        self.adpix = None
-        self.adbox = None
-        pix = gui.readImageFromFile ("progress_first.png")
-        if pix:
-            frame = gtk.Frame()
-            frame.set_shadow_type(gtk.SHADOW_NONE)
-            box = gtk.EventBox()
-            self.adpix = pix
-            box.add(self.adpix)
-            self.adbox = box
-            frame.add(box)
-            vbox.pack_start(frame, False)
-
-
-	self.progress = gtk.ProgressBar()
-        vbox.pack_start(self.progress, False)
-
-        self.infolabel = gui.WrappingLabel("")
-        self.infolabel.set_alignment(0,0)
-        vbox.pack_start(self.infolabel)
-
-	# All done with creating components of UI
-	self.intf.setPackageProgressWindow(self)
-	self.intf.setInstallProgressClass(self)
-
-	vbox.set_border_width(6)
-
-	return vbox
diff --git a/iw/raid_dialog_gui.py b/iw/raid_dialog_gui.py
deleted file mode 100644
index 2255815..0000000
--- a/iw/raid_dialog_gui.py
+++ /dev/null
@@ -1,615 +0,0 @@
-#
-# raid_dialog_gui.py: dialog for editting a raid request
-#
-# Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007  Red Hat, Inc.
-# 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 as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# 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, see <http://www.gnu.org/licenses/>.
-#
-# Author(s): Michael Fulbright <msf@xxxxxxxxxx>
-#            Jeremy Katz <katzj@xxxxxxxxxx>
-#
-
-import copy
-
-import gobject
-import gtk
-import datacombo
-
-import gui
-import storage.devicelibs.mdraid as mdraidlib
-from storage.devices import *
-from storage.deviceaction import *
-from partition_ui_helpers_gui import *
-from constants import *
-
-import gettext
-_ = lambda x: gettext.ldgettext("anaconda", x)
-
-class RaidEditor:
-
-    def createAllowedRaidPartitionsList(self, allraidparts, reqraidpart,
-                                        preexist):
-
-	store = gtk.TreeStore(gobject.TYPE_BOOLEAN,
-			      gobject.TYPE_STRING,
-			      gobject.TYPE_STRING)
-	partlist = WideCheckList(2, store, 
-                                 clickCB=self.raidlist_toggle_callback)
-
-	sw = gtk.ScrolledWindow()
-	sw.add(partlist)
-	sw.set_policy(gtk.POLICY_NEVER, gtk.POLICY_AUTOMATIC)
-	sw.set_shadow_type(gtk.SHADOW_IN)
-
-        tempDevList = []
-        if not self.isNew:
-            # We need this list if we are editing.
-            for dev in reqraidpart:
-                tempDevList.append(dev)
-
-	partrow = 0
-	for part in allraidparts:
-	    partname = "%s" % part.name
-	    partsize = "%8.0f MB" % part.size
-
-            if part in tempDevList:
-                #list the partition and put it as selected
-                partlist.append_row((partname, partsize), True)
-            else:
-                if not self.origrequest.exists:
-                    partlist.append_row((partname, partsize), False)
-
-
-	return (partlist, sw)
-
-    def createRaidLevelMenu(self, levels, reqlevel):
-        levelcombo = gtk.combo_box_new_text()
-	defindex = 0
-        if mdraidlib.RAID1 in levels:
-            defindex = levels.index(mdraidlib.RAID1)
-	i = 0
-	for lev in levels:
-            levelcombo.append_text("RAID%d" % lev)
-
-	    if reqlevel is not None and lev == reqlevel:
-		defindex = i
-	    i = i + 1
-
-        levelcombo.set_active(defindex)
-
-	if reqlevel is not None and reqlevel == mdraidlib.RAID0:
-	    self.sparesb.set_sensitive(0)
-
-        if self.sparesb:
-            levelcombo.connect("changed", self.raidlevelchangeCB, self.sparesb)
-            
-	return levelcombo
-
-    def createRaidMinorMenu(self, minors, reqminor):
-        minorcombo = datacombo.DataComboBox()
-	defindex = 0
-	i = 0
-	for minor in minors:
-            minorcombo.append("md%d" %(minor,), minor)
-	    if reqminor and minor == reqminor:
-		defindex = i
-	    i = i + 1
-
-        minorcombo.set_active(defindex)
-
-	return minorcombo
-
-
-    def raidlevelchangeCB(self, widget, sparesb):
-	raidlevel = widget.get_model()[widget.get_active()][0]
-	numparts = sparesb.get_data("numparts")
-	maxspares = mdraidlib.get_raid_max_spares(raidlevel, numparts)
-
-	if maxspares > 0 and not mdraidlib.isRaid(mdraidlib.RAID0, raidlevel):
-	    adj = sparesb.get_adjustment() 
-	    value = adj.value 
-	    if adj.value > maxspares: 
-		value = maxspares 
-
-	    sparesb.set_sensitive(1)
-	    spareAdj = gtk.Adjustment(value = value, lower = 0,
-				      upper = maxspares, step_incr = 1)
-	    spareAdj.clamp_page(0, maxspares)
-	    sparesb.set_adjustment(spareAdj)
-	    sparesb.set_value(value)
-	else:
-	    sparesb.set_value(0)
-	    sparesb.set_sensitive(0)
-
-    def run(self):
-	if self.dialog is None:
-	    return []
-	
-	while 1:
-	    self.allow_ok_button()
-	    rc = self.dialog.run()
-
-	    # user hit cancel, do nothing
-	    if rc in [gtk.RESPONSE_CANCEL, gtk.RESPONSE_DELETE_EVENT]:
-		self.destroy()
-		return []
-
-            actions = []
-            luksdev = None
-	    raidmembers = []
-            migrate = None
-	    model = self.raidlist.get_model()
-	    iter = model.get_iter_first()
-            format = None
-	    while iter:
-		val   = model.get_value(iter, 0)
-		part = model.get_value(iter, 1)
-
-		if val:
-		    dev = self.storage.devicetree.getDeviceByName(part)
-		    raidmembers.append(dev)
-
-                iter = model.iter_next(iter)
-
-            # The user has to select some devices to be part of the array.
-            if not raidmembers:
-                continue
-
-            mountpoint = self.mountCombo.get_children()[0].get_text()
-            if mountpoint == _("<Not Applicable>"):
-                mountpoint = ""
-
-            if mountpoint:
-                used = False
-                for (mp, dev) in self.storage.mountpoints.iteritems():
-                    if mp == mountpoint and \
-                       dev.id != self.origrequest.id and \
-                       not (self.origrequest.format.type == "luks" and
-                            self.origrequest in dev.parents):
-                        used = True
-                        break
-
-                if used:
-                    self.intf.messageWindow(_("Mount point in use"),
-                                            _("The mount point \"%s\" is in "
-                                              "use. Please pick another.") %
-                                            (mountpoint,),
-                                            custom_icon="error")
-                    continue
-
-            if not self.origrequest.exists:
-                # new device
-                fmt_class = self.fstypeCombo.get_active_value()
-                raidminor = int(self.minorCombo.get_active_value())
-
-                model = self.levelcombo.get_model()
-                raidlevel = model[self.levelcombo.get_active()][0]
-
-                if not mdraidlib.isRaid(mdraidlib.RAID0, raidlevel):
-                    self.sparesb.update()
-                    spares = self.sparesb.get_value_as_int()
-                else:
-                    spares = 0
-
-                format = fmt_class(mountpoint=mountpoint)
-                members = len(raidmembers) - spares
-
-                try:
-                    request = self.storage.newMDArray(minor=raidminor,
-                                                  level=raidlevel,
-                                                  format=format,
-                                                  parents=raidmembers,
-                                                  totalDevices=len(raidmembers),
-                                                  memberDevices=members)
-                except ValueError, e:
-                    self.intf.messageWindow(_("Error"), str(e),
-                                            custom_icon="error")
-                    continue
-
-                # we must destroy luks leaf before original raid request
-                if self.origrequest.format.type == "luks":
-                    # => not self.isNew
-                    # destroy luks format and mapped device
-                    # XXX remove catching, it should always succeed
-                    try:
-                        luksdev = self.storage.devicetree.getChildren(self.origrequest)[0]
-                    except IndexError:
-                        pass
-                    else:
-                        actions.append(ActionDestroyFormat(luksdev))
-                        actions.append(ActionDestroyDevice(luksdev))
-                        luksdev = None
-
-                if self.lukscb and self.lukscb.get_active():
-                    luksdev = LUKSDevice("luks-%s" % request.name,
-                                         format=format,
-                                         parents=request)
-                    format = getFormat("luks",
-                                       passphrase=self.storage.encryptionPassphrase)
-                    request.format = format
-                elif self.lukscb and not self.lukscb.get_active() and \
-                    self.origrequest.format.type == "luks":
-
-                    # XXXRV not needed as we destroy origrequest ?
-                    actions.append(ActionDestroyFormat(self.origrequest))
-
-                if not self.isNew:
-                    # This may be handled in devicetree.registerAction,
-                    # but not in case when we change minor and thus
-                    # device name/path (at least with current md)
-                    actions.append(ActionDestroyDevice(self.origrequest))
-                actions.append(ActionCreateDevice(request))
-                actions.append(ActionCreateFormat(request))
-            
-	    else:
-                # existing device
-                fmt_class = self.fsoptionsDict["fstypeCombo"].get_active_value()
-		if self.fsoptionsDict.has_key("formatcb") and \
-                   self.fsoptionsDict["formatcb"].get_active():
-                    format = fmt_class(mountpoint=mountpoint)
-                    if self.fsoptionsDict.has_key("lukscb") and \
-                       self.fsoptionsDict["lukscb"].get_active() and \
-                       (self.origrequest.format.type != "luks" or
-                        (self.origrequest.format.exists and
-                         not self.origrequest.format.hasKey)):
-                        luksdev = LUKSDevice("luks-%s" % self.origrequest.name,
-                                             format=format,
-                                             parents=self.origrequest)
-                        format = getFormat("luks",
-                                           device=self.origrequest.path,
-                                           passphrase=self.storage.encryptionPassphrase)
-                    elif self.fsoptionsDict.has_key("lukscb") and \
-                         not self.fsoptionsDict["lukscb"].get_active() and \
-                         self.origrequest.format.type == "luks":
-                        # destroy luks format and mapped device
-                        try:
-                            luksdev = self.storage.devicetree.getChildren(self.origrequest)[0]
-                        except IndexError:
-                            pass
-                        else:
-                            actions.append(ActionDestroyFormat(luksdev))
-                            actions.append(ActionDestroyDevice(luksdev))
-                            luksdev = None
-
-                        actions.append(ActionDestroyFormat(self.origrequest))
-                elif self.fsoptionsDict.has_key("formatcb") and \
-                     not self.fsoptionsDict["formatcb"].get_active():
-                    # if the format checkbutton is inactive, cancel all
-                    # actions on this device that create or destroy formats
-                    devicetree = self.storage.devicetree
-                    request = self.origrequest
-                    cancel = []
-                    if request.originalFormat.type == "luks":
-                        path = "/dev/mapper/luks-%s" % request.originalFormat.uuid
-                        cancel.extend(devicetree.findActions(path=path))
-
-                    cancel.extend(devicetree.findActions(type="destroy",
-                                                         object="format",
-                                                         devid=request.id))
-                    cancel.extend(devicetree.findActions(type="create",
-                                                         object="format",
-                                                         devid=request.id))
-                    for action in cancel:
-                        devicetree.cancelAction(action)
-
-                    # even though we cancelled a bunch of actions, it's
-                    # pretty much impossible to be sure we cancelled them
-                    # in the correct order. make sure things are back to
-                    # their original state.
-                    request.format = request.originalFormat
-                    if request.format.type == "luks":
-                        try:
-                            usedev = devicetree.getChildren(request)[0]
-                        except IndexError:
-                            usedev = request
-                        else:
-                            usedev.format = usedev.originalFormat
-                    else:
-                        usedev = request
-
-                    if usedev.format.mountable:
-                        usedev.format.mountpoint = mountpoint
-
-                if self.origrequest.format.mountable:
-                    self.origrequest.format.mountpoint = mountpoint
-
-		if self.fsoptionsDict.has_key("migratecb") and \
-		   self.fsoptionsDict["migratecb"].get_active():
-                    if self.origrequest.format.type == "luks":
-                        try:
-                            usedev = self.storage.devicetree.getChildren(self.origrequest)[0]
-                        except IndexError:
-                            usedev = self.origrequest
-                    else:
-                        usedev = self.origrequest
-                    migrate = True
-
-                if self.origrequest.format.exists and not format and \
-                   self.storage.formatByDefault(self.origrequest):
-                    if not queryNoFormatPreExisting(self.intf):
-		        continue
-
-                if format:
-                    actions.append(ActionCreateFormat(self.origrequest, format))
-
-	    # everything ok, break out
-	    break
-
-
-        if luksdev:
-            actions.append(ActionCreateDevice(luksdev))
-            actions.append(ActionCreateFormat(luksdev))
-
-        if migrate:
-            actions.append(ActionMigrateFormat(usedev))
-
-	return actions
-
-    def destroy(self):
-	if self.dialog:
-	    self.dialog.destroy()
-
-	self.dialog = None
-	
-    def __init__(self, storage, intf, parent, origrequest, isNew = 0):
-	self.storage = storage
-	self.origrequest = origrequest
-	self.isNew = isNew
-	self.intf = intf
-	self.parent = parent
-
-	self.dialog = None
-
-	#
-	# start of editRaidRequest
-	#
-        availraidparts = self.storage.unusedMDMembers(array=self.origrequest)
-
-	# if no raid partitions exist, raise an error message and return
-	if len(availraidparts) < 2:
-	    dlg = gtk.MessageDialog(self.parent, 0, gtk.MESSAGE_ERROR,
-				    gtk.BUTTONS_OK,
-				    _("At least two unused software RAID "
-				      "partitions are needed to create "
-				      "a RAID device.\n\n"
-				      "First create at least two partitions "
-				      "of type \"software RAID\", and then "
-				      "select the \"RAID\" option again."))
-	    gui.addFrame(dlg)
-	    dlg.show_all()
-	    dlg.set_position(gtk.WIN_POS_CENTER)
-	    dlg.run()
-	    dlg.destroy()
-	    return
-
-	if isNew:
-	    tstr = _("Make RAID Device")
-	else:
-	    if origrequest.minor is not None:
-		tstr = _("Edit RAID Device: %s") % (origrequest.path,)
-	    else:
-		tstr = _("Edit RAID Device")
-		
-	dialog = gtk.Dialog(tstr, self.parent)
-	gui.addFrame(dialog)
-	dialog.add_button('gtk-cancel', gtk.RESPONSE_CANCEL)
-	self.ok_button = dialog.add_button('gtk-ok', 1)
-	dialog.set_position(gtk.WIN_POS_CENTER)
-
-	maintable = gtk.Table()
-	maintable.set_row_spacings(5)
-	maintable.set_col_spacings(5)
-	row = 0
-
-        # we'll maybe add this further down
-        self.lukscb = gtk.CheckButton(_("_Encrypt"))
-        self.lukscb.set_data("formatstate", 1)
-
-        if origrequest.format.type == "luks":
-            try:
-                luksdev = self.storage.devicetree.getChildren(origrequest)[0]
-            except IndexError:
-                luksdev = None
-                usedev = origrequest
-                format = origrequest.format
-            else:
-                usedev = luksdev
-                format = usedev.format
-        else:
-            luksdev = None
-            usedev = origrequest
-            format = origrequest.format
-
-	# Mount Point entry
-	lbl = createAlignedLabel(_("_Mount Point:"))
-	maintable.attach(lbl, 0, 1, row, row + 1)
-	self.mountCombo = createMountPointCombo(usedev)
-	lbl.set_mnemonic_widget(self.mountCombo)
-	maintable.attach(self.mountCombo, 1, 2, row, row + 1)
-	row = row + 1
-
-	# Filesystem Type
-        if not origrequest.exists:
-            lbl = createAlignedLabel(_("_File System Type:"))
-            maintable.attach(lbl, 0, 1, row, row + 1)
-            self.fstypeCombo = createFSTypeMenu(format,
-                                                fstypechangeCB,
-                                                self.mountCombo,
-                                                ignorefs = ["mdmember", "efi", "prepboot", "appleboot"])
-	    lbl.set_mnemonic_widget(self.fstypeCombo)
-            maintable.attach(self.fstypeCombo, 1, 2, row, row + 1)
-            row += 1
-        else:
-            maintable.attach(createAlignedLabel(_("Original File System Type:")),
-                             0, 1, row, row + 1)
-            self.fstypeCombo = gtk.Label(usedev.originalFormat.name)
-            maintable.attach(self.fstypeCombo, 1, 2, row, row + 1)
-            row += 1
-
-            if getattr(usedev.originalFormat, "label", None):
-                maintable.attach(createAlignedLabel(_("Original File System "
-                                                      "Label:")),
-                                 0, 1, row, row + 1)
-                maintable.attach(gtk.Label(usedev.originalFormat.label),
-                                 1, 2, row, row + 1)
-                row += 1
-
-	# raid minors
-	lbl = createAlignedLabel(_("RAID _Device:"))	
-	maintable.attach(lbl, 0, 1, row, row + 1)
-
-        if not origrequest.exists:
-            availminors = self.storage.unusedMDMinors[:16]
-            reqminor = origrequest.minor
-            if reqminor is not None and reqminor not in availminors:
-                availminors.append(reqminor)
-
-            availminors.sort()
-            self.minorCombo = self.createRaidMinorMenu(availminors, reqminor)
-	    lbl.set_mnemonic_widget(self.minorCombo)
-        else:
-            self.minorCombo = gtk.Label("%s" %(origrequest.name,))
-	maintable.attach(self.minorCombo, 1, 2, row, row + 1)
-	row = row + 1
-
-	# raid level
-	lbl = createAlignedLabel(_("RAID _Level:"))
-	maintable.attach(lbl, 0, 1, row, row + 1)
-
-        if not origrequest.exists:
-            # Create here, pack below
-            numparts =  len(availraidparts)
-            if origrequest.spares:
-                nspares = origrequest.spares
-            else:
-                nspares = 0
-
-            if origrequest.level:
-                maxspares = mdraidlib.get_raid_max_spares(origrequest.level,
-                                                          numparts)
-            else:
-                maxspares = 0
-
-            spareAdj = gtk.Adjustment(value = nspares, lower = 0,
-                                      upper = maxspares, step_incr = 1)
-            self.sparesb = gtk.SpinButton(spareAdj, digits = 0)
-            self.sparesb.set_data("numparts", numparts)
-
-            if maxspares > 0:
-                self.sparesb.set_sensitive(1)
-            else:
-                self.sparesb.set_value(0)
-                self.sparesb.set_sensitive(0)
-        else:
-            self.sparesb = gtk.Label(str(origrequest.spares))
-
-
-        if not origrequest.exists:
-            self.levelcombo = self.createRaidLevelMenu(mdraidlib.raid_levels,
-                                                       origrequest.level)
-	    lbl.set_mnemonic_widget(self.levelcombo)
-        else:
-            self.levelcombo = gtk.Label(origrequest.level)
-
-	maintable.attach(self.levelcombo, 1, 2, row, row + 1)
-	row = row + 1
-
-	# raid members
-	lbl=createAlignedLabel(_("_RAID Members:"))
-	maintable.attach(lbl, 0, 1, row, row + 1)
-
-	# XXX need to pass in currently used partitions for this device
-	(self.raidlist, sw) = self.createAllowedRaidPartitionsList(availraidparts,
-                                                                   origrequest.devices,
-                                                                   origrequest.exists)
-
-	lbl.set_mnemonic_widget(self.raidlist)
-	self.raidlist.set_size_request(275, 80)
-	maintable.attach(sw, 1, 2, row, row + 1)
-	row = row + 1
-
-        if origrequest.exists:
-            self.raidlist.set_sensitive(False)
-
-	# number of spares - created widget above
-	lbl = createAlignedLabel(_("Number of _spares:"))
-	maintable.attach(lbl, 0, 1, row, row + 1)
-	maintable.attach(self.sparesb, 1, 2, row, row + 1)
-	lbl.set_mnemonic_widget(self.sparesb)
-	row = row + 1
-
-	# format or not?
-	self.formatButton = None
-	self.fsoptionsDict = {}
-	if not format.exists and not origrequest.exists:
-	    self.formatButton = gtk.CheckButton(_("_Format partition?"))
-	    if not format.type:
-		self.formatButton.set_active(1)
-	    else:
-		self.formatButton.set_active(0)
-            # it only makes sense to show this for preexisting RAID
-            if origrequest.exists:
-                maintable.attach(self.formatButton, 0, 2, row, row + 1)
-                row = row + 1
-
-            # checkbutton for encryption using dm-crypt/LUKS
-            if origrequest.format.type == "luks":
-                self.lukscb.set_active(1)
-            else:
-                self.lukscb.set_active(0)
-            maintable.attach(self.lukscb, 0, 2, row, row + 1)
-            row = row + 1
-	else:
-	    (row, self.fsoptionsDict) = createPreExistFSOptionSection(origrequest, maintable, row, self.mountCombo, self.storage, luksdev=luksdev)
-
-	# put main table into dialog
-	dialog.vbox.pack_start(maintable)
-
-	dialog.show_all()
-	self.dialog = dialog
-	return
-
-    def allow_ok_button(self, path=None):
-        """
-        Determine if the OK button should be enabled.
-        
-        If path is given it points to the row where the toggle state is about to
-        change.
-        """
-        model = self.raidlist.get_model()
-        allow = False
-        iter = model.get_iter_first()
-        toggled_iter = None
-        if path:
-            toggled_iter = model.get_iter(path)
-        while iter:
-            val = model.get_value(iter, 0)
-            if toggled_iter and \
-                    model.get_value(toggled_iter, 1) == \
-                    model.get_value(iter, 1):
-                # this is being toggled, negate the value:
-                if not val:
-                    allow = True
-            else:
-                if val:
-                    allow = True
-            iter = model.iter_next(iter)
-
-        self.ok_button.set_sensitive(allow)
-
-    def raidlist_toggle_callback(self, data, path):
-        self.allow_ok_button(path)
-        return 1
-
diff --git a/iw/task_gui.py b/iw/task_gui.py
deleted file mode 100644
index 5716309..0000000
--- a/iw/task_gui.py
+++ /dev/null
@@ -1,705 +0,0 @@
-#
-# task_gui.py: Choose tasks for installation
-#
-# Copyright (C) 2006, 2007, 2008 Red Hat, Inc.  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 as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# 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, see <http://www.gnu.org/licenses/>.
-#
-
-import gtk
-import gtk.glade
-import gobject
-import gui
-import gzip
-from iw_gui import *
-from image import *
-from constants import *
-import isys
-import shutil
-
-import gettext
-_ = lambda x: gettext.ldgettext("anaconda", x)
-
-import network
-import iutil
-
-from yuminstall import AnacondaYumRepo
-import urlgrabber.grabber
-import yum.Errors
-
-import logging
-log = logging.getLogger("anaconda")
-
-def setupRepo(anaconda, repo):
-    if repo.needsNetwork() and not network.hasActiveNetDev():
-        if not anaconda.intf.enableNetwork():
-            return False
-        urlgrabber.grabber.reset_curl_obj()
-    try:
-        anaconda.backend.doRepoSetup(anaconda, thisrepo=repo.id, fatalerrors=False)
-        anaconda.backend.doSackSetup(anaconda, thisrepo=repo.id, fatalerrors=False)
-        log.info("added (UI) repository %s with source URL %s, id:%s" % (repo.name, repo.mirrorlist or repo.baseurl, repo.id))
-    except (IOError, yum.Errors.RepoError) as e:
-        anaconda.intf.messageWindow(_("Error"),
-              _("Unable to read package metadata from repository.  "
-                "This may be due to a missing repodata directory.  "
-                "Please ensure that your repository has been "
-                "correctly generated.\n\n%s" % str(e)),
-                                type="ok", custom_icon="error")
-        repo.disable()
-        repo.close()
-        anaconda.backend.ayum.repos.delete(repo.id)
-        return False
-
-    return True
-
-class RepoEditor:
-    # Window-level callbacks
-    def on_addRepoDialog_destroy(self, widget, *args):
-        pass
-
-    def on_cancelButton_clicked(self, widget, *args):
-        pass
-
-    def on_okButton_clicked(self, widget, *args):
-        pass
-
-    def on_typeComboBox_changed(self, widget, *args):
-        if widget.get_active() == -1:
-            return
-
-        # When the combo box's value is changed, set the notebook's current
-        # page to match.  This requires that the combo box and notebook have
-        # the same method types at the same indices (so, HTTP must be the
-        # same position on both, etc.).
-        self.notebook.set_current_page(widget.get_active())
-
-        if widget.get_active() == 1:
-            if self.repo:
-                self.proxyCheckbox.set_active(self.repo.proxy is True)
-                self.proxyTable.set_sensitive(self.repo.proxy is True)
-            else:
-                self.proxyCheckbox.set_active(False)
-                self.proxyTable.set_sensitive(False)
-
-    # URL-specific callbacks
-    def on_proxyCheckbox_toggled(self, widget, *args):
-        table = self.dxml.get_widget("proxyTable")
-        table.set_sensitive(widget.get_active())
-
-    def on_mirrorlistCheckbox_toggled(self, widget, *args):
-        pass
-
-    def __init__(self, anaconda, repoObj):
-        self.anaconda = anaconda
-        self.backend = self.anaconda.backend
-        self.intf = self.anaconda.intf
-        self.repo = repoObj
-
-        (self.dxml, self.dialog) = gui.getGladeWidget("addrepo.glade", "addRepoDialog")
-        self.dxml.signal_autoconnect(self)
-
-        self.notebook = self.dxml.get_widget("typeNotebook")
-        self.nameEntry = self.dxml.get_widget("nameEntry")
-        self.typeComboBox = self.dxml.get_widget("typeComboBox")
-
-        self.baseurlEntry = self.dxml.get_widget("baseurlEntry")
-        self.mirrorlistCheckbox = self.dxml.get_widget("mirrorlistCheckbox")
-        self.proxyCheckbox = self.dxml.get_widget("proxyCheckbox")
-        self.proxyEntry = self.dxml.get_widget("proxyEntry")
-        self.proxyTable = self.dxml.get_widget("proxyTable")
-        self.usernameEntry = self.dxml.get_widget("usernameEntry")
-        self.passwordEntry = self.dxml.get_widget("passwordEntry")
-
-        self.nfsServerEntry = self.dxml.get_widget("nfsServerEntry")
-        self.nfsPathEntry = self.dxml.get_widget("nfsPathEntry")
-        self.nfsOptionsEntry = self.dxml.get_widget("nfsOptionsEntry")
-
-        self.partitionComboBox = self.dxml.get_widget("partitionComboBox")
-        self.directoryChooser = self.dxml.get_widget("directoryChooserButton")
-
-        self.dialog.set_title(_("Edit Repository"))
-
-        # Remove these until they are actually implemented
-        self.typeComboBox.remove_text(3)
-
-    # Given a method string, return the index of the typeComboBox that should
-    # be made active in order to match.
-    def _methodToIndex(self, method):
-        mapping = {"http": 0, "ftp": 0, "https": 0,
-                   "cdrom": 1,
-                   "nfs": 2}
-#                   "nfs": 2, "nfsiso": 2,
-#                   "hd": 3}
-
-        try:
-            return mapping[method.split(':')[0].lower()]
-        except:
-            return 0
-
-    def _addAndEnableRepo(self, repo):
-        try:
-            self.backend.ayum.repos.add(repo)
-        except yum.Errors.DuplicateRepoError, e:
-            self.intf.messageWindow(_("Error"),
-                  _("The repository %s has already been added.  Please "
-                    "choose a different repository name and "
-                    "URL.") % self.repo.name, type="ok", custom_icon="error")
-            return False
-
-        repo.enable()
-        return True
-
-    def _validURL(self, url):
-        return len(url) > 0 and (url.startswith("http://";) or
-                                 url.startswith("https://";) or
-                                 url.startswith("ftp://";))
-
-    def createDialog(self):
-
-        if self.repo:
-            self.nameEntry.set_text(self.repo.name)
-            if self.repo.anacondaBaseURLs:
-                url = self.repo.anacondaBaseURLs[0]
-            else:
-                url = ''
-            self.typeComboBox.set_active(self._methodToIndex(url))
-
-            if not url or url.startswith("http") or url.startswith("ftp"):
-                if self.repo.mirrorlist:
-                    self.baseurlEntry.set_text(self.repo.mirrorlist)
-                    self.mirrorlistCheckbox.set_active(True)
-                else:
-                    self.baseurlEntry.set_text(url)
-
-                    self.mirrorlistCheckbox.set_active(False)
-
-                if self.repo.proxy:
-                    self.proxyCheckbox.set_active(True)
-                    self.proxyTable.set_sensitive(True)
-                    self.proxyEntry.set_text(self.repo.proxy)
-                    self.usernameEntry.set_text(self.repo.proxy_username or '')
-                    self.passwordEntry.set_text(self.repo.proxy_password or '')
-                else:
-                    self.proxyCheckbox.set_active(False)
-                    self.proxyTable.set_sensitive(False)
-            elif url.startswith("nfs"):
-                (opts, server, path) = iutil.parseNfsUrl(url)
-                self.nfsServerEntry.set_text(server)
-                self.nfsPathEntry.set_text(path)
-                self.nfsOptionsEntry.set_text(opts)
-            elif url.startswith("cdrom:"):
-                pass
-            elif url.startswith("hd:"):
-                m = url[3:]
-                if m.count(":") == 1:
-                    (device, path) = m.split(":")
-                    fstype = "auto"
-                else:
-                    (device, fstype, path) = m.split(":")
-
-                # find device in self.partitionComboBox and select it
-                self.directoryChooser.set_current_folder("%s%s" % (self.anaconda.backend.ayum.isodir, path))
-            else:
-                self.baseurlEntry.set_text(url)
-
-        else:
-            self.typeComboBox.set_active(0)
-            self.proxyCheckbox.set_active(False)
-            self.proxyTable.set_sensitive(False)
-
-        gui.addFrame(self.dialog)
-
-        lbl = self.dxml.get_widget("descLabel")
-        txt = lbl.get_text()
-        lbl.set_text(txt)
-
-        self.dialog.show_all()
-
-    def _applyURL(self, repo):
-        if self.proxyCheckbox.get_active():
-            proxy = self.proxyEntry.get_text()
-            proxy.strip()
-
-            if not self._validURL(proxy):
-                self.intf.messageWindow(_("Invalid Proxy URL"),
-                                        _("You must provide an HTTP, HTTPS, "
-                                          "or FTP URL to a proxy."))
-                return False
-
-            repo.proxy = proxy
-            # with empty string yum would create invalid proxy string
-            repo.proxy_username = self.usernameEntry.get_text() or None
-            repo.proxy_password = self.passwordEntry.get_text() or None
-
-        repourl = self.baseurlEntry.get_text()
-        repourl.strip()
-        if not self._validURL(repourl):
-            self.intf.messageWindow(_("Invalid Repository URL"),
-                                    _("You must provide an HTTP, HTTPS, "
-                                      "or FTP URL to a repository."))
-            return False
-
-        if self.mirrorlistCheckbox.get_active():
-            repo.baseurl = []
-            repo.mirrorlist = repourl
-        else:
-            repo.baseurl = [repourl]
-            repo.mirrorlist = None
-        repo.anacondaBaseURLs = repo.baseurl
-
-        repo.name = self.nameEntry.get_text()
-
-        return True
-
-    def _applyMedia(self, repo):
-        # FIXME works only if storage has detected format of cdrom drive
-        ayum = self.anaconda.backend.ayum
-        cdr = scanForMedia(ayum.tree, self.anaconda.storage)
-        if not cdr:
-            self.intf.messageWindow(_("No Media Found"),
-                                    _("No installation media was found. "
-                                      "Please insert a disc into your drive "
-                                      "and try again."))
-            return False
-
-        log.info("found installation media on %s" % cdr)
-        repo.name = self.nameEntry.get_text()
-        repo.anacondaBaseURLs = ["cdrom://%s:%s" % (cdr, self.anaconda.backend.ayum.tree)]
-        repo.baseurl = "file://%s" % ayum.tree
-        ayum.mediagrabber = ayum.mediaHandler
-        self.anaconda.mediaDevice = cdr
-        ayum.currentMedia = 1
-        repo.mediaid = getMediaId(ayum.tree)
-        log.info("set mediaid of repo %s to: %s" % (repo.name, repo.mediaid))
-
-        return True
-
-    def _applyNfs(self, repo):
-        server = self.nfsServerEntry.get_text()
-        server.strip()
-
-        path = self.nfsPathEntry.get_text()
-        path.strip()
-
-        options = self.nfsOptionsEntry.get_text()
-        options.strip()
-
-        repo.name = self.nameEntry.get_text()
-
-        if not server or not path:
-            self.intf.messageWindow(_("Error"),
-                                    _("Please enter an NFS server and path."))
-            return False
-
-        if not network.hasActiveNetDev():
-            if not self.anaconda.intf.enableNetwork():
-                self.intf.messageWindow(_("No Network Available"),
-                    _("Some of your software repositories require "
-                      "networking, but there was an error enabling the "
-                      "network on your system."))
-                return False
-            urlgrabber.grabber.reset_curl_obj()
-
-        import tempfile
-        dest = tempfile.mkdtemp("", repo.name.replace(" ", ""), "/mnt")
-
-        try:
-            isys.mount("%s:%s" % (server, path), dest, "nfs", options=options)
-        except Exception as e:
-            self.intf.messageWindow(_("Error Setting Up Repository"),
-                _("The following error occurred while setting up the "
-                  "repository:\n\n%s") % e)
-            return False
-
-        repo.baseurl = "file://%s" % dest
-        repo.anacondaBaseURLs = ["nfs:%s:%s:%s" % (options,server,path)]
-        return True
-
-    def _applyHd(self, repo):
-        return True
-
-    def run(self):
-        applyFuncs = [ self._applyURL, self._applyMedia, self._applyNfs,
-                       self._applyHd ]
-
-        while True:
-            rc = self.dialog.run()
-            if rc in [gtk.RESPONSE_CANCEL, gtk.RESPONSE_DELETE_EVENT]:
-                break
-
-            reponame = self.nameEntry.get_text()
-            reponame.strip()
-            if len(reponame) == 0:
-                self.intf.messageWindow(_("Invalid Repository Name"),
-                                        _("You must provide a repository name."))
-                continue
-
-            # Always create a new repo object here instead of attempting to
-            # somehow expire the metadata and refetch.  We'll just have to make
-            # sure that if we're just editing the repo, we grab all the
-            # attributes from the old one before deleting it.
-            if self.repo:
-                # use temporary id so that we don't get Duplicate Repo error
-                # when adding
-                newRepoObj = AnacondaYumRepo("UIedited_%s" %
-                                             self.anaconda.backend.ayum.repoIDcounter.next())
-                newRepoObj.cost = self.repo.cost
-                removeOld = True
-            else:
-                newRepoObj = AnacondaYumRepo(reponame.replace(" ", ""))
-                removeOld = False
-
-            # corresponds to self.repos.setCacheDir in AnacondaYum.doConfigSetup
-            newRepoObj.basecachedir = self.anaconda.backend.ayum.conf.cachedir
-
-            type = self.typeComboBox.get_active()
-            if not applyFuncs[type](newRepoObj) or not self._addAndEnableRepo(newRepoObj) or not \
-                   setupRepo(self.anaconda, newRepoObj):
-                continue
-
-            if removeOld:
-                try:
-                    os.unlink("%s/cachecookie" % self.repo.cachedir)
-                    os.unlink("%s/repomd.xml" % self.repo.cachedir)
-                except:
-                    pass
-
-                self.repo.disable()
-                self.repo.close()
-                self.anaconda.backend.ayum.repos.delete(self.repo.id)
-                log.info("deleted (UI) repository %s with source URL %s, id:%s"
-                         % (self.repo.name, self.repo.mirrorlist or self.repo.baseurl, self.repo.id))
-                try:
-                    shutil.rmtree(self.repo.cachedir)
-                except Exception as e:
-                    log.warning("error removing cachedir for %s: %s" %(self.repo, e))
-                    pass
-
-            if (newRepoObj.enablegroups or 
-                (removeOld and self.repo.enablegroups)):
-                # update groups information
-                try:
-                    self.anaconda.backend.ayum.doGroupSetup()
-                except Exception as e:
-                    log.debug("unable to reset group information after UI repo edit: %s"
-                              % e)
-                else:
-                    log.info("group information reset after UI repo edit")
-
-            self.repo = newRepoObj
-            break
-
-        self.dialog.hide()
-        return rc
-
-class RepoMethodstrEditor(RepoEditor):
-    def __init__(self, anaconda, methodstr):
-        # Create temporary repo to store methodstr needed for
-        # createDialog parent method.
-        temprepo = AnacondaYumRepo("UITmpMethodstrRepo")
-        temprepo.name = "Installation Repo"
-        temprepo.anacondaBaseURLs = [methodstr]
-        RepoEditor.__init__(self, anaconda, temprepo)
-
-    def createDialog(self):
-        RepoEditor.createDialog(self)
-
-        # Hide a bunch of stuff that doesn't apply when we're just prompting
-        # for enough information to form a methodstr.
-        self.nameEntry.set_sensitive(False)
-        self.mirrorlistCheckbox.hide()
-        self.proxyCheckbox.hide()
-        self.proxyTable.hide()
-
-    def _applyURL(self):
-        repourl = self.baseurlEntry.get_text()
-        repourl.strip()
-        if not self._validURL(repourl):
-            self.intf.messageWindow(_("Invalid Repository URL"),
-                                    _("You must provide an HTTP, HTTPS, "
-                                      "or FTP URL to a repository."))
-            return False
-
-        return repourl
-
-    def _applyMedia(self):
-        cdr = scanForMedia(self.anaconda.backend.ayum.tree, self.anaconda.storage)
-        if not cdr:
-            self.intf.messageWindow(_("No Media Found"),
-                                    _("No installation media was found. "
-                                      "Please insert a disc into your drive "
-                                      "and try again."))
-            return False
-
-        self.anaconda.backend.ayum.mediagrabber = self.anaconda.backend.ayum.mediaHandler
-        self.anaconda.backend.ayum.anaconda.mediaDevice = cdr
-        self.anaconda.backend.ayum.currentMedia = 1
-        log.info("found installation media on %s" % cdr)
-        return "cdrom://%s:%s" % (cdr, self.anaconda.backend.ayum.tree)
-
-    def _applyNfs(self):
-        server = self.nfsServerEntry.get_text()
-        server.strip()
-
-        path = self.nfsPathEntry.get_text()
-        path.strip()
-
-        options = self.nfsOptionsEntry.get_text()
-        options.strip()
-
-        if not server or not path:
-            self.intf.messageWindow(_("Error"),
-                                    _("Please enter an NFS server and path."))
-            return False
-
-        return "nfs:%s:%s:%s" % (options, server, path)
-
-    def _applyHd(self):
-        return None
-
-    def run(self):
-        applyFuncs = [ self._applyURL, self._applyMedia, self._applyNfs,
-                       self._applyHd ]
-
-        while True:
-            rc = self.dialog.run()
-            if rc in [gtk.RESPONSE_CANCEL, gtk.RESPONSE_DELETE_EVENT]:
-                rc = None
-                break
-
-            type = self.typeComboBox.get_active()
-            retval = applyFuncs[type]()
-            if not retval:
-                continue
-
-            rc = retval
-            break
-
-        self.dialog.hide()
-        return rc
-
-class RepoCreator(RepoEditor):
-    def __init__(self, anaconda):
-        RepoEditor.__init__(self, anaconda, None)
-        self.dialog.set_title(_("Add Repository"))
-
-class TaskWindow(InstallWindow):
-    def getNext(self):
-        if not self._anyRepoEnabled():
-            self.anaconda.intf.messageWindow(_("No Software Repos Enabled"),
-                _("You must have at least one software repository enabled to "
-                  "continue installation."))
-            raise gui.StayOnScreen
-
-        if self.xml.get_widget("customRadio").get_active():
-            self.dispatch.skipStep("group-selection", skip = 0)
-        else:
-            self.dispatch.skipStep("group-selection", skip = 1)
-
-        tasks = self.xml.get_widget("taskList").get_model()
-        for (cb, task, grps) in filter(lambda x: not x[0], tasks):
-            map(lambda g: setattr(self.backend.ayum.comps.return_group(g),
-                                  "default", False), grps)
-        for (cb, task, grps) in filter(lambda x: x[0], tasks):
-            map(lambda g: setattr(self.backend.ayum.comps.return_group(g),
-                                  "default", True), grps)
-
-    def _editRepo(self, *args):
-        repo = None
-
-        # If we were passed an extra argument, it's the repo store and we
-        # are editing an existing repo as opposed to adding a new one.
-        if len(args) > 1:
-            (model, iter) = args[1].get_selection().get_selected()
-            if iter:
-                repo = model.get_value(iter, 2)
-            else:
-                return
-        else:
-            return
-
-        if repo.needsNetwork() and not network.hasActiveNetDev():
-            if not self.anaconda.intf.enableNetwork():
-                return gtk.RESPONSE_CANCEL
-
-            urlgrabber.grabber.reset_curl_obj()
-
-        dialog = RepoEditor(self.anaconda, repo)
-        dialog.createDialog()
-        dialog.run()
-
-        model.set_value(iter, 0, dialog.repo.isEnabled())
-        model.set_value(iter, 1, dialog.repo.name)
-        model.set_value(iter, 2, dialog.repo)
-
-    def _addRepo(self, *args):
-        dialog = RepoCreator(self.anaconda)
-        dialog.createDialog()
-        if dialog.run() in [gtk.RESPONSE_CANCEL, gtk.RESPONSE_DELETE_EVENT]:
-            return gtk.RESPONSE_CANCEL
-
-        s = self.xml.get_widget("repoList").get_model()
-        s.append([dialog.repo.isEnabled(), dialog.repo.name, dialog.repo])
-
-    def _taskToggled(self, button, path, store):
-        # First, untoggle everything in the store.
-        for row in store:
-            row[0] = False
-
-        # Then, enable the one that was clicked.
-        store[path][0] = True
-
-    def _anyRepoEnabled(self):
-        model = self.rs.get_model()
-        iter = model.get_iter_first()
-
-        while True:
-            if model.get_value(iter, 0):
-                return True
-
-            iter = model.iter_next(iter)
-            if not iter:
-                return False
-
-        return False
-
-    def _repoToggled(self, button, row, store):
-        i = store.get_iter(int(row))
-        wasChecked = store.get_value(i, 0)
-        repo = store.get_value(i, 2)
-
-        if not wasChecked:
-            if repo.needsNetwork() and not network.hasActiveNetDev():
-                if not self.anaconda.intf.enableNetwork():
-                    return
-
-                urlgrabber.grabber.reset_curl_obj()
-
-            repo.enable()
-            if not setupRepo(self.anaconda, repo):
-                return
-        else:
-            repo.disable()
-            repo.close()
-
-        store.set_value(i, 0, not wasChecked)
-
-    def _createTaskStore(self):
-        store = gtk.ListStore(gobject.TYPE_BOOLEAN,
-                              gobject.TYPE_STRING,
-                              gobject.TYPE_PYOBJECT)
-        tl = self.xml.get_widget("taskList")
-        tl.set_model(store)
-
-        cbr = gtk.CellRendererToggle()
-        cbr.set_radio(True)
-        cbr.connect("toggled", self._taskToggled, store)
-
-        col = gtk.TreeViewColumn('', cbr, active = 0)
-        tl.append_column(col)
-
-        col = gtk.TreeViewColumn('Text', gtk.CellRendererText(), text = 1)
-        col.set_clickable(False)
-        tl.append_column(col)
-
-        anyEnabled = False
-
-        for (txt, grps) in self.tasks:
-            if not self.backend.groupListExists(grps):
-                continue
-
-            enabled = self.backend.groupListDefault(grps)
-            store.append([not anyEnabled and enabled, _(txt), grps])
-
-            if enabled:
-                anyEnabled = True
-
-        return tl
-
-    def __sortRepos(self, store, aIter, bIter):
-        aStr = store.get_value(aIter, 1)
-        bStr = store.get_value(bIter, 1)
-
-        if aStr == "Installation Repo":
-            return -1
-        elif bStr == "Installation Repo":
-            return 1
-        elif aStr < bStr or bStr is None:
-            return -1
-        elif aStr > bStr or aStr is None:
-            return 1
-        else:
-            return aStr == bStr
-
-    def _createRepoStore(self):
-        store = gtk.ListStore(gobject.TYPE_BOOLEAN,
-                              gobject.TYPE_STRING,
-                              gobject.TYPE_PYOBJECT)
-
-        tl = self.xml.get_widget("repoList")
-        tl.set_model(store)
-
-        cbr = gtk.CellRendererToggle()
-        col = gtk.TreeViewColumn('', cbr, active = 0)
-        cbr.connect("toggled", self._repoToggled, store)
-        tl.append_column(col)
-
-        col = gtk.TreeViewColumn('Text', gtk.CellRendererText(), text = 1)
-        col.set_clickable(False)
-        tl.append_column(col)
-
-        for (reponame, repo) in self.repos.repos.items():
-            store.append([repo.isEnabled(), repo.name, repo])
-
-        store.set_sort_column_id(1, gtk.SORT_ASCENDING)
-        store.set_sort_func(1, self.__sortRepos)
-
-        return tl
-
-    def getScreen (self, anaconda):
-        self.intf = anaconda.intf
-        self.dispatch = anaconda.dispatch
-        self.backend = anaconda.backend
-        self.anaconda = anaconda
-
-        self.tasks = anaconda.instClass.tasks
-        self.repos = anaconda.backend.ayum.repos
-
-        (self.xml, vbox) = gui.getGladeWidget("tasksel.glade", "taskBox")
-
-        lbl = self.xml.get_widget("mainLabel")
-        if anaconda.instClass.description:
-            lbl.set_text(_(anaconda.instClass.description))
-        else:
-            txt = lbl.get_text()
-            lbl.set_text(txt %(productName,))
-
-        custom = not self.dispatch.stepInSkipList("group-selection")
-        if custom:
-            self.xml.get_widget("customRadio").set_active(True)
-        else:
-            self.xml.get_widget("customRadio").set_active(False)
-
-        self.ts = self._createTaskStore()
-        self.rs = self._createRepoStore()
-
-        if len(self.ts.get_model()) == 0:
-            self.xml.get_widget("cbVBox").hide()
-            self.xml.get_widget("mainLabel").hide()
-
-        self.xml.get_widget("addRepoButton").connect("clicked", self._addRepo)
-        self.xml.get_widget("editRepoButton").connect("clicked", self._editRepo, self.rs)
-
-        return vbox
diff --git a/iw/timezone_gui.py b/iw/timezone_gui.py
deleted file mode 100644
index c5ecd88..0000000
--- a/iw/timezone_gui.py
+++ /dev/null
@@ -1,181 +0,0 @@
-#
-# timezone_gui.py: gui timezone selection.
-#
-# Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006  Red Hat, Inc.
-# 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 as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# 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, see <http://www.gnu.org/licenses/>.
-#
-
-import string
-import gtk
-import gtk.glade
-import gtk.gdk
-import gobject
-from scdate.core import zonetab
-import pango
-import sys
-
-from timezone_map_gui import TimezoneMap, Enum
-from iw_gui import *
-from booty.bootloaderInfo import dosFilesystems
-from bootloader import hasWindows
-
-from constants import *
-import gettext
-_ = lambda x: gettext.ldgettext("anaconda", x)
-
-try:
-    import gnomecanvas
-except ImportError:
-    import gnome.canvas as gnomecanvas
-
-class TimezoneWindow(InstallWindow):
-    def __init__(self, ics):
-        InstallWindow.__init__(self, ics)
-
-        # Need to set the custom handler before loading the glade file or
-        # this won't work.
-        gtk.glade.set_custom_handler(self.custom_widget_handler)
-
-        # Set the default now.  We'll fix it for real in getScreen.
-        self.default = "America/New York"
-
-        self.zonetab = zonetab.ZoneTab()
-
-        # Pull in a bunch of widgets.
-        self.xml = gtk.glade.XML("/usr/share/system-config-date/system-config-date.glade", domain="system-config-date")
-        self.vbox = self.xml.get_widget("tz_vbox")
-        self.utcCheckbox = self.xml.get_widget("utc_check")
-        self.notebook = self.xml.get_widget("notebook")
-
-        ics.setTitle(_("Time Zone Selection"))
-        ics.setNextEnabled(1)
-
-    def custom_widget_handler(self, xml, function_name, widget_name, str1, str2,
-                              int1, int2):
-        if hasattr(self, function_name):
-            handler = getattr(self, function_name)
-            return handler(str1, str2, int1, int2)
-        else:
-            # Lame.
-            return gtk.Label()
-
-    def timezone_widget_create (self, str1, str2, int1, int2):
-        mappath = "/usr/share/system-config-date/pixmaps/map1440.png"
-
-        self.tz = AnacondaTZMap(self.zonetab, self.default, map=mappath,
-                                viewportWidth=480)
-        self.tz.show_all()
-        return self.tz
-
-    def getNext(self):
-        newzone = self.tz.getCurrent().tz
-        self.timezone.setTimezoneInfo(newzone.replace(" ", "_"), self.utcCheckbox.get_active())
-        return None
-
-    # TimezoneWindow tag="timezone"
-    def getScreen(self, anaconda):
-	self.intf = anaconda.intf        
-        self.timezone = anaconda.timezone
-        (self.default, asUTC) = self.timezone.getTimezoneInfo()
-
-        if not self.default:
-            self.default = anaconda.instLanguage.getDefaultTimeZone(anaconda.rootPath)
-            asUTC = 0
-
-        if (string.find(self.default, "UTC") != -1):
-            self.default = "America/New_York"
-
-        self.default = self.default.replace("_", " ")
-
-        # Now fix the default we set when we made the timezone map widget.
-        self.tz.setCurrent(self.zonetab.findEntryByTZ(self.default))
-        self.utcCheckbox.set_active(asUTC)
-
-        if not anaconda.ksdata:
-            self.utcCheckbox.set_active(not hasWindows(anaconda.bootloader))
-
-        self.notebook.remove(self.vbox)
-        return self.vbox
-
-class AnacondaTZMap(TimezoneMap):
-    def __init__(self, zonetab, default, map="", viewportWidth=480):
-        TimezoneMap.__init__(self, zonetab, default, map=map, viewportWidth=viewportWidth)
-        self.columns = Enum("TRANSLATED", "TZ", "ENTRY")
-
-    def status_bar_init(self):
-        self.status = None
-
-    def load_entries (self, root):
-        iter = self.tzStore.get_iter_first()
-
-        for entry in self.zonetab.getEntries():
-            if entry.lat is not None and entry.long is not None:
-                x, y = self.map2canvas(entry.lat, entry.long)
-                marker = root.add(gnomecanvas.CanvasText, x=x, y=y,
-                                  text=u'\u00B7', fill_color='yellow',
-                                  anchor=gtk.ANCHOR_CENTER,
-                                  weight=pango.WEIGHT_BOLD)
-                self.markers[entry.tz] = marker
-
-                if entry.tz == "America/New York":
-                    # In case the /etc/sysconfig/clock is messed up, use New
-                    # York as the default.
-                    self.fallbackEntry = entry
-
-            iter = self.tzStore.insert_after(iter, [gettext.ldgettext("system-config-date", entry.tz), entry.tz, entry])
-
-    def timezone_list_init (self, default):
-        self.hbox = gtk.HBox()
-        self.tzStore = gtk.ListStore(gobject.TYPE_STRING, gobject.TYPE_STRING,
-                                     gobject.TYPE_PYOBJECT)
-
-        root = self.canvas.root()
-
-        self.load_entries(root)
-
-        # Add the ListStore to the sorted model after the list has been
-        # populated, since otherwise we end up resorting on every addition.
-        self.tzSorted = gtk.TreeModelSort(self.tzStore)
-        self.tzSorted.set_sort_column_id(0, gtk.SORT_ASCENDING)
-        self.tzCombo = gtk.ComboBox(model=self.tzSorted)
-        cell = gtk.CellRendererText()
-        self.tzCombo.pack_start(cell, True)
-        self.tzCombo.add_attribute(cell, 'text', 0)
-        self.tzCombo.connect("changed", self.selectionChanged)
-        self.hbox.pack_start(self.tzCombo, False, False)
-
-        self.pack_start(self.hbox, False, False)
-
-    def selectionChanged(self, widget, *args):
-        iter = widget.get_active_iter()
-        if iter is None:
-            return
-        entry = widget.get_model().get_value(iter, self.columns.ENTRY)
-        if entry:
-            self.setCurrent (entry, skipList=1)
-            if entry.long != None and entry.lat != None:
-                self.move_to (entry.long, entry.lat)
-
-    def updateTimezoneList(self):
-        # Find the currently selected item in the combo box and update both
-        # the combo and the comment label.
-        iter = self.tzCombo.get_model().get_iter_first()
-        while iter:
-            if self.tzCombo.get_model().get_value(iter, 1) == self.currentEntry.tz:
-                self.tzCombo.set_active_iter(iter)
-                break
-
-            iter = self.tzCombo.get_model().iter_next(iter)
diff --git a/iw/upgrade_bootloader_gui.py b/iw/upgrade_bootloader_gui.py
deleted file mode 100644
index caaf2f3..0000000
--- a/iw/upgrade_bootloader_gui.py
+++ /dev/null
@@ -1,209 +0,0 @@
-#
-# upgrade_bootloader_gui.py: gui bootloader dialog for upgrades
-#
-# Copyright (C) 2002, 2007  Red Hat, Inc.  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 as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# 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, see <http://www.gnu.org/licenses/>.
-#
-# Author(s): Jeremy Katz <katzj@xxxxxxxxxx>
-#
-
-# must replace with explcit form so update disks will work
-from iw_gui import *
-
-import gtk
-from booty import checkbootloader
-from storage.devices import devicePathToName
-
-from constants import *
-import gettext
-_ = lambda x: gettext.ldgettext("anaconda", x)
-
-import logging
-log = logging.getLogger("anaconda")
-
-class UpgradeBootloaderWindow (InstallWindow):
-    windowTitle = N_("Upgrade Boot Loader Configuration")
-
-    def getPrev(self):
-        pass
-
-    def getNext(self):
-        if self.nobl_radio.get_active():
-            self.dispatch.skipStep("bootloadersetup", skip = 1)
-            self.dispatch.skipStep("bootloader", skip = 1)
-            self.dispatch.skipStep("bootloaderadvanced", skip = 1)
-            self.dispatch.skipStep("instbootloader", skip = 1)
-        elif self.newbl_radio.get_active():
-            self.dispatch.skipStep("bootloadersetup", skip = 0)
-            self.dispatch.skipStep("bootloader", skip = 0)
-            self.dispatch.skipStep("bootloaderadvanced", skip = 0)
-            self.dispatch.skipStep("instbootloader", skip = 0)
-            self.bl.doUpgradeOnly = 0
-        else:
-            self.dispatch.skipStep("bootloadersetup", skip = 0)
-            self.dispatch.skipStep("bootloader", skip = 1)
-            self.dispatch.skipStep("bootloaderadvanced", skip = 1)
-            self.dispatch.skipStep("instbootloader", skip = 0)
-            self.bl.doUpgradeOnly = 1
-
-            if self.type == "GRUB":
-                self.bl.useGrubVal = 1
-            else:
-                self.bl.useGrubVal = 0
-            self.bl.setDevice(devicePathToName(self.bootDev))
-
-    def _newToLibata(self, rootPath):
-        # NOTE: any changes here need to be done in upgrade_bootloader_text too
-        try:
-            f = open("/proc/modules", "r")
-            buf = f.read()
-            if buf.find("libata") == -1:
-                return False
-        except:
-            log.debug("error reading /proc/modules")
-            pass
-
-        try:
-            f = open(rootPath + "/etc/modprobe.conf")
-        except:
-            log.debug("error reading /etc/modprobe.conf")
-            return False
-
-        modlines = f.readlines()
-        f.close()
-
-        try:
-            f = open("/tmp/scsidisks")
-        except:
-            log.debug("error reading /tmp/scsidisks")
-            return False
-        mods = []
-        for l in f.readlines():
-            (disk, mod) = l.split()
-            if mod.strip() not in mods:
-                mods.append(mod.strip())
-        f.close()
-
-        for l in modlines:
-            stripped = l.strip()
-
-            if stripped == "" or stripped[0] == "#":
-                continue
-
-            if stripped.find("scsi_hostadapter") != -1:
-                mod = stripped.split()[-1]
-                if mod in mods:
-                    mods.remove(mod)
-
-        if len(mods) > 0:
-            return True
-        return False
-
-    def getScreen(self, anaconda):
-        self.dispatch = anaconda.dispatch
-        self.bl = anaconda.bootloader
-
-        newToLibata = self._newToLibata(anaconda.rootPath)
-
-        (self.type, self.bootDev) = \
-                    checkbootloader.getBootloaderTypeAndBoot(anaconda.rootPath, storage=anaconda.storage)
-
-        self.update_radio = gtk.RadioButton(None, _("_Update boot loader configuration"))
-        updatestr = _("This will update your current boot loader.")
-
-        if newToLibata or (self.type is None or self.bootDev is None):
-            if newToLibata:
-                current = _("Due to system changes, your boot loader "
-                            "configuration can not be automatically updated.")
-            else:
-                current = _("The installer is unable to detect the boot loader "
-                            "currently in use on your system.")
-            self.update_label = gtk.Label("%s" % (updatestr,))
-            self.update_radio.set_sensitive(False)
-            self.update_label.set_sensitive(False)
-            update = 0
-        else:
-            current = _("The installer has detected the %(type)s boot loader "
-                        "currently installed on %(bootDev)s.") \
-                      % {'type': self.type, 'bootDev': self.bootDev}
-            self.update_label = gtk.Label("%s  %s" % (updatestr,
-                                         _("This is the recommended option.")))
-            self.update_radio.set_active(False)
-            update = 1
-
-        self.newbl_radio = gtk.RadioButton(self.update_radio,
-                                          _("_Create new boot loader "
-                                            "configuration"))
-        self.newbl_label = gtk.Label(_("This option creates a "
-                                      "new boot loader configuration.  If "
-                                      "you wish to switch boot loaders, you "
-                                      "should choose this."))
-
-        self.newbl_radio.set_active(False)
-        self.nobl_radio = gtk.RadioButton(self.update_radio,
-                                         _("_Skip boot loader updating"))
-        self.nobl_label = gtk.Label(_("This option makes no changes to boot "
-                                     "loader configuration.  If you are "
-                                     "using a third party boot loader, you "
-                                     "should choose this."))
-        self.nobl_radio.set_active(False)
-
-        for label in [self.update_label, self.nobl_label, self.newbl_label]:
-            label.set_alignment(0.8, 0)
-            label.set_size_request(275, -1)
-            label.set_line_wrap(True)
-
-        str = _("What would you like to do?")
-        # if they have one, the default is to update, otherwise the
-        # default is to not touch anything
-        if update == 1:
-            default = self.update_radio
-        elif newToLibata:
-            default = self.newbl_radio
-        else:
-            default = self.nobl_radio
-
-        if not self.dispatch.stepInSkipList("bootloader"):
-            self.newbl_radio.set_active(True)
-        elif self.dispatch.stepInSkipList("instbootloader"):
-            self.nobl_radio.set_active(True)
-        else:
-            default.set_active(True)
-
-        box = gtk.VBox(False, 5)
-
-        label = gtk.Label(current)
-        label.set_line_wrap(True)
-        label.set_alignment(0.5, 0.0)
-        label.set_size_request(300, -1)
-        label2 = gtk.Label(str)
-        label2.set_line_wrap(True)
-        label2.set_alignment(0.5, 0.0)
-        label2.set_size_request(300, -1)
-
-        box.pack_start(label, False)
-        box.pack_start(label2, False, padding = 10)
-
-        box.pack_start(self.update_radio, False)
-        box.pack_start(self.update_label, False)
-        box.pack_start(self.nobl_radio, False)
-        box.pack_start(self.nobl_label, False)
-        box.pack_start(self.newbl_radio, False)
-        box.pack_start(self.newbl_label, False)
-
-        a = gtk.Alignment(0.2, 0.1)
-        a.add(box)
-
-        return a
diff --git a/iw/upgrade_migratefs_gui.py b/iw/upgrade_migratefs_gui.py
deleted file mode 100644
index dd3de5c..0000000
--- a/iw/upgrade_migratefs_gui.py
+++ /dev/null
@@ -1,118 +0,0 @@
-#
-# upgrade_migratefs_gui.py: dialog for migrating filesystems on upgrades
-#
-# Copyright (C) 2001, 2002  Red Hat, Inc.  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 as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# 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, see <http://www.gnu.org/licenses/>.
-#
-# Author(s): Mike Fulbright <msf@xxxxxxxxxx>
-#
-
-from iw_gui import *
-from constants import *
-from storage.formats import getFormat
-from storage.deviceaction import ActionMigrateFormat
-import string
-import isys 
-import iutil
-import gtk
-
-import gettext
-_ = lambda x: gettext.ldgettext("anaconda", x)
-
-import logging
-log = logging.getLogger("anaconda")
-
-class UpgradeMigrateFSWindow (InstallWindow):		
-    windowTitle = N_("Migrate File Systems")
-
-    def getNext (self):
-        # I don't like this but I also don't see a better way right now
-        for (cb, entry) in self.cbs:
-            action = self.devicetree.findActions(device=entry,
-                                                 type="migrate")
-            if cb.get_active():
-                if action:
-                    # the migrate action has already been scheduled
-                    continue
-
-                newfs = getFormat(entry.format.migrationTarget)
-                if not newfs:
-                    log.warning("failed to get new filesystem type (%s)"
-                                % entry.format.migrationTarget)
-                    continue
-                action = ActionMigrateFormat(entry)
-                self.devicetree.registerAction(action)
-            elif action:
-                self.devicetree.cancelAction(action)
-
-        return None
-
-    def getScreen (self, anaconda):
-        self.devicetree = anaconda.storage.devicetree
-        self.migent = anaconda.storage.migratableDevices
-        
-        box = gtk.VBox (False, 5)
-        box.set_border_width (5)
-
-	text = (_("This release of %(productName)s supports "
-                 "an updated file system, which has several "
-                 "benefits over the file system traditionally shipped "
-                 "in %(productName)s.  This installation program can migrate "
-                 "formatted partitions without data loss.\n\n"
-                 "Which of these partitions would you like to migrate?") %
-                  {'productName': productName})
-        
-	label = gtk.Label (text)
-        label.set_alignment (0.5, 0.0)
-        label.set_size_request(400, -1)
-        label.set_line_wrap (True)
-        box.pack_start(label, False)
-
-        cbox = gtk.VBox(False, 5)
-        self.cbs = []
-        for entry in self.migent:
-            # don't allow the user to migrate /boot to ext4 (#439944)
-            if (getattr(entry.format, "mountpoint", None) == "/boot" and
-                not entry.format.migrate and entry.format.type == "ext3"):
-                continue
-            
-            cb = gtk.CheckButton("%s - %s - %s" % (entry.path,
-                                                   entry.format.name,
-                                                   getattr(entry.format,
-                                                           "mountpoint",
-                                                           None)))
-            cb.set_active(entry.format.migrate)
-            cbox.pack_start(cb, False)
-
-            self.cbs.append((cb, entry))
-
-        sw = gtk.ScrolledWindow()
-        sw.set_policy(gtk.POLICY_NEVER, gtk.POLICY_AUTOMATIC)
-        sw.add_with_viewport(cbox)
-        sw.set_size_request(-1, 175)
-        
-        viewport = sw.get_children()[0]
-        viewport.set_shadow_type(gtk.SHADOW_IN)
-        
-        a = gtk.Alignment(0.25, 0.5)
-        a.add(sw)
-
-        box.pack_start(a, True)
-        
-        a = gtk.Alignment(0.5, 0.5)
-        a.add(box)
-        return a
-    
-                       
diff --git a/iw/upgrade_swap_gui.py b/iw/upgrade_swap_gui.py
deleted file mode 100644
index 0edba09..0000000
--- a/iw/upgrade_swap_gui.py
+++ /dev/null
@@ -1,209 +0,0 @@
-#
-# upgrade_swap_gui.py: dialog for adding swap files for 2.4
-#
-# Copyright (C) 2001, 2002  Red Hat, Inc.  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 as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# 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, see <http://www.gnu.org/licenses/>.
-#
-# Author(s): Mike Fulbright <msf@xxxxxxxxxx>
-#
-
-import iutil
-import upgrade
-import gui
-import gobject
-import gtk
-from iw_gui import *
-from flags import flags
-
-from constants import *
-import gettext
-_ = lambda x: gettext.ldgettext("anaconda", x)
-
-class UpgradeSwapWindow (InstallWindow):		
-    windowTitle = N_("Upgrade Swap Partition")
-
-    def getNext (self):
-        #-If the user doesn't need to add swap, we don't do anything
-        if not self.neededSwap:
-            return None
-
-        if self.option2.get_active():
-            rc = self.warning()
-
-            if rc == 0:
-                raise gui.StayOnScreen
-            else:
-                return None
-
-	selection = self.view.get_selection()
-	(model, iter) = selection.get_selected()
-	if iter:
-	    dev = model.get_value(iter, 0)
-	    size = model.get_value(iter, 1)
-            val = int(self.entry.get_text())
-	else:
-	    raise RuntimeError, "unknown value for upgrade swap location"
-
-        if val > 2000 or val < 1:
-            rc = self.swapWrongSize()
-            raise gui.StayOnScreen
-
-        elif (val+16) > size:
-            rc = self.swapTooBig()
-            raise gui.StayOnScreen            
-
-        else:
-            self.storage.createSwapFile(dev, val)
-            self.dispatch.skipStep("addswap", 1)
-                
-        return None
-
-    def toggle (self, data):
-        self.swapbox.set_sensitive(self.option1.get_active())
-
-    def clist_cb(self, clist, row, col, data):
-        self.row = row
-    
-    def getScreen (self, anaconda):
-        self.neededSwap = 0
-        self.storage = anaconda.storage
-        self.intf = anaconda.intf
-        self.dispatch = anaconda.dispatch
-        
-        rc = anaconda.upgradeSwapInfo
-
-        self.neededSwap = 1
-        self.row = 0
-        box = gtk.VBox (False, 5)
-        box.set_border_width (5)
-
-	label = gtk.Label (_("Recent kernels (2.4 or newer) need significantly more "
-                            "swap than older kernels, up to twice "
-                            "the amount of RAM on the system.  "
-                            "You currently have %dMB of swap configured, but "
-                            "you may create additional swap space on one of "
-                            "your file systems now.")
-                          % (iutil.swapAmount() / 1024) +
-                          _("\n\nThe installer has detected %s MB of RAM.\n") %
-                          (iutil.memInstalled()/1024))
-
-        label.set_alignment (0.5, 0.0)
-#        label.set_size_request(400, 200)
-        label.set_line_wrap (True)
-        box.pack_start(label, False)
-
-        hs = gtk.HSeparator()
-        box.pack_start(hs, False)
-
-        self.option1 = gtk.RadioButton(None,
-                                      (_("I _want to create a swap file")))
-        box.pack_start(self.option1, False)
-
-        (fsList, suggSize, suggMntPoint) = rc
-
-        self.swapbox = gtk.VBox(False, 5)
-        box.pack_start(self.swapbox, False)
-        
-
-        label = gui.MnemonicLabel (_("Select the _partition to put the swap file on:"))
-        a = gtk.Alignment(0.2, 0.5)
-        a.add(label)
-        self.swapbox.pack_start(a, False)
-
-	self.store = gtk.ListStore(gobject.TYPE_STRING,
-				   gobject.TYPE_STRING,
-				   gobject.TYPE_STRING)
-
-        for (dev, size) in fsList:
-	    iter = self.store.append()
-	    self.store.set_value(iter, 0, dev)
-	    self.store.set_value(iter, 1, str(size))
-
-	self.view=gtk.TreeView(self.store)
-        label.set_mnemonic_widget(self.view)
-
-	i = 0
-	for title in [(_("Mount Point")), (_("Partition")), (_("Free Space (MB)"))]:
-	    col = gtk.TreeViewColumn(title, gtk.CellRendererText(), text=i)
-	    self.view.append_column(col)
-	    i = i + 1
-
-	sw = gtk.ScrolledWindow()
-	sw.add(self.view)
-	sw.set_shadow_type(gtk.SHADOW_IN)
-	sw.set_policy(gtk.POLICY_NEVER, gtk.POLICY_AUTOMATIC)
-	sw.set_size_request(300, 90)
-	a = gtk.Alignment(0.5, 0.5)
-        a.add(sw)
-        self.swapbox.pack_start(a, False, True, 10)
-
-	rootiter = self.store.get_iter_first()
-	sel = self.view.get_selection()
-	sel.select_iter(rootiter)
-
-        label = gtk.Label (_("A minimum swap file size of "
-                            "%d MB is recommended.  Please enter a size for the swap "
-                            "file:") % suggSize)
-        label.set_size_request(400, 40)
-        label.set_line_wrap (True)
-        a = gtk.Alignment(0.5, 0.5)
-        a.add(label)
-        self.swapbox.pack_start(a, False, True, 10)
-
-
-        hbox = gtk.HBox(False, 5)
-        a = gtk.Alignment(0.4, 0.5)
-        a.add(hbox)
-        self.swapbox.pack_start(a, False)
-
-        label = gui.MnemonicLabel (_("Swap file _size (MB):"))
-        hbox.pack_start(label, False)
-
-        self.entry = gtk.Entry(4)
-        label.set_mnemonic_widget(self.entry)
-        self.entry.set_size_request(40, 25)
-        self.entry.set_text(str(suggSize))
-        hbox.pack_start(self.entry, False, True, 10)
-
-        self.option2 = gtk.RadioButton(self.option1,
-                                      (_("I _don't want to create a swap "
-                                         "file")))
-        box.pack_start(self.option2, False, True, 20)
-
-        self.option1.connect("toggled", self.toggle)
-        return box
-
-
-    def warning(self):
-        rc = self.intf.messageWindow(_("Warning"), 
-                    _("A swap file is strongly recommended. "
-                      "Failure to create one could cause the installer "
-                      "to abort abnormally.  Are you sure you wish "
-                      "to continue?"), type = "yesno")
-        return rc
-
-    def swapWrongSize(self):
-        rc = self.intf.messageWindow(_("Warning"), 
-                    _("The swap file must be between 1 and 2000 MB in size."),
-                       type = "okcancel")
-        return rc
-
-    def swapTooBig(self):
-        
-        rc = self.intf.messageWindow(_("Warning"), 
-                    _("There is not enough space on the device you "
-			  "selected for the swap partition."),
-                       type = "okcancel")
-        return rc
diff --git a/iw/welcome_gui.py b/iw/welcome_gui.py
deleted file mode 100644
index d2e6fc5..0000000
--- a/iw/welcome_gui.py
+++ /dev/null
@@ -1,68 +0,0 @@
-#
-# welcome_gui.py: gui welcome screen.
-#
-# Copyright (C) 2000, 2001, 2002  Red Hat, Inc.  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 as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# 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, see <http://www.gnu.org/licenses/>.
-#
-
-import gtk
-import gui
-import sys
-from iw_gui import *
-
-from constants import *
-import gettext
-_ = lambda x: gettext.ldgettext("anaconda", x)
-
-class WelcomeWindow (InstallWindow):
-
-    windowTitle = "" #N_("Welcome")
-
-    def __init__ (self, ics):
-        InstallWindow.__init__ (self, ics)
-        ics.setGrabNext (1)
-        self.anaconda = None
-
-    # WelcomeWindow tag="wel"
-    def getScreen (self, anaconda):
-        self.anaconda = anaconda
-        # this is a bit ugly... but scale the image if we're not at 800x600
-        (w, h) = self.ics.cw.window.get_size_request()
-        if w >= 800:
-            height = None
-            width = None
-        else:
-            width = 500
-            height = 258
-        pix = gui.readImageFromFile("splash.png", width, height, dither=False)
-        box = gtk.EventBox ()
-        box.add (pix)
-        return box
-
-    def getNext (self):
-        if self.anaconda.requiresNetworkInstall():
-            self.anaconda.intf.messageWindow(_("Network Install Required"),
-                                             _("Your installation source is set to "
-                                               "a network location, but no netork "
-                                               "devices were found on your "
-                                               "system.  To avoid a network "
-                                               "installation, boot with the full "
-                                               "DVD, full CD set, or do not pass "
-                                               "a repo= parameter that specifies "
-                                               "a network source."),
-                                             type="custom",
-                                             custom_icon="error",
-                                             custom_buttons=[_("E_xit Installer")])
-            sys.exit(0)
diff --git a/iw/zipl_gui.py b/iw/zipl_gui.py
deleted file mode 100644
index 9f2bdc2..0000000
--- a/iw/zipl_gui.py
+++ /dev/null
@@ -1,132 +0,0 @@
-#
-# zipl_gui.py
-#
-# Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006  Red Hat, Inc.
-# 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 as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# 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, see <http://www.gnu.org/licenses/>.
-#
-
-# must replace with explcit form so update disks will work
-import gtk
-import string
-from iw_gui import *
-from constants import *
-from storage.dasd import getDasdPorts
-import gettext
-_ = lambda x: gettext.ldgettext("anaconda", x)
-
-class ZiplWindow (InstallWindow):
-    checkMark = None
-    checkMark_Off = None
-
-    def __init__ (self, ics):
-        InstallWindow.__init__ (self, ics)
-        self.ics.setTitle ("z/IPL")
-        self.ics.windowTitle = N_("z/IPL Boot Loader Configuration")
-
-    def getPrev (self):
-        # avoid coming back in here if the user backs past and then tries
-        # to skip this screen
-	pass
-
-    def getNext (self):
-        self.bl.args.set(self.kernelEntry.get_text())
-
-
-    # ZiplWindow tag="zipl"
-    def getScreen(self, anaconda):
-	self.dispatch = anaconda.dispatch
-	self.bl = anaconda.bootloader
-        self.intf = anaconda.intf
-
-	imageList = self.bl.images.getImages()
-	defaultDevice = self.bl.images.getDefault()
-        self.ignoreSignals = 0
-
-        box  = gtk.VBox(False, 5)
-        box.set_border_width(5)
-
-        label = gtk.Label(_("The z/IPL boot loader will be installed on your "
-                            "system."))
-        label = gtk.Label(_("The z/IPL Boot Loader will now be installed "
-                           "on your system."
-                           "\n"
-                           "\n"
-                           "The root partition will be the one you "
-                           "selected previously in the partition setup."
-                           "\n"
-                           "\n"
-                           "The kernel used to start the machine will be "
-                           "the one to be installed by default."
-                           "\n"
-                           "\n"
-                           "If you wish to make changes later after "
-                           "the installation feel free to change the "
-                           "/etc/zipl.conf configuration file."
-                           "\n"
-                           "\n"
-                           "You can now enter any additional kernel parameters "
-                           "which your machine or your setup may require."))
-        label.set_size_request(500, -1)
-        label.set_line_wrap(True)
-        label.set_alignment(0.0, 0.0)
-        label.set_padding(50,50)
-        box.pack_start(label, False)
-
-        box.pack_start (gtk.HSeparator (), False)
-
-        label = gtk.Label(_("Kernel Parameters") + ":")
-        label.set_alignment(0.0, 0.5)
-        self.kernelEntry = gtk.Entry()
-        clabel1 = gtk.Label(_("Chandev Parameters") + ":")
-        clabel1.set_alignment(0.0, 0.5)
-        self.chandeventry1 = gtk.Entry()
-        clabel2 = gtk.Label(_("Chandev Parameters") + ":")
-        clabel2.set_alignment(0.0, 0.5)
-        self.chandeventry2 = gtk.Entry()
-
-        if self.bl.args and self.bl.args.get():
-            kernelparms = self.bl.args.get()
-        else:
-            kernelparms = ""
-        if getDasdPorts() and (kernelparms.find("dasd=") == -1):
-            if len(kernelparms) > 0:
-                kernelparms = "%s dasd=%s" %(kernelparms, getDasdPorts())
-            else:
-                kernelparms = "dasd=%s" %(getDasdPorts(),)
-        self.kernelEntry.set_text(kernelparms)
-        
-        if self.bl.args and self.bl.args.chandevget():
-            cdevs = self.bl.args.chandevget()
-            self.chandeventry1.set_text('')
-            self.chandeventry2.set_text('')
-            if len(cdevs) > 0:
-                self.chandeventry1.set_text(cdevs[0])
-            if len(cdevs) > 1:
-                self.chandeventry2.set_text(string.join(cdevs[1:],';'))
-        hbox = gtk.HBox(False, 5)
-        hbox.pack_start(label, False)
-        hbox.pack_start(self.kernelEntry)
-        box.pack_start(hbox, False)
-        hbox1 = gtk.HBox(False, 5)
-        hbox1.pack_start(clabel1, False)
-        hbox1.pack_start(self.chandeventry1)
-        box.pack_start(hbox1, False)
-        hbox2 = gtk.HBox(False, 5)
-        hbox2.pack_start(clabel2, False)
-        hbox2.pack_start(self.chandeventry2)
-        box.pack_start(hbox2, False)
-
-        return box
diff --git a/kickstart.py b/kickstart.py
deleted file mode 100644
index 8e3368d..0000000
--- a/kickstart.py
+++ /dev/null
@@ -1,1499 +0,0 @@
-#
-# kickstart.py: kickstart install support
-#
-# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007
-# Red Hat, Inc.  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 as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# 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, see <http://www.gnu.org/licenses/>.
-#
-
-from storage.deviceaction import *
-from storage.devices import LUKSDevice
-from storage.devicelibs.lvm import getPossiblePhysicalExtents
-from storage.formats import getFormat
-from storage.partitioning import clearPartitions
-from storage.partitioning import shouldClear
-import storage.iscsi
-import storage.fcoe
-import storage.zfcp
-
-from errors import *
-import iutil
-import isys
-import os
-import os.path
-import tempfile
-from flags import flags
-from constants import *
-import sys
-import string
-import urlgrabber
-import warnings
-import network
-import upgrade
-import pykickstart.commands as commands
-from storage.devices import *
-from scdate.core import zonetab
-from pykickstart.base import KickstartCommand, BaseData
-from pykickstart.constants import *
-from pykickstart.errors import *
-from pykickstart.parser import *
-from pykickstart.version import *
-
-import gettext
-_ = lambda x: gettext.ldgettext("anaconda", x)
-
-import logging
-log = logging.getLogger("anaconda")
-stderrLog = logging.getLogger("anaconda.stderr")
-from anaconda_log import logger, logLevelMap, setHandlersLevel,\
-    DEFAULT_TTY_LEVEL
-
-class AnacondaKSScript(Script):
-    def run(self, chroot, serial, intf = None):
-        if self.inChroot:
-            scriptRoot = chroot
-        else:
-            scriptRoot = "/"
-
-        (fd, path) = tempfile.mkstemp("", "ks-script-", scriptRoot + "/tmp")
-
-        os.write(fd, self.script)
-        os.close(fd)
-        os.chmod(path, 0700)
-
-        # Always log stdout/stderr from scripts.  Using --logfile just lets you
-        # pick where it goes.  The script will also be logged to program.log
-        # because of execWithRedirect, and to anaconda.log if the script fails.
-        if self.logfile:
-            if self.inChroot:
-                messages = "%s/%s" % (scriptRoot, self.logfile)
-            else:
-                messages = self.logfile
-
-            d = os.path.basename(messages)
-            if not os.path.exists(d):
-                os.makedirs(d)
-        else:
-            messages = "%s.log" % path
-
-        if intf:
-            intf.suspend()
-        rc = iutil.execWithRedirect(self.interp, ["/tmp/%s" % os.path.basename(path)],
-                                    stdin = messages, stdout = messages, stderr = messages,
-                                    root = scriptRoot)
-        if intf:
-            intf.resume()
-
-        # Always log an error.  Only fail if we have a handle on the
-        # windowing system and the kickstart file included --erroronfail.
-        if rc != 0:
-            log.error("Error code %s running the kickstart script at line %s" % (rc, self.lineno))
-
-            try:
-                f = open(messages, "r")
-                err = f.readlines()
-                f.close()
-                for l in err:
-                    log.error("\t%s" % l)
-            except:
-                err = None
-
-            if self.errorOnFail:
-                if intf != None:
-                    msg = _("There was an error running the kickstart "
-                            "script at line %(lineno)s.  You may examine the "
-                            "output in %(msgs)s.  This is a fatal error and "
-                            "installation will be aborted.  Press the "
-                            "OK button to exit the installer.") \
-                          % {'lineno': self.lineno, 'msgs': messages}
-
-                    if err:
-                        intf.detailedMessageWindow(_("Scriptlet Failure"), msg, err)
-                    else:
-                        intf.messageWindow(_("Scriptlet Failure"), msg)
-
-                sys.exit(0)
-
-        if serial or self.logfile is not None:
-            os.chmod("%s" % messages, 0600)
-
-class AnacondaKSPackages(Packages):
-    def __init__(self):
-        Packages.__init__(self)
-
-        # Has the %packages section been seen at all?
-        self.seen = False
-
-
-def getEscrowCertificate(anaconda, url):
-    if not url:
-        return None
-
-    if url in anaconda.storage.escrowCertificates:
-        return anaconda.storage.escrowCertificates[url]
-
-    needs_net = not url.startswith("/") and not url.startswith("file:")
-    if needs_net and not network.hasActiveNetDev():
-        if not anaconda.intf.enableNetwork(anaconda):
-            anaconda.intf.messageWindow(_("No Network Available"),
-                                        _("Encryption key escrow requires "
-                                          "networking, but there was an error "
-                                          "enabling the network on your "
-                                          "system."), type="custom",
-                                        custom_icon="error",
-                                        custom_buttons=[_("_Exit installer")])
-            sys.exit(1)
-
-    log.info("escrow: downloading %s" % (url,))
-
-    try:
-        f = urlgrabber.urlopen(url)
-    except urlgrabber.grabber.URLGrabError as e:
-        msg = _("The following error was encountered while downloading the escrow certificate:\n\n%s" % e)
-        if anaconda.intf:
-            anaconda.intf.kickstartErrorWindow(msg)
-            sys.exit(1)
-        else:
-            stderrLog.critical(msg)
-            sys.exit(1)
-
-    try:
-        anaconda.storage.escrowCertificates[url] = f.read()
-    finally:
-        f.close()
-
-    return anaconda.storage.escrowCertificates[url]
-
-def deviceMatches(spec):
-    if not spec.startswith("/dev/"):
-        spec = os.path.normpath("/dev/" + spec)
-
-    matches = udev_resolve_glob(spec)
-    dev = udev_resolve_devspec(spec)
-
-    # udev_resolve_devspec returns None if there's no match, but we don't
-    # want that ending up in the list.
-    if dev and dev not in matches:
-        matches.append(dev)
-
-    return matches
-
-# Remove any existing formatting on a device, but do not remove the partition
-# itself.  This sets up an existing device to be used in a --onpart option.
-def removeExistingFormat(device, storage):
-    deps = storage.deviceDeps(device)
-    while deps:
-        leaves = [d for d in deps if d.isleaf]
-        for leaf in leaves:
-            storage.destroyDevice(leaf)
-            deps.remove(leaf)
-
-    storage.devicetree.registerAction(ActionDestroyFormat(device))
-
-###
-### SUBCLASSES OF PYKICKSTART COMMAND HANDLERS
-###
-
-class Authconfig(commands.authconfig.FC3_Authconfig):
-    def execute(self, anaconda):
-        anaconda.security.auth = self.authconfig
-
-class AutoPart(commands.autopart.F12_AutoPart):
-    def execute(self, anaconda):
-        # sets up default autopartitioning.  use clearpart separately
-        # if you want it
-        anaconda.instClass.setDefaultPartitioning(anaconda.storage, anaconda.platform)
-        anaconda.storage.doAutoPart = True
-
-        if self.encrypted:
-            anaconda.storage.encryptedAutoPart = True
-            anaconda.storage.encryptionPassphrase = self.passphrase
-            anaconda.storage.autoPartEscrowCert = \
-                getEscrowCertificate(anaconda, self.escrowcert)
-            anaconda.storage.autoPartAddBackupPassphrase = \
-                self.backuppassphrase
-
-        anaconda.ksdata.skipSteps.extend(["partition", "zfcpconfig", "parttype"])
-
-class AutoStep(commands.autostep.FC3_AutoStep):
-    def execute(self, anaconda):
-        flags.autostep = 1
-        flags.autoscreenshot = self.autoscreenshot
-
-class Bootloader(commands.bootloader.F12_Bootloader):
-    def execute(self, anaconda):
-        if self.location == "none":
-            location = None
-        elif self.location == "partition":
-            location = "boot"
-        else:
-            location = self.location
-
-        if self.upgrade and not anaconda.upgrade:
-            raise KickstartValueError, formatErrorMsg(self.lineno, msg="Selected upgrade mode for bootloader but not doing an upgrade")
-
-        if self.upgrade:
-            anaconda.bootloader.kickstart = 1
-            anaconda.bootloader.doUpgradeOnly = 1
-
-        if location is None:
-            anaconda.ksdata.permanentSkipSteps.extend(["bootloadersetup", "instbootloader"])
-        else:
-            anaconda.ksdata.showSteps.append("bootloader")
-
-            if self.appendLine:
-                anaconda.bootloader.args.append(self.appendLine)
-
-            if self.password:
-                anaconda.bootloader.setPassword(self.password, isCrypted = 0)
-
-            if self.md5pass:
-                anaconda.bootloader.setPassword(self.md5pass)
-
-            if location != None:
-                anaconda.bootloader.defaultDevice = location
-            else:
-                anaconda.bootloader.defaultDevice = -1
-
-            if self.timeout:
-                anaconda.bootloader.timeout = self.timeout
-
-            # add unpartitioned devices that will get partitioned into
-            # bootloader.drivelist
-            disks = anaconda.storage.disks
-            partitioned = anaconda.storage.partitioned
-            for disk in [d for d in disks if not d.partitioned]:
-                if shouldClear(disk, anaconda.storage.clearPartType,
-                               anaconda.storage.clearPartDisks):
-                    # add newly partitioned disks to the drivelist
-                    anaconda.bootloader.drivelist.append(disk.name)
-                elif disk.name in anaconda.bootloader.drivelist:
-                    # remove unpartitioned disks from the drivelist
-                    anaconda.bootloader.drivelist.remove(disk.name)
-            anaconda.bootloader.drivelist.sort(
-                cmp=anaconda.storage.compareDisks)
-
-            # Throw out drives specified that don't exist.
-            if self.driveorder and len(self.driveorder) > 0:
-                new = []
-                for drive in self.driveorder:
-                    if drive in anaconda.bootloader.drivelist:
-                        new.append(drive)
-                    else:
-                        log.warning("requested drive %s in boot drive order "
-                                    "doesn't exist" %(drive,))
-
-                anaconda.bootloader.updateDriveList(new)
-
-        anaconda.ksdata.permanentSkipSteps.extend(["upgbootloader", "bootloader"])
-
-class ClearPart(commands.clearpart.FC3_ClearPart):
-    def parse(self, args):
-        retval = commands.clearpart.FC3_ClearPart.parse(self, args)
-
-        if self.type is None:
-            self.type = CLEARPART_TYPE_NONE
-
-        # Do any glob expansion now, since we need to have the real list of
-        # disks available before the execute methods run.
-        drives = []
-        for spec in self.drives:
-            matched = deviceMatches(spec)
-            if matched:
-                drives.extend(matched)
-            else:
-                raise KickstartValueError, formatErrorMsg(self.lineno, msg="Specified nonexistent disk %s in clearpart command" % spec)
-
-        self.drives = drives
-
-        return retval
-
-    def execute(self, anaconda):
-        anaconda.storage.clearPartType = self.type
-        anaconda.storage.clearPartDisks = self.drives
-        if self.initAll:
-            anaconda.storage.reinitializeDisks = self.initAll
-
-        clearPartitions(anaconda.storage)
-        anaconda.ksdata.skipSteps.append("cleardiskssel")
-
-class Fcoe(commands.fcoe.F13_Fcoe):
-    def parse(self, args):
-        fc = commands.fcoe.F13_Fcoe.parse(self, args)
-
-        if fc.nic not in isys.getDeviceProperties():
-            raise KickstartValueError, formatErrorMsg(self.lineno, msg="Specified nonexistent nic %s in fcoe command" % fc.nic)
-
-        storage.fcoe.fcoe().addSan(nic=fc.nic, dcb=fc.dcb)
-
-        return fc
-
-class Firewall(commands.firewall.F10_Firewall):
-    def execute(self, anaconda):
-        anaconda.firewall.enabled = self.enabled
-        anaconda.firewall.trustdevs = self.trusts
-
-        for port in self.ports:
-            anaconda.firewall.portlist.append (port)
-
-        for svc in self.services:
-            anaconda.firewall.servicelist.append (svc)
-
-class IgnoreDisk(commands.ignoredisk.F8_IgnoreDisk):
-    def parse(self, args):
-        retval = commands.ignoredisk.F8_IgnoreDisk.parse(self, args)
-
-        # See comment in ClearPart.parse
-        drives = []
-        for spec in self.ignoredisk:
-            matched = deviceMatches(spec)
-            if matched:
-                drives.extend(matched)
-            else:
-                raise KickstartValueError, formatErrorMsg(self.lineno, msg="Specified nonexistent disk %s in ignoredisk command" % spec)
-
-        self.ignoredisk = drives
-
-        drives = []
-        for spec in self.onlyuse:
-            matched = deviceMatches(spec)
-            if matched:
-                drives.extend(matched)
-            else:
-                raise KickstartValueError, formatErrorMsg(self.lineno, msg="Specified nonexistent disk %s in ignoredisk command" % spec)
-
-        self.onlyuse = drives
-
-        return retval
-
-    def execute(self, anaconda):
-        anaconda.storage.ignoredDisks = self.ignoredisk
-        anaconda.storage.exclusiveDisks = self.onlyuse
-        anaconda.ksdata.skipSteps.extend(["filter", "filtertype"])
-
-class Iscsi(commands.iscsi.F10_Iscsi):
-    def parse(self, args):
-        tg = commands.iscsi.F10_Iscsi.parse(self, args)
-
-        try:
-            storage.iscsi.iscsi().addTarget(tg.ipaddr, tg.port,
-                tg.user, tg.password, tg.user_in, tg.password_in)
-            log.info("added iscsi target: %s" %(tg.ipaddr,))
-        except (IOError, ValueError), e:
-            raise KickstartValueError, formatErrorMsg(self.lineno,
-                                                      msg=str(e))
-        return tg
-
-class IscsiName(commands.iscsiname.FC6_IscsiName):
-    def parse(self, args):
-        retval = commands.iscsiname.FC6_IscsiName.parse(self, args)
-
-        storage.iscsi.iscsi().initiator = self.iscsiname
-        return retval
-
-class Keyboard(commands.keyboard.FC3_Keyboard):
-    def execute(self, anaconda):
-        anaconda.keyboard.set(self.keyboard)
-        anaconda.keyboard.beenset = 1
-        anaconda.ksdata.skipSteps.append("keyboard")
-
-class Lang(commands.lang.FC3_Lang):
-    def execute(self, anaconda):
-        anaconda.instLanguage.instLang = self.lang
-        anaconda.instLanguage.systemLang = self.lang
-        anaconda.ksdata.skipSteps.append("language")
-
-class LogVolData(commands.logvol.F12_LogVolData):
-    def execute(self, anaconda):
-        storage = anaconda.storage
-        devicetree = storage.devicetree
-
-        storage.doAutoPart = False
-
-        if self.mountpoint == "swap":
-            type = "swap"
-            self.mountpoint = ""
-            if self.recommended:
-                (self.size, self.maxSizeMB) = iutil.swapSuggestion()
-                self.grow = True
-        else:
-            if self.fstype != "":
-                type = self.fstype
-            else:
-                type = storage.defaultFSType
-
-        # Sanity check mountpoint
-        if self.mountpoint != "" and self.mountpoint[0] != '/':
-            raise KickstartValueError, formatErrorMsg(self.lineno, msg="The mount point \"%s\" is not valid." % (self.mountpoint,))
-
-        # Check that the VG this LV is a member of has already been specified.
-        vg = devicetree.getDeviceByName(self.vgname)
-        if not vg:
-            raise KickstartValueError, formatErrorMsg(self.lineno, msg="No volume group exists with the name \"%s\".  Specify volume groups before logical volumes." % self.vgname)
-
-        # If this specifies an existing request that we should not format,
-        # quit here after setting up enough information to mount it later.
-        if not self.format:
-            if not self.name:
-                raise KickstartValueError, formatErrorMsg(self.lineno, msg="--noformat used without --name")
-
-            dev = devicetree.getDeviceByName("%s-%s" % (vg.name, self.name))
-            if not dev:
-                raise KickstartValueError, formatErrorMsg(self.lineno, msg="No preexisting logical volume with the name \"%s\" was found." % self.name)
-
-            dev.format.mountpoint = self.mountpoint
-            dev.format.mountopts = self.fsopts
-            anaconda.ksdata.skipSteps.extend(["partition", "zfcpconfig", "parttype"])
-            return
-
-        # Make sure this LV name is not already used in the requested VG.
-        if not self.preexist:
-            tmp = devicetree.getDeviceByName("%s-%s" % (vg.name, self.name))
-            if tmp:
-                raise KickstartValueError, formatErrorMsg(self.lineno, msg="Logical volume name already used in volume group %s" % vg.name)
-
-            # Size specification checks
-            if not self.percent:
-                if not self.size:
-                    raise KickstartValueError, formatErrorMsg(self.lineno, msg="Size required")
-                elif not self.grow and self.size*1024 < vg.peSize:
-                    raise KickstartValueError, formatErrorMsg(self.lineno, msg="Logical volume size must be larger than the volume group physical extent size.")
-            elif self.percent <= 0 or self.percent > 100:
-                raise KickstartValueError, formatErrorMsg(self.lineno, msg="Percentage must be between 0 and 100")
-
-        # Now get a format to hold a lot of these extra values.
-        format = getFormat(type,
-                           mountpoint=self.mountpoint,
-                           mountopts=self.fsopts)
-        if not format:
-            raise KickstartValueError, formatErrorMsg(self.lineno, msg="The \"%s\" filesystem type is not supported." % type)
-
-        # If we were given a pre-existing LV to create a filesystem on, we need
-        # to verify it and its VG exists and then schedule a new format action
-        # to take place there.  Also, we only support a subset of all the
-        # options on pre-existing LVs.
-        if self.preexist:
-            device = devicetree.getDeviceByName("%s-%s" % (vg.name, self.name))
-            if not device:
-                raise KickstartValueError, formatErrorMsg(self.lineno, msg="Specified nonexistent LV %s in logvol command" % self.name)
-
-            removeExistingFormat(device, storage)
-            devicetree.registerAction(ActionCreateFormat(device, format))
-        else:
-            # If a previous device has claimed this mount point, delete the
-            # old one.
-            try:
-                if self.mountpoint:
-                    device = storage.mountpoints[self.mountpoint]
-                    storage.destroyDevice(device)
-            except KeyError:
-                pass
-
-            request = storage.newLV(format=format,
-                                    name=self.name,
-                                    vg=vg,
-                                    size=self.size,
-                                    grow=self.grow,
-                                    maxsize=self.maxSizeMB,
-                                    percent=self.percent)
-
-            if self.fsprofile and hasattr(request.format, "fsprofile"):
-                request.format.fsprofile = self.fsprofile
-
-            storage.createDevice(request)
-
-        if self.encrypted:
-            if self.passphrase and not storage.encryptionPassphrase:
-                storage.encryptionPassphrase = self.passphrase
-
-            cert = getEscrowCertificate(anaconda, self.escrowcert)
-            if self.preexist:
-                luksformat = format
-                device.format = getFormat("luks", passphrase=self.passphrase, device=device.path,
-                                          escrow_cert=cert,
-                                          add_backup_passphrase=self.backuppassphrase)
-                luksdev = LUKSDevice("luks%d" % storage.nextID,
-                                     format=luksformat,
-                                     parents=device)
-            else:
-                luksformat = request.format
-                request.format = getFormat("luks", passphrase=self.passphrase,
-                                           escrow_cert=cert,
-                                           add_backup_passphrase=self.backuppassphrase)
-                luksdev = LUKSDevice("luks%d" % storage.nextID,
-                                     format=luksformat,
-                                     parents=request)
-            storage.createDevice(luksdev)
-
-        anaconda.ksdata.skipSteps.extend(["partition", "zfcpconfig", "parttype"])
-
-class Logging(commands.logging.FC6_Logging):
-    def execute(self, anaconda):
-        if logger.tty_loglevel == DEFAULT_TTY_LEVEL:
-            # not set from the command line
-            level = logLevelMap[self.level]
-            logger.tty_loglevel = level
-            storage_log = logging.getLogger("storage")
-            setHandlersLevel(log, level)
-            setHandlersLevel(storage_log, level)
-
-        if logger.remote_syslog == None and len(self.host) > 0:
-            # not set from the command line, ok to use kickstart
-            remote_server = self.host
-            if self.port:
-                remote_server = "%s:%s" %(self.host, self.port)
-            logger.updateRemote(remote_server)
-    
-class NetworkData(commands.network.F8_NetworkData):
-    def execute(self, anaconda):
-        if self.bootProto:
-            devices = anaconda.network.netdevices
-            if (devices and self.bootProto):
-                if not self.device:
-                    list = devices.keys ()
-                    list.sort()
-                    device = list[0]
-                else:
-                    device = self.device
-
-                try:
-                    dev = devices[device]
-                except KeyError:
-                    raise KickstartValueError, formatErrorMsg(self.lineno, msg="The provided network interface %s does not exist" % device)
-
-                dev.set (("bootproto", self.bootProto))
-                dev.set (("dhcpclass", self.dhcpclass))
-
-                if self.onboot:
-                    dev.set (("onboot", "yes"))
-                else:
-                    dev.set (("onboot", "no"))
-
-                if self.bootProto == "static":
-                    if (self.ip):
-                        dev.set (("ipaddr", self.ip))
-                    if (self.netmask):
-                        dev.set (("netmask", self.netmask))
-
-                if self.ethtool:
-                    dev.set (("ethtool_opts", self.ethtool))
-
-                if isys.isWireless(device):
-                    if self.essid:
-                        dev.set(("essid", self.essid))
-                    if self.wepkey:
-                        dev.set(("wepkey", self.wepkey))
-
-        if self.hostname != "":
-            anaconda.network.setHostname(self.hostname)
-            anaconda.network.overrideDHCPhostname = True
-
-        if self.nameserver != "":
-            anaconda.network.setDNS(self.nameserver, device)
-
-        if self.gateway != "":
-            anaconda.network.setGateway(self.gateway, device)
-
-        needs_net = (anaconda.methodstr and
-                     (anaconda.methodstr.startswith("http:") or
-                      anaconda.methodstr.startswith("ftp:") or
-                      anaconda.methodstr.startswith("nfs:")))
-        if needs_net and not network.hasActiveNetDev():
-            log.info("Bringing up network in stage2 kickstart ...")
-            rc = anaconda.network.bringUp()
-            log.info("Network setup %s" % (rc and 'succeeded' or 'failed',))
-
-class MultiPath(commands.multipath.FC6_MultiPath):
-    def parse(self, args):
-        raise NotImplementedError("The multipath kickstart command is not currently supported")
-
-class DmRaid(commands.dmraid.FC6_DmRaid):
-    def parse(self, args):
-        raise NotImplementedError("The dmraid kickstart command is not currently supported")
-
-class PartitionData(commands.partition.F12_PartData):
-    def execute(self, anaconda):
-        storage = anaconda.storage
-        devicetree = storage.devicetree
-        kwargs = {}
-
-        storage.doAutoPart = False
-
-        if self.onbiosdisk != "":
-            for (disk, biosdisk) in storage.eddDict.iteritems():
-                if str(biosdisk) == self.onbiosdisk:
-                    self.disk = disk
-                    break
-
-            if self.disk == "":
-                raise KickstartValueError, formatErrorMsg(self.lineno, msg="Specified BIOS disk %s cannot be determined" % self.onbiosdisk)
-
-        if self.mountpoint == "swap":
-            type = "swap"
-            self.mountpoint = ""
-            if self.recommended:
-                (self.size, self.maxSizeMB) = iutil.swapSuggestion()
-                self.grow = True
-        # if people want to specify no mountpoint for some reason, let them
-        # this is really needed for pSeries boot partitions :(
-        elif self.mountpoint == "None":
-            self.mountpoint = ""
-            if self.fstype:
-                type = self.fstype
-            else:
-                type = storage.defaultFSType
-        elif self.mountpoint == 'appleboot':
-            type = "Apple Bootstrap"
-            self.mountpoint = ""
-            kwargs["weight"] = anaconda.platform.weight(fstype="appleboot")
-        elif self.mountpoint == 'prepboot':
-            type = "PPC PReP Boot"
-            self.mountpoint = ""
-            kwargs["weight"] = anaconda.platform.weight(fstype="prepboot")
-        elif self.mountpoint.startswith("raid."):
-            type = "mdmember"
-            kwargs["name"] = self.mountpoint
-
-            if devicetree.getDeviceByName(kwargs["name"]):
-                raise KickstartValueError, formatErrorMsg(self.lineno, msg="RAID partition defined multiple times")
-
-            # store "raid." alias for other ks partitioning commands
-            if self.onPart:
-                anaconda.ksdata.onPart[kwargs["name"]] = self.onPart
-            self.mountpoint = ""
-        elif self.mountpoint.startswith("pv."):
-            type = "lvmpv"
-            kwargs["name"] = self.mountpoint
-
-            if devicetree.getDeviceByName(kwargs["name"]):
-                raise KickstartValueError, formatErrorMsg(self.lineno, msg="PV partition defined multiple times")
-
-            # store "pv." alias for other ks partitioning commands
-            if self.onPart:
-                anaconda.ksdata.onPart[kwargs["name"]] = self.onPart
-            self.mountpoint = ""
-        elif self.mountpoint == "/boot/efi":
-            type = "EFI System Partition"
-            self.fsopts = "defaults,uid=0,gid=0,umask=0077,shortname=winnt"
-            kwargs["weight"] = anaconda.platform.weight(fstype="efi")
-        else:
-            if self.fstype != "":
-                type = self.fstype
-            elif self.mountpoint == "/boot":
-                type = anaconda.platform.defaultBootFSType
-            else:
-                type = storage.defaultFSType
-
-        # If this specified an existing request that we should not format,
-        # quit here after setting up enough information to mount it later.
-        if not self.format:
-            if not self.onPart:
-                raise KickstartValueError, formatErrorMsg(self.lineno, msg="--noformat used without --onpart")
-
-            dev = devicetree.getDeviceByName(udev_resolve_devspec(self.onPart))
-            if not dev:
-                raise KickstartValueError, formatErrorMsg(self.lineno, msg="No preexisting partition with the name \"%s\" was found." % self.onPart)
-
-            dev.format.mountpoint = self.mountpoint
-            dev.format.mountopts = self.fsopts
-            anaconda.ksdata.skipSteps.extend(["partition", "zfcpconfig", "parttype"])
-            return
-
-        # Size specification checks.
-        if not self.size and not self.onPart:
-            raise KickstartValueError, formatErrorMsg(self.lineno, msg="Partition requires a size specification")
-
-        # Now get a format to hold a lot of these extra values.
-        kwargs["format"] = getFormat(type,
-                                     mountpoint=self.mountpoint,
-                                     label=self.label,
-                                     mountopts=self.fsopts)
-        if not kwargs["format"]:
-            raise KickstartValueError, formatErrorMsg(self.lineno, msg="The \"%s\" filesystem type is not supported." % type)
-
-        # If we were given a specific disk to create the partition on, verify
-        # that it exists first.  If it doesn't exist, see if it exists with
-        # mapper/ on the front.  If that doesn't exist either, it's an error.
-        if self.disk:
-            names = [self.disk, "mapper/" + self.disk]
-            for n in names:
-                disk = devicetree.getDeviceByName(udev_resolve_devspec(n))
-                if not disk:
-                    raise KickstartValueError, formatErrorMsg(self.lineno, msg="Specified nonexistent disk %s in partition command" % n)
-
-                should_clear = shouldClear(disk,
-                                           storage.clearPartType,
-                                           storage.clearPartDisks)
-                if disk and (disk.partitioned or should_clear):
-                    kwargs["disks"] = [disk]
-                    break
-                elif disk:
-                    raise KickstartValueError, formatErrorMsg(self.lineno, msg="Specified unpartitioned disk %s in partition command" % self.disk)
-
-            if not kwargs["disks"]:
-                raise KickstartValueError, formatErrorMsg(self.lineno, msg="Specified nonexistent disk %s in partition command" % self.disk)
-
-        kwargs["grow"] = self.grow
-        kwargs["size"] = self.size
-        kwargs["maxsize"] = self.maxSizeMB
-        kwargs["primary"] = self.primOnly
-
-        # If we were given a pre-existing partition to create a filesystem on,
-        # we need to verify it exists and then schedule a new format action to
-        # take place there.  Also, we only support a subset of all the options
-        # on pre-existing partitions.
-        if self.onPart:
-            device = devicetree.getDeviceByName(udev_resolve_devspec(self.onPart))
-            if not device:
-                raise KickstartValueError, formatErrorMsg(self.lineno, msg="Specified nonexistent partition %s in partition command" % self.onPart)
-
-            removeExistingFormat(device, storage)
-            devicetree.registerAction(ActionCreateFormat(device, kwargs["format"]))
-        else:
-            # If a previous device has claimed this mount point, delete the
-            # old one.
-            try:
-                if self.mountpoint:
-                    device = storage.mountpoints[self.mountpoint]
-                    storage.destroyDevice(device)
-            except KeyError:
-                pass
-
-            request = storage.newPartition(**kwargs)
-
-            if self.fsprofile and hasattr(request.format, "fsprofile"):
-                request.format.fsprofile = self.fsprofile
-
-            storage.createDevice(request)
-
-        if self.encrypted:
-            if self.passphrase and not storage.encryptionPassphrase:
-               storage.encryptionPassphrase = self.passphrase
-
-            cert = getEscrowCertificate(anaconda, self.escrowcert)
-            if self.onPart:
-                luksformat = format
-                device.format = getFormat("luks", passphrase=self.passphrase, device=device.path,
-                                          escrow_cert=cert,
-                                          add_backup_passphrase=self.backuppassphrase)
-                luksdev = LUKSDevice("luks%d" % storage.nextID,
-                                     format=luksformat,
-                                     parents=device)
-            else:
-                luksformat = request.format
-                request.format = getFormat("luks", passphrase=self.passphrase,
-                                           escrow_cert=cert,
-                                           add_backup_passphrase=self.backuppassphrase)
-                luksdev = LUKSDevice("luks%d" % storage.nextID,
-                                     format=luksformat,
-                                     parents=request)
-            storage.createDevice(luksdev)
-
-        anaconda.ksdata.skipSteps.extend(["partition", "zfcpconfig", "parttype"])
-
-class Reboot(commands.reboot.FC6_Reboot):
-    def execute(self, anaconda):
-        anaconda.ksdata.skipSteps.append("complete")
-
-class RaidData(commands.raid.F12_RaidData):
-    def execute(self, anaconda):
-        raidmems = []
-        devicename = "md%d" % self.device
-
-        storage = anaconda.storage
-        devicetree = storage.devicetree
-        kwargs = {}
-
-        storage.doAutoPart = False
-
-        if self.mountpoint == "swap":
-            type = "swap"
-            self.mountpoint = ""
-        elif self.mountpoint.startswith("pv."):
-            type = "lvmpv"
-            kwargs["name"] = self.mountpoint
-            anaconda.ksdata.onPart[kwargs["name"]] = devicename
-
-            if devicetree.getDeviceByName(kwargs["name"]):
-                raise KickstartValueError, formatErrorMsg(self.lineno, msg="PV partition defined multiple times")
-
-            self.mountpoint = ""
-        else:
-            if self.fstype != "":
-                type = self.fstype
-            elif self.mountpoint == "/boot" and anaconda.platform.supportsMdRaidBoot:
-                type = anaconda.platform.defaultBootFSType
-            else:
-                type = storage.defaultFSType
-
-        # Sanity check mountpoint
-        if self.mountpoint != "" and self.mountpoint[0] != '/':
-            raise KickstartValueError, formatErrorMsg(self.lineno, msg="The mount point is not valid.")
-
-        # If this specifies an existing request that we should not format,
-        # quit here after setting up enough information to mount it later.
-        if not self.format:
-            if not devicename:
-                raise KickstartValueError, formatErrorMsg(self.lineno, msg="--noformat used without --device")
-
-            dev = devicetree.getDeviceByName(devicename)
-            if not dev:
-                raise KickstartValueError, formatErrorMsg(self.lineno, msg="No preexisting RAID device with the name \"%s\" was found." % devicename)
-
-            dev.format.mountpoint = self.mountpoint
-            dev.format.mountopts = self.fsopts
-            anaconda.ksdata.skipSteps.extend(["partition", "zfcpconfig", "parttype"])
-            return
-
-        # Get a list of all the RAID members.
-        for member in self.members:
-            # if member is using --onpart, use original device
-            member = anaconda.ksdata.onPart.get(member, member)
-            dev = devicetree.getDeviceByName(member)
-            if dev and dev.format.type == "luks":
-                try:
-                    dev = devicetree.getChildren(dev)[0]
-                except IndexError:
-                    dev = None
-            if not dev:
-                raise KickstartValueError, formatErrorMsg(self.lineno, msg="Tried to use undefined partition %s in RAID specification" % member)
-
-            raidmems.append(dev)
-
-        if not self.preexist:
-            if len(raidmems) == 0:
-                raise KickstartValueError, formatErrorMsg(self.lineno, msg="RAID Partition defined without any RAID members")
-
-            if self.level == "":
-                raise KickstartValueError, formatErrorMsg(self.lineno, msg="RAID Partition defined without RAID level")
-
-        # Now get a format to hold a lot of these extra values.
-        kwargs["format"] = getFormat(type,
-                                     mountpoint=self.mountpoint,
-                                     mountopts=self.fsopts)
-        if not kwargs["format"]:
-            raise KickstartValueError, formatErrorMsg(self.lineno, msg="The \"%s\" filesystem type is not supported." % type)
-
-        kwargs["name"] = devicename
-        kwargs["level"] = self.level
-        kwargs["parents"] = raidmems
-        kwargs["memberDevices"] = len(raidmems)
-        kwargs["totalDevices"] = kwargs["memberDevices"]+self.spares
-
-        # If we were given a pre-existing RAID to create a filesystem on,
-        # we need to verify it exists and then schedule a new format action
-        # to take place there.  Also, we only support a subset of all the
-        # options on pre-existing RAIDs.
-        if self.preexist:
-            device = devicetree.getDeviceByName(devicename)
-            if not device:
-                raise KickstartValueError, formatErrorMsg(self.lineno, msg="Specifeid nonexistent RAID %s in raid command" % devicename)
-
-            removeExistingFormat(device, storage)
-            devicetree.registerAction(ActionCreateFormat(device, kwargs["format"]))
-        else:
-            # If a previous device has claimed this mount point, delete the
-            # old one.
-            try:
-                if self.mountpoint:
-                    device = storage.mountpoints[self.mountpoint]
-                    storage.destroyDevice(device)
-            except KeyError:
-                pass
-
-            try:
-                request = storage.newMDArray(**kwargs)
-            except ValueError, e:
-                raise KickstartValueError, formatErrorMsg(self.lineno, msg=str(e))
-
-            if self.fsprofile and hasattr(request.format, "fsprofile"):
-                request.format.fsprofile = self.fsprofile
-
-            storage.createDevice(request)
-
-        if self.encrypted:
-            if self.passphrase and not storage.encryptionPassphrase:
-               storage.encryptionPassphrase = self.passphrase
-
-            cert = getEscrowCertificate(anaconda, self.escrowcert)
-            if self.preexist:
-                luksformat = format
-                device.format = getFormat("luks", passphrase=self.passphrase, device=device.path,
-                                          escrow_cert=cert,
-                                          add_backup_passphrase=self.backuppassphrase)
-                luksdev = LUKSDevice("luks%d" % storage.nextID,
-                                     format=luksformat,
-                                     parents=device)
-            else:
-                luksformat = request.format
-                request.format = getFormat("luks", passphrase=self.passphrase,
-                                           escrow_cert=cert,
-                                           add_backup_passphrase=self.backuppassphrase)
-                luksdev = LUKSDevice("luks%d" % storage.nextID,
-                                     format=luksformat,
-                                     parents=request)
-            storage.createDevice(luksdev)
-
-        anaconda.ksdata.skipSteps.extend(["partition", "zfcpconfig", "parttype"])
-
-class RootPw(commands.rootpw.F8_RootPw):
-    def execute(self, anaconda):
-        anaconda.users.rootPassword["password"] = self.password
-        anaconda.users.rootPassword["isCrypted"] = self.isCrypted
-        anaconda.users.rootPassword["lock"] = self.lock
-        anaconda.ksdata.skipSteps.append("accounts")
-
-class SELinux(commands.selinux.FC3_SELinux):
-    def execute(self, anaconda):
-        anaconda.security.setSELinux(self.selinux)
-
-class SkipX(commands.skipx.FC3_SkipX):
-    def execute(self, anaconda):
-        anaconda.ksdata.skipSteps.extend(["setsanex", "videocard", "xcustom"])
-
-        if anaconda.desktop is not None:
-            anaconda.desktop.setDefaultRunLevel(3)
-
-class Timezone(commands.timezone.FC6_Timezone):
-    def execute(self, anaconda):
-        # check validity
-        tab = zonetab.ZoneTab()
-        if self.timezone not in (entry.tz.replace(' ','_') for entry in
-                                 tab.getEntries()):
-            log.warning("Timezone %s set in kickstart is not valid." % (self.timezone,))
-
-        anaconda.timezone.setTimezoneInfo(self.timezone, self.isUtc)
-        anaconda.ksdata.skipSteps.append("timezone")
-
-class Upgrade(commands.upgrade.F11_Upgrade):
-    def execute(self, anaconda):
-        anaconda.upgrade = self.upgrade
-
-class VolGroupData(commands.volgroup.FC3_VolGroupData):
-    def execute(self, anaconda):
-        pvs = []
-
-        storage = anaconda.storage
-        devicetree = storage.devicetree
-
-        storage.doAutoPart = False
-
-        # Get a list of all the physical volume devices that make up this VG.
-        for pv in self.physvols:
-            # if pv is using --onpart, use original device
-            pv = anaconda.ksdata.onPart.get(pv, pv)
-            dev = devicetree.getDeviceByName(pv)
-            if dev and dev.format.type == "luks":
-                try:
-                    dev = devicetree.getChildren(dev)[0]
-                except IndexError:
-                    dev = None
-            if not dev:
-                raise KickstartValueError, formatErrorMsg(self.lineno, msg="Tried to use undefined partition %s in Volume Group specification" % pv)
-
-            pvs.append(dev)
-
-        if len(pvs) == 0 and not self.preexist:
-            raise KickstartValueError, formatErrorMsg(self.lineno, msg="Volume group defined without any physical volumes.  Either specify physical volumes or use --useexisting.")
-
-        if self.pesize not in getPossiblePhysicalExtents(floor=1024):
-            raise KickstartValueError, formatErrorMsg(self.lineno, msg="Volume group specified invalid pesize")
-
-        # If --noformat or --useexisting was given, there's really nothing to do.
-        if not self.format or self.preexist:
-            if not self.vgname:
-                raise KickstartValueError, formatErrorMsg(self.lineno, msg="--noformat or --useexisting used without giving a name")
-
-            dev = devicetree.getDeviceByName(self.vgname)
-            if not dev:
-                raise KickstartValueError, formatErrorMsg(self.lineno, msg="No preexisting VG with the name \"%s\" was found." % self.vgname)
-        else:
-            request = storage.newVG(pvs=pvs,
-                                    name=self.vgname,
-                                    peSize=self.pesize/1024.0)
-
-            storage.createDevice(request)
-
-class XConfig(commands.xconfig.F10_XConfig):
-    def execute(self, anaconda):
-        if self.startX:
-            anaconda.desktop.setDefaultRunLevel(5)
-
-        if self.defaultdesktop:
-            anaconda.desktop.setDefaultDesktop(self.defaultdesktop)
-
-class ZeroMbr(commands.zerombr.F9_ZeroMbr):
-    def execute(self, anaconda):
-        anaconda.storage.zeroMbr = 1
-
-class ZFCP(commands.zfcp.F12_ZFCP):
-    def parse(self, args):
-        fcp = commands.zfcp.F12_ZFCP.parse(self, args)
-        try:
-            storage.zfcp.ZFCP().addFCP(fcp.devnum, fcp.wwpn, fcp.fcplun)
-        except ValueError, e:
-            log.warning(str(e))
-
-        return fcp
-
-###
-### HANDLERS
-###
-
-# This is just the latest entry from pykickstart.handlers.control with all the
-# classes we're overriding in place of the defaults.
-commandMap = {
-        "auth": Authconfig,
-        "authconfig": Authconfig,
-        "autopart": AutoPart,
-        "autostep": AutoStep,
-        "bootloader": Bootloader,
-        "clearpart": ClearPart,
-        "dmraid": DmRaid,
-        "fcoe": Fcoe,
-        "firewall": Firewall,
-        "halt": Reboot,
-        "ignoredisk": IgnoreDisk,
-        "install": Upgrade,
-        "iscsi": Iscsi,
-        "iscsiname": IscsiName,
-        "keyboard": Keyboard,
-        "lang": Lang,
-        "logging": Logging,
-        "multipath": MultiPath,
-        "poweroff": Reboot,
-        "reboot": Reboot,
-        "rootpw": RootPw,
-        "selinux": SELinux,
-        "shutdown": Reboot,
-        "skipx": SkipX,
-        "timezone": Timezone,
-        "upgrade": Upgrade,
-        "xconfig": XConfig,
-        "zerombr": ZeroMbr,
-        "zfcp": ZFCP,
-}
-
-dataMap = {
-        "LogVolData": LogVolData,
-        "NetworkData": NetworkData,
-        "PartData": PartitionData,
-        "RaidData": RaidData,
-        "VolGroupData": VolGroupData,
-}
-
-superclass = returnClassForVersion()
-
-class AnacondaKSHandler(superclass):
-    def __init__ (self, anaconda):
-        superclass.__init__(self, commandUpdates=commandMap, dataUpdates=dataMap)
-        self.packages = AnacondaKSPackages()
-
-        self.permanentSkipSteps = []
-        self.skipSteps = []
-        self.showSteps = []
-        self.anaconda = anaconda
-        self.id = self.anaconda.id
-        self.onPart = {}
-
-        # All the KickstartCommand and KickstartData objects that
-        # handleCommand returns, so we can later iterate over them and run
-        # the execute methods.  These really should be stored in the order
-        # they're seen in the kickstart file.
-        self._dataObjs = []
-
-    def add(self, obj):
-        if isinstance(obj, KickstartCommand):
-            # Commands can only be run once, and the latest one seen takes
-            # precedence over any earlier ones.
-            i = 0
-            while i < len(self._dataObjs):
-                if self._dataObjs[i].__class__ == obj.__class__:
-                    self._dataObjs.pop(i)
-                    break
-
-                i += 1
-
-            self._dataObjs.append(obj)
-        else:
-            # Data objects can be seen over and over again.
-            self._dataObjs.append(obj)
-
-    def execute(self):
-        for obj in filter(lambda o: hasattr(o, "execute"), self._dataObjs):
-            obj.execute(self.anaconda)
-
-class AnacondaPreParser(KickstartParser):
-    # A subclass of KickstartParser that only looks for %pre scripts and
-    # sets them up to be run.  All other scripts and commands are ignored.
-    def __init__ (self, handler, followIncludes=True, errorsAreFatal=True,
-                  missingIncludeIsFatal=True):
-        KickstartParser.__init__(self, handler, missingIncludeIsFatal=False)
-
-    def addScript (self):
-        if self._script["type"] != KS_SCRIPT_PRE:
-            return
-
-        s = AnacondaKSScript (self._script["body"], type=self._script["type"],
-                              interp=self._script["interp"],
-                              lineno=self._script["lineno"],
-                              inChroot=self._script["chroot"],
-                              logfile=self._script["log"],
-                              errorOnFail=self._script["errorOnFail"])
-        self.handler.scripts.append(s)
-
-    def addPackages (self, line):
-        pass
-
-    def handleCommand (self, lineno, args):
-        pass
-
-    def handlePackageHdr (self, lineno, args):
-        pass
-
-    def handleScriptHdr (self, lineno, args):
-        if not args[0] == "%pre":
-            return
-
-        KickstartParser.handleScriptHdr(self, lineno, args)
-
-class AnacondaKSParser(KickstartParser):
-    def __init__ (self, handler, followIncludes=True, errorsAreFatal=True,
-                  missingIncludeIsFatal=True):
-        KickstartParser.__init__(self, handler)
-
-    def addScript (self):
-        if string.join(self._script["body"]).strip() == "":
-            return
-
-        s = AnacondaKSScript (self._script["body"], type=self._script["type"],
-                              interp=self._script["interp"],
-                              lineno=self._script["lineno"],
-                              inChroot=self._script["chroot"],
-                              logfile=self._script["log"],
-                              errorOnFail=self._script["errorOnFail"])
-        self.handler.scripts.append(s)
-
-    def handlePackageHdr (self, lineno, args):
-        KickstartParser.handlePackageHdr (self, lineno, args)
-        self.handler.packages.seen = True
-
-    def handleCommand (self, lineno, args):
-        if not self.handler:
-            return
-
-        retval = KickstartParser.handleCommand(self, lineno, args)
-        self.handler.add(retval)
-        return retval
-
-def preScriptPass(anaconda, file):
-    # The first pass through kickstart file processing - look for %pre scripts
-    # and run them.  This must come in a separate pass in case a script
-    # generates an included file that has commands for later.
-    ksparser = AnacondaPreParser(AnacondaKSHandler(anaconda))
-
-    try:
-        ksparser.readKickstart(file)
-    except IOError, e:
-        if anaconda.intf:
-            anaconda.intf.kickstartErrorWindow("Could not open kickstart file or included file named %s" % e.filename)
-            sys.exit(1)
-        else:
-            stderrLog.critical(_("The following error was found while parsing the kickstart "
-                              "configuration file:\n\n%s") % e)
-            sys.exit(1)
-    except KickstartError, e:
-       if anaconda.intf:
-           anaconda.intf.kickstartErrorWindow(e.__str__())
-           sys.exit(1)
-       else:
-            stderrLog.critical(_("The following error was found while parsing the kickstart "
-                              "configuration file:\n\n%s") % e)
-            sys.exit(1)
-
-    # run %pre scripts
-    runPreScripts(anaconda, ksparser.handler.scripts)
-
-def parseKickstart(anaconda, file):
-    try:
-        file = preprocessKickstart(file)
-    except KickstartError, msg:
-        stderrLog.critical(_("Error processing %%ksappend lines: %s") % msg)
-        sys.exit(1)
-    except Exception, e:
-        stderrLog.critical(_("Unknown error processing %%ksappend lines: %s") % e)
-        sys.exit(1)
-
-    handler = AnacondaKSHandler(anaconda)
-    ksparser = AnacondaKSParser(handler)
-
-    # We need this so all the /dev/disk/* stuff is set up before parsing.
-    udev_trigger(subsystem="block", action="change")
-    # So that drives onlined by these can be used in the ks file
-    storage.iscsi.iscsi().startup()
-    storage.fcoe.fcoe().startup()
-    storage.zfcp.ZFCP().startup()
-    # Note we do NOT call dasd.startup() here, that does not online drives, but
-    # only checks if they need formatting, which requires zerombr to be known
-
-    try:
-        ksparser.readKickstart(file)
-    except IOError, e:
-        # We may not have an intf now, but we can do better than just raising
-        # the exception.
-        if anaconda.intf:
-            anaconda.intf.kickstartErrorWindow("Could not open kickstart file or included file named %s" % e.filename)
-            sys.exit(1)
-        else:
-            stderrLog.critical(_("The following error was found while parsing the kickstart "
-                              "configuration file:\n\n%s") % e)
-            sys.exit(1)
-    except KickstartError, e:
-        if anaconda.intf:
-            anaconda.intf.kickstartErrorWindow(e.__str__())
-            sys.exit(1)
-        else:
-            stderrLog.critical(_("The following error was found while parsing the kickstart "
-                              "configuration file:\n\n%s") % e)
-            sys.exit(1)
-
-    return handler
-
-def runPostScripts(anaconda):
-    if not anaconda.ksdata:
-        return
-
-    postScripts = filter (lambda s: s.type == KS_SCRIPT_POST,
-                          anaconda.ksdata.scripts)
-
-    if len(postScripts) == 0:
-        return
-
-    # Remove environment variables that cause problems for %post scripts.
-    for var in ["LIBUSER_CONF"]:
-        if os.environ.has_key(var):
-            del(os.environ[var])
-
-    log.info("Running kickstart %%post script(s)")
-    if anaconda.intf is not None:
-        w = anaconda.intf.waitWindow(_("Post-Installation"),
-                            _("Running post-installation scripts"))
-        
-    map (lambda s: s.run(anaconda.rootPath, flags.serial, anaconda.intf), postScripts)
-
-    log.info("All kickstart %%post script(s) have been run")
-    if anaconda.intf is not None:
-        w.pop()
-
-def runPreScripts(anaconda, scripts):
-    preScripts = filter (lambda s: s.type == KS_SCRIPT_PRE, scripts)
-
-    if len(preScripts) == 0:
-        return
-
-    log.info("Running kickstart %%pre script(s)")
-    if anaconda.intf is not None:
-        w = anaconda.intf.waitWindow(_("Pre-Installation"),
-                            _("Running pre-installation scripts"))
-    
-    map (lambda s: s.run("/", flags.serial, anaconda.intf), preScripts)
-
-    log.info("All kickstart %%pre script(s) have been run")
-    if anaconda.intf is not None:
-        w.pop()
-
-def runTracebackScripts(anaconda):
-    log.info("Running kickstart %%traceback script(s)")
-    for script in filter (lambda s: s.type == KS_SCRIPT_TRACEBACK,
-                          anaconda.ksdata.scripts):
-        script.run("/", flags.serial)
-    log.info("All kickstart %%traceback script(s) have been run")
-
-def selectPackages(anaconda):
-    ksdata = anaconda.ksdata
-    ignoreAll = False
-
-    # If no %packages header was seen, use the installclass's default group
-    # selections.  This can also be explicitly specified with %packages
-    # --default.  Otherwise, select whatever was given (even if it's nothing).
-    if not ksdata.packages.seen or ksdata.packages.default:
-        anaconda.instClass.setGroupSelection(anaconda)
-        return
-
-    for pkg in ksdata.packages.packageList:
-        num = anaconda.backend.selectPackage(pkg)
-        if ksdata.packages.handleMissing == KS_MISSING_IGNORE or ignoreAll:
-            continue
-        if num > 0:
-            continue
-        rc = anaconda.intf.messageWindow(_("Missing Package"),
-                                _("You have specified that the "
-                                  "package '%s' should be installed.  "
-                                  "This package does not exist. "
-                                  "Would you like to continue or "
-                                  "abort this installation?") %(pkg,),
-                                type="custom",
-                                custom_buttons=[_("_Abort"),
-                                                _("_Ignore All"),
-                                                _("_Continue")])
-        if rc == 0:
-            sys.exit(1)
-        elif rc == 1:
-            ignoreAll = True
-
-    ksdata.packages.groupList.insert(0, Group("Core"))
-
-    if ksdata.packages.addBase:
-        ksdata.packages.groupList.insert(1, Group("Base"))
-    else:
-        log.warning("not adding Base group")
-
-    for grp in ksdata.packages.groupList:
-        default = False
-        optional = False
-
-        if grp.include == GROUP_DEFAULT:
-            default = True
-        elif grp.include == GROUP_ALL:
-            default = True
-            optional = True
-
-        try:
-            anaconda.backend.selectGroup(grp.name, (default, optional))
-        except NoSuchGroup, e:
-            if ksdata.packages.handleMissing == KS_MISSING_IGNORE or ignoreAll:
-                pass
-            else:
-                rc = anaconda.intf.messageWindow(_("Missing Group"),
-                                        _("You have specified that the "
-                                          "group '%s' should be installed. "
-                                          "This group does not exist. "
-                                          "Would you like to continue or "
-                                          "abort this installation?")
-                                        %(grp.name,),
-                                        type="custom",
-                                        custom_buttons=[_("_Abort"),
-                                                        _("_Ignore All"),
-                                                        _("_Continue")])
-                if rc == 0:
-                    sys.exit(1)
-                elif rc == 1:
-                    ignoreAll = True
-
-    map(anaconda.backend.deselectPackage, ksdata.packages.excludedList)
-    map(lambda g: anaconda.backend.deselectGroup(g.name),
-        ksdata.packages.excludedGroupList)
-
-def setSteps(anaconda):
-    def havePackages(packages):
-        return len(packages.groupList) > 0 or len(packages.packageList) > 0 or \
-               len(packages.excludedList) > 0 or len(packages.excludedGroupList) > 0
-
-    dispatch = anaconda.dispatch
-    ksdata = anaconda.ksdata
-    interactive = ksdata.interactive.interactive
-
-    if ksdata.upgrade.upgrade:
-        upgrade.setSteps(anaconda)
-
-        # we have no way to specify migrating yet
-        dispatch.skipStep("upgrademigfind")
-        dispatch.skipStep("upgrademigratefs")
-        dispatch.skipStep("upgradecontinue")
-        dispatch.skipStep("findinstall", permanent = 1)
-        dispatch.skipStep("language")
-        dispatch.skipStep("keyboard")
-        dispatch.skipStep("betanag")
-        dispatch.skipStep("installtype")
-    else:
-        anaconda.instClass.setSteps(anaconda)
-        dispatch.skipStep("findrootparts")
-
-    if interactive or flags.autostep:
-        dispatch.skipStep("installtype")
-        dispatch.skipStep("bootdisk")
-
-    dispatch.skipStep("bootdisk")
-    dispatch.skipStep("betanag")
-    dispatch.skipStep("installtype")
-    dispatch.skipStep("network")
-
-    # Storage is initialized for us right when kickstart processing starts.
-    dispatch.skipStep("storageinit")
-
-    if not interactive:
-        # Don't show confirmation screens on non-interactive installs.
-        dispatch.skipStep("confirminstall")
-        dispatch.skipStep("confirmupgrade")
-        dispatch.skipStep("welcome")
-
-        # Since ignoredisk is optional and not specifying it means you want to
-        # consider all possible disks, we should not stop on the filter steps
-        # unless it's an interactive install.
-        dispatch.skipStep("filter")
-        dispatch.skipStep("filtertype")
-
-    # Make sure to automatically reboot even in interactive if told to.
-    if interactive and ksdata.reboot.action in [KS_REBOOT, KS_SHUTDOWN]:
-        dispatch.skipStep("complete")
-
-    # If the package section included anything, skip group selection unless
-    # they're in interactive.
-    if ksdata.upgrade.upgrade:
-        ksdata.skipSteps.extend(["tasksel", "group-selection"])
-
-        # Special check for this, since it doesn't make any sense.
-        if ksdata.packages.seen:
-            warnings.warn("Ignoring contents of %packages section due to upgrade.")
-    elif havePackages(ksdata.packages):
-        if interactive:
-            ksdata.showSteps.extend(["tasksel", "group-selection"])
-        else:
-            ksdata.skipSteps.extend(["tasksel", "group-selection"])
-    else:
-        if ksdata.packages.seen:
-            ksdata.skipSteps.extend(["tasksel", "group-selection"])
-        else:
-            ksdata.showSteps.extend(["tasksel", "group-selection"])
-
-    if not interactive:
-        for n in ksdata.skipSteps:
-            dispatch.skipStep(n)
-        for n in ksdata.permanentSkipSteps:
-            dispatch.skipStep(n, permanent=1)
-    for n in ksdata.showSteps:
-        dispatch.skipStep(n, skip = 0)
-
-    # Text mode doesn't have all the steps that graphical mode does, so we
-    # can't stop and prompt for missing information.  Make sure we've got
-    # everything that would be provided by a missing section now and error
-    # out if we don't.
-    if anaconda.displayMode == "t":
-        missingSteps = [("bootloader", "Bootloader configuration"),
-                        ("filter", "Disks to use in installation"),
-                        ("cleardiskssel", "Disks to clear"),
-                        ("group-selection", "Package selection")]
-        errors = []
-
-        for (step, msg) in missingSteps:
-            if not dispatch.stepInSkipList(step):
-                errors.append(msg)
-
-        if len(errors) > 0:
-            anaconda.intf.kickstartErrorWindow(_("The kickstart configuration "
-                "file is missing required information that anaconda cannot "
-                "prompt for.  Please add the following sections and try "
-                "again:\n%s") % ", ".join(errors))
-            sys.exit(0)
diff --git a/lang-table b/lang-table
deleted file mode 100644
index 2378b8d..0000000
--- a/lang-table
+++ /dev/null
@@ -1,61 +0,0 @@
-Afrikaans	af	latarcyrheb-sun16	af_ZA.UTF-8	us	Africa/Johannesburg
-Arabic	ar	none	ar_SA.UTF-8	us	Asia/Riyadh
-Assamese	as	none	as_IN.UTF-8	us	Asia/Kolkata
-Bengali	bn	none	bn_BD.UTF-8	us	Asia/Dhaka
-Bengali(India)	bn	none	bn_IN.UTF-8	us	Asia/Kolkata
-Bulgarian	bg	latarcyrheb-sun16	bg_BG.UTF-8	bg_bds-utf8	Europe/Sofia
-Catalan	ca	latarcyrheb-sun16	ca_ES.UTF-8	es	Europe/Madrid
-Chinese(Simplified)	zh_CN	none	zh_CN.UTF-8	us	Asia/Shanghai
-Chinese(Traditional)	zh_TW	none	zh_TW.UTF-8	us	Asia/Taipei
-Croatian	hr	latarcyrheb-sun16	hr_HR.UTF-8	croat	Europe/Zagreb
-Czech	cs	latarcyrheb-sun16	cs_CZ.UTF-8	cz-lat2	Europe/Prague
-Danish	da	latarcyrheb-sun16	da_DK.UTF-8	dk	Europe/Copenhagen
-Dutch	nl	latarcyrheb-sun16	nl_NL.UTF-8	nl	Europe/Amsterdam
-English	en	latarcyrheb-sun16	en_US.UTF-8	us	America/New_York
-Estonian	et	latarcyrheb-sun16	et_EE.UTF-8	et	Europe/Tallinn
-Finnish	fi	latarcyrheb-sun16	fi_FI.UTF-8	fi	Europe/Helsinki
-French	fr	latarcyrheb-sun16	fr_FR.UTF-8	fr-latin9	Europe/Paris
-German	de	latarcyrheb-sun16	de_DE.UTF-8	de-latin1-nodeadkeys	Europe/Berlin
-Greek	el	iso07u-16	el_GR.UTF-8	gr	Europe/Athens
-Gujarati	gu	none	gu_IN.UTF-8	us	Asia/Kolkata
-Hebrew	he	none	he_IL.UTF-8	us	Asia/Jerusalem
-Hindi	hi	none	hi_IN.UTF-8	us	Asia/Kolkata
-Hungarian	hu	latarcyrheb-sun16	hu_HU.UTF-8	hu	Europe/Budapest
-Icelandic	is	latarcyrheb-sun16	is_IS.UTF-8	is-latin1	Atlantic/Reykjavik
-Iloko	ilo	latarcyrheb-sun16	ilo_PH.UTF-8	us	Asia/Manila
-Indonesian	id	latarcyrheb-sun16	id_ID.UTF-8	us	Asia/Jakarta
-Italian	it	latarcyrheb-sun16	it_IT.UTF-8	it	Europe/Rome
-Japanese	ja	none	ja_JP.UTF-8	jp106	Asia/Tokyo	
-Kannada	kn	none	kn_IN.UTF-8	us	Asia/Kolkata
-Korean	ko	none	ko_KR.UTF-8	us	Asia/Seoul	
-Macedonian	mk	latarcyrheb-sun16	mk_MK.UTF-8	mk	Europe/Skopje
-Maithili	mai	none	mai_IN.UTF-8	us	Asia/Kolkata
-Malay	ms	latarcyrheb-sun16	ms_MY.UTF-8	us	Asia/Kuala_Lumpur
-Malayalam	ml	none	ml_IN.UTF-8	us	Asia/Kolkata
-Marathi	mr	none	mr_IN.UTF-8	us	Asia/Kolkata
-Nepali	ne	none	ne_NP.UTF-8	us	Asia/Kathmandu
-Norwegian(Bokmål)	nb	latarcyrheb-sun16	nb_NO.UTF-8	no	Europe/Oslo
-Northern Sotho	nso	latarcyrheb-sun16	nso_ZA.UTF-8	us	Africa/Johannesburg
-Oriya	or	none	or_IN.UTF-8	us	Asia/Kolkata
-Persian	fa	none	fa_IR.UTF-8	us	Asia/Tehran
-Polish	pl	latarcyrheb-sun16	pl_PL.UTF-8	pl2	Europe/Warsaw
-Portuguese	pt	latarcyrheb-sun16	pt_PT.UTF-8	pt-latin1	Europe/Lisbon
-Portuguese(Brazilian)	pt_BR	latarcyrheb-sun16	pt_BR.UTF-8	br-abnt2	America/Sao_Paulo
-Punjabi	pa	none	pa_IN.UTF-8	us	Asia/Kolkata
-Romanian	ro	Lat2-Terminus16	ro_RO.UTF-8	ro	Europe/Bucharest
-Russian	ru	none	ru_RU.UTF-8	ru	Europe/Moscow
-Serbian	sr	latarcyrheb-sun16	sr_RS.UTF-8	sr-cy	Europe/Belgrade
-Serbian(Latin)	sr@latin	latarcyrheb-sun16	sr_RS.UTF-8@latin	sr-latin	Europe/Belgrade
-Sinhala	si	none	si_LK.UTF-8	us	Asia/Colombo
-Slovak	sk	latarcyrheb-sun16	sk_SK.UTF-8	sk-qwerty	Europe/Bratislava
-Slovenian	sl	latarcyrheb-sun16	sl_SI.UTF-8	slovene	Europe/Ljubljana
-Spanish	es	latarcyrheb-sun16	es_ES.UTF-8	es	Europe/Madrid
-Swedish	sv	latarcyrheb-sun16	sv_SE.UTF-8	sv-latin1	Europe/Stockholm
-Tajik	tg	none	tg_TG.UTF-8	tj	Asia/Dushanbe
-Tamil	ta	none	ta_IN.UTF-8	us	Asia/Kolkata
-Telugu	te	none	te_IN.UTF-8	us	Asia/Kolkata
-Turkish	tr	latarcyrheb-sun16	tr_TR.UTF-8	trq	Europe/Istanbul
-Ukrainian	uk	latarcyrheb-sun16	uk_UA.UTF-8	ua-utf	Europe/Kiev
-Vietnamese	vi	latarcyrheb-sun16	vi_VN.UTF-8	us	Asia/Saigon
-Welsh	cy	latarcyrheb-sun16	cy_GB.UTF-8	uk	Europe/London
-Zulu	zu	latarcyrheb-sun16	zu_ZA.UTF-8	us	Africa/Johannesburg
diff --git a/language.py b/language.py
deleted file mode 100644
index 4de330c..0000000
--- a/language.py
+++ /dev/null
@@ -1,280 +0,0 @@
-#
-# language.py: install data component that stores information about both
-#              installer runtime language choice and installed system
-#              language support.
-#
-# Copyright (C) 2001, 2002, 2003, 2004, 2005, 2009  Red Hat, Inc.
-# 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 as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# 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, see <http://www.gnu.org/licenses/>.
-#
-
-import os
-import string
-import locale
-
-import gettext
-from simpleconfig import SimpleConfigFile
-import system_config_keyboard.keyboard as keyboard
-
-import logging
-log = logging.getLogger("anaconda")
-
-# Converts a single language into a "language search path". For example,
-# fr_FR.utf8@euro would become "fr_FR.utf8@eueo fr_FR.utf8 fr_FR fr"
-def expandLangs(astring):
-    langs = [astring]
-    charset = None
-    base = None
-
-    # remove charset ...
-    if '.' in astring:
-        langs.append(string.split(astring, '.')[0])
-
-    if '@' in astring:
-        charset = string.split(astring, '@')[1]
-
-    if '_' in astring:
-        base = string.split(astring, '_')[0]
-
-        if charset:
-            langs.append("%s@%s" % (base, charset))
-
-        langs.append(base)
-    else:
-        langs.append(astring[:2])
-
-    return langs
-
-class Language(object):
-    def _setInstLang(self, value):
-        # Always store in its full form so we know what we're comparing with.
-        try:
-            self._instLang = self._canonLang(value)
-        except ValueError:
-            # If the language isn't listed in lang-table, we won't know what
-            # keyboard/font/etc. to use.  However, we can still set the $LANG
-            # to that and make sure it works in the installed system.
-            self._instLang = value
-
-        # If we're running in text mode, value may not be a supported language
-        # to display.  We need to default to en_US.UTF-8 for now.
-        if self.displayMode == 't':
-            for (lang, info) in self.localeInfo.iteritems():
-                # If there's no font, it's not a supported language.
-                if lang == self._instLang and info[2] == "none":
-                    self._instLang = self._default
-                    break
-
-        # Now set some things to make sure the language setting takes effect
-        # right now.
-        os.environ["LANG"] = self._instLang
-        os.environ["LC_NUMERIC"] = "C"
-
-        try:
-            locale.setlocale(locale.LC_ALL, "")
-        except locale.Error:
-            pass
-
-        # XXX: oh ick.  this is the sort of thing which you should never do...
-        # but we switch languages at runtime and thus need to invalidate
-        # the set of languages/mofiles which gettext knows about
-        gettext._translations = {}
-
-    def _getInstLang(self):
-        # If we were given a language that's not in lang-table, lie and say
-        # we're using the default.  This prevents us from having to check all
-        # over the place.  Unfortunately, it also means anaconda will be
-        # running with the wrong font and keyboard in these cases.
-        if self._instLang in self.localeInfo.keys():
-            return self._instLang
-        else:
-            return self._default
-
-    # The language being displayed while anaconda is running.
-    instLang = property(lambda s: s._getInstLang(), lambda s, v: s._setInstLang(v))
-
-    def _setSystemLang(self, value):
-        # Always store in its full form so we know what we're comparing with.
-        try:
-            self._systemLang = self._canonLang(value)
-        except ValueError:
-            # If the language isn't listed in lang-table, we won't know what
-            # keyboard/font/etc. to use.  However, we can still set the $LANG
-            # to that and make sure it works in the installed system.
-            self._systemLang = value
-
-        # Now set a bunch of other things that'll get written to
-        # /etc/sysconfig/i18n on the installed system.
-        self.info["LANG"] = self._systemLang
-
-        if not self.localeInfo.has_key(self._systemLang):
-            return
-
-        if self.localeInfo[self._systemLang][2] == "none":
-            self.info["SYSFONT"] = None
-        else:
-            self.info["SYSFONT"] = self.localeInfo[self._systemLang][2]
-
-        # XXX hack - because of exceptional cases on the var - zh_CN.GB2312
-        if self._systemLang == "zh_CN.GB18030":
-            self.info["LANGUAGE"] = "zh_CN.GB18030:zh_CN.GB2312:zh_CN"
-
-    # The language to use on the installed system.  This can differ from the
-    # language being used during anaconda.  For instance, text installs cannot
-    # display all languages (CJK, Indic, etc.).
-    systemLang = property(lambda s: s._systemLang, lambda s, v: s._setSystemLang(v))
-
-    def __init__ (self, display_mode = 'g'):
-        self._default = "en_US.UTF-8"
-        self.displayMode = display_mode
-        self.info = {}
-        self.localeInfo = {}
-        self.nativeLangNames = {}
-
-        # English name -> native name mapping
-        search = ('lang-names', '/usr/share/anaconda/lang-names')
-        for path in search:
-            if os.access(path, os.R_OK):
-                f = open(path, 'r')
-                for line in f.readlines():
-                    lang, native = string.split(line, '\t')
-                    native = native.strip()
-                    self.nativeLangNames[lang] = native
-
-                f.close()
-                break
-
-        # nick -> (name, short name, font, keyboard, timezone) mapping
-        search = ('lang-table', '/tmp/updates/lang-table', '/etc/lang-table',
-                  '/usr/share/anaconda/lang-table')
-        for path in search:
-            if os.access(path, os.R_OK):
-                f = open(path, "r")
-                for line in f.readlines():
-                    string.strip(line)
-                    l = string.split(line, '\t')
-
-                    # throw out invalid lines
-                    if len(l) < 6:
-                        continue
-
-                    self.localeInfo[l[3]] = (l[0], l[1], l[2], l[4], string.strip(l[5]))
-
-                f.close()
-                break
-
-        # Hard code this to prevent errors in the build environment.
-        self.localeInfo['C'] = self.localeInfo[self._default]
-
-        # instLang must be set after localeInfo is populated, in case the
-        # current setting is unsupported by anaconda..
-        self.instLang = os.environ.get("LANG", self._default)
-        self.systemLang = os.environ.get("LANG", self._default)
-
-    def _canonLang(self, lang):
-        """Convert the shortened form of a language name into the full
-           version.  If it's not found, raise ValueError.
-
-           Example:  fr    -> fr_FR.UTF-8
-                     fr_FR -> fr_FR.UTF-8
-                     fr_CA -> ValueError
-        """
-        for key in self.localeInfo.keys():
-            if lang in expandLangs(key):
-                return key
-
-        raise ValueError
-
-    def available(self):
-        return self.nativeLangNames.keys()
-
-    def dracutSetupString(self):
-        args=""
-
-        for (key, val) in self.info.iteritems():
-            if val != None:
-                args += " %s=%s" % (key, val)
-
-        return args
-
-    def getCurrentLangSearchList(self):
-        return expandLangs(self.systemLang) + ['C']
-
-    def getDefaultKeyboard(self, instPath):
-        try:
-            return self.localeInfo[self.systemLang][3]
-        except KeyError:
-            try:
-                kbd = keyboard.Keyboard()
-                kbd.read(instPath)
-                return kbd.get()
-            except:
-                return self.localeInfo[self._default][3]
-
-    def getDefaultTimeZone(self, instPath):
-        try:
-            return self.localeInfo[self.systemLang][4]
-        except KeyError:
-            # If doing an upgrade and the system language is something not
-            # recognized by anaconda, we should try to see if we can figure
-            # it out from the running system.
-            if os.path.exists(instPath + "/etc/sysconfig/clock"):
-                cfg = SimpleConfigFile()
-                cfg.read(instPath + "/etc/sysconfig/clock")
-
-                try:
-                    return cfg.get("ZONE")
-                except:
-                    return self.localeInfo[self._default][4]
-            else:
-                return self.localeInfo[self._default][4]
-
-    def getFontFile(self, lang):
-        # Note: in /etc/fonts.cgz fonts are named by the map
-        # name as that's unique, font names are not
-        try:
-            l = self._canonLang(lang)
-        except ValueError:
-            l = self._default
-
-        return self.localeInfo[l][2]
-
-    def getLangName(self, lang):
-        try:
-            l = self._canonLang(lang)
-        except ValueError:
-            l = self._default
-
-        return self.localeInfo[l][0]
-
-    def getLangByName(self, name):
-        for (key, val) in self.localeInfo.iteritems():
-            if val[0] == name:
-                return key
-
-    def getNativeLangName(self, lang):
-        return self.nativeLangNames[lang]
-
-    def write(self, instPath):
-        f = open(instPath + "/etc/sysconfig/i18n", "w")
-
-        for (key, val) in self.info.iteritems():
-            if val != None:
-                f.write("%s=\"%s\"\n" % (key, val))
-
-        f.close()
-
-    def writeKS(self, f):
-        f.write("lang %s\n" % self.info['LANG'])
diff --git a/livecd.py b/livecd.py
deleted file mode 100644
index 9df91b4..0000000
--- a/livecd.py
+++ /dev/null
@@ -1,469 +0,0 @@
-#
-# livecd.py: An anaconda backend to do an install from a live CD image
-#
-# The basic idea is that with a live CD, we already have an install
-# and should be able to just copy those bits over to the disk.  So we dd
-# the image, move things to the "right" filesystem as needed, and then
-# resize the rootfs to the size of its container.
-#
-# Copyright (C) 2007  Red Hat, Inc.  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 as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# 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, see <http://www.gnu.org/licenses/>.
-#
-# Author(s): Jeremy Katz <katzj@xxxxxxxxxx>
-#
-
-import os, sys
-import stat
-import shutil
-import time
-import subprocess
-import storage
-
-import selinux
-
-from flags import flags
-from constants import *
-
-import gettext
-_ = lambda x: gettext.ldgettext("anaconda", x)
-
-import backend
-import isys
-import iutil
-
-import packages
-
-import logging
-log = logging.getLogger("anaconda")
-
-class Error(EnvironmentError):
-    pass
-def copytree(src, dst, symlinks=False, preserveOwner=False,
-             preserveSelinux=False):
-    def tryChown(src, dest):
-        try:
-            os.chown(dest, os.stat(src)[stat.ST_UID], os.stat(src)[stat.ST_GID])
-        except OverflowError:
-            log.error("Could not set owner and group on file %s" % dest)
-
-    def trySetfilecon(src, dest):
-        try:
-            selinux.lsetfilecon(dest, selinux.lgetfilecon(src)[1])
-        except:
-            log.error("Could not set selinux context on file %s" % dest)
-
-    # copy of shutil.copytree which doesn't require dst to not exist
-    # and which also has options to preserve the owner and selinux contexts
-    names = os.listdir(src)
-    if not os.path.isdir(dst):
-        os.makedirs(dst)
-    errors = []
-    for name in names:
-        srcname = os.path.join(src, name)
-        dstname = os.path.join(dst, name)
-        try:
-            if symlinks and os.path.islink(srcname):
-                linkto = os.readlink(srcname)
-                os.symlink(linkto, dstname)
-                if preserveSelinux:
-                    trySetfilecon(srcname, dstname)
-            elif os.path.isdir(srcname):
-                copytree(srcname, dstname, symlinks, preserveOwner, preserveSelinux)
-            else:
-                shutil.copyfile(srcname, dstname)
-                if preserveOwner:
-                    tryChown(srcname, dstname)
-
-                if preserveSelinux:
-                    trySetfilecon(srcname, dstname)
-
-                shutil.copystat(srcname, dstname)
-        except (IOError, os.error), why:
-            errors.append((srcname, dstname, str(why)))
-        # catch the Error from the recursive copytree so that we can
-        # continue with other files
-        except Error, err:
-            errors.extend(err.args[0])
-    try:
-        if preserveOwner:
-            tryChown(src, dst)
-        if preserveSelinux:
-            trySetfilecon(src, dst)
-
-        shutil.copystat(src, dst)
-    except OSError as e:
-        errors.extend((src, dst, e.strerror))
-    if errors:
-        raise Error, errors
-
-class LiveCDCopyBackend(backend.AnacondaBackend):
-    def __init__(self, anaconda):
-        backend.AnacondaBackend.__init__(self, anaconda)
-        flags.livecdInstall = True
-        self.supportsUpgrades = False
-        self.supportsPackageSelection = False
-        self.skipFormatRoot = True
-
-        self.osimg = anaconda.methodstr[8:]
-        if not stat.S_ISBLK(os.stat(self.osimg)[stat.ST_MODE]):
-            anaconda.intf.messageWindow(_("Unable to find image"),
-                               _("The given location isn't a valid %s "
-                                 "live CD to use as an installation source.")
-                               %(productName,), type = "custom",
-                               custom_icon="error",
-                               custom_buttons=[_("Exit installer")])
-            sys.exit(0)
-        self.rootFsType = isys.readFSType(self.osimg)
-
-    def _getLiveBlockDevice(self):
-        return os.path.normpath(self.osimg)
-
-    def _getLiveSize(self):
-        def parseField(output, field):
-            for line in output.split("\n"):
-                if line.startswith(field + ":"):
-                    return line[len(field) + 1:].strip()
-            raise KeyError("Failed to find field '%s' in output" % field)
-
-        output = subprocess.Popen(['/sbin/dumpe2fs', '-h', self.osimg],
-                                  stdout=subprocess.PIPE,
-                                  stderr=open('/dev/null', 'w')
-                                  ).communicate()[0]
-        blkcnt = int(parseField(output, "Block count"))
-        blksize = int(parseField(output, "Block size"))
-        return blkcnt * blksize
-
-    def _getLiveSizeMB(self):
-        return self._getLiveSize() / 1048576
-
-    def _unmountNonFstabDirs(self, anaconda):
-        # unmount things that aren't listed in /etc/fstab.  *sigh*
-        dirs = []
-        if flags.selinux:
-            dirs.append("/selinux")
-        for dir in dirs:
-            try:
-                isys.umount("%s/%s" %(anaconda.rootPath,dir), removeDir = False)
-            except Exception, e:
-                log.error("unable to unmount %s: %s" %(dir, e))
-
-    def postAction(self, anaconda):
-        self._unmountNonFstabDirs(anaconda)
-        try:
-            anaconda.storage.umountFilesystems(swapoff = False)
-            os.rmdir(anaconda.rootPath)
-        except Exception, e:
-            log.error("Unable to unmount filesystems: %s" % e) 
-
-    def doPreInstall(self, anaconda):
-        if anaconda.dir == DISPATCH_BACK:
-            self._unmountNonFstabDirs(anaconda)
-            return
-        anaconda.storage.umountFilesystems(swapoff = False)
-
-    def doInstall(self, anaconda):
-        log.info("Preparing to install packages")
-
-        progress = anaconda.intf.instProgress
-        progress.set_label(_("Copying live image to hard drive."))
-        progress.processEvents()
-
-        osimg = self._getLiveBlockDevice() # the real image
-        osfd = os.open(osimg, os.O_RDONLY)
-
-        rootDevice = anaconda.storage.rootDevice
-        rootDevice.setup()
-        rootfd = os.open(rootDevice.path, os.O_WRONLY)
-
-        readamt = 1024 * 1024 * 8 # 8 megs at a time
-        size = self._getLiveSize()
-        copied = 0
-        while copied < size:
-            try:
-                buf = os.read(osfd, readamt)
-                written = os.write(rootfd, buf)
-            except:
-                rc = anaconda.intf.messageWindow(_("Error"),
-                        _("There was an error installing the live image to "
-                          "your hard drive.  This could be due to bad media.  "
-                          "Please verify your installation media.\n\nIf you "
-                          "exit, your system will be left in an inconsistent "
-                          "state that will require reinstallation."),
-                        type="custom", custom_icon="error",
-                        custom_buttons=[_("_Exit installer"), _("_Retry")])
-
-                if rc == 0:
-                    sys.exit(0)
-                else:
-                    os.lseek(osfd, 0, 0)
-                    os.lseek(rootfd, 0, 0)
-                    copied = 0
-                    continue
-
-            if (written < readamt) and (written < len(buf)):
-                raise RuntimeError, "error copying filesystem!"
-            copied += written
-            progress.set_fraction(pct = copied / float(size))
-            progress.processEvents()
-
-        os.close(osfd)
-        os.close(rootfd)
-
-        anaconda.intf.setInstallProgressClass(None)
-
-    def _doFilesystemMangling(self, anaconda):
-        log.info("doing post-install fs mangling")
-        wait = anaconda.intf.waitWindow(_("Post-Installation"),
-                                        _("Performing post-installation filesystem changes.  This may take several minutes."))
-
-        # resize rootfs first, since it is 100% full due to genMinInstDelta
-        self._resizeRootfs(anaconda, wait)
-
-        # remount filesystems
-        anaconda.storage.mountFilesystems()
-
-        # restore the label of / to what we think it is
-        rootDevice = anaconda.storage.rootDevice
-        rootDevice.setup()
-        # ensure we have a random UUID on the rootfs
-        # FIXME: this should be abstracted per filesystem type
-        iutil.execWithRedirect("tune2fs",
-                               ["-U",
-                                "random",
-                                rootDevice.path],
-                               stdout="/dev/tty5",
-                               stderr="/dev/tty5")
-        # and now set the uuid in the storage layer
-        rootDevice.updateSysfsPath()
-        iutil.notify_kernel("/sys%s" %rootDevice.sysfsPath)
-        storage.udev.udev_settle()
-        rootDevice.updateSysfsPath()
-        info = storage.udev.udev_get_block_device(rootDevice.sysfsPath)
-        rootDevice.format.uuid = storage.udev.udev_device_get_uuid(info)
-        log.info("reset the rootdev (%s) to have a uuid of %s" %(rootDevice.sysfsPath, rootDevice.format.uuid))
-
-        # for any filesystem that's _not_ on the root, we need to handle
-        # moving the bits from the livecd -> the real filesystems.
-        # this is pretty distasteful, but should work with things like
-        # having a separate /usr/local
-
-        def _setupFilesystems(mounts, chroot="", teardown=False):
-            """ Setup or teardown all filesystems except for "/" """
-            mountpoints = sorted(mounts.keys(),
-                                 reverse=teardown is True)
-            if teardown:
-                method = "teardown"
-                kwargs = {}
-            else:
-                method = "setup"
-                kwargs = {"chroot": chroot}
-
-            mountpoints.remove("/")
-            for mountpoint in mountpoints:
-                device = mounts[mountpoint]
-                getattr(device.format, method)(**kwargs)
-
-        # Start by sorting the mountpoints in decreasing-depth order.
-        mountpoints = sorted(anaconda.storage.mountpoints.keys(),
-                             reverse=True)
-        # We don't want to copy the root filesystem.
-        mountpoints.remove("/")
-        stats = {} # mountpoint: posix.stat_result
-
-        # unmount the filesystems, except for /
-        _setupFilesystems(anaconda.storage.mountpoints, teardown=True)
-
-        # mount all of the filesystems under /mnt so we can copy in content
-        _setupFilesystems(anaconda.storage.mountpoints,
-                          chroot=anaconda.rootPath + "/mnt")
-
-        # And now let's do the real copies
-        for tocopy in mountpoints:
-            device = anaconda.storage.mountpoints[tocopy]
-
-            # FIXME: all calls to wait.refresh() are kind of a hack... we
-            # should do better about not doing blocking things in the
-            # main thread.  but threading anaconda is a job for another
-            # time.
-            wait.refresh()
-
-            if not os.path.exists("%s/%s" % (anaconda.rootPath, tocopy)):
-                # the directory does not exist in the live image, so there's
-                # nothing to move
-                continue
-
-            copytree("%s/%s" % (anaconda.rootPath, tocopy),
-                     "%s/mnt/%s" % (anaconda.rootPath, tocopy),
-                     True, True, flags.selinux)
-            wait.refresh()
-            shutil.rmtree("%s/%s" % (anaconda.rootPath, tocopy))
-            wait.refresh()
-
-        # now unmount each fs, collect stat info for the mountpoint, then
-        # remove the entire tree containing the mountpoint
-        for tocopy in mountpoints:
-            device = anaconda.storage.mountpoints[tocopy]
-            device.format.teardown()
-            if not os.path.exists("%s/%s" % (anaconda.rootPath, tocopy)):
-                continue
-
-            try:
-                stats[tocopy]= os.stat("%s/mnt/%s" % (anaconda.rootPath,
-                                                      tocopy))
-            except Exception as e:
-                log.info("failed to get stat info for mountpoint %s: %s"
-                            % (tocopy, e))
-
-            shutil.rmtree("%s/mnt/%s" % (anaconda.rootPath,
-                                         tocopy.split("/")[1]))
-            wait.refresh()
-
-        # now mount all of the filesystems so that post-install writes end
-        # up where they're supposed to end up
-        _setupFilesystems(anaconda.storage.mountpoints,
-                          chroot=anaconda.rootPath)
-
-        # restore stat info for each mountpoint
-        for mountpoint in reversed(mountpoints):
-            if mountpoint not in stats:
-                # there's no info to restore since the mountpoint did not
-                # exist in the live image
-                continue
-
-            dest = "%s/%s" % (anaconda.rootPath, mountpoint)
-            st = stats[mountpoint]
-
-            # restore the correct stat info for this mountpoint
-            os.utime(dest, (st.st_atime, st.st_mtime))
-            os.chown(dest, st.st_uid, st.st_gid)
-            os.chmod(dest, stat.S_IMODE(st.st_mode))
-
-        # ensure that non-fstab filesystems are mounted in the chroot
-        if flags.selinux:
-            try:
-                isys.mount("/selinux", anaconda.rootPath + "/selinux", "selinuxfs")
-            except Exception, e:
-                log.error("error mounting selinuxfs: %s" %(e,))
-
-        wait.pop()
-
-    def _resizeRootfs(self, anaconda, win = None):
-        log.info("going to do resize")
-        rootDevice = anaconda.storage.rootDevice
-
-        # FIXME: we'd like to have progress here to give an idea of
-        # how long it will take.  or at least, to give an indefinite
-        # progress window.  but, not for this time
-        cmd = ["resize2fs", rootDevice.path, "-p"]
-        out = open("/dev/tty5", "w")
-        proc = subprocess.Popen(cmd, stdout=out, stderr=out)
-        rc = proc.poll()
-        while rc is None:
-            win and win.refresh()
-            time.sleep(0.5)
-            rc = proc.poll()
-
-        if rc:
-            log.error("error running resize2fs; leaving filesystem as is")
-            return
-
-        # we should also do a fsck afterwards
-        cmd = ["e2fsck", "-f", "-y", rootDevice.path]
-        out = open("/dev/tty5", "w")
-        proc = subprocess.Popen(cmd, stdout=out, stderr=out)
-        rc = proc.poll()
-        while rc is None:
-            win and win.refresh()
-            time.sleep(0.5)
-            rc = proc.poll()
-
-    def doPostInstall(self, anaconda):
-        import rpm
-
-        self._doFilesystemMangling(anaconda)
-
-        # setup /etc/rpm/ for the post-install environment
-        iutil.writeRpmPlatform(anaconda.rootPath)
-
-        storage.writeEscrowPackets(anaconda)
-
-        packages.rpmSetupGraphicalSystem(anaconda)
-
-        # now write out the "real" fstab and mtab
-        anaconda.storage.write(anaconda.rootPath)
-        f = open(anaconda.rootPath + "/etc/mtab", "w+")
-        f.write(anaconda.storage.mtab)
-        f.close()        
-        
-        # copy over the modprobe.conf
-        if os.path.exists("/etc/modprobe.conf"):
-            shutil.copyfile("/etc/modprobe.conf", 
-                            anaconda.rootPath + "/etc/modprobe.conf")
-        # set the same keyboard the user selected in the keyboard dialog:
-        anaconda.keyboard.write(anaconda.rootPath)
-
-        # rebuild the initrd(s)
-        vers = self.kernelVersionList(anaconda.rootPath)
-        for (n, arch, tag) in vers:
-            packages.recreateInitrd(n, anaconda.rootPath)
-
-    def writeConfiguration(self):
-        pass
-
-    def kernelVersionList(self, rootPath = "/"):
-        return packages.rpmKernelVersionList(rootPath)
-
-    def getMinimumSizeMB(self, part):
-        if part == "/":
-            return self._getLiveSizeMB()
-        return 0
-
-    def doBackendSetup(self, anaconda):
-        # ensure there's enough space on the rootfs
-        # FIXME: really, this should be in the general sanity checking, but
-        # trying to weave that in is a little tricky at present.
-        ossize = self._getLiveSizeMB()
-        slash = anaconda.storage.rootDevice
-        if slash.size < ossize:
-            rc = anaconda.intf.messageWindow(_("Error"),
-                                        _("The root filesystem you created is "
-                                          "not large enough for this live "
-                                          "image (%.2f MB required).") % ossize,
-                                        type = "custom",
-                                        custom_icon = "error",
-                                        custom_buttons=[_("_Back"),
-                                                        _("_Exit installer")])
-            if rc == 0:
-                return DISPATCH_BACK
-            else:
-                sys.exit(1)
-
-    # package/group selection doesn't apply for this backend
-    def groupExists(self, group):
-        pass
-    def selectGroup(self, group, *args):
-        pass
-    def deselectGroup(self, group, *args):
-        pass
-    def selectPackage(self, pkg, *args):
-        pass
-    def deselectPackage(self, pkg, *args):
-        pass
-    def packageExists(self, pkg):
-        return True
-    def getDefaultGroups(self, anaconda):
-        return []
-    def writePackagesKS(self, f, anaconda):
-        pass
diff --git a/liveinst/.gitignore b/liveinst/.gitignore
deleted file mode 100644
index 48d183f..0000000
--- a/liveinst/.gitignore
+++ /dev/null
@@ -1 +0,0 @@
-liveinst.desktop
diff --git a/liveinst/Makefile.am b/liveinst/Makefile.am
deleted file mode 100644
index 2f51dfa..0000000
--- a/liveinst/Makefile.am
+++ /dev/null
@@ -1,56 +0,0 @@
-# liveinst/Makefile.am for anaconda
-#
-# Copyright (C) 2009  Red Hat, Inc.
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU Lesser General Public License as published
-# by the Free Software Foundation; either version 2.1 of the License, or
-# (at your option) any later version.
-#
-# 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 Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public License
-# along with this program.  If not, see <http://www.gnu.org/licenses/>.
-#
-# Author: David Cantrell <dcantrell@xxxxxxxxxx>
-
-SUBDIRS = console.apps pam.d
-
-if IS_LIVEINST_ARCH
-dist_sbin_SCRIPTS  = liveinst
-
-desktopdir         = $(datadir)/applications
-desktop_DATA       = liveinst.desktop
-
-xinitdir           = /etc/X11/xinit/xinitrc.d
-dist_xinit_SCRIPTS = zz-liveinst.sh
-endif
-
-EXTRA_DIST = README liveinst.desktop.in
-
-CLEANFILES = liveinst.desktop *.h
-
-MAINTAINERCLEANFILES = Makefile.in
-
-intltool_merge_verbose = $(intltool_merge_verbose_$(V))
-intltool_merge_verbose_ = $(intltool_merge_verbose_$(AM_DEFAULT_VERBOSITY))
-intltool_merge_verbose_0 = @echo "  MERGE  "$@;
-
-liveinst.desktop: liveinst.desktop.in
-	$(intltool_merge_verbose)LC_ALL=C intltool-merge -q -d -u $(top_srcdir)/po liveinst.desktop.in liveinst.desktop
-
-install-exec-local:
-	mkdir -p $(DESTDIR)$(bindir)
-	ln -s consolehelper $(DESTDIR)$(bindir)/liveinst
-
-uninstall-local:
-	rm -f $(DESTDIR)$(bindir)/liveinst
-	for d in $(DESTDIR)$(bindir) ; do
-		while [ ! -z "$$d" ]; do \
-			rmdir $$d 2>/dev/null ; \
-			d="`dirname $$d`" ; \
-		done ; \
-	done
diff --git a/liveinst/README b/liveinst/README
deleted file mode 100644
index afa64e0..0000000
--- a/liveinst/README
+++ /dev/null
@@ -1 +0,0 @@
-Simple wrapper around anaconda to kick off an install from a live CD
diff --git a/liveinst/console.apps/Makefile.am b/liveinst/console.apps/Makefile.am
deleted file mode 100644
index f153902..0000000
--- a/liveinst/console.apps/Makefile.am
+++ /dev/null
@@ -1,26 +0,0 @@
-# liveinst/console.apps/Makefile.am for anaconda
-#
-# Copyright (C) 2009  Red Hat, Inc.
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU Lesser General Public License as published
-# by the Free Software Foundation; either version 2.1 of the License, or
-# (at your option) any later version.
-#
-# 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 Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public License
-# along with this program.  If not, see <http://www.gnu.org/licenses/>.
-#
-# Author: David Cantrell <dcantrell@xxxxxxxxxx>
-
-if IS_LIVEINST_ARCH
-consoledir        = /etc/security/console.apps
-dist_console_DATA = liveinst
-endif
-
-CLEANFILES = *.h
-MAINTAINERCLEANFILES = Makefile.in
diff --git a/liveinst/console.apps/liveinst b/liveinst/console.apps/liveinst
deleted file mode 100644
index 7c31081..0000000
--- a/liveinst/console.apps/liveinst
+++ /dev/null
@@ -1,6 +0,0 @@
-USER=root
-PROGRAM=/usr/sbin/liveinst
-SESSION=true
-# has to be here otherwise consolehelper switches off the waiting cursor too early
-STARTUP_NOTIFICATION_NAME="Starting Install to Hard Drive"
-DOMAIN=anaconda
\ No newline at end of file
diff --git a/liveinst/liveinst b/liveinst/liveinst
deleted file mode 100755
index 95bd35f..0000000
--- a/liveinst/liveinst
+++ /dev/null
@@ -1,95 +0,0 @@
-#!/bin/sh
-#
-# Simple script to kick off an install from a live CD
-#
-# Copyright (C) 2007  Red Hat, Inc.  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 as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# 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, see <http://www.gnu.org/licenses/>.
-#
-
-if [ -z "$LIVE_BLOCK" ]; then
-    if [ -b "/dev/mapper/live-osimg-min" ]; then
-       LIVE_BLOCK="/dev/mapper/live-osimg-min"
-    else
-       LIVE_BLOCK="/dev/live-osimg"
-    fi
-fi
-
-if [ ! -b $LIVE_BLOCK ]; then
-  zenity --error --title="Not a Live image" --text "Can't do live image installation unless running from a live image"
-  exit 1
-fi
-
-# load modules that would get loaded by the loader... (#230945)
-for i in raid0 raid1 raid5 raid6 raid456 raid10 dm-mod dm-zero dm-mirror dm-snapshot dm-multipath dm-round-robin vfat dm-crypt cbc sha256 lrw xts ; do /sbin/modprobe $i 2>/dev/null ; done
-
-export ANACONDA_PRODUCTNAME=$( cat /etc/system-release | sed -r -e 's/ *release.*//' )
-export ANACONDA_PRODUCTVERSION=$( cat /etc/system-release | sed -r -e 's/^.* ([0-9\.]+).*$/\1/' )
-export ANACONDA_BUGURL=${ANACONDA_BUGURL:="https://bugzilla.redhat.com/bugzilla/"}
-
-export PATH=/sbin:/usr/sbin:$PATH
-
-if [ -n "$DISPLAY" -a -n "$LANG" ]; then
-    INSTLANG="--lang $LANG"
-fi
-
-# eventually, we might want to allow a more "normal" install path
-ANACONDA="/usr/sbin/anaconda --liveinst --method=livecd://$LIVE_BLOCK $INSTLANG"
-
-if [ -x /usr/sbin/setenforce -a -e /selinux/enforce ]; then
-    current=$(cat /selinux/enforce)
-    /usr/sbin/setenforce 0
-fi
-
-if [ ! -e /selinux/load ]; then
-    ANACONDA="$ANACONDA --noselinux"
-fi
-
-# devkit-disks is now mounting lots of stuff.  for now, let's just try to unmount it all
-umount /media/*
-tac /proc/mounts | grep ^/dev | grep -v live | while read dev mntpoint rest; do
-    if [ -b $dev ]; then
-       umount $mntpoint 2>/dev/null
-    fi
-done
-
-/sbin/swapoff -a
-/sbin/lvm vgchange -an --ignorelockingfailure
-for i in /dev/md*; do
-    if [ ! -b $i ]; then
-        continue
-    fi
-
-    case "$i" in
-        /dev/md*p*)
-            ;;
-        *)
-            mdadm --stop $i >/dev/null 2>&1
-            ;;
-    esac
-done
-
-/sbin/udevadm control --env=ANACONDA=1
-
-if [ -x /usr/bin/devkit-disks ]; then
-    /usr/bin/devkit-disks --inhibit -- /usr/bin/hal-lock --interface org.freedesktop.Hal.Device.Storage --exclusive --run "$ANACONDA $*"
-elif [ -x /usr/bin/hal-lock -a -e /var/lock/subsys/haldaemon ]; then
-    /usr/bin/hal-lock --interface org.freedesktop.Hal.Device.Storage --exclusive --run "$ANACONDA $*"
-else
-    $ANACONDA $*
-fi
-
-if [ -n "$current" ]; then
-    /usr/sbin/setenforce $current
-fi
diff --git a/liveinst/liveinst.desktop.in b/liveinst/liveinst.desktop.in
deleted file mode 100644
index b0ef188..0000000
--- a/liveinst/liveinst.desktop.in
+++ /dev/null
@@ -1,12 +0,0 @@
-[Desktop Entry]
-_Name=Install to Hard Drive
-_GenericName=Install
-_Comment=Install the live CD to your hard disk
-Categories=System;Utility;X-Red-Hat-Base;X-Fedora;GNOME;GTK;
-Exec=/usr/bin/liveinst
-Terminal=false
-Type=Application
-Icon=anaconda
-Encoding=UTF-8
-StartupNotify=true
-NoDisplay=true
diff --git a/liveinst/pam.d/Makefile.am b/liveinst/pam.d/Makefile.am
deleted file mode 100644
index 9b2bf06..0000000
--- a/liveinst/pam.d/Makefile.am
+++ /dev/null
@@ -1,25 +0,0 @@
-# liveinst/pam.d/Makefile.am for anaconda
-#
-# Copyright (C) 2009  Red Hat, Inc.
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU Lesser General Public License as published
-# by the Free Software Foundation; either version 2.1 of the License, or
-# (at your option) any later version.
-#
-# 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 Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public License
-# along with this program.  If not, see <http://www.gnu.org/licenses/>.
-#
-# Author: David Cantrell <dcantrell@xxxxxxxxxx>
-
-if IS_LIVEINST_ARCH
-pamdir        = /etc/pam.d
-dist_pam_DATA = liveinst
-endif
-
-MAINTAINERCLEANFILES = Makefile.in
diff --git a/liveinst/pam.d/liveinst b/liveinst/pam.d/liveinst
deleted file mode 100644
index c7d67e3..0000000
--- a/liveinst/pam.d/liveinst
+++ /dev/null
@@ -1,4 +0,0 @@
-#%PAM-1.0
-auth		include		config-util
-account		include		config-util
-session		include		config-util
diff --git a/liveinst/zz-liveinst.sh b/liveinst/zz-liveinst.sh
deleted file mode 100755
index c141290..0000000
--- a/liveinst/zz-liveinst.sh
+++ /dev/null
@@ -1,14 +0,0 @@
-#!/bin/bash
-# Set up a launcher on the desktop for the live installer if we're on
-# a live CD
-
-# don't run on geode (olpc)
-if [ `grep -c Geode /proc/cpuinfo` -eq 0 ]; then
-  if [ -b /dev/mapper/live-osimg-min ]; then
-    test -f ${XDG_CONFIG_HOME:-~/.config}/user-dirs.dirs && source ${XDG_CONFIG_HOME:-~/.config}/user-dirs.dirs
-    cp /usr/share/applications/liveinst.desktop "${XDG_DESKTOP_DIR:-$HOME/Desktop}"
-  elif [ -f /.livecd-configured ]; then  # FIXME: old way... this should go away
-    test -f ${XDG_CONFIG_HOME:-~/.config}/user-dirs.dirs && source ${XDG_CONFIG_HOME:-~/.config}/user-dirs.dirs
-    cp /usr/share/applications/liveinst.desktop "${XDG_DESKTOP_DIR:-$HOME/Desktop}"
-  fi
-fi
diff --git a/loader/.gitignore b/loader/.gitignore
deleted file mode 100644
index 021a962..0000000
--- a/loader/.gitignore
+++ /dev/null
@@ -1,12 +0,0 @@
-ctype.c
-mkctype
-loader
-init
-debug.log
-loader.tr
-.depend
-font.bgf.gz
-loader.po
-shutdown
-checkisomd5
-tr
diff --git a/loader/Makefile.am b/loader/Makefile.am
deleted file mode 100644
index 18f1fbe..0000000
--- a/loader/Makefile.am
+++ /dev/null
@@ -1,118 +0,0 @@
-# loader/Makefile.am for anaconda
-#
-# Copyright (C) 2009  Red Hat, Inc.
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU Lesser General Public License as published
-# by the Free Software Foundation; either version 2.1 of the License, or
-# (at your option) any later version.
-#
-# 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 Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public License
-# along with this program.  If not, see <http://www.gnu.org/licenses/>.
-#
-# Author: David Cantrell <dcantrell@xxxxxxxxxx>
-
-bootdir            = $(libdir)/$(PACKAGE_NAME)
-shareddir          = $(datadir)/$(PACKAGE_NAME)
-
-boot_PROGRAMS      = loader
-shared_DATA        = loader.tr
-dist_shared_DATA   = unicode-linedraw-chars.txt
-noinst_PROGRAMS    = mkctype dirbrowser
-noinst_DATA        = ctype.c
-noinst_HEADERS     = *.h
-
-if IS_S390
-boot_PROGRAMS      += shutdown
-dist_shared_SCRIPTS  = linuxrc.s390
-else
-boot_PROGRAMS       += init
-endif
-
-if IS_KEYMAPS_OVERRIDE_ARCH
-keymapsdir         = $(datadir)/$(PACKAGE_NAME)
-keymaps_DATA       = keymaps-override-$(ARCH)
-endif
-
-COMMON_CFLAGS      = -DUSE_LOGDEV -DVERSION='"$(PACKAGE_VERSION)"'
-
-loader_CFLAGS      = $(COMMON_CFLAGS) $(GLIB_CFLAGS) $(LIBNM_GLIB_CFLAGS) \
-                     $(LIBCURL_CFLAGS) $(IPV6_CFLAGS) $(LIBARCHIVE_CFLAGS) \
-                     $(RPM_CFLAGS) -DINCLUDE_LOCAL -DINCLUDE_NETWORK
-loader_LDADD       = $(NEWT_LIBS) $(GLIB_LIBS) $(LIBNL_LIBS) \
-                     $(LIBNM_GLIB_LIBS) $(CHECKISOMD5_LIBS) \
-                     $(LIBCURL_LIBS) $(LIBARCHIVE_LIBS) $(RPM_LIBS) \
-                     $(ISCSI_LIBS) $(top_srcdir)/isys/libisys.la -lm
-loader_SOURCES     = loader.c copy.c moduleinfo.c loadermisc.c \
-                     modules.c windows.c lang.c kbd.c driverdisk.c \
-                     selinux.c mediacheck.c kickstart.c driverselect.c \
-                     getparts.c dirbrowser.c fwloader.c ibft.c hardware.c \
-                     method.c cdinstall.c hdinstall.c nfsinstall.c \
-                     urlinstall.c net.c urls.c telnet.c telnetd.c \
-                     rpmextract.c
-
-init_CFLAGS        = $(COMMON_CFLAGS) $(GLIB_CFLAGS)
-init_LDADD	   = $(GLIB_LIBS)
-init_SOURCES       = init.c undomounts.c shutdown.c copy.c
-
-shutdown_CFLAGS    = $(COMMON_CFLAGS) -DAS_SHUTDOWN=1
-shutdown_SOURCES   = shutdown.c undomounts.c
-
-mkctype_CFLAGS     = $(COMMON_CFLAGS)
-mkctype_SOURCES    = mkctype.c
-
-dirbrowser_CFLAGS  = $(COMMON_CFLAGS) -DSTANDALONE
-dirbrowser_LDADD   = $(NEWT_LIBS)
-dirbrowser_SOURCES = dirbrowser.c
-
-EXTRA_DIST = simplemot keymaps-*
-
-CLEANFILES = keymaps-override-$(ARCH) ctype.c tr/*.tr
-
-MAINTAINERCLEANFILES = Makefile.in
-
-sed_verbose = $(sed_verbose_$(V))
-sed_verbose_ = $(sed_verbose_$(AM_DEFAULT_VERBOSITY))
-sed_verbose_0 = @echo "  SED    "$@;
-
-cp_verbose = $(cp_verbose_$(V))
-cp_verbose_ = $(cp_verbose_$(AM_DEFAULT_VERBOSITY))
-cp_verbose_0 = @echo "  CP     "$@;
-
-mkctype_verbose = $(mkctype_verbose_$(V))
-mkctype_verbose_ = $(mkctype_verbose_$(AM_DEFAULT_VERBOSITY))
-mkctype_verbose_0 = @echo "  MAKE   "$@;
-
-msgmerge_verbose = $(msgmerge_verbose_$(V))
-msgmerge_verbose_ = $(msgmerge_verbose_$(AM_DEFAULT_VERBOSITY))
-msgmerge_verbose_0 = echo "  MERGE  "$${lang}.po;
-
-xgettext_verbose = $(xgettext_verbose_$(V))
-xgettext_verbose_ = $(xgettext_verbose_$(AM_DEFAULT_VERBOSITY))
-xgettext_verbose_0 = @echo "  GETTXT "$@;
-
-keymaps-override-$(ARCH): keymaps-$(ARCH)
-	$(cp_verbose)cp -p $< $@
-
-ctype.c: mkctype
-	$(mkctype_verbose)./mkctype > ctype.c
-
-loader.tr: $(top_srcdir)/lang-table loader.po
-	@LANGS="`cut -f 2 $(top_srcdir)/lang-table | egrep -v '(^en$$)'`" ; \
-	if [ ! -d tr ]; then \
-		mkdir -p tr ; \
-	fi ; \
-	for lang in $$LANGS ; do \
-		$(msgmerge_verbose)msgmerge -q $(top_srcdir)/po/$$lang.po loader.po | msgconv -t utf-8 | ./simplemot > tr/$$lang.tr ; \
-	done ; \
-	(cd tr ; ls -1 *.tr | cpio --quiet -Hcrc -o | gzip -9) > $@
-
-loader.po:
-	$(xgettext_verbose)xgettext --default-domain=loader --add-comments \
-		--keyword=_ --keyword=N_ *.c
-	$(sed_verbose)sed -i 's/charset=CHARSET/charset=UTF-8/' $@
diff --git a/loader/cdinstall.c b/loader/cdinstall.c
deleted file mode 100644
index 9d5cee1..0000000
--- a/loader/cdinstall.c
+++ /dev/null
@@ -1,509 +0,0 @@
-/*
- * cdinstall.c - code to set up cdrom installs
- *
- * Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003  Red Hat, Inc.
- * 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 as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * 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, see <http://www.gnu.org/licenses/>.
- *
- * Author(s): Erik Troan <ewt@xxxxxxxxxx>
- *            Matt Wilson <msw@xxxxxxxxxx>
- *            Michael Fulbright <msf@xxxxxxxxxx>
- *            Jeremy Katz <katzj@xxxxxxxxxx>
- */
-
-#include <ctype.h>
-#include <dirent.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <newt.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/mount.h>
-#include <sys/ioctl.h>
-#include <unistd.h>
-/* FIXME Remove hack when: https://bugzilla.redhat.com/show_bug.cgi?id=478663
-   is resolved */
-/* Hack both __BIG_ENDIAN and __LITTLE_ENDIAN get defined by glibc, the
-   kernel headers we need do not like this! */
-#if __BYTE_ORDER == __LITTLE_ENDIAN
-#undef __BIG_ENDIAN 
-#else
-#undef __LITTLE_ENDIAN
-#endif
-#include <asm/types.h>
-#include <limits.h>
-#include <linux/cdrom.h>
-
-#include "kickstart.h"
-#include "loader.h"
-#include "loadermisc.h"
-#include "lang.h"
-#include "modules.h"
-#include "method.h"
-#include "cdinstall.h"
-#include "mediacheck.h"
-#include "windows.h"
-
-#include "../isys/imount.h"
-#include "../isys/isys.h"
-#include "../isys/log.h"
-
-/* boot flags */
-extern uint64_t flags;
-
-/* ejects the CD device the device node points at */
-static void ejectCdrom(char *device) {
-    int ejectfd;
-
-    if (!device) return;
-    logMessage(INFO, "ejecting %s...",device);
-    if ((ejectfd = open(device, O_RDONLY | O_NONBLOCK, 0)) >= 0) {
-        ioctl(ejectfd, CDROM_LOCKDOOR, 0);
-        if (ioctl(ejectfd, CDROMEJECT, 0))
-            logMessage(ERROR, "eject failed on device %s: %m", device);
-        close(ejectfd);
-    } else {
-        logMessage(ERROR, "could not open device %s: %m", device);
-    }
-}
-
-static char *cdrom_drive_status(int rc) {
-    struct {
-        int code;
-        char *str;
-    } status_codes[] =
-        {
-            { CDS_NO_INFO, "CDS_NO_INFO" },
-            { CDS_NO_DISC, "CDS_NO_DISC" },
-            { CDS_TRAY_OPEN, "CDS_TRAY_OPEN" },
-            { CDS_DRIVE_NOT_READY, "CDS_DRIVE_NOT_READY" },
-            { CDS_DISC_OK, "CDS_DISC_OK" },
-            { CDS_AUDIO, "CDS_AUDIO" },
-            { CDS_DATA_1, "CDS_DATA_1" },
-            { CDS_DATA_2, "CDS_DATA_2" },
-            { CDS_XA_2_1, "CDS_XA_2_1" },
-            { CDS_XA_2_2, "CDS_XA_2_2" },
-            { CDS_MIXED, "CDS_MIXED" },
-            { INT_MAX, NULL },
-        };
-    int i;
-
-    if (rc < 0)
-        return strerror(-rc);
-
-    for (i = 0; status_codes[i].code != INT_MAX; i++) {
-        if (status_codes[i].code == rc)
-            return status_codes[i].str;
-    }
-    return NULL;
-}
-
-static int waitForCdromTrayClose(int fd) {
-    int rc;
-    int prev = INT_MAX;
-
-    do {
-        char *status = NULL;
-        rc = ioctl(fd, CDROM_DRIVE_STATUS, CDSL_CURRENT);
-        if (rc < 0)
-            rc = -errno;
-
-        /* only bother to print the status if it changes */
-        if (prev == INT_MAX || prev != rc) {
-            status = cdrom_drive_status(rc);
-            if (status != NULL) {
-                logMessage(INFO, "drive status is %s", status);
-            } else {
-                logMessage(INFO, "drive status is unknown status code %d", rc);
-            }
-        }
-        prev = rc;
-        if (rc == CDS_DRIVE_NOT_READY)
-            usleep(100000);
-    } while (rc == CDS_DRIVE_NOT_READY);
-    return rc;
-}
-
-static void closeCdromTray(char *device) {
-    int fd;
-
-    if (!device || !*device)
-        return;
-
-    logMessage(INFO, "closing CD tray on %s .", device);
-    if ((fd = open(device, O_RDONLY | O_NONBLOCK, 0)) >= 0) {
-        if (ioctl(fd, CDROMCLOSETRAY, 0)) {
-            logMessage(ERROR, "closetray failed on device %s: %m", device);
-        } else {
-            waitForCdromTrayClose(fd);
-            ioctl(fd, CDROM_LOCKDOOR, 1);
-        }
-        close(fd);
-    } else {
-        logMessage(ERROR, "could not open device %s: %m", device);
-    }
-}
-
-/* Given cd device cddriver, this function will attempt to check its internal
- * checksum.
- */
-static void mediaCheckCdrom(char *cddriver) {
-    int rc;
-    int first;
-
-    first = 1;
-    do {
-        char *descr;
-        char *tstamp;
-        int ejectcd;
-
-        /* init every pass */
-        ejectcd = 0;
-        descr = NULL;
-
-        closeCdromTray(cddriver);
-
-        /* if first time through, see if they want to eject the CD      */
-        /* currently in the drive (most likely the CD they booted from) */
-        /* and test a different disk.  Otherwise just test the disk in  */
-        /* the drive since it was inserted in the previous pass through */
-        /* this loop, so they want it tested.                           */
-        if (first) {
-            first = 0;
-            rc = newtWinChoice(_("Media Check"), _("Test"), _("Eject Disc"),
-                               _("Choose \"%s\" to test the disc currently in "
-                                 "the drive, or \"%s\" to eject the disc and "
-                                 "insert another for testing."), _("Test"),
-                               _("Eject Disc"));
-
-            if (rc == 2)
-                ejectcd = 1;
-        }
-
-        if (!ejectcd) {
-            /* XXX MSFFIXME: should check return code for error */
-            readStampFileFromIso(cddriver, &tstamp, &descr);
-            doMediaCheck(cddriver, descr);
-
-            if (descr)
-                free(descr);
-        }
-
-        ejectCdrom(cddriver);
-
-        rc = newtWinChoice(_("Media Check"), _("Test"), _("Continue"),
-                       _("If you would like to test additional media, "
-                       "insert the next disc and press \"%s\". "
-                       "Testing each disc is not strictly required, however "
-                       "it is highly recommended.  Minimally, the discs should "
-                       "be tested prior to using them for the first time. "
-                       "After they have been successfully tested, it is not "
-                       "required to retest each disc prior to using it again."),
-                       _("Test"), _("Continue"));
-
-        if (rc == 2) {
-            closeCdromTray(cddriver);
-            return;
-        } else {
-            continue;
-        }
-    } while (1);
-}
-
-/* output an error message when CD in drive is not the correct one */
-/* Used by mountCdromStage2()                                      */
-static void wrongCDMessage(void) {
-    newtWinMessage(_("Error"), _("OK"),
-                   _("The %s disc was not found "
-                     "in any of your drives. Please insert "
-                     "the %s disc and press %s to retry."),
-                   getProductName(), getProductName(), _("OK"));
-}
-
-/* ask about doing media check */
-static void queryCDMediaCheck(char *dev, char *location) {
-    int rc;
-    char *stage2loc;
-
-    /* dont bother to test in automated installs */
-    if (FL_KICKSTART(flags) && !FL_MEDIACHECK(flags))
-        return;
-
-    /* see if we should check image(s) */
-    /* in rescue mode only test if they explicitly asked to */
-    if (!FL_RESCUE(flags) || FL_MEDIACHECK(flags)) {
-        startNewt();
-        rc = newtWinChoice(_("Disc Found"), _("OK"), _("Skip"),
-             _("To begin testing the media before installation press %s.\n\n"
-               "Choose %s to skip the media test and start the installation."),
-             _("OK"), _("Skip"));
-
-        if (rc != 2) {
-            /* We already mounted the CD earlier to verify there's at least a
-             * stage2 image.  Now we need to unmount to perform the check, then
-             * remount to pretend nothing ever happened.
-             */
-            umount(location);
-            mediaCheckCdrom(dev);
-
-            do {
-                if (doPwMount(dev, location, "iso9660", "ro", NULL)) {
-                    ejectCdrom(dev);
-                    wrongCDMessage();
-                    continue;
-                }
-
-                checked_asprintf(&stage2loc, "%s/images/install.img",
-                                 location);
-
-                if (access(stage2loc, R_OK)) {
-                    free(stage2loc);
-                    umount(location);
-                    ejectCdrom(dev);
-                    wrongCDMessage();
-                    continue;
-                }
-
-                free(stage2loc);
-                break;
-            } while (1);
-        }
-    }
-}
-
-/* Set up a CD/DVD drive to mount the stage2 image from.  If successful, the
- * stage2 image will be left mounted on /mnt/runtime.
- *
- * location:     Where to mount the media at (usually /mnt/stage2)
- * loaderData:   The usual, can be NULL if no info
- * interactive:  Whether or not to prompt about questions/errors
- * mediaCheck:   Do we run media check or not?
- */
-static char *setupCdrom(char *location, struct loaderData_s *loaderData,
-                        int interactive, int mediaCheck) {
-    int i, rc;
-    int stage2inram = 0;
-    char *retbuf = NULL, *stage2loc, *stage2img;
-    struct device ** devices;
-    char *cddev = NULL;
-
-    devices = getDevices(DEVICE_CDROM);
-    if (!devices) {
-        logMessage(ERROR, "got to setupCdrom without a CD device");
-        return NULL;
-    }
-
-    checked_asprintf(&stage2loc, "%s/images/install.img", location);
-
-    /* JKFIXME: ASSERT -- we have a cdrom device when we get here */
-    do {
-        for (i = 0; devices[i]; i++) {
-            char *tmp = NULL;
-            int fd;
-
-            if (!devices[i]->device)
-                continue;
-
-            if (strncmp("/dev/", devices[i]->device, 5)) {
-                checked_asprintf(&tmp, "/dev/%s", devices[i]->device);
-
-                free(devices[i]->device);
-                devices[i]->device = tmp;
-            }
-
-            logMessage(INFO, "trying to mount CD device %s on %s",
-                       devices[i]->device, location);
-
-            if (!FL_CMDLINE(flags))
-                winStatus(60, 3, _("Scanning"), _("Looking for installation images on CD device %s\n"), devices[i]->device);
-            else
-                printf(_("Looking for installation images on CD device %s"), devices[i]->device);
-
-            fd = open(devices[i]->device, O_RDONLY | O_NONBLOCK);
-            if (fd < 0) {
-                logMessage(ERROR, "Couldn't open %s: %m", devices[i]->device);
-                if (!FL_CMDLINE(flags))
-                    newtPopWindow();
-                continue;
-            }
-
-            rc = waitForCdromTrayClose(fd);
-            close(fd);
-            switch (rc) {
-                case CDS_NO_INFO:
-                    logMessage(ERROR, "Drive tray reports CDS_NO_INFO");
-                    break;
-                case CDS_NO_DISC:
-                    if (!FL_CMDLINE(flags))
-                            newtPopWindow();
-                    continue;
-                case CDS_TRAY_OPEN:
-                    logMessage(ERROR, "Drive tray reports open when it should be closed");
-                    break;
-                default:
-                    break;
-            }
-
-            if (!FL_CMDLINE(flags))
-                newtPopWindow();
-
-            if (!(rc=doPwMount(devices[i]->device, location, "iso9660", "ro", NULL))) {
-                cddev = devices[i]->device;
-                if (!access(stage2loc, R_OK)) {
-                    char *updpath;
-
-                    if (mediaCheck)
-                        queryCDMediaCheck(devices[i]->device, location);
-
-                    /* if in rescue mode lets copy stage 2 into RAM so we can */
-                    /* free up the CD drive and user can have it avaiable to  */
-                    /* aid system recovery.                                   */
-                    if (FL_RESCUE(flags) && !FL_TEXT(flags) &&
-                        totalMemory() > MIN_GUI_RAM ) {
-                        rc = copyFile(stage2loc, "/tmp/install.img");
-                        stage2img = strdup("/tmp/install.img");
-                        stage2inram = 1;
-                    } else {
-                        stage2img = strdup(stage2loc);
-                        stage2inram = 0;
-                    }
-
-                    rc = mountStage2(stage2img);
-                    free(stage2img);
-
-                    if (rc) {
-                        logMessage(INFO, "mounting stage2 failed");
-                        umount(location);
-                        continue;
-                    }
-
-                    checked_asprintf(&updpath, "%s/images/updates.img", location);
-
-                    logMessage(INFO, "Looking for updates in %s", updpath);
-                    copyUpdatesImg(updpath);
-                    free(updpath);
-
-                    checked_asprintf(&updpath, "%s/images/product.img", location);
-
-                    logMessage(INFO, "Looking for product in %s", updpath);
-                    copyProductImg(updpath);
-                    free(updpath);
-
-                    /* if in rescue mode and we copied stage2 to RAM */
-                    /* we can now unmount the CD                     */
-                    if (FL_RESCUE(flags) && stage2inram) {
-                        umount(location);
-                    }
-
-                    checked_asprintf(&retbuf, "cdrom://%s:%s",
-                                     devices[i]->device, location);
-                } else {
-                    /* this wasnt the CD we were looking for, clean up and */
-                    /* try the next CD drive                               */
-                    umount(location);
-                }
-            }
-        }
-
-        if (!retbuf) {
-            if (interactive) {
-                char * buf;
-
-                checked_asprintf(&buf, _("The %s disc was not found in any of your "
-                                         "CDROM drives. Please insert the %s disc "
-                                         "and press %s to retry."),
-                                 getProductName(), getProductName(), _("OK"));
-
-                ejectCdrom(cddev);
-                rc = newtWinChoice(_("Disc Not Found"),
-                                   _("OK"), _("Back"), buf, _("OK"));
-                free(buf);
-                if (rc == 2)
-                    goto err;
-            } else {
-                /* we can't ask them about it, so just return not found */
-                goto err;
-            }
-        }
-    } while (!retbuf);
-
-err:
-    free(stage2loc);
-    return retbuf;
-}
-
-/* try to find a install CD non-interactively */
-char * findAnacondaCD(char *location) {
-    return setupCdrom(location, NULL, 0, 1);
-}
-
-/* look for a CD and mount it.  if we have problems, ask */
-char * mountCdromImage(struct installMethod * method,
-                       char * location, struct loaderData_s * loaderData) {
-    return setupCdrom(location, loaderData, 1, 1);
-}
-
-void setKickstartCD(struct loaderData_s * loaderData, int argc, char ** argv) {
-
-    logMessage(INFO, "kickstartFromCD");
-    loaderData->method = METHOD_CDROM;
-}
-
-int kickstartFromCD(char *kssrc) {
-    int rc, i;
-    char *p, *kspath;
-    struct device ** devices;
-
-    logMessage(INFO, "getting kickstart file from first CDROM");
-
-    devices = getDevices(DEVICE_CDROM);
-    /* usb can take some time to settle, even with the various hacks we
-     * have in place.  some systems use portable USB CD-ROM drives, try to
-     * make sure there really isn't one before bailing */
-    for (i = 0; !devices && i < 10; ++i) {
-        logMessage(INFO, "sleeping to wait for a USB CD-ROM");
-        sleep(2);
-        devices = getDevices(DEVICE_CDROM);
-    }
-    if (!devices) {
-        logMessage(ERROR, "No CDROM devices found!");
-        return 1;
-    }
-
-    /* format is cdrom:[/path/to/ks.cfg] */
-    kspath = "";
-    p = strchr(kssrc, ':');
-    if (p)
-        kspath = p + 1;
-
-    if (!p || strlen(kspath) < 1)
-        kspath = "/ks.cfg";
-
-    for (i=0; devices[i]; i++) {
-        if (!devices[i]->device)
-            continue;
-
-        rc = getKickstartFromBlockDevice(devices[i]->device, kspath);
-        if (rc == 0)
-            return 0;
-    }
-
-    startNewt();
-    newtWinMessage(_("Error"), _("OK"),
-                   _("Cannot find kickstart file on CDROM."));
-    return 1;
-}
-
-/* vim:set shiftwidth=4 softtabstop=4 et */
diff --git a/loader/cdinstall.h b/loader/cdinstall.h
deleted file mode 100644
index a0ecbc3..0000000
--- a/loader/cdinstall.h
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * cdinstall.h
- *
- * Copyright (C) 2007  Red Hat, Inc.  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 as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * 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, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef H_CDINSTALL
-#define H_CDINSTALL
-
-#include "method.h"
-
-char * mountCdromImage(struct installMethod * method,
-                       char * location, struct loaderData_s * loaderData);
-
-char * findAnacondaCD(char * location);
-
-void setKickstartCD(struct loaderData_s * loaderData, int argc,
-		    char ** argv);
-
-int kickstartFromCD(char *kssrc);
-#endif
diff --git a/loader/copy.c b/loader/copy.c
deleted file mode 100644
index 1c61233..0000000
--- a/loader/copy.c
+++ /dev/null
@@ -1,141 +0,0 @@
-/*
- * copy.c - functions for copying files and directories
- *
- * Copyright (C) 2007  Red Hat, Inc.  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 as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * 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, see <http://www.gnu.org/licenses/>.
- */
-
-#include <dirent.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-#include <stdio.h>
-#include <string.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-
-#include "lang.h"
-
-/* Recursive */
-int copyDirectory(char * from, char * to, void (*warnFn)(char *),
-                  void (*errorFn)(char *)) {
-    char *msg;
-    DIR * dir;
-    struct dirent * ent;
-    int fd, outfd;
-    char buf[4096];
-    int i;
-    struct stat sb;
-    char filespec[256];
-    char filespec2[256];
-    char link[1024];
-
-    mkdir(to, 0755);
-
-    if (!(dir = opendir(from))) {
-        if (errorFn) {
-           if (asprintf(&msg, N_("Failed to read directory %s: %m"), from) == -1) {
-               fprintf(stderr, "%s: %d: %m\n", __func__, __LINE__);
-               fflush(stderr);
-               abort();
-           }
-
-           errorFn(msg);
-           free(msg);
-        }
-
-        return 1;
-    }
-
-    errno = 0;
-    while ((ent = readdir(dir))) {
-        if (!strcmp(ent->d_name, ".") || !strcmp(ent->d_name, ".."))
-           continue;
-
-        sprintf(filespec, "%s/%s", from, ent->d_name);
-        sprintf(filespec2, "%s/%s", to, ent->d_name);
-
-        lstat(filespec, &sb);
-
-        if (S_ISDIR(sb.st_mode)) {
-            if (copyDirectory(filespec, filespec2, warnFn, errorFn)) {
-                closedir(dir);
-                return 1;
-            }
-        } else if (S_ISLNK(sb.st_mode)) {
-            i = readlink(filespec, link, sizeof(link) - 1);
-            link[i] = '\0';
-            if (symlink(link, filespec2)) {
-                if (warnFn) {
-                    if (asprintf(&msg, "Failed to symlink %s to %s: %m",
-                                 filespec2, link) == -1) {
-                        fprintf(stderr, "%s: %d: %m\n", __func__, __LINE__);
-                        fflush(stderr);
-                        abort();
-                    }
-
-                    warnFn(msg);
-                    free(msg);
-                }
-            }
-        } else {
-            fd = open(filespec, O_RDONLY);
-            if (fd == -1) {
-                if (errorFn) {
-                    if (asprintf(&msg, "Failed to open %s: %m", filespec) == -1) {
-                        fprintf(stderr, "%s: %d: %m\n", __func__, __LINE__);
-                        fflush(stderr);
-                        abort();
-                    }
-
-                    errorFn(msg);
-                    free(msg);
-                }
-
-                closedir(dir);
-                return 1;
-            } 
-            outfd = open(filespec2, O_RDWR | O_TRUNC | O_CREAT, 0644);
-            if (outfd == -1) {
-                if (warnFn) {
-                    if (asprintf(&msg, "Failed to create %s: %m", filespec2) == -1) {
-                        fprintf(stderr, "%s: %d: %m\n", __func__, __LINE__);
-                        fflush(stderr);
-                        abort();
-                    }
-
-                    warnFn(msg);
-                    free(msg);
-                }
-            } else {
-                fchmod(outfd, sb.st_mode & 07777);
-
-                while ((i = read(fd, buf, sizeof(buf))) > 0)
-                    i = write(outfd, buf, i);
-                close(outfd);
-            }
-
-            close(fd);
-        }
-
-        errno = 0;
-    }
-
-    closedir(dir);
-
-    return 0;
-}
diff --git a/loader/copy.h b/loader/copy.h
deleted file mode 100644
index 1153bf8..0000000
--- a/loader/copy.h
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * copy.h
- *
- * Copyright (C) 2007  Red Hat, Inc.  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 as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * 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, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef H_COPY
-#define H_COPY
-
-int copyDirectory (char *from, char *to, void (*warnFn)(char *),
-                   void (*errorFn)(char *));
-
-#endif
diff --git a/loader/devices.h b/loader/devices.h
deleted file mode 100644
index 974e792..0000000
--- a/loader/devices.h
+++ /dev/null
@@ -1,103 +0,0 @@
-/*
- * devices.h: handle declaration of devices to be created under /dev
- *
- * Copyright (C) 2004  Red Hat, Inc.  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 as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * 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, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef LOADER_INIT_DEVICES_H
-#define LOADER_INIT_DEVICES_H
-
-struct devnode {
-    char * devname;
-    int type;
-    int major;
-    int minor;
-    int perms;
-    char * owner;
-    char * group;
-};
-
-#define CHARDEV 0
-#define BLOCKDEV 1
-#define DIRTYPE 2
-
-struct devnode devnodes[] = {
-    /* consoles */
-    {"console", CHARDEV, 5, 1, 0600, "root", "root"},
-    {"ttyS0", CHARDEV, 4, 64, 0600, "root", "root"},
-    {"ttyS1", CHARDEV, 4, 65, 0600, "root", "root"},
-    {"ttyS2", CHARDEV, 4, 66, 0600, "root", "root"},
-    {"ttyS3", CHARDEV, 4, 67, 0600, "root", "root"},
-#ifdef __ia64__
-    {"ttySG0", CHARDEV, 204, 40, 0600, "root", "root"},
-#endif
-#ifdef __powerpc__
-    {"hvsi0", CHARDEV, 229, 128, 0600, "root", "root"},
-    {"hvsi1", CHARDEV, 229, 129, 0600, "root", "root"},
-    {"hvsi2", CHARDEV, 229, 130, 0600, "root", "root"},
-#endif
-    {"hvc0", CHARDEV, 229, 0, 0600, "root", "root"},
-#if defined(__i386__) || defined(__x86_64__) || defined(__ia64__)
-    {"xvc0", CHARDEV, 204, 191, 0600, "root", "root"},
-#endif
-    /* base unix */
-    {"null", CHARDEV, 1, 3, 0666, "root", "root"},
-    {"zero", CHARDEV, 1, 5, 0666, "root", "root"},
-    {"mem", CHARDEV, 1, 1, 0600, "root", "root"},
-    /* ttys */
-    {"pts", DIRTYPE, 0, 0, 0755, "root", "root"},
-    {"ptmx", CHARDEV, 5, 2, 0666, "root", "root"},
-    {"tty", CHARDEV, 5, 0, 0666, "root", "root"},
-    {"tty0", CHARDEV, 4, 0, 0600, "root", "tty"},
-    {"tty1", CHARDEV, 4, 1, 0600, "root", "tty"},
-    {"tty2", CHARDEV, 4, 2, 0600, "root", "tty"},
-    {"tty3", CHARDEV, 4, 3, 0600, "root", "tty"},
-    {"tty4", CHARDEV, 4, 4, 0600, "root", "tty"},
-    {"tty5", CHARDEV, 4, 5, 0600, "root", "tty"},
-    {"tty6", CHARDEV, 4, 6, 0600, "root", "tty"},
-    {"tty7", CHARDEV, 4, 7, 0600, "root", "tty"},
-    {"tty8", CHARDEV, 4, 8, 0600, "root", "tty"},
-    {"tty9", CHARDEV, 4, 9, 0600, "root", "tty"},
-    /* fb */
-    {"fb0", CHARDEV, 29, 0, 0600, "root", "tty"},
-    /* sparc specific */
-#ifdef __sparc__
-    {"openprom", CHARDEV, 10, 139, 0644, "root", "root"},
-    {"sunmouse", CHARDEV, 10, 6, 0644, "root", "root"},
-    {"kbd", CHARDEV, 11, 0, 0644, "root", "root"},
-#endif
-    /* X */
-    {"agpgart", CHARDEV, 10, 175, 0664, "root", "root"},
-    {"psaux", CHARDEV, 10, 1, 0644, "root", "root"},
-    {"input", DIRTYPE, 0, 0, 0755, "root", "root"},
-    {"input/mice", CHARDEV, 13, 63, 0664, "root", "root"},
-    /* floppies */
-    {"fd0", BLOCKDEV, 2, 0, 0644, "root", "root"},
-    {"fd1", BLOCKDEV, 2, 1, 0644, "root", "root"},
-    /* random */
-    {"random", CHARDEV, 1, 8, 0644, "root", "root"},
-    {"urandom", CHARDEV, 1, 9, 0644, "root", "root"},
-    /* mac stuff */
-#ifdef __powerpc__
-    {"nvram", CHARDEV, 10, 144, 0644, "root", "root"},
-    {"adb", CHARDEV, 56, 0, 0644, "root", "root"},
-    {"iseries", DIRTYPE, 0, 0, 0755, "root", "root" },
-#endif
-    {"rtc", CHARDEV, 10, 135, 0644, "root", "root"},
-    { NULL, 0, 0, 0, 0, NULL, NULL },
-};
-
-#endif
diff --git a/loader/devt.h b/loader/devt.h
deleted file mode 100644
index 364a134..0000000
--- a/loader/devt.h
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * devt.h: handle declaration of dev_t to be sane for loopback purposes
- *
- * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003  Red Hat, Inc.
- * 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 as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * 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, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef DEVT_H
-#define DEVT_H
-
-/* Need to tell loop.h what the actual dev_t type is. */
-#undef dev_t
-#if defined(__alpha) || (defined(__sparc__) && defined(__arch64__))
-#define dev_t unsigned int
-#else
-#if defined(__x86_64__)
-#define dev_t unsigned long
-#else
-#define dev_t unsigned short
-#endif
-#endif
-#include <linux/loop.h>
-#undef dev_t
-#define dev_t dev_t
-
-#endif
diff --git a/loader/dirbrowser.c b/loader/dirbrowser.c
deleted file mode 100644
index 9199850..0000000
--- a/loader/dirbrowser.c
+++ /dev/null
@@ -1,199 +0,0 @@
-/*
- * dirbrowser.c - newt-based directory browser to get a file name
- *
- * Copyright (C) 2004  Red Hat, Inc.  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 as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * 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, see <http://www.gnu.org/licenses/>.
- *
- * Author(s): Jeremy Katz <katzj@xxxxxxxxxx>
- */
-
-#include <newt.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <sys/types.h>
-#include <dirent.h>
-#include <errno.h>
-#include <string.h>
-#include <sys/stat.h>
-
-#ifndef STANDALONE
-#include "../isys/log.h"
-
-#include "loader.h"
-#include "loadermisc.h"
-#include "lang.h"
-#endif
-
-#ifdef STANDALONE
-#define _(x) x
-
-static int simpleStringCmp(const void * a, const void * b) {
-    const char * first = *((const char **) a);
-    const char * second = *((const char **) b);
-
-    return strcmp(first, second);
-}
-#endif
-
-#define FSTEP 10
-
-static char ** get_file_list(char * dirname, 
-                             int (*filterfunc)(char *, struct dirent *)) {
-    DIR * dir;
-    struct dirent *entry;
-    char ** files;
-    int numfiles = FSTEP, i = 0;
-
-    dir = opendir(dirname);
-    if (dir == NULL) {
-        fprintf(stderr, "error opening %s: %m", dirname);
-        return NULL;
-    }
-
-    files = malloc(numfiles * sizeof(char *));
-
-    while ((entry = readdir(dir))) {
-        if ((strlen(entry->d_name) == 1) && !strncmp(entry->d_name, ".", 1))
-            continue;
-        if ((strlen(entry->d_name) == 2) && !strncmp(entry->d_name, "..", 2))
-            continue;
-        if (filterfunc && filterfunc(dirname, entry))
-            continue;
-
-        files[i] = strdup(entry->d_name);
-        if (i++ >= (numfiles - 1)) {
-            numfiles += FSTEP;
-            files = realloc(files, numfiles * sizeof(char *));
-        }
-    }
-    files[i] = NULL;
-    closedir(dir);
-
-    qsort(files, i, sizeof(*files), simpleStringCmp);
-    return files;
-}
-
-/* Browse through a directory structure looking for a file.
- * Returns the full path to the file.
- *
- * Parameters:
- * title: Title for newt dialog window
- * dirname: Directory to use for root of browsing.  NOTE: you cannot go
- *          up above this root.
- * filterfunc: An (optional)  function to filter out files based on whatever 
- *             criteria you want.  Returns 1 if it passes, 0 if not.  
- *             Function should take arguments of the directory name and 
- *             the dirent for the file.
- */
-char * newt_select_file(char * title, char * text, char * dirname,
-                        int (*filterfunc)(char *, struct dirent *)) {
-    char ** files;
-    char * fn = NULL;
-    int i, done = 0;
-    char * topdir = dirname;
-    char * dir = malloc(PATH_MAX);
-    char * path = NULL;
-    newtGrid grid, buttons;
-    newtComponent f, tb, listbox, ok, cancel;
-    struct stat sb;
-    struct newtExitStruct es;
-
-    dir = realpath(dirname, dir);
-
-    do {
-        files = get_file_list(dir, filterfunc);
-
-        f = newtForm(NULL, NULL, 0);
-        grid = newtCreateGrid(1, 4);
-
-        tb = newtTextboxReflowed(-1, -1, text, 60, 0, 10, 0);
-
-        listbox = newtListbox(12, 65, 10, 
-                              NEWT_FLAG_SCROLL | NEWT_FLAG_RETURNEXIT);
-
-        newtListboxSetWidth(listbox, 55);
-        buttons = newtButtonBar(_("OK"), &ok, _("Cancel"), &cancel, NULL);
-        newtGridSetField(grid, 0, 0, NEWT_GRID_COMPONENT, tb,
-                         0, 0, 0, 1, 0, 0);
-        newtGridSetField(grid, 0, 1, NEWT_GRID_COMPONENT, listbox,
-                         0, 0, 0, 1, 0, 0);
-        newtGridSetField(grid, 0, 3, NEWT_GRID_SUBGRID, buttons,
-                         0, 0, 0, 0, 0, NEWT_GRID_FLAG_GROWX);
-        
-        /* if this isn't our topdir, we want to let them go up a dir */
-        if (strcmp(topdir, dir))
-            newtListboxAppendEntry(listbox, "../", "..");
-
-        for (i = 0; (files[i] != NULL); i++) {
-            if ((files[i] == NULL) || (strlen(files[i]) == 0)) continue;
-            path = malloc(strlen(files[i]) + strlen(dir) + 2);
-            sprintf(path, "%s/%s", dir, files[i]);
-            stat(path, &sb);
-            free(path);
-            if (S_ISDIR(sb.st_mode)) {
-                char *dir = malloc(strlen(files[i]) + 2);
-                sprintf(dir, "%s/", files[i]);
-                newtListboxAppendEntry(listbox, dir, files[i]);
-            } else {
-                newtListboxAppendEntry(listbox, files[i], files[i]);
-            }
-        }
-
-        newtGridWrappedWindow(grid, title);
-        newtGridAddComponentsToForm(grid, f, 1);
-        newtFormRun(f, &es);
-
-        if (es.reason  == NEWT_EXIT_COMPONENT && es.u.co == cancel) {
-            fn = NULL;
-            done = -1;
-        } else {
-            fn = (char *) newtListboxGetCurrent(listbox);
-            path = malloc(strlen(fn) + strlen(dir) + 2);
-            sprintf(path, "%s/%s", dir, fn);
-
-            stat(path, &sb);
-            if (!S_ISDIR(sb.st_mode)) {
-                fn = path;
-                done = 1;
-            } else { 
-                dir = realpath(path, dir);
-                free(path);
-            }
-        }
-
-        newtGridFree(grid, 1);
-        newtFormDestroy(f);
-        newtPopWindow();
-    } while (done == 0);
-
-    return fn;
-}
-
-#ifdef STANDALONE
-int main(int argc, char ** argv) {
-    char * foo;
-
-    newtInit();
-    newtCls();
-      
-    foo = newt_select_file("Get File Name", "foo, blah blah blah", 
-                           "/etc", NULL);
-    newtFinished();
-    printf("got %s\n", foo);
-    return 0;
-}
-#endif
diff --git a/loader/dirbrowser.h b/loader/dirbrowser.h
deleted file mode 100644
index 7fb22f2..0000000
--- a/loader/dirbrowser.h
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * dirbrowser.h
- *
- * Copyright (C) 2007  Red Hat, Inc.  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 as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * 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, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef DIRBROWSER_H
-#define DIRBROWSER_H
-
-#include <dirent.h>
-
-char * newt_select_file(char * title, char * text, char * dirname,
-                        int (*filterfunc)(char *, struct dirent *));
-
-#endif
diff --git a/loader/driverdisk.c b/loader/driverdisk.c
deleted file mode 100644
index 4f4446c..0000000
--- a/loader/driverdisk.c
+++ /dev/null
@@ -1,861 +0,0 @@
-/*
- * driverdisk.c - driver disk functionality
- *
- * Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007  Red Hat, Inc.
- * 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 as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * 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, see <http://www.gnu.org/licenses/>.
- *
- * Author(s): Jeremy Katz <katzj@xxxxxxxxxx>
- */
-
-#include <errno.h>
-#include <fcntl.h>
-#include <newt.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <sys/stat.h>
-#include <unistd.h>
-#include <glib.h>
-
-#include <blkid/blkid.h>
-
-#include <glob.h>
-#include <rpm/rpmlib.h>
-#include <sys/utsname.h>
-
-#include "copy.h"
-#include "loader.h"
-#include "loadermisc.h"
-#include "lang.h"
-#include "fwloader.h"
-#include "method.h"
-#include "modules.h"
-#include "moduleinfo.h"
-#include "windows.h"
-#include "hardware.h"
-#include "driverdisk.h"
-#include "getparts.h"
-#include "dirbrowser.h"
-
-#include "nfsinstall.h"
-#include "urlinstall.h"
-
-#include "rpmextract.h"
-
-#include "../isys/isys.h"
-#include "../isys/imount.h"
-#include "../isys/eddsupport.h"
-#include "../isys/log.h"
-
-/* boot flags */
-extern uint64_t flags;
-
-/*
- * check if the RPM in question provides
- * Provides: userptr
- * we use it to check kernel-modules-<kernelversion>
- */
-int dlabelProvides(const char* dep, void *userptr)
-{
-    char *kernelver = (char*)userptr;
-
-    logMessage(DEBUGLVL, "Provides: %s\n", dep);
-
-    return strcmp(dep, kernelver);
-}
-
-/*
- * during cpio extraction, only extract files we need
- * eg. module .ko files and firmware directory
- */
-int dlabelFilter(const char* name, const struct stat *fstat, void *userptr)
-{
-    int l = strlen(name);
-
-    logMessage(DEBUGLVL, "Unpacking %s\n", name);
-
-    /* we want firmware files */
-    if (!strncmp("lib/firmware/", name, 13)) return 0; 
-
-    if (l<3)
-        return 1;
-    l-=3;
-
-    /* and we want only .ko files */
-    if (strcmp(".ko", name+l))
-        return 1;
-
-    /* TODO we are unpacking kernel module, read it's description */
-
-    return 0;
-}
-
-char* moduleDescription(const char* modulePath)
-{
-    char *command = NULL;
-    FILE *f = NULL;
-    char *description = NULL;
-    int size;
-
-    checked_asprintf(&command, "modinfo --description '%s'", modulePath);
-    f = popen(command, "r");
-    free(command);
-
-    if (f==NULL)
-        return NULL;
-
-    description = malloc(sizeof(char)*256);
-    if (!description)
-        return NULL;
-
-    size = fread(description, 1, 255, f);
-    if (size == 0) {
-        free(description);
-        return NULL;
-    }
-
-    description[size-1]=0; /* strip the trailing newline */
-    pclose(f);
-
-    return description;
-}
-
-int globErrFunc(const char *epath, int eerrno)
-{
-    /* TODO check fatal errors */
-
-    return 0;
-}
-
-int dlabelUnpackRPMDir(char* rpmdir, char* destination)
-{
-    char *kernelver;
-    struct utsname unamedata;
-    char *oldcwd;
-    char *globpattern;
-    int rc;
-
-    /* get current working directory */ 
-    oldcwd = getcwd(NULL, 0);
-    if (!oldcwd) {
-        logMessage(ERROR, "getcwd() failed: %m");
-        return 1;
-    }
-
-    /* set the cwd to destination */
-    if (chdir(destination)) {
-        logMessage(ERROR, "We weren't able to CWD to \"%s\": %m", destination);
-        free(oldcwd);
-        return 1;
-    }
-
-    /* get running kernel version */
-    rc = uname(&unamedata);
-    checked_asprintf(&kernelver, "kernel-modules-%s",
-            rc ? "unknown" : unamedata.release);
-    logMessage(DEBUGLVL, "Kernel version: %s\n", kernelver);
-
-    checked_asprintf(&globpattern, "%s/*.rpm", rpmdir);
-    glob_t globres;
-    char** globitem;
-    if (!glob(globpattern, GLOB_NOSORT|GLOB_NOESCAPE, globErrFunc, &globres)) {
-        /* iterate over all rpm files */
-        globitem = globres.gl_pathv;
-        while (globres.gl_pathc>0 && globitem != NULL) {
-            explodeRPM(*globitem, dlabelFilter, dlabelProvides, NULL, kernelver);
-        }
-        globfree(&globres);
-        /* end of iteration */
-    }
-    free(globpattern);
-
-    /* restore CWD */
-    if (chdir(oldcwd)) {
-        logMessage(WARNING, "We weren't able to restore CWD to \"%s\": %m", oldcwd);
-    }
-
-    /* cleanup */
-    free(kernelver);
-    free(oldcwd);
-    return rc;
-}
-
-
-static char * driverDiskFiles[] = { "repodata", NULL };
-
-static int verifyDriverDisk(char *mntpt) {
-    char ** fnPtr;
-    char file[200];
-    struct stat sb;
-
-    /* check for dd descriptor */
-    sprintf(file, "%s/rhdd3", mntpt);
-    if (access(file, R_OK)) {
-        logMessage(ERROR, "can't find driver disk identifier, bad "
-                          "driver disk");
-        return LOADER_BACK;
-    }
-
-    /* side effect: file is still mntpt/ddident */
-    stat(file, &sb);
-    if (!sb.st_size)
-        return LOADER_BACK;
-
-    for (fnPtr = driverDiskFiles; *fnPtr; fnPtr++) {
-        snprintf(file, 200, "%s/rpms/%s/%s", mntpt, getProductArch(), *fnPtr);
-        if (access(file, R_OK)) {
-            logMessage(ERROR, "cannot find %s, bad driver disk", file);
-            return LOADER_BACK;
-        }
-    }
-
-    return LOADER_OK;
-}
-
-static void copyWarnFn (char *msg) {
-   logMessage(WARNING, msg);
-}
-
-static void copyErrorFn (char *msg) {
-   newtWinMessage(_("Error"), _("OK"), _(msg));
-}
-
-/* this copies the contents of the driver disk to a ramdisk and loads
- * the moduleinfo, etc.  assumes a "valid" driver disk mounted at mntpt */
-static int loadDriverDisk(struct loaderData_s *loaderData, char *mntpt) {
-    /* FIXME moduleInfoSet modInfo = loaderData->modInfo; */
-    char file[200], dest[200], src[200];
-    char *title;
-    char *fwdir = NULL;
-    struct moduleBallLocation * location;
-    struct stat sb;
-    static int disknum = 0;
-    int fd, ret;
-
-    /* check for new version */
-    sprintf(file, "%s/rhdd3", mntpt);
-    if (access(file, R_OK)) {
-      /* this can't happen, we already verified it! */
-      return LOADER_BACK;
-    }
-    stat(file, &sb);
-    title = malloc(sb.st_size + 1);
-
-    fd = open(file, O_RDONLY);
-    ret = read(fd, title, sb.st_size);
-    if (title[sb.st_size - 1] == '\n')
-        sb.st_size--;
-    title[sb.st_size] = '\0';
-    close(fd);
-
-    sprintf(file, DD_RPMDIR_TEMPLATE, disknum);
-    mkdirChain(file);
-    mkdirChain(DD_MODULES);
-    mkdirChain(DD_FIRMWARE);
-
-    if (!FL_CMDLINE(flags)) {
-        startNewt();
-        winStatus(40, 3, _("Loading"), _("Reading driver disk"));
-    }
-
-    location = malloc(sizeof(struct moduleBallLocation));
-    location->title = strdup(title);
-    checked_asprintf(&location->path, DD_MODULES);
-
-    sprintf(dest, DD_RPMDIR_TEMPLATE, disknum);
-    sprintf(src, "%s/rpms/%s", mntpt, getProductArch());
-    copyDirectory(src, dest, copyWarnFn, copyErrorFn);
-
-    /* unpack packages from dest into location->path */
-    if (dlabelUnpackRPMDir(dest, DD_EXTRACTED)) {
-        /* fatal error, log this and jump to exception handler */
-        logMessage(ERROR, "Error unpacking RPMs from driver disc no.%d",
-                disknum);
-        goto loadDriverDiscException;
-    }
-
-    /* run depmod to refresh modules db */
-    if (system("depmod -a")) {
-      /* this is not really fatal error, it might still work, log it */
-      logMessage(ERROR, "Error running depmod -a for driverdisc no.%d", disknum);
-    }
-
-    checked_asprintf(&fwdir, DD_FIRMWARE);
-    if (!access(fwdir, R_OK|X_OK)) {
-        add_fw_search_dir(loaderData, fwdir);
-        stop_fw_loader(loaderData);
-        start_fw_loader(loaderData);
-    }
-    free(fwdir);
-
-    /* TODO generate and read module info
-     *
-     * sprintf(file, "%s/modinfo", mntpt);
-     * readModuleInfo(file, modInfo, location, 1);
-     */
-
-loadDriverDiscException:
-
-    if (!FL_CMDLINE(flags))
-        newtPopWindow();
-
-    disknum++;
-    return 0;
-}
-
-/* Get the list of removable devices (floppy/cdrom) available.  Used to
- * find suitable devices for update disk / driver disk source.  
- * Returns the number of devices.  ***devNames will be a NULL-terminated list
- * of device names
- */
-int getRemovableDevices(char *** devNames) {
-    struct device **devs;
-    int numDevices = 0;
-    int i = 0;
-
-    devs = getDevices(DEVICE_DISK | DEVICE_CDROM);
-
-    if (!devs)
-        return numDevices;
-
-    for (i = 0; devs[i] ; i++) {
-        logMessage(DEBUGLVL, "Considering device %s (isremovable: %d)", devs[i]->device, devs[i]->priv.removable);
-        if (devs[i]->priv.removable) {
-            *devNames = realloc(*devNames, (numDevices + 2) * sizeof(char *));
-            (*devNames)[numDevices] = strdup(devs[i]->device);
-            (*devNames)[numDevices+1] = NULL;
-            numDevices ++;
-        }
-    }
-    if (!numDevices) {
-        logMessage(ERROR, "no devices found to load drivers from");
-    }
-    return numDevices;
-}
-
-/* Prompt for loading a driver from "media"
- *
- * class: type of driver to load.
- * usecancel: if 1, use cancel instead of back
- */
-int loadDriverFromMedia(int class, struct loaderData_s *loaderData,
-                        int usecancel, int noprobe, GTree *moduleState) {
-    char * device = NULL, * part = NULL, * ddfile = NULL;
-    char ** devNames = NULL;
-    enum { DEV_DEVICE, DEV_PART, DEV_CHOOSEFILE, DEV_LOADFILE, 
-           DEV_INSERT, DEV_LOAD, DEV_PROBE, 
-           DEV_DONE } stage = DEV_DEVICE;
-    int rc, num = 0;
-    int dir = 1;
-    int found = 0, before = 0;
-
-    while (stage != DEV_DONE) {
-        switch(stage) {
-        case DEV_DEVICE:
-            rc = getRemovableDevices(&devNames);
-            if (rc == 0)
-                return LOADER_BACK;
-
-            /* we don't need to ask which to use if they only have one */
-            if (rc == 1) {
-                device = strdup(devNames[0]);
-                free(devNames);
-                if (dir == -1)
-                    return LOADER_BACK;
-                
-                stage = DEV_PART;
-                break;
-            }
-            dir = 1;
-
-            startNewt();
-            rc = newtWinMenu(_("Driver Disk Source"),
-                             _("You have multiple devices which could serve "
-                               "as sources for a driver disk.  Which would "
-                               "you like to use?"), 40, 10, 10,
-                             rc < 6 ? rc : 6, devNames,
-                             &num, _("OK"), 
-                             (usecancel) ? _("Cancel") : _("Back"), NULL);
-
-            if (rc == 2) {
-                free(devNames);
-                return LOADER_BACK;
-            }
-            device = strdup(devNames[num]);
-            free(devNames);
-
-            stage = DEV_PART;
-        case DEV_PART: {
-            char ** part_list = getPartitionsList(device);
-            int nump = 0, num = 0;
-
-            if (part != NULL)
-                free(part);
-
-            if ((nump = lenPartitionsList(part_list)) == 0) {
-                if (dir == -1)
-                    stage = DEV_DEVICE;
-                else
-                    stage = DEV_INSERT;
-                break;
-            }
-            dir = 1;
-
-            startNewt();
-            rc = newtWinMenu(_("Driver Disk Source"),
-                             _("There are multiple partitions on this device "
-                               "which could contain the driver disk image.  "
-                               "Which would you like to use?"), 40, 10, 10,
-                             nump < 6 ? nump : 6, part_list, &num, _("OK"),
-                             _("Back"), NULL);
-
-            if (rc == 2) {
-                freePartitionsList(part_list);
-                stage = DEV_DEVICE;
-                dir = -1;
-                break;
-            }
-
-            part = strdup(part_list[num]);
-            stage = DEV_CHOOSEFILE;
-
-        }
-
-        case DEV_CHOOSEFILE: {
-            if (part == NULL) {
-                logMessage(ERROR, "somehow got to choosing file with a NULL part, going back");
-                stage = DEV_PART;
-                break;
-            }
-            /* make sure nothing is mounted when we get here */
-            num = umount("/tmp/dpart");
-            if (num == -1) { 
-                logMessage(ERROR, "error unmounting: %m");
-                if ((errno != EINVAL) && (errno != ENOENT))
-                    exit(1);
-            }
-
-            logMessage(INFO, "trying to mount %s as partition", part);
-            if (doPwMount(part, "/tmp/dpart", "auto", "ro", NULL)) {
-                newtWinMessage(_("Error"), _("OK"),
-                               _("Failed to mount partition."));
-                stage = DEV_PART;
-                break;
-            }
-
-            ddfile = newt_select_file(_("Select driver disk image"),
-                                      _("Select the file which is your driver "
-                                        "disk image."),
-                                      "/tmp/dpart", NULL);
-            if (ddfile == NULL) {
-                umount("/tmp/dpart");
-                stage = DEV_PART;
-                dir = -1;
-                break;
-            }
-            dir = 1;
-
-            stage = DEV_LOADFILE;
-        }
-
-        case DEV_LOADFILE: {
-            if (ddfile == NULL) {
-                logMessage(DEBUGLVL, "trying to load dd from NULL");
-                stage = DEV_CHOOSEFILE;
-                break;
-            }
-            if (dir == -1) {
-                umountLoopback("/tmp/drivers", "/dev/loop6");
-                unlink("/tmp/drivers");
-                ddfile = NULL;
-                stage = DEV_CHOOSEFILE;
-                break;
-            }
-            if (mountLoopback(ddfile, "/tmp/drivers", "/dev/loop6")) {
-                newtWinMessage(_("Error"), _("OK"),
-                               _("Failed to load driver disk from file."));
-                stage = DEV_CHOOSEFILE;
-                break;
-            }
-            stage = DEV_LOAD;
-            break;
-        }
-
-        case DEV_INSERT: {
-            char * buf;
-
-            checked_asprintf(&buf,
-                             _("Insert your driver disk into /dev/%s "
-                               "and press \"OK\" to continue."), device);
-
-            rc = newtWinChoice(_("Insert Driver Disk"), _("OK"), _("Back"),
-                               buf);
-            free(buf);
-            if (rc == 2) {
-                stage = DEV_DEVICE;
-                dir = -1;
-                break;
-            }
-            dir = 1;
-
-            logMessage(INFO, "trying to mount %s", device);
-            if (doPwMount(device, "/tmp/drivers", "auto", "ro", NULL)) {
-                newtWinMessage(_("Error"), _("OK"),
-                               _("Failed to mount driver disk."));
-                stage = DEV_INSERT;
-                break;
-            }
-
-            rc = verifyDriverDisk("/tmp/drivers");
-            if (rc == LOADER_BACK) {
-                newtWinMessage(_("Error"), _("OK"),
-                               _("Driver disk is invalid for this "
-                                 "release of %s."), getProductName());
-                umount("/tmp/drivers");
-                stage = DEV_INSERT;
-                break;
-            }
-
-            stage = DEV_LOAD;
-            break;
-        }
-        case DEV_LOAD: {
-            struct device ** devices;
-
-	    before = 0;
-	    found = 0;
-
-            devices = getDevices(class);
-            if (devices)
-                for(; devices[before]; before++);
-
-            rc = loadDriverDisk(loaderData, "/tmp/drivers");
-            umount("/tmp/drivers");
-            if (rc == LOADER_BACK) {
-                dir = -1;
-                if (ddfile != NULL)
-                    stage = DEV_CHOOSEFILE;
-                else
-                    stage = DEV_INSERT;
-                break;
-            }
-            /* fall through to probing */
-            stage = DEV_PROBE;
-
-            if (ddfile != NULL) {
-                umountLoopback("/tmp/drivers", "/dev/loop6");
-                unlink("/tmp/drivers");
-                umount("/tmp/dpart");
-            }
-        }
-
-        case DEV_PROBE: {
-            struct device ** devices;
-
-            /* if they didn't specify that we should probe, then we should
-             * just fall out */
-            if (noprobe) {
-                stage = DEV_DONE;
-                break;
-            }
-
-            /* Unload all devices and load them again to use the updated modules */
-            logMessage(INFO, "Trying to refresh loaded drivers");
-            mlRestoreModuleState(moduleState);
-            busProbe(0);
-
-            devices = getDevices(class);
-            if (devices)
-                for(; devices[found]; found++);
-
-            if (found > before) {
-                stage = DEV_DONE;
-                break;
-            }
-
-            /* we don't have any more modules of the proper class.  ask
-             * them to manually load */
-            rc = newtWinTernary(_("Error"), _("Manually choose"), 
-                                _("Continue"), _("Load another disk"),
-                                _("No devices of the appropriate type were "
-                                  "found on this driver disk.  Would you "
-                                  "like to manually select the driver, "
-                                  "continue anyway, or load another "
-                                  "driver disk?"));
-
-            if (rc == 2) {
-                /* if they choose to continue, just go ahead and continue */
-                stage = DEV_DONE;
-            } else if (rc == 3) {
-                /* if they choose to load another disk, back to the 
-                 * beginning with them */
-                stage = DEV_DEVICE;
-            } else {
-                rc = chooseManualDriver(class, loaderData);
-                /* if they go back from a manual driver, we'll ask again.
-                 * if they load something, assume it's what we need */
-                if (rc == LOADER_OK) {
-                    stage = DEV_DONE;
-                }
-            }
-
-            break;
-        }
-
-        case DEV_DONE:
-            break;
-        }
-    }
-
-    return LOADER_OK;
-}
-
-
-/* looping way to load driver disks */
-int loadDriverDisks(int class, struct loaderData_s *loaderData, GTree *moduleState) {
-    int rc;
-
-    rc = newtWinChoice(_("Driver disk"), _("Yes"), _("No"), 
-                       _("Do you have a driver disk?"));
-    if (rc != 1)
-        return LOADER_OK;
-
-    rc = loadDriverFromMedia(DEVICE_ANY, loaderData, 1, 0, moduleState);
-    if (rc == LOADER_BACK)
-        return LOADER_OK;
-
-    do {
-        rc = newtWinChoice(_("More Driver Disks?"), _("Yes"), _("No"),
-                           _("Do you wish to load any more driver disks?"));
-        if (rc != 1)
-            break;
-        loadDriverFromMedia(DEVICE_ANY, loaderData, 0, 0, moduleState);
-    } while (1);
-
-    return LOADER_OK;
-}
-
-static void loadFromLocation(struct loaderData_s * loaderData, char * dir, GTree *moduleState) {
-    if (verifyDriverDisk(dir) == LOADER_BACK) {
-        logMessage(ERROR, "not a valid driver disk");
-        return;
-    }
-
-    loadDriverDisk(loaderData, dir);
-
-    /* Unload all devices and load them again to use the updated modules */
-    logMessage(INFO, "Trying to refresh loaded drivers");
-    mlRestoreModuleState(moduleState);
-    busProbe(0);
-}
-
-void getDDFromSource(struct loaderData_s * loaderData, char * src, GTree *moduleState) {
-    char *path = "/tmp/dd.img";
-    int unlinkf = 0;
-
-    if (!strncmp(src, "nfs:", 4)) {
-        unlinkf = 1;
-        if (getFileFromNfs(src + 4, "/tmp/dd.img", loaderData)) {
-            logMessage(ERROR, "unable to retrieve driver disk: %s", src);
-            return;
-        }
-    } else if (!strncmp(src, "ftp://";, 6) || !strncmp(src, "http", 4)) {
-        unlinkf = 1;
-        if (getFileFromUrl(src, "/tmp/dd.img", loaderData)) {
-            logMessage(ERROR, "unable to retrieve driver disk: %s", src);
-            return;
-        }
-    /* FIXME: this is a hack so that you can load a driver disk from, eg, 
-     * scsi cdrom drives */
-#if !defined(__s390__) && !defined(__s390x__)
-    } else if (!strncmp(src, "cdrom", 5)) {
-        loadDriverDisks(DEVICE_ANY, loaderData, moduleState);
-        return;
-#endif
-    } else if (!strncmp(src, "path:", 5)) {
-	path = src + 5;
-    } else {
-        newtWinMessage(_("Kickstart Error"), _("OK"),
-                       _("Unknown driver disk kickstart source: %s"), src);
-        return;
-    }
-
-    if (!mountLoopback(path, "/tmp/drivers", "/dev/loop6")) {
-        loadFromLocation(loaderData, "/tmp/drivers", moduleState);
-        umountLoopback("/tmp/drivers", "/dev/loop6");
-        unlink("/tmp/drivers");
-        if (unlinkf) unlink(path);
-    }
-
-}
-
-static void getDDFromDev(struct loaderData_s * loaderData, char * dev, GTree *moduleState);
-
-void useKickstartDD(struct loaderData_s * loaderData,
-                    int argc, char ** argv) {
-    char * dev = NULL;
-    char * biospart = NULL, * p = NULL; 
-    gchar *fstype = NULL, *src = NULL;
-    gint usebiosdev = 0;
-    gchar **remaining = NULL;
-    GOptionContext *optCon = g_option_context_new(NULL);
-    GError *optErr = NULL;
-    GOptionEntry ksDDOptions[] = {
-        /* The --type option is deprecated and now has no effect. */
-        { "type", 0, 0, G_OPTION_ARG_STRING, &fstype, NULL, NULL },
-        { "source", 0, 0, G_OPTION_ARG_STRING, &src, NULL, NULL },
-        { "biospart", 0, 0, G_OPTION_ARG_INT, &usebiosdev, NULL, NULL },
-        { G_OPTION_REMAINING, 0, 0, G_OPTION_ARG_STRING_ARRAY, &remaining,
-          NULL, NULL },
-        { NULL },
-    };
-
-    g_option_context_set_help_enabled(optCon, FALSE);
-    g_option_context_add_main_entries(optCon, ksDDOptions, NULL);
-
-    if (!g_option_context_parse(optCon, &argc, &argv, &optErr)) {
-        newtWinMessage(_("Kickstart Error"), _("OK"),
-                       _("The following invalid argument was specified for "
-                         "the kickstart driver disk command: %s"),
-                       optErr->message);
-        g_error_free(optErr);
-        g_option_context_free(optCon);
-        g_strfreev(remaining);
-        return;
-    }
-
-    g_option_context_free(optCon);
-
-    if ((remaining != NULL) && (g_strv_length(remaining) == 1)) {
-        dev = remaining[0];
-    }
-
-    if (!dev && !src) {
-        logMessage(ERROR, "bad arguments to kickstart driver disk command");
-        return;
-    }
-
-    if (usebiosdev != 0) {
-        p = strchr(dev,'p');
-        if (!p){
-            logMessage(ERROR, "Bad argument for biospart");
-            return;
-        }
-        *p = '\0';
-        
-        biospart = getBiosDisk(dev);
-        if (biospart == NULL) {
-            logMessage(ERROR, "Unable to locate BIOS dev %s",dev);
-            return;
-        }
-        dev = malloc(strlen(biospart) + strlen(p + 1) + 2);
-        sprintf(dev, "%s%s", biospart, p + 1);
-    }
-
-    if (dev) {
-        getDDFromDev(loaderData, dev, NULL);
-    } else {
-        getDDFromSource(loaderData, src, NULL);
-    }
-
-    g_strfreev(remaining);
-    return;
-}
-
-static void getDDFromDev(struct loaderData_s * loaderData, char * dev, GTree* moduleState) {
-    if (doPwMount(dev, "/tmp/drivers", "auto", "ro", NULL)) {
-        logMessage(ERROR, "unable to mount driver disk %s", dev);
-        return;
-    }
-
-    loadFromLocation(loaderData, "/tmp/drivers", moduleState);
-    umount("/tmp/drivers");
-    unlink("/tmp/drivers");
-}
-
-
-/*
- * Look for partition with specific label (part of #316481)
- */
-GSList* findDriverDiskByLabel(void)
-{
-    char *ddLabel = "OEMDRV";
-    GSList *ddDevice = NULL;
-    blkid_cache bCache;
-    
-    int res;
-    blkid_dev_iterate bIter;
-    blkid_dev bDev;
-
-    if (blkid_get_cache(&bCache, NULL)<0) {
-        logMessage(ERROR, "Cannot initialize cache instance for blkid");
-        return NULL;
-    }
-    if ((res = blkid_probe_all(bCache))<0) {
-        logMessage(ERROR, "Cannot probe devices in blkid: %d", res);
-        return NULL;
-    }
-    if ((res = blkid_probe_all_removable(bCache))<0) {
-        logMessage(ERROR, "Cannot probe removable devices in blkid: %d", res);
-    }
-
-    bIter = blkid_dev_iterate_begin(bCache);
-    blkid_dev_set_search(bIter, "LABEL", ddLabel);
-    while ((res = blkid_dev_next(bIter, &bDev)) == 0) {
-        bDev = blkid_verify(bCache, bDev);
-        if (!bDev)
-            continue;
-
-        char *devname = strdup(blkid_dev_devname(bDev));
-        logMessage(DEBUGLVL, "Adding driver disc %s to the list "
-                             "of available DDs.", devname);
-        ddDevice = g_slist_prepend(ddDevice, (gpointer)devname);
-        /* Freeing bDev is taken care of by the put cache call */
-    }
-    blkid_dev_iterate_end(bIter);
-
-    blkid_put_cache(bCache);
-
-    return ddDevice;
-}
-
-int loadDriverDiskFromPartition(struct loaderData_s *loaderData, char* device)
-{
-    int rc;
-
-    logMessage(INFO, "trying to mount %s", device);
-    if (doPwMount(device, "/tmp/drivers", "auto", "ro", NULL)) {
-        logMessage(ERROR, "Failed to mount driver disk.");
-        return -1;
-    }
-
-    rc = verifyDriverDisk("/tmp/drivers");
-    if (rc == LOADER_BACK) {
-        logMessage(ERROR, "Driver disk is invalid for this "
-                "release of %s.", getProductName());
-        umount("/tmp/drivers");
-        return -2;
-    }
-
-    rc = loadDriverDisk(loaderData, "/tmp/drivers");
-    umount("/tmp/drivers");
-    if (rc == LOADER_BACK) {
-        return -3;
-    }
-
-    return 0;
-}
-
diff --git a/loader/driverdisk.h b/loader/driverdisk.h
deleted file mode 100644
index 4dc8685..0000000
--- a/loader/driverdisk.h
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * driverdisk.h
- *
- * Copyright (C) 2007  Red Hat, Inc.  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 as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * 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, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef DRIVERDISK_H
-#define DRIVERDISK_H
-
-#include "loader.h"
-#include "modules.h"
-#include "moduleinfo.h"
-
-#define DD_RPMDIR_TEMPLATE "/tmp/DD-%d"
-#define DD_EXTRACTED "/tmp/DD"
-#define DD_MODULES "/tmp/DD/lib/modules"
-#define DD_FIRMWARE "/tmp/DD/lib/firmware"
-
-extern char *ddFsTypes[];
-
-int loadDriverFromMedia(int class, struct loaderData_s *loaderData,
-                        int usecancel, int noprobe, GTree *moduleState);
-
-int loadDriverDisks(int class, struct loaderData_s *loaderData, GTree *moduleState);
-
-int getRemovableDevices(char *** devNames);
-
-int chooseManualDriver(int class, struct loaderData_s *loaderData);
-void useKickstartDD(struct loaderData_s * loaderData, int argc, 
-                    char ** argv);
-
-void getDDFromSource(struct loaderData_s * loaderData, char * src, GTree *moduleState);
-
-int loadDriverDiskFromPartition(struct loaderData_s *loaderData, char* device);
-
-GSList* findDriverDiskByLabel(void);
-
-#endif
diff --git a/loader/driverselect.c b/loader/driverselect.c
deleted file mode 100644
index 85b777b..0000000
--- a/loader/driverselect.c
+++ /dev/null
@@ -1,251 +0,0 @@
-/*
- * driverselect.c - functionality for manually selecting drivers
- *
- * Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002  Red Hat, Inc.
- * 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 as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * 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, see <http://www.gnu.org/licenses/>.
- *
- * Author(s): Erik Troan <ewt@xxxxxxxxxx>
- *            Jeremy Katz <katzj@xxxxxxxxxx>
- */
-
-#include <ctype.h>
-#include <newt.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-#include <errno.h>
-
-#include "../isys/log.h"
-
-#include "modules.h"
-#include "moduleinfo.h"
-#include "loader.h"
-#include "loadermisc.h"
-#include "lang.h"
-#include "driverdisk.h"
-
-struct sortModuleList {
-    int index;
-    moduleInfoSet modInfo;
-};
-
-static int sortDrivers(const void * a, const void * b) {
-    const struct sortModuleList * one = a;
-    const struct sortModuleList * two = b;
-
-    return strcmp(one->modInfo->moduleList[one->index].description,
-                  one->modInfo->moduleList[two->index].description);
-}
-
-static int getManualModuleArgs(struct moduleInfo * mod, gchar *** moduleArgs) {
-    newtGrid grid, buttons;
-    newtComponent text, f, ok, back, entry;
-    struct newtExitStruct es;
-    int done = 0, i;
-    char * buf;
-    char *argsEntry = "";
-
-    if (*moduleArgs) {
-        for (i = 0; (*moduleArgs)[i]; i++)
-            argsEntry = strcat(argsEntry, (*moduleArgs)[i]);
-    }
-
-    f = newtForm(NULL, NULL, 0);
-    checked_asprintf(&buf,
-                     _("Please enter any parameters which you wish to pass "
-                       "to the %s module separated by spaces.  If you don't "
-                       "know what parameters to supply, skip this screen "
-                       "by pressing the \"OK\" button."), mod->moduleName);
-
-    text = newtTextboxReflowed(-1, -1, buf, 60, 0, 10, 0);
-    entry = newtEntry(-1, -1, argsEntry, 50, (const char **) &argsEntry, 
-                      NEWT_ENTRY_SCROLL);
-    
-    newtFormAddHotKey(f, NEWT_KEY_F12);
-    
-    buttons = newtButtonBar(_("OK"), &ok, _("Back"), &back, NULL);
-    
-    grid = newtCreateGrid(1, 3);
-    newtGridSetField(grid, 0, 0, NEWT_GRID_COMPONENT, text,
-                     0, 0, 0, 1, 0, 0);
-    newtGridSetField(grid, 0, 1, NEWT_GRID_COMPONENT, entry, 
-                     0, 0, 0, 1, 0, 0);
-    newtGridSetField(grid, 0, 2, NEWT_GRID_SUBGRID, buttons,
-                     0, 0, 0, 0, 0, NEWT_GRID_FLAG_GROWX);
-    
-    newtGridWrappedWindow(grid, _("Enter Module Parameters"));
-    newtGridAddComponentsToForm(grid, f, 1);
-    
-    do {
-        newtFormRun(f, &es);
-
-        if (es.reason  == NEWT_EXIT_COMPONENT && es.u.co == back) {
-            done = -1;
-        } else {
-            done = 1;
-        }
-    } while (done == 0);
-
-    free(buf);
-    newtGridFree(grid, 1);
-
-    if (done == -1) {
-        newtFormDestroy(f);
-        newtPopWindow();
-
-        return LOADER_BACK;
-    }
-    logMessage(INFO, "specified args of %s for %s", argsEntry, mod->moduleName);
-
-    if (strlen(argsEntry) > 0) {
-        *moduleArgs = g_strsplit(argsEntry, " ", 0);
-    }
-
-    newtFormDestroy(f);
-    newtPopWindow();
-
-    return LOADER_OK;
-}
-
-int chooseManualDriver(int class, struct loaderData_s *loaderData) {
-    int i, numSorted, num = 0, done = 0;
-    enum driverMajor type;
-    struct sortModuleList * sortedOrder;
-    char giveArgs = ' ';
-    gchar **moduleArgs = NULL;
-    moduleInfoSet modInfo = loaderData->modInfo;
-
-    newtComponent text, f, ok, back, argcheckbox, listbox;
-    newtGrid grid, buttons;
-    struct newtExitStruct es;
-
-    if (class == DEVICE_NETWORK)
-        type = DRIVER_NET;
-    else if (class == DEVICE_DISK || class == DEVICE_CDROM)
-        type = DRIVER_SCSI;
-    else
-        type = DRIVER_ANY;
-
-    do {
-        sortedOrder = malloc(sizeof(*sortedOrder) * modInfo->numModules);
-        numSorted = 0;
-        
-        for (i = 0; i < modInfo->numModules; i++) {
-            sortedOrder[numSorted].index = i;
-            sortedOrder[numSorted++].modInfo = modInfo;
-        }
-        
-        if (numSorted == 0) {
-            i = newtWinChoice(_("No drivers found"), _("Load driver disk"), 
-                              _("Back"), _("No drivers were found to manually "
-                                           "insert.  Would you like to use "
-                                           "a driver disk?"));
-            if (i != 1)
-                return LOADER_BACK;
-            
-            loadDriverFromMedia(class, loaderData, 1, 1, NULL);
-            continue;
-        } else {
-            break;
-        }
-    } while (1);
-        
-    qsort(sortedOrder, numSorted, sizeof(*sortedOrder), sortDrivers);
-
-    f = newtForm(NULL, NULL, 0);
-
-    text = newtTextboxReflowed(-1, -1,
-                               _("Please select the driver below which you "
-                                 "wish to load.  If it does not appear and "
-                                 "you have a driver disk, press F2."),
-                               60, 0, 10, 0);
-
-    listbox = newtListbox(-1, -1, 6, NEWT_FLAG_SCROLL | NEWT_FLAG_RETURNEXIT);
-    newtListboxSetWidth(listbox, 55);
-
-    buttons = newtButtonBar(_("OK"), &ok, _("Back"), &back, NULL);
-    argcheckbox = newtCheckbox(-1, -1, _("Specify optional module arguments"),
-                               giveArgs, NULL, &giveArgs);
-
-    newtFormAddHotKey(f, NEWT_KEY_F2);
-    newtFormAddHotKey(f, NEWT_KEY_F12);
-
-    for (i = 0; i < numSorted; i++) {
-        char *buf = NULL;
-
-        checked_asprintf(&buf, "%s (%s)", 
-                         modInfo->moduleList[sortedOrder[i].index].description,
-                         modInfo->moduleList[sortedOrder[i].index].moduleName);
-
-        newtListboxAppendEntry(listbox, buf, 
-                INT_TO_POINTER(sortedOrder[i].index));
-    }
-
-    grid = newtCreateGrid(1, 4);
-    newtGridSetField(grid, 0, 0, NEWT_GRID_COMPONENT, text, 0, 0, 0, 1, 0, 0);
-    newtGridSetField(grid, 0, 1, NEWT_GRID_COMPONENT, listbox, 
-                     0, 0, 0, 1, 0, 0);
-    newtGridSetField(grid, 0, 2, NEWT_GRID_COMPONENT, argcheckbox,
-                     0, 0, 0, 1, 0, 0);
-    newtGridSetField(grid, 0, 3, NEWT_GRID_SUBGRID, buttons, 
-                     0, 0, 0, 0, 0, NEWT_GRID_FLAG_GROWX);
-    newtGridWrappedWindow(grid, _("Select Device Driver to Load"));
-
-    newtGridAddComponentsToForm(grid, f, 1);
-
-    do { 
-        newtFormRun(f, &es);
-
-        num = POINTER_TO_INT(newtListboxGetCurrent(listbox));
-
-        if (es.reason == NEWT_EXIT_COMPONENT && es.u.co == back) {
-            done = -1;
-        } else if (es.reason == NEWT_EXIT_HOTKEY && es.u.key == NEWT_KEY_F2) {
-            done = -2;
-        } else {
-            if (giveArgs != ' ') {
-                i = getManualModuleArgs(&(modInfo->moduleList[num]),
-                                        &moduleArgs);
-                if (i == LOADER_BACK)
-                    done = 0;
-                else
-                    done = 1;
-            } else {
-                done = 1;
-            }
-        }
-    } while (done == 0);
-
-    newtGridFree(grid, 1);
-    newtFormDestroy(f);
-    newtPopWindow();
-
-    if (done == -1) 
-        return LOADER_BACK;
-    if (done == -2) {
-        loadDriverFromMedia(class, loaderData, 1, 1, NULL);
-        return chooseManualDriver(class, loaderData);
-    }
-
-    mlLoadModule(modInfo->moduleList[num].moduleName, moduleArgs);
-    free(sortedOrder);
-
-    if (moduleArgs) {
-        g_strfreev(moduleArgs);
-    }
-
-    return LOADER_OK;
-}
diff --git a/loader/fwloader.c b/loader/fwloader.c
deleted file mode 100644
index 5ad1d8e..0000000
--- a/loader/fwloader.c
+++ /dev/null
@@ -1,675 +0,0 @@
-/*
- * fwloader.c -- a small firmware loader.
- *
- * Copyright (C) 2006, 2007  Red Hat, Inc.  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 as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * 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, see <http://www.gnu.org/licenses/>.
- *
- * Author(s): Peter Jones (pjones@xxxxxxxxxx)
- */
-
-#define _GNU_SOURCE 1
-
-#include <argz.h>
-#include <envz.h>
-#include <fcntl.h>
-#include <poll.h>
-#include <signal.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <sys/mman.h>
-#include <sys/poll.h>
-#include <sys/prctl.h>
-#include <sys/socket.h>
-#include <sys/stat.h>
-#include <sys/types.h>
-#include <sys/wait.h>
-#include <unistd.h>
-
-#include <asm/types.h>
-#include <linux/netlink.h>
-
-#include "../isys/log.h"
-
-#include "loader.h"
-#include "fwloader.h"
-#include "udelay.h"
-
-#ifndef FWDEBUG
-#define logMessage(x, ...)
-#endif
-
-struct fw_loader {
-    int netlinkfd;
-    sigset_t sigmask;
-    char *fw_pathz;
-    size_t fw_pathz_len;
-    struct pollfd *fds;
-};
-
-int done = 0;
-
-static inline int set_fd_coe(int fd, int enable)
-{
-    int rc;
-    long flags = 0;
-
-    rc = fcntl(fd, F_GETFD, &flags);
-    if (rc < 0)
-        return rc;
-
-    if (enable)
-        flags |= FD_CLOEXEC;
-    else
-        flags &= ~FD_CLOEXEC;
-
-    rc = fcntl(fd, F_SETFD, flags);
-    return rc;
-}
-
-static int open_uevent_socket(struct fw_loader *fwl)
-{
-    int fd, rc;
-    struct sockaddr_nl sa;
-
-    fd = socket(PF_NETLINK, SOCK_DGRAM, NETLINK_KOBJECT_UEVENT);
-    if (fd < 0)
-        return -1;
-    set_fd_coe(fd, 1);
-
-    memset(&sa, '\0', sizeof (sa));
-    sa.nl_family = AF_NETLINK;
-    sa.nl_pid = getpid();
-    sa.nl_groups = -1;
-
-    if (bind(fd, (struct sockaddr *)&sa, sizeof (sa)) < 0) {
-        close(fd);
-        return -1;
-    }
-
-    fwl->netlinkfd = fd;
-
-    fd = open("/proc/sys/kernel/hotplug", O_RDWR);
-    if (fd >= 0) {
-        rc = ftruncate(fd, 0);
-        rc = write(fd, "\n", 1);
-        close(fd);
-    }
-
-    fd = open("/sys/class/firmware/timeout", O_RDWR);
-    if (fd >= 0) {
-        rc = write(fd, "10", 2);
-        close(fd);
-    }
-
-    return 0;
-}
-
-extern void loaderSegvHandler(int signum);
-
-static void kill_hotplug_signal(int signum)
-{
-    signal(signum, kill_hotplug_signal);
-    logMessage(DEBUGLVL, "fwloader: got exit signal, quitting");
-    done = 1;
-}
-
-static int daemonize(struct fw_loader *fwl)
-{
-    int fd;
-    int rc;
-
-    signal(SIGTERM, kill_hotplug_signal);
-    signal(SIGSEGV, loaderSegvHandler);
-    signal(SIGTTOU, SIG_IGN);
-    signal(SIGTTIN, SIG_IGN);
-    signal(SIGTSTP, SIG_IGN);
-
-    sigfillset(&fwl->sigmask);
-    sigdelset(&fwl->sigmask, SIGTERM);
-    sigdelset(&fwl->sigmask, SIGSEGV);
-    sigemptyset(&fwl->sigmask);
-
-    prctl(PR_SET_NAME, "hotplug", 0, 0, 0);
-    rc = chdir("/");
-
-    fd = open("/proc/self/oom_adj", O_RDWR);
-    if (fd >= 0) {
-        rc = write(fd, "-17", 3);
-        close(fd);
-    }
-
-    for (fd = 0; fd < getdtablesize(); fd++) {
-        if (fd == STDIN_FILENO || fd == STDOUT_FILENO || fd == STDERR_FILENO)
-            continue;
-        if (fd == tty_logfd || fd == file_logfd)
-            continue;
-        close(fd);
-    }
-
-    setsid();
-    fd = open("/dev/null", O_RDONLY);
-    close(STDIN_FILENO);
-    dup2(fd, STDIN_FILENO);
-    set_fd_coe(STDIN_FILENO, 1);
-    close(fd);
-    fd = open("/dev/null", O_WRONLY);
-    close(STDOUT_FILENO);
-    dup2(fd, STDOUT_FILENO);
-    set_fd_coe(STDOUT_FILENO, 1);
-    close(STDERR_FILENO);
-    dup2(fd, STDERR_FILENO);
-    set_fd_coe(STDERR_FILENO, 1);
-    close(fd);
-
-    logMessage(DEBUGLVL, "fwloader: starting up (pid %d)", getpid());
-    return 0;
-}
-
-struct uevent {
-    char *msg;
-    char *path;
-    char *envz;
-    size_t envz_len;
-};
-
-static int get_netlink_msg(struct fw_loader *fwl, struct uevent *uevent)
-{
-    size_t len;
-    ssize_t size;
-    static char buffer[2560];
-    char *pos;
-    char *msg = NULL, *path = NULL, *envz = NULL;
-    char *argv[] = { NULL };
-    size_t envz_len;
-    error_t errnum;
-
-    size = recv(fwl->netlinkfd, &buffer, sizeof (buffer), 0);
-    if (size < 0)
-        return -1;
-
-    if ((size_t)size > sizeof (buffer) - 1)
-        size = sizeof (buffer) - 1;
-    buffer[size] = '\0';
-
-    len = strcspn(buffer, "@");
-    if (!buffer[len])
-        return -1;
-
-    if ((errnum = argz_create(argv, &envz, &envz_len)) > 0)
-        goto err;
-
-    pos = buffer;
-    msg = strndup(pos, len++);
-    pos += len;
-    path = strdup(pos);
-
-    pos += strlen(pos) + 1;
-    if (len < size + 1) {
-        while (pos[0]) {
-            char *value = strchr(pos, '=');
-            if (value)
-                *(value++) = '\0';
-
-            if ((errnum = envz_add(&envz, &envz_len, pos, value)) > 0)
-                goto err;
-            pos += strlen(pos) + 1;
-            if (*pos)
-                pos += strlen(pos) + 1;
-        }
-    }
-
-    uevent->msg = msg;
-    uevent->path = path;
-    uevent->envz = envz;
-    uevent->envz_len = envz_len;
-    return 0;
-err:
-    if (msg)
-        free(msg);
-    if (path)
-        free(path);
-    while(envz)
-        argz_delete(&envz, &envz_len, envz);
-    errno = errnum;
-    return -1;
-}
-
-/* Set the 'loading' attribute for a firmware device.
- * 1 == currently loading
- * 0 == done loading
- * -1 == error
- */
-static int
-get_loading_fd(const char *device)
-{
-    int fd = -1;
-    char *loading_path = NULL;
-
-    if (asprintf(&loading_path, "%s/loading", device) < 0) {
-        logMessage(ERROR, "fwloader: device %s: asprintf: %m", device);
-        return -1;
-    }
-    logMessage(DEBUGLVL, "fwloader: looking for loading file at %s", loading_path);
-    fd = open(loading_path, O_RDWR | O_SYNC );
-    if (fd < 0)
-        logMessage(ERROR, "fwloader: open %s: %m", loading_path);
-    free(loading_path);
-    return fd;
-}
-
-static int
-set_loading(int fd, int value)
-{
-    int rc = 0;
-
-    if (value == -1)
-        rc = write(fd, "-1", 3);
-    else if (value == 0)
-        rc = write(fd, "0", 2);
-    else if (value == 1)
-        rc = write(fd, "1", 2);
-    fsync(fd);
-    fdatasync(fd);
-
-    return rc < 0 ? rc : 0;
-}
-
-static int
-fd_map(int fd, char **buf, size_t *bufsize)
-{
-    struct stat stats;
-    int en = 0;
-
-    if (fstat(fd, &stats) < 0) {
-        en = errno;
-        close(fd);
-        errno = en;
-        return -1;
-    }
-
-    *buf = mmap(NULL, stats.st_size, PROT_READ, MAP_SHARED, fd, 0);
-    if (*buf == MAP_FAILED) {
-        *buf = NULL;
-        en = errno;
-        close(fd);
-        errno = en;
-        return -1;
-    }
-    *bufsize = stats.st_size;
-    return 0;
-}
-
-static int
-file_map(const char *filename, char **buf, size_t *bufsize, int flags)
-{
-    int fd, en, rc = 0;
-
-    if ((fd = open(filename, flags ? flags : O_RDONLY)) < 0)
-        return -1;
-
-    if (fd_map(fd, buf, bufsize) < 0)
-        rc = -1;
-
-    en = errno;
-    close(fd);
-    errno = en;
-
-    return rc;
-}
-
-static void
-file_unmap(void *buf, size_t bufsize)
-{
-    munmap(buf, bufsize);
-}
-
-static int
-fetcher(char *inpath, int outfd)
-{
-    char *inbuf = NULL;
-    size_t inlen;
-    int count;
-    int en = 0;
-    int rc;
-
-    errno = 0;
-    if (access(inpath, F_OK))
-        goto out;
-
-    if (file_map(inpath, &inbuf, &inlen, O_RDONLY) < 0)
-        goto out;
-
-    lseek(outfd, 0, SEEK_SET);
-    rc = ftruncate(outfd, 0);
-    rc = ftruncate(outfd, inlen);
-
-    count = 0;
-    while (count < inlen) {
-        ssize_t c;
-        c = write(outfd, inbuf + count, inlen - count);
-        if (c <= 0)
-            goto out;
-        count += c;
-    }
-
-out:
-    en = errno;
-    if (inbuf)
-        file_unmap(inbuf, inlen);
-    if (en) {
-        errno = en;
-        return -1;
-    }
-    return 0;
-}
-
-
-static int
-_load_firmware(struct fw_loader *fwl, int fw_fd, char *sysdir, int timeout)
-{
-    int rc = 0;
-    char *fw_buf = NULL, *data = NULL;
-    size_t fw_len = 0;
-    int dfd = -1, lfd = -1;
-    int loading = -2;
-    size_t count;
-
-    logMessage(DEBUGLVL, "fwloader: waiting for firmware dir at %s", sysdir);
-    timeout *= 1000000;
-    while (access(sysdir, F_OK) && timeout) {
-        udelay(100);
-        timeout -= 100;
-    }
-    if (!timeout) {
-        logMessage(ERROR, "fwloader: never found firmware dir at %s", sysdir);
-        return -ENOENT;
-    }
-
-    if ((lfd = get_loading_fd(sysdir)) < 0)
-        return lfd;
-
-    set_loading(lfd, 1);
-    loading = -1;
-
-    if (fd_map(fw_fd, &fw_buf, &fw_len) < 0) {
-        rc = -errno;
-        goto out;
-    }
-
-    if (asprintf(&data, "%s/data", sysdir) < 0) {
-        rc = -errno;
-        goto out;
-    }
-    if ((dfd = open(data, O_RDWR)) < 0) {
-        rc = -errno;
-        goto out;
-    }
-    count = 0;
-    while (count < fw_len) {
-        ssize_t c;
-        if ((c = write(dfd, fw_buf + count, fw_len - count)) <= 0)
-            goto out;
-        count += c;
-    }
-    loading = 0;
-
-out:
-    if (dfd >= 0)
-        close(dfd);
-    if (fw_buf)
-        file_unmap(fw_buf, fw_len);
-    if (loading != -2)
-        set_loading(lfd, loading);
-    if (lfd >= 0)
-        close(lfd);
-    if (data)
-        free(data);
-
-    return rc;
-}
-
-static void load_firmware(struct fw_loader *fwl, struct uevent *uevent)
-{
-    char *devpath = NULL, *firmware = NULL, *timeout;
-    char *fw_file = NULL, *sys_file = NULL;
-    char *entry;
-    int timeout_secs;
-    char *tempfile;
-    int fd = -1;
-
-    tempfile = strdup("/tmp/fw-XXXXXX");
-    fd = mkstemp(tempfile);
-    if (fd < 0) {
-        logMessage(ERROR, "fwloader: mkstemp(\"%s\") failed: %m", tempfile);
-        free(tempfile);
-        return;
-    }
-    unlink(tempfile);
-    free(tempfile);
-
-    devpath = envz_get(uevent->envz, uevent->envz_len, "DEVPATH");
-    firmware = envz_get(uevent->envz, uevent->envz_len, "FIRMWARE");
-    timeout = envz_get(uevent->envz, uevent->envz_len, "TIMEOUT");
-    
-    if (!devpath || !firmware) {
-        argz_stringify(uevent->envz, uevent->envz_len, ' ');
-        logMessage(ERROR, "fwloader: environment: %s", uevent->envz);
-        return;
-    }
-
-    errno = 0;
-    timeout_secs = strtol(timeout, NULL, 10);
-
-    if ((errno == ERANGE && (timeout_secs == LONG_MIN ||
-                             timeout_secs == LONG_MAX)) ||
-        (errno != 0 && timeout_secs == 0)) {
-        logMessage(ERROR, "%s: %d: %m", __func__, __LINE__);
-        abort();
-    }
-
-    /* find the file */
-    for (entry = fwl->fw_pathz; entry;
-            entry = argz_next(fwl->fw_pathz, fwl->fw_pathz_len, entry)) {
-        if (asprintf(&fw_file, "%s/%s", entry, firmware) < 0)
-            return;
-
-        logMessage(INFO, "fwloader: trying to find %s at %s", firmware, fw_file);
-
-        if (fetcher(fw_file, fd) >= 0)
-            break;
-
-        free(fw_file);
-        fw_file = NULL;
-        if (errno == ENOENT || errno == EPERM)
-            continue;
-        break;
-    }
-    if (!fw_file)
-        goto out;
-
-    if (asprintf(&sys_file, "/sys%s/", devpath) < 0)
-        goto out;
-
-    _load_firmware(fwl, fd, sys_file, timeout_secs);
-
-out:
-    if (fw_file)
-        free(fw_file);
-    if (sys_file)
-        free(sys_file);
-    if (fd != -1)
-        close(fd);
-}
-
-static void handle_single_uevent(struct fw_loader *fwl, struct uevent *uevent)
-{
-    char *action = NULL;
-    char *subsystem = NULL;
-
-    action = envz_get(uevent->envz, uevent->envz_len, "ACTION");
-    subsystem = envz_get(uevent->envz, uevent->envz_len, "SUBSYSTEM");
-
-    logMessage(DEBUGLVL, "fwloader: subsystem %s got action %s", subsystem, action);
-    if (!strcmp(action, "add") && !strcmp(subsystem, "firmware"))
-        load_firmware(fwl, uevent);
-}
-
-static void handle_events(struct fw_loader *fwl)
-{
-    int rc;
-    struct uevent uevent;
-    if (fwl->fds == NULL)
-        fwl->fds = calloc(1, sizeof (struct pollfd));
-
-    do {
-        do {
-            if (done)
-                exit(0);
-            fwl->fds[0].events = POLLIN | POLLPRI;
-            fwl->fds[0].revents = 0;
-            fwl->fds[0].fd = fwl->netlinkfd;
-
-            //logMessage(DEBUGLVL, "fwloader: polling on netlink socket");
-            errno = 0;
-            rc = poll(fwl->fds, 1, -1);
-            //logMessage(DEBUGLVL, "fwloader: poll returned %d", rc);
-
-            if (done)
-                exit(0);
-        } while (rc < 1 || (rc < 0 && errno == EINTR));
-
-        memset(&uevent, '\0', sizeof (uevent));
-        if (get_netlink_msg(fwl, &uevent) < 0)
-            continue;
-
-        handle_single_uevent(fwl, &uevent);
-    } while (1);
-
-    if (fwl->fds) {
-        free(fwl->fds);
-        fwl->fds = NULL;
-    }
-}
-
-void set_fw_search_path(struct loaderData_s *loaderData, char *path)
-{
-    char *old = loaderData->fw_search_pathz, *new = NULL;
-    size_t old_len = loaderData->fw_search_pathz_len;
-
-    loaderData->fw_search_pathz = NULL;
-    loaderData->fw_search_pathz_len = -1;
-    if (!path) {
-        if (old)
-            free(old);
-        return;
-    }
-
-    if ((new = strdup(path)) == NULL)
-        goto out;
-
-    loaderData->fw_search_pathz = NULL;
-    loaderData->fw_search_pathz_len = 0;
-    if (argz_create_sep(new, ':', &loaderData->fw_search_pathz,
-                &loaderData->fw_search_pathz_len) != 0)
-        goto out;
-
-    if (old)
-        free(old);
-
-    return;
-out:
-    if (new)
-        free(new);
-    loaderData->fw_search_pathz = old;
-    loaderData->fw_search_pathz_len = old_len;
-
-    return;
-}
-
-void add_fw_search_dir(struct loaderData_s *loaderData, char *dir)
-{
-    argz_add(&loaderData->fw_search_pathz, &loaderData->fw_search_pathz_len,
-            dir);
-}
-
-void do_fw_loader(struct loaderData_s *loaderData)
-{
-    struct fw_loader fwl;
-    int rc;
-
-    memset(&fwl, '\0', sizeof (fwl));
-    fwl.netlinkfd = -1;
-
-    fwl.fw_pathz = loaderData->fw_search_pathz;
-    fwl.fw_pathz_len = loaderData->fw_search_pathz_len;
-
-    logMessage(INFO, "fwloader: starting firmware loader");
-
-    rc = daemonize(&fwl);
-    if (rc < 0) {
-        logMessage(ERROR, "fwloader: daemonize() failed with %d: %m", rc);
-        exit(1);
-    }
-
-    if (open_uevent_socket(&fwl) < 0) {
-        logMessage(ERROR, "fwloader: open_uevent_socket() failed: %m");
-        exit(1);
-    }
-
-    logMessage(DEBUGLVL, "fwloader: entering event loop");
-    handle_events(&fwl);
-
-    exit(1);
-}
-
-
-void start_fw_loader(struct loaderData_s *loaderData) {
-    pid_t loader;
-
-    loader = fork();
-    if (loader > 0)
-        loaderData->fw_loader_pid = loader;
-    if (loader != 0)
-        return;
-    
-    do_fw_loader(loaderData);
-}
-
-void stop_fw_loader(struct loaderData_s *loaderData) {
-    int x = 0, rc;
-    siginfo_t siginfo;
-    if (loaderData->fw_loader_pid > 0)
-        kill(loaderData->fw_loader_pid, SIGTERM);
-    while (x <= 100) {
-        if (x > 90)
-            kill(loaderData->fw_loader_pid, SIGKILL);
-        memset(&siginfo, '\0', sizeof (siginfo));
-        rc = waitid(P_PID, loaderData->fw_loader_pid, &siginfo, WNOHANG|WEXITED);
-        if (rc < 0 && errno == ECHILD)
-            return;
-        else if (rc == 0 && siginfo.si_pid != 0)
-            return;
-        else if (rc == 0)
-            x++;
-        usleep(10000);
-    }
-    return;
-}
-
-
-/*
- * vim:ts=8:sw=4:sts=4:et
- */
diff --git a/loader/fwloader.h b/loader/fwloader.h
deleted file mode 100644
index e0b0fe8..0000000
--- a/loader/fwloader.h
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * fwloader.h -- a small firmware loader.
- *
- * Copyright (C) 2006, 2007  Red Hat, Inc.  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 as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * 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, see <http://www.gnu.org/licenses/>.
- *
- * Author(s): Peter Jones <pjones@xxxxxxxxxx>
- */
-
-#ifndef FWLOADER_H
-#define FWLOADER_H 1
-
-#include "loader.h"
-
-extern void set_fw_search_path(struct loaderData_s *loaderData, char *path);
-extern void add_fw_search_dir(struct loaderData_s *loaderData, char *dir);
-extern void start_fw_loader(struct loaderData_s *loaderData);
-extern void stop_fw_loader(struct loaderData_s *loaderData);
-
-#endif /* FWLOADER_H */
-/*
- * vim:ts=8:sw=4:sts=4:et
- */
diff --git a/loader/getparts.c b/loader/getparts.c
deleted file mode 100644
index c60dc83..0000000
--- a/loader/getparts.c
+++ /dev/null
@@ -1,180 +0,0 @@
-/*
- * getparts.c - functions associated with getting partitions for a disk
- *
- * Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004  Red Hat, Inc.
- * 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 as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * 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, see <http://www.gnu.org/licenses/>.
- *
- * Author(s): Michael Fulbright <msf@xxxxxxxxxx>
- *            Jeremy Katz <katzj@xxxxxxxxxx>
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <errno.h>
-#include <ctype.h>
-#include <string.h>
-
-#include "../isys/log.h"
-
-/* see if this is a partition name or not */
-static int isPartitionName(char *pname) {
-
-    /* if it doesnt start with a alpha its not one */
-    if (!isalpha(*pname) || strstr(pname, "ram"))
-	return 0;
-
-    /* if it has a '/' in it then treat it specially */
-    if (strchr(pname, '/') && !strstr(pname, "iseries") && 
-        !strstr(pname, "i2o")) {
-	/* assume its either a /dev/ida/ or /dev/cciss device */
-	/* these have form of c?d?p? if its a partition */
-	return strchr(pname, 'p') != NULL;
-    } else {
-	/* if it ends with a digit we're ok */
-	return isdigit(pname[strlen(pname)-1]);
-    }
-}
-
-/* return NULL terminated array of pointers to names of partitons in
- * /proc/partitions
- */
-char **getPartitionsList(char * disk) {
-    FILE *f;
-    int numfound = 0;
-    char **rc=NULL;
-
-    f = fopen("/proc/partitions", "r");
-    if (!f) {
-	logMessage(ERROR, "getPartitionsList: could not open /proc/partitions");
-	return NULL;
-    }
-
-    /* read through /proc/partitions and parse out partitions */
-    while (1) {
-	char *tmpptr, *pptr;
-	char tmpstr[4096];
-
-	tmpptr = fgets(tmpstr, sizeof(tmpstr), f);
-
-	if (tmpptr) {
-	    char *a, *b;
-	    int toknum = 0;
-
-	    a = tmpstr;
-	    while (1) {
-		b = strsep(&a, " \n");
-
-		/* if no fields left abort */
-		if (!b)
-		    break;
-
-		/* if field was empty means we hit another delimiter */
-		if (!*b)
-		    continue;
-
-		/* make sure this is a valid partition line, should start */
-		/* with a numeral */
-		if (toknum == 0) {
-		    if (!isdigit(*b))
-			break;
-		} else if (toknum == 2) {
-		    /* if size is exactly 1 then ignore it as an extended */
-		    if (!strcmp(b, "1"))
-			break;
-		} else if (toknum == 3) {
-		    /* this should be the partition name */
-		    /* now we need to see if this is the block device or */
-		    /* actually a partition name                         */
-		    if (!isPartitionName(b))
-			break;
-
-                    /* make sure that either we don't care about the disk
-                     * or it's this one */
-                    if ((disk != NULL) && (strncmp(disk, b, strlen(disk))))
-                        break;
-
-		    /* we found a partition! */
-		    pptr = (char *) malloc(strlen(b) + 7);
-		    sprintf(pptr, "/dev/%s", b);
-
-		    if (!rc) {
-			rc = (char **) malloc(2*sizeof(char *));
-		        rc[0] = pptr;
-			rc[1] = NULL;
-		    } else {
-			int idx;
-			
-			rc = (char **) realloc(rc, (numfound+2)*sizeof(char *));
-			idx = 0;
-			while (idx < numfound) {
-			    if (strcmp(pptr, rc[idx]) < 0)
-				break;
-
-			    idx++;
-			}
-
-			/* move existing out of way if necessary */
-			if (idx != numfound)
-			    memmove(rc+idx+1, rc+idx, (numfound-idx)*sizeof(char *));
-
-			rc[idx] = pptr;
-			rc[numfound+1] = NULL;
-		    }
-		    numfound++;
-		    break;
-		}
-		toknum++;
-	    }
-	} else {
-	    break;
-	}
-    }
-
-    fclose(f);
-
-    return rc;
-}
-
-/* returns length of partitionlist */
-int lenPartitionsList(char **list) {
-    char **part;
-    int  rc;
-
-    if (!list) return 0;
-    for (rc = 0, part = list; *part; rc++, part++);
-
-    return rc;
-}
-
-/* frees partition list */
-void freePartitionsList(char **list) {
-    char **part;
-
-    if (!list)
-        return;
-
-    for (part = list; *part; part++) {
-	if (*part) {
-            free(*part);
-            *part = NULL;
-        }
-    }
-
-    free(list);
-    list = NULL;
-}
diff --git a/loader/getparts.h b/loader/getparts.h
deleted file mode 100644
index b672a77..0000000
--- a/loader/getparts.h
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * getparts.h
- *
- * Copyright (C) 2007  Red Hat, Inc.  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 as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * 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, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef GETPARTS_H
-#define GETPARTS_H
-
-char **getPartitionsList(char * disk);
-int lenPartitionsList(char **list);
-void freePartitionsList(char **list);
-
-#endif
diff --git a/loader/hardware.c b/loader/hardware.c
deleted file mode 100644
index ad20ed5..0000000
--- a/loader/hardware.c
+++ /dev/null
@@ -1,150 +0,0 @@
-/*
- * hardware.c - various hardware probing functionality
- *
- * Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003  Red Hat, Inc.
- * 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 as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * 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, see <http://www.gnu.org/licenses/>.
- *
- * Author(s): Erik Troan <ewt@xxxxxxxxxx>
- *            Matt Wilson <msw@xxxxxxxxxx>
- *            Michael Fulbright <msf@xxxxxxxxxx>
- *            Jeremy Katz <katzj@xxxxxxxxxx>
- */
-
-#include <errno.h>
-#include <fcntl.h>
-#include <string.h>
-#include <strings.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <ctype.h>
-#include <sys/wait.h>
-#include <glib.h>
-
-#include "loader.h"
-#include "hardware.h"
-
-/* FIXME: for turning off dma */
-#include <sys/ioctl.h>
-#include <linux/hdreg.h>
-#include "../isys/isys.h"
-#include "../isys/log.h"
-
-/* boot flags */
-extern uint64_t flags;
-
-static int detectHardware() {
-    int child, rc, status;
-    int timeout = 0; /* FIXME: commandline option for this */
-
-    fprintf(stderr, "detecting hardware...\n");
-    logMessage(DEBUGLVL, "probing buses");
-
-    if (!(child = fork())) {
-        int fd = open("/dev/tty3", O_RDWR);
-
-        dup2(fd, 0);
-        dup2(fd, 1);
-        dup2(fd, 2);
-        close(fd);
-
-        rc = execl("/sbin/udevadm", "udevadm", "trigger", NULL);
-        _exit(1);
-    }
-
-    waitpid(child, &status, 0);
-    if (!WIFEXITED(status) || (WIFEXITED(status) && WEXITSTATUS(status))) {
-        rc = 1;
-    } else {
-        rc = 0;
-    }
-
-    fprintf(stderr, "waiting for hardware to initialize...\n");
-    logMessage(DEBUGLVL, "waiting for hardware to initialize");
-
-    if (!(child = fork())) {
-        char *args[] = { "/sbin/udevadm", "settle", NULL, NULL };
-        int fd = open("/dev/tty3", O_RDWR);
-
-        dup2(fd, 0);
-        dup2(fd, 1);
-        dup2(fd, 2);
-        close(fd);
-
-        if (timeout) {
-            checked_asprintf(&args[2], "--timeout=%d", timeout);
-        }
-
-        rc = execv("/sbin/udevadm", args);
-        _exit(1);
-    }
-
-    waitpid(child, &status, 0);
-    if (!WIFEXITED(status) || (WIFEXITED(status) && WEXITSTATUS(status))) {
-        rc = 1;
-    } else {
-        rc = 0;
-    }
-    if (rc) {
-        return LOADER_ERROR;
-    }
-    return LOADER_OK;
-}
-
-/* this allows us to do an early load of modules specified on the
- * command line to allow automating the load order of modules so that
- * eg, certain scsi controllers are definitely first.
- * FIXME: this syntax is likely to change in a future release
- *        but is done as a quick hack for the present.
- */
-int earlyModuleLoad(int justProbe) {
-    int fd, len, i;
-    char buf[1024], *cmdLine;
-    gint argc = 0;
-    gchar **argv = NULL;
-    GError *optErr = NULL;
-
-    /* FIXME: reparsing /proc/cmdline to avoid major loader changes.  
-     * should probably be done in loader.c:parseCmdline() like everything 
-     * else
-     */
-    if ((fd = open("/proc/cmdline", O_RDONLY)) < 0) return 1;
-    len = read(fd, buf, sizeof(buf) - 1);
-    close(fd);
-    if (len <= 0) return 1;
-
-    buf[len] = '\0';
-    cmdLine = buf;
-
-    if (!g_shell_parse_argv(cmdLine, &argc, &argv, &optErr)) {
-        g_error_free(optErr);
-        return 1;
-    }
-
-    for (i=0; i < argc; i++) {
-        if (!strncasecmp(argv[i], "driverload=", 11)) {
-            logMessage(INFO, "loading %s early", argv[i] + 11);
-            mlLoadModuleSet(argv[i] + 11);
-        }
-    }
-    return 0;
-}
-
-int busProbe(int justProbe) {
-    /* autodetect whatever we can */
-    if (justProbe)
-        return 0;
-    return detectHardware();
-}
diff --git a/loader/hardware.h b/loader/hardware.h
deleted file mode 100644
index 47c34d2..0000000
--- a/loader/hardware.h
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * hardware.h
- *
- * Copyright (C) 2007  Red Hat, Inc.  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 as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * 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, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef LOADERHW_H
-#define LOADERHW_H
-
-#include "modules.h"
-
-int earlyModuleLoad(int justProbe);
-int busProbe(int justProbe);
-
-#endif
diff --git a/loader/hdinstall.c b/loader/hdinstall.c
deleted file mode 100644
index 4bb31a8..0000000
--- a/loader/hdinstall.c
+++ /dev/null
@@ -1,496 +0,0 @@
-/*
- * hdinstall.c - code to set up hard drive installs
- *
- * Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003  Red Hat, Inc.
- * 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 as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * 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, see <http://www.gnu.org/licenses/>.
- *
- * Author(s): Erik Troan <ewt@xxxxxxxxxx>
- *            Matt Wilson <msw@xxxxxxxxxx>
- *            Michael Fulbright <msf@xxxxxxxxxx>
- *            Jeremy Katz <katzj@xxxxxxxxxx>
- */
-
-#include <ctype.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <newt.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/mount.h>
-#include <unistd.h>
-#include <glib.h>
-
-#include "driverdisk.h"
-#include "hdinstall.h"
-#include "getparts.h"
-#include "kickstart.h"
-#include "loader.h"
-#include "loadermisc.h"
-#include "lang.h"
-#include "modules.h"
-#include "method.h"
-#include "mediacheck.h"
-#include "cdinstall.h"
-#include "windows.h"
-
-#include "../isys/imount.h"
-#include "../isys/isys.h"
-#include "../isys/eddsupport.h"
-#include "../isys/log.h"
-
-/* boot flags */
-extern uint64_t flags;
-
-/* given a partition device and directory, tries to mount hd install image */
-static char * setupIsoImages(char * device, char * dirName, char * location) {
-    int rc = 0;
-    char *url = NULL, *dirspec, *updpath, *path;
-
-    logMessage(INFO, "mounting device %s for hard drive install", device);
-
-    if (doPwMount(device, "/mnt/isodir", "auto", "ro", NULL))
-        return NULL;
-
-    checked_asprintf(&dirspec, "/mnt/isodir%.*s",
-                     (int) (strrchr(dirName, '/') - dirName), dirName);
-    checked_asprintf(&path, "/mnt/isodir%s", dirName);
-
-    if (path) {
-        logMessage(INFO, "Path to stage2 image is %s", path);
-
-        rc = copyFile(path, "/tmp/install.img");
-        rc = mountStage2("/tmp/install.img");
-
-        free(path);
-
-        if (rc) {
-            umountLoopback("/mnt/runtime", "/dev/loop0");
-            umount("/mnt/isodir");
-            goto err;
-        }
-
-        checked_asprintf(&updpath, "%s/updates.img", dirspec);
-
-        logMessage(INFO, "Looking for updates for HD in %s", updpath);
-        copyUpdatesImg(updpath);
-        free(updpath);
-
-        checked_asprintf(&updpath, "%s/product.img", dirspec);
-
-        logMessage(INFO, "Looking for product for HD in %s", updpath);
-        copyProductImg(updpath);
-
-        free(updpath);
-        free(dirspec);
-        umount("/mnt/isodir");
-
-        checked_asprintf(&url, "hd:%s:/%s", device,
-                         dirName ? dirName : ".");
-
-        return url;
-    } else {
-        free(dirspec);
-        free(path);
-
-        if (rc) {
-            umount("/mnt/isodir");
-            return NULL;
-        }
-    }
-
-err:
-    newtWinMessage(_("Error"), _("OK"),
-                   _("An error occured finding the installation image "
-                     "on your hard drive.  Please check your images and "
-                     "try again."));
-    return NULL;
-}
-
-/* setup hard drive based install from a partition with a filesystem and
- * ISO images on that filesystem
- */
-char * mountHardDrive(struct installMethod * method,
-		      char * location, struct loaderData_s * loaderData) {
-    int rc;
-    int i;
-
-    newtComponent listbox, label, dirEntry, form, okay, back, text;
-    struct newtExitStruct es;
-    newtGrid entryGrid, grid, buttons;
-
-    int done = 0;
-    char * dir = g_strdup("");
-    char * tmpDir;
-    char * url = NULL;
-    char * buf;
-    int numPartitions;
-
-    char **partition_list;
-    char *selpart;
-    char *kspartition = NULL, *ksdirectory = NULL;
-    char *imgpath = "/images/install.img";
-
-    /* handle kickstart/stage2= data first if available */
-    if (loaderData->method == METHOD_HD && loaderData->stage2Data) {
-        kspartition = ((struct hdInstallData *)loaderData->stage2Data)->partition;
-        if (kspartition) {
-            kspartition = g_strdup(kspartition);
-        }
-
-        ksdirectory = ((struct hdInstallData *)loaderData->stage2Data)->directory;
-        if (ksdirectory) {
-            if (g_str_has_suffix(ksdirectory, ".img")) {
-                ksdirectory = g_strdup(ksdirectory);
-            } else {
-                ksdirectory = g_strconcat(ksdirectory, imgpath, NULL);
-            }
-        } else {
-            ksdirectory = g_strdup(imgpath);
-        }
-
-        logMessage(INFO, "partition is %s, dir is %s", kspartition, ksdirectory);
-
-        if (!kspartition || !ksdirectory) {
-            logMessage(ERROR, "missing partition or directory specification");
-            loaderData->method = -1;
-
-            if (loaderData->inferredStage2)
-                loaderData->invalidRepoParam = 1;
-        } else {
-            /* if we start with /dev, strip it (#121486) */
-            char *kspart = kspartition;
-            if (!strncmp(kspart, "/dev/", 5))
-                kspart = kspart + 5;
-
-            url = setupIsoImages(kspart, ksdirectory, location);
-            if (!url) {
-                logMessage(ERROR, "unable to find %s installation images on hd",
-                           getProductName());
-                loaderData->method = -1;
-
-                if (loaderData->inferredStage2)
-                    loaderData->invalidRepoParam = 1;
-            } else {
-                g_free(kspartition);
-                g_free(ksdirectory);
-                return url;
-            }
-        }
-    } else {
-        kspartition = NULL;
-        ksdirectory = NULL;
-    }
-
-    /* if we're here its either because this is interactive, or the */
-    /* hd kickstart directive was faulty and we have to prompt for  */
-    /* location of harddrive image                                  */
-
-    partition_list = NULL;
-    while (!done) {
-        /* if we're doing another pass free this up first */
-        if (partition_list)
-            freePartitionsList(partition_list);
-
-        partition_list = getPartitionsList(NULL);
-        numPartitions = lenPartitionsList(partition_list);
-
-        /* no partitions found, try to load a device driver disk for storage */
-        if (!numPartitions) {
-            rc = newtWinChoice(_("Hard Drives"), _("Yes"), _("Back"),
-                               _("You don't seem to have any hard drives on "
-                                 "your system! Would you like to configure "
-                                 "additional devices?"));
-            if (rc == 2) {
-                loaderData->stage2Data = NULL;
-                return NULL;
-            }
-
-            rc = loadDriverFromMedia(DEVICE_DISK, loaderData, 0, 0, NULL);
-            continue;
-        }
-
-        /* now find out which partition has the stage2 image */
-        checked_asprintf(&buf, _("What partition and directory on that "
-                                 "partition holds the installation image "
-                                 "for %s?  If you don't see the disk drive "
-                                 "you're using listed here, press F2 to "
-                                 "configure additional devices."),
-                         getProductName());
-
-        text = newtTextboxReflowed(-1, -1, buf, 62, 5, 5, 0);
-        free(buf);
-
-        listbox = newtListbox(-1, -1, numPartitions > 5 ? 5 : numPartitions,
-                              NEWT_FLAG_RETURNEXIT | 
-                              (numPartitions > 5 ? NEWT_FLAG_SCROLL : 0));
-
-        for (i = 0; i < numPartitions; i++)
-            newtListboxAppendEntry(listbox,partition_list[i],partition_list[i]);
-
-        /* if we had ks data around use it to prime entry, then get rid of it*/
-        if (kspartition) {
-            newtListboxSetCurrentByKey(listbox, kspartition);
-            g_free(kspartition);
-            kspartition = NULL;
-        }
-
-        label = newtLabel(-1, -1, _("Directory holding image:"));
-
-        dirEntry = newtEntry(28, 11, dir, 28, (const char **) &tmpDir,
-                             NEWT_ENTRY_SCROLL);
-
-        /* if we had ks data around use it to prime entry, then get rid of it*/
-        if (ksdirectory) {
-            newtEntrySet(dirEntry, ksdirectory, 1);
-            g_free(ksdirectory);
-            ksdirectory = NULL;
-        }
-
-        entryGrid = newtGridHStacked(NEWT_GRID_COMPONENT, label,
-                                     NEWT_GRID_COMPONENT, dirEntry,
-                                     NEWT_GRID_EMPTY);
-
-        buttons = newtButtonBar(_("OK"), &okay, _("Back"), &back, NULL);
-
-        grid = newtCreateGrid(1, 4);
-        newtGridSetField(grid, 0, 0, NEWT_GRID_COMPONENT, text,
-                         0, 0, 0, 1, 0, 0);
-        newtGridSetField(grid, 0, 1, NEWT_GRID_COMPONENT, listbox,
-                         0, 0, 0, 1, 0, 0);
-        newtGridSetField(grid, 0, 2, NEWT_GRID_SUBGRID, entryGrid,
-                         0, 0, 0, 1, 0, 0);
-        newtGridSetField(grid, 0, 3, NEWT_GRID_SUBGRID, buttons,
-                         0, 0, 0, 0, 0, NEWT_GRID_FLAG_GROWX);
-
-        newtGridWrappedWindow(grid, _("Select Partition"));
-
-        form = newtForm(NULL, NULL, 0);
-        newtFormAddHotKey(form, NEWT_KEY_F2);
-        newtFormAddHotKey(form, NEWT_KEY_F12);
-
-        newtGridAddComponentsToForm(grid, form, 1);
-        newtGridFree(grid, 1);
-
-        newtFormRun(form, &es);
-
-        selpart = newtListboxGetCurrent(listbox);
-
-        g_free(dir);
-        if (tmpDir && *tmpDir) {
-            /* Protect from form free. */
-            dir = g_strdup(tmpDir);
-        } else  {
-            dir = g_strdup("");
-        }
-
-        newtFormDestroy(form);
-        newtPopWindow();
-
-        if (es.reason == NEWT_EXIT_COMPONENT && es.u.co == back) {
-            loaderData->stage2Data = NULL;
-            return NULL;
-        } else if (es.reason == NEWT_EXIT_HOTKEY && es.u.key == NEWT_KEY_F2) {
-            rc = loadDriverFromMedia(DEVICE_DISK, loaderData, 0, 0, NULL);
-            continue;
-        }
-
-        logMessage(INFO, "partition %s selected", selpart);
-
-        /* If the user-provided URL points at a repo instead of a stage2
-         * image, fix that up now.
-         */
-        if (!g_str_has_suffix(dir, ".img")) {
-            char *tmp = g_strconcat(dir, imgpath, NULL);
-            g_free(dir);
-            dir = tmp;
-        }
-
-        loaderData->invalidRepoParam = 1;
-
-        url = setupIsoImages(selpart, dir, location);
-        if (!url) {
-            newtWinMessage(_("Error"), _("OK"), 
-                           _("Device %s does not appear to contain "
-                             "an installation image."), selpart, getProductName());
-            continue;
-        }
-
-        done = 1; 
-    }
-
-    g_free(dir);
-
-    return url;
-}
-
-void setKickstartHD(struct loaderData_s * loaderData, int argc,
-                     char ** argv) {
-    char *p;
-    gchar *biospart = NULL, *partition = NULL, *dir = NULL;
-    GOptionContext *optCon = g_option_context_new(NULL);
-    GError *optErr = NULL;
-    GOptionEntry ksHDOptions[] = {
-        { "biospart", 0, 0, G_OPTION_ARG_STRING, &biospart, NULL, NULL },
-        { "partition", 0, 0, G_OPTION_ARG_STRING, &partition, NULL, NULL },
-        { "dir", 0, 0, G_OPTION_ARG_STRING, &dir, NULL, NULL },
-        { NULL },
-    };
-
-    logMessage(INFO, "kickstartFromHD");
-
-    g_option_context_set_help_enabled(optCon, FALSE);
-    g_option_context_add_main_entries(optCon, ksHDOptions, NULL);
-
-    if (!g_option_context_parse(optCon, &argc, &argv, &optErr)) {
-        startNewt();
-        newtWinMessage(_("Kickstart Error"), _("OK"),
-                       _("Bad argument to HD kickstart method "
-                         "command: %s"), optErr->message);
-        g_error_free(optErr);
-        g_option_context_free(optCon);
-        return;
-    }
-
-    g_option_context_free(optCon);
-
-    if (biospart) {
-        char * dev;
-
-        p = strchr(biospart,'p');
-        if(!p){
-            logMessage(ERROR, "Bad argument for --biospart");
-            return;
-        }
-        *p = '\0';
-        dev = getBiosDisk(biospart);
-        if (dev == NULL) {
-            logMessage(ERROR, "Unable to location BIOS partition %s", biospart);
-            return;
-        }
-        partition = malloc(strlen(dev) + strlen(p + 1) + 2);
-        sprintf(partition, "%s%s", dev, p + 1);
-    }
-
-    loaderData->method = METHOD_HD;
-    loaderData->stage2Data = calloc(sizeof(struct hdInstallData *), 1);
-    if (partition)
-        ((struct hdInstallData *)loaderData->stage2Data)->partition = partition;
-    if (dir)
-        ((struct hdInstallData *)loaderData->stage2Data)->directory = dir;
-
-    logMessage(INFO, "results of hd ks, partition is %s, dir is %s", partition,
-               dir);
-}
-
-int kickstartFromHD(char *kssrc) {
-    int rc;
-    char *p, *np = NULL, *tmpstr, *ksdev, *kspath;
-
-    logMessage(INFO, "getting kickstart file from harddrive");
-
-    /* format is hd:[device]:/path/to/ks.cfg */
-    /* split up pieces */
-    tmpstr = strdup(kssrc);
-    p = strchr(tmpstr, ':');
-    if (p)
-        np = strchr(p+1, ':');
-    
-    /* no second colon, assume its the old format of                     */
-    /*        hd:[device]/path/to/ks.cfg                                 */
-    /* this format is bad however because some devices have '/' in them! */
-    if (!np)
-        np = strchr(p+1, '/');
-
-    if (!p || !np) {
-        logMessage(WARNING, "Format of command line is ks=hd:[device]:/path/to/ks.cfg");
-        free(tmpstr);
-        return 1;
-    }
-
-    *np = '\0';
-    ksdev = p+1;
-    kspath = np+1;
-
-    logMessage(INFO, "Loading ks from device %s on path %s", ksdev, kspath);
-    if ((rc=getKickstartFromBlockDevice(ksdev, kspath))) {
-        if (rc == 3) {
-            startNewt();
-            newtWinMessage(_("Error"), _("OK"),
-                           _("Cannot find kickstart file on hard drive."));
-        }
-        return 1;
-    }
-
-    return 0;
-}
-
-
-int kickstartFromBD(char *kssrc) {
-    int rc;
-    char *p, *np = NULL, *r = NULL, *tmpstr, *ksdev, *kspath, *biosksdev;
-
-    logMessage(INFO, "getting kickstart file from biosdrive");
-
-    /* format is bd:[device]:/path/to/ks.cfg */
-    /* split of pieces */
-    tmpstr = strdup(kssrc);
-    p = strchr(tmpstr, ':');
-    if (p)
-        np = strchr(p+1, ':');
-    
-    if (!p || !np) {
-        logMessage(WARNING, "Format of command line is ks=bd:device:/path/to/ks.cfg");
-        free(tmpstr);
-        return 1;
-    }
-
-    *np = '\0';
-    kspath = np+1;
-
-    r = strchr(p+1,'p');
-    if(!r){
-        logMessage(INFO, "Format of biosdisk is 80p1");
-        free(tmpstr);
-        return 1;
-    }                                                          
-
-    *r = '\0';
-    biosksdev = getBiosDisk((p + 1));
-    if(!biosksdev){
-        startNewt();
-        newtWinMessage(_("Error"), _("OK"),
-                       _("Cannot find hard drive for BIOS disk %s"),
-                       p + 1);
-        return 1;
-    }
-
-
-    ksdev = malloc(strlen(biosksdev) + 3);
-    sprintf(ksdev, "%s%s", biosksdev, r + 1);
-    logMessage(INFO, "Loading ks from device %s on path %s", ksdev, kspath);
-    if ((rc=getKickstartFromBlockDevice(ksdev, kspath))) {
-        if (rc == 3) {
-            startNewt();
-            newtWinMessage(_("Error"), _("OK"),
-                           _("Cannot find kickstart file on hard drive."));
-        }
-        return 1;
-    }
-
-    return 0;
-}
-
-/* vim:set shiftwidth=4 softtabstop=4: */
diff --git a/loader/hdinstall.h b/loader/hdinstall.h
deleted file mode 100644
index 44351a3..0000000
--- a/loader/hdinstall.h
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * hdinstall.h
- *
- * Copyright (C) 2007  Red Hat, Inc.  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 as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * 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, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef H_HDINSTALL
-#define H_HDINSTALL
-
-#include "method.h"
-
-struct hdInstallData {
-    char * partition;
-    char * directory;
-};
-
-
-void setKickstartHD(struct loaderData_s * loaderData, int argc,
-		    char ** argv);
-char * mountHardDrive(struct installMethod * method,
-                      char * location, struct loaderData_s * loaderData);
-int kickstartFromHD(char *kssrc);
-int kickstartFromBD(char *kssrc);
-
-#endif
diff --git a/loader/ibft.c b/loader/ibft.c
deleted file mode 100644
index b3a3827..0000000
--- a/loader/ibft.c
+++ /dev/null
@@ -1,105 +0,0 @@
-/*
-   File name: ibft.c
-   Date:      2008/09/02
-   Author:    Martin Sivak <msivak@xxxxxxxxxx>
-
-   Copyright (C) 2008 Red Hat
-
-   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; either version 2 of the
-   License, or (at your option) any later version.
-
-   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
-   in a file called COPYING along with this program; if not, write to
-   the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA
-   02139, USA.
-*/
-
-
-#include <stddef.h>
-#include <stdio.h>
-#include <string.h>
-
-#include <libiscsi.h>
-#include "ibft.h"
-
-struct libiscsi_network_config ibft_context;
-int ibft_ispresent = 0;
-int ibft_initialized = 0;
-
-int ibft_init(void)
-{
-  int ret;
-
-  memset(&ibft_context, 0, sizeof(ibft_context));
-
-  ret = libiscsi_get_firmware_network_config(&ibft_context);
-
-  /* ret == 0 -> OK */
-  ibft_ispresent = !ret;
-  ibft_initialized = 1;
-
-  return ibft_initialized;
-}
-
-/* Is iBFT available on this system */
-int ibft_present()
-{
-  if(!ibft_initialized)
-    ibft_init();
-
-  return ibft_ispresent;
-}
-
-/* Is the iBFT network configured to use DHCP */
-int ibft_iface_dhcp()
-{
-  if(!ibft_initialized)
-    ibft_init();
-
-  if(!ibft_present())
-    return -1;
-
-  return ibft_context.dhcp;
-}
-
-#define ibft_iface_charfunc(name, var) char* ibft_iface_##name()\
-{\
-  if(!ibft_initialized)\
-    ibft_init();\
-\
-  if(!ibft_present())\
-    return NULL;\
-\
-  if(!strlen(ibft_context.var))\
-    return NULL;\
-\
-  return ibft_context.var;\
-}
-
-
-/* Get the iBFT MAC address */
-ibft_iface_charfunc(mac, mac_address)
-
-/* Get the iBFT ip address */
-ibft_iface_charfunc(ip, ip_address)
-
-/* Get the iBFT subnet mask */
-ibft_iface_charfunc(mask, netmask)
-
-/* Get the iBFT gateway */
-ibft_iface_charfunc(gw, gateway)
-
-/* Get the iBFT iface name */
-ibft_iface_charfunc(iface, iface_name)
-
-/* Get the iBFT dns servers */
-ibft_iface_charfunc(dns1, primary_dns)
-ibft_iface_charfunc(dns2, secondary_dns)
-
diff --git a/loader/ibft.h b/loader/ibft.h
deleted file mode 100644
index a922c91..0000000
--- a/loader/ibft.h
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
-   File name: ibft.h
-   Date:      2008/09/02
-   Author:    Martin Sivak
-
-   Copyright (C) 2008 Red Hat
-
-   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; either version 2 of the
-   License, or (at your option) any later version.
-
-   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
-   in a file called COPYING along with this program; if not, write to
-   the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA
-   02139, USA.
-*/
-
-
-#ifndef __IBFT_H__
-#define __IBFT_H__
-
-
-int ibft_init();
-int ibft_present();
-
-int ibft_iface_dhcp();
-
-char* ibft_iface_mac();
-char* ibft_iface_ip();
-char* ibft_iface_mask();
-char* ibft_iface_gw();
-char* ibft_iface_iface();
-char* ibft_iface_dns1();
-char* ibft_iface_dns2();
-
-
-#endif
-
-/* end of ibft.h */
diff --git a/loader/init.c b/loader/init.c
deleted file mode 100644
index 1a38df3..0000000
--- a/loader/init.c
+++ /dev/null
@@ -1,798 +0,0 @@
-/*
- * init.c: This is the install type init
- *
- * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004
- * Red Hat, Inc.  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 as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * 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, see <http://www.gnu.org/licenses/>.
- *
- * Author(s): Erik Troan (ewt@xxxxxxxxxx)
- *            Jeremy Katz (katzj@xxxxxxxxxx)
- */
-
-#if USE_MINILIBC
-#include "minilibc.h"
-#ifndef SOCK_STREAM
-# define SOCK_STREAM 1
-#endif 
-#define klogctl syslog
-#else
-#include <ctype.h>
-#include <dirent.h>
-#include <errno.h>
-#include <execinfo.h>
-#include <fcntl.h>
-#include <net/if.h>
-#include <signal.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/ioctl.h>
-#include <sys/klog.h>
-#include <sys/mount.h>
-#include <sys/socket.h>
-#include <sys/stat.h>
-#include <sys/swap.h>
-#include <sys/time.h>
-#include <sys/types.h>
-#include <sys/un.h>
-#include <sys/wait.h>
-#include <unistd.h>
-#include <sys/ioctl.h>
-#include <sys/reboot.h>
-#include <linux/vt.h>
-#include <termios.h>
-#include <libgen.h>
-#include <glib.h>
-
-#include "init.h"
-#include "copy.h"
-#include "devt.h"
-#include "devices.h"
-
-#endif
-
-#include <asm/types.h>
-#include <linux/serial.h>
-
-#ifndef MS_REMOUNT
-#define MS_REMOUNT          32
-#endif
-
-#define ENV_PATH            0
-#define ENV_LD_LIBRARY_PATH 1
-#define ENV_HOME            2
-#define ENV_TERM            3
-#define ENV_DEBUG           4
-#define ENV_TERMINFO        5
-#define ENV_PYTHONPATH      6
-#define ENV_MALLOC_CHECK    7
-#define ENV_MALLOC_PERTURB  8
-
-char * env[] = {
-    "PATH=/usr/bin:/bin:/sbin:/usr/sbin:/mnt/sysimage/bin:"
-    "/mnt/sysimage/usr/bin:/mnt/sysimage/usr/sbin:/mnt/sysimage/sbin:"
-    "/mnt/sysimage/usr/X11R6/bin",
-
-    /* we set a nicer ld library path specifically for bash -- a full
-       one makes anaconda unhappy */
-#if defined(__x86_64__) || defined(__s390x__) || defined(__powerpc64__) || (defined(__sparc__) && defined(__arch64__))
-    "LD_LIBRARY_PATH=/lib64:/usr/lib64:/lib:/usr/lib",
-#else
-    "LD_LIBRARY_PATH=/lib:/usr/lib",
-#endif
-    "HOME=/",
-    "TERM=linux",
-    "DEBUG=",
-    "TERMINFO=/etc/linux-terminfo",
-    "PYTHONPATH=/tmp/updates",
-    "MALLOC_CHECK_=2",
-    "MALLOC_PERTURB_=204",
-    NULL
-};
-
-/* 
- * this needs to handle the following cases:
- *
- *	1) run from a CD root filesystem
- *	2) run from a read only nfs rooted filesystem
- *      3) run from a floppy
- *	4) run from a floppy that's been loaded into a ramdisk 
- *
- */
-
-void shutDown(int doKill, reboot_action rebootAction);
-static int getKillPolicy(void);
-static void getSyslog(char*);
-struct termios ts;
-
-static int expected_exit = 0;
-
-static void doExit(int) __attribute__ ((noreturn));
-static void doExit(int result)
-{
-    expected_exit = 1;
-    exit(result);
-}
-
-static void printstr(char * string) {
-    int ret;
-    ret = write(1, string, strlen(string));
-}
-
-static void fatal_error(int usePerror) {
-    printf("failed.\n");
-
-    printf("\nI can't recover from this.\n");
-#if !defined(__s390__) && !defined(__s390x__)
-    while (1) ;
-#endif
-}
-
-/* sets up and launches syslog */
-static void startSyslog(void) {
-    int conf_fd;
-    int ret;
-    char addr[128];
-    char forwardtcp[] = "*.* @@";
-    
-    /* update the config file with command line arguments first */
-    getSyslog(addr);
-    if (strlen(addr) > 0) {
-        conf_fd = open("/etc/rsyslog.conf", O_WRONLY|O_APPEND);
-        if (conf_fd < 0) {
-            printf("error opening /etc/rsyslog.conf: %d\n", errno);
-            printf("syslog forwarding will not be enabled\n");
-            sleep(5);
-        } else {
-            ret = write(conf_fd, forwardtcp, strlen(forwardtcp));
-            ret = write(conf_fd, addr, strlen(addr));
-            ret = write(conf_fd, "\n", 1);
-            close(conf_fd);
-        }
-    }
-
-    /* rsyslog is going to take care of things, so disable console logging */
-    klogctl(8, NULL, 1);
-    /* now we really start the daemon. */
-    int status;
-    status = system("/sbin/rsyslogd -c 4");
-    if (status < 0 || 
-        !WIFEXITED(status) || 
-        WEXITSTATUS(status)  != 0) {
-        printf("Unable to start syslog daemon.\n");
-        fatal_error(1);
-    }
-}
-
-static int setupTerminal(int fd) {
-    struct winsize winsize;
-    int fdn, len;
-    char buf[65535];
-
-    if (ioctl(fd, TIOCGWINSZ, &winsize)) {
-        printf("failed to get winsize");
-        fatal_error(1);
-    }
-
-    winsize.ws_row = 24;
-    winsize.ws_col = 80;
-
-    if (ioctl(fd, TIOCSWINSZ, &winsize)) {
-        printf("failed to set winsize");
-        fatal_error(1);
-    }
-
-    if (!strcmp(ttyname(fd), "/dev/hvc0")) {
-        /* using an HMC on a POWER system, use vt320 */
-        env[ENV_TERM] = "TERM=vt320";
-    } else {
-        /* use the no-advanced-video vt100 definition */
-        env[ENV_TERM] = "TERM=vt100-nav";
-
-        /* unless the user specifies that they want utf8 */
-        if ((fdn = open("/proc/cmdline", O_RDONLY, 0)) != -1) {
-            len = read(fdn, buf, sizeof(buf) - 1);
-            close(fdn);
-            if (len > 0 && strstr(buf, "utf8"))
-                env[ENV_TERM] = "TERM=vt100";
-        }
-    }
-
-    return 0;
-}
-#if defined(__sparc__)
-static int termcmp(struct termios *a, struct termios *b) {
-    if (a->c_iflag != b->c_iflag || a->c_oflag != b->c_oflag ||
-    a->c_cflag != b->c_cflag || a->c_lflag != b->c_lflag)
-    return 1;
-    return memcmp(a->c_cc, b->c_cc, sizeof(a->c_cc));
-}
-#endif
-
-#if !defined(__s390__) && !defined(__s390x__) && !defined(__sparc__)
-static int termcmp(struct termios *a, struct termios *b) {
-    if (a->c_iflag != b->c_iflag || a->c_oflag != b->c_oflag ||
-        a->c_cflag != b->c_cflag || a->c_lflag != b->c_lflag ||
-        a->c_ispeed != b->c_ispeed || a->c_ospeed != b->c_ospeed)
-        return 1;
-    return memcmp(a->c_cc, b->c_cc, sizeof(a->c_cc));
-}
-#endif
-
-static void createDevices(void) {
-    int i;
-
-    /*	unset the umask so devices are created with correct perms
-	and not complemented by the previous umask call */
-
-    mode_t previous_umask = umask(0); 
-
-    for (i = 0; devnodes[i].devname != NULL; i++) {
-        char devname[64];
-        int type = -1;
-
-        snprintf(devname, 63, "/dev/%s", devnodes[i].devname);
-        switch (devnodes[i].type) {
-        case DIRTYPE:
-            if (mkdir(devname, devnodes[i].perms) < 0) {
-                fprintf(stderr, "Unable to create directory %s: %m\n",
-                        devname);
-            }
-            break;
-        case CHARDEV:
-            type = S_IFCHR;
-            break;
-        case BLOCKDEV:
-            type = S_IFBLK;
-            break;
-        }
-        if (type == -1) continue;
-
-        if (mknod(devname, type | devnodes[i].perms, 
-                  makedev(devnodes[i].major, devnodes[i].minor)) < 0)
-            fprintf(stderr, "Unable to create device %s: %m\n", devname);
-    }
-
-    /* Hurray for hacks, this stops /lib/udev/rules.d/65-md-incremental.rules
-       from medling with mdraid sets. */
-    i = creat("/dev/.in_sysinit", 0644);
-    close(i);
-
-    /* Restore umask for minimal side affects */
-    umask(previous_umask); 
-}
-
-static void termReset(void) {
-    /* change to tty1 */
-    ioctl(0, VT_ACTIVATE, 1);
-    /* reset terminal */
-    tcsetattr(0, TCSANOW, &ts);
-    /* Shift in, default color, move down 100 lines */
-    /* ^O        ^[[0m          ^[[100E */
-    printf("\017\033[0m\033[100E\n");
-}
-
-/* reboot handler */
-static void sigintHandler(int signum) {
-    termReset();
-    shutDown(getKillPolicy(), REBOOT);
-}
-
-/* halt handler */
-static void sigUsr1Handler(int signum) {
-    termReset();
-    shutDown(getKillPolicy(), HALT);
-}
-
-/* poweroff handler */
-static void sigUsr2Handler(int signum) {
-    termReset();
-    shutDown(getKillPolicy(), POWEROFF);
-}
-
-static int getKillPolicy(void) {
-    int fd;
-    int len;
-    char buf[1024];
-
-    /* look through /proc/cmdline for special options */
-    if ((fd = open("/proc/cmdline", O_RDONLY,0)) > 0) {
-        len = read(fd, buf, sizeof(buf) - 1);
-        close(fd);
-        if ((len > 0) && strstr(buf, "nokill"))
-            return 0;
-    }
-    return 1;
-}
-
-/* Looks through /proc/cmdline for remote syslog paramters. */
-static void getSyslog(char *addr) {
-    int fd;
-    int len;
-    char buf[1024];
-
-    /* assume nothing gets found */
-    addr[0] = '\0';
-    if ((fd = open("/proc/cmdline", O_RDONLY,0)) <= 0) {
-        return;
-    }
-    len = read(fd, buf, sizeof(buf) - 1);
-    close(fd);
-    buf[len] = '\0';
-    
-    /* Parse the command line into argument vector using glib */
-    int i;
-    int argc;
-    char** argv;
-    GError* err = NULL;
-    if (!g_shell_parse_argv(buf, &argc, &argv, &err )) {
-        g_error_free(err);
-        return;
-    }
-    for (i = 0; i < argc; ++i) {
-        /* find what we are looking for */
-        if (!strncmp(argv[i], "syslog=", 7)) {
-            strncpy(addr, argv[i] + 7, 127);
-            addr[127] = '\0';
-            break;
-        }
-    }
-    g_strfreev(argv);
-
-    /* address can be either a hostname or IPv4 or IPv6, with or without port;
-       thus we only allow the following characters in the address: letters and
-       digits, dots, colons, slashes, dashes and square brackets */
-    if (!g_regex_match_simple("^[\\w.:/\\-\\[\\]]*$", addr, 0, 0)) {
-        /* the parameter is malformed, disable its use */
-        addr[0] = '\0';
-        printf("The syslog= command line parameter is malformed and will be\n");
-        printf("ignored by the installer.\n");
-        sleep(5);
-    }
-
-}
-
-static int getInitPid(void) {
-    int fd = 0, pid = -1, ret;
-    char * buf = calloc(1, 10);
-
-    fd = open("/var/run/init.pid", O_RDONLY);
-    if (fd < 0) {
-        fprintf(stderr, "Unable to find pid of init!!!\n");
-        return -1;
-    }
-    ret = read(fd, buf, 9);
-    close(fd);
-    ret = sscanf(buf, "%d", &pid);
-    return pid;
-}
-
-static void copyErrorFn (char *msg) {
-    printf(msg);
-}
-
-void initSegvHandler(int signum) {
-    void *array[30];
-    size_t i;
-    const char const * const errmsgs[] = {
-        "init received SIG",
-        "!  Backtrace:\n",
-        "init exited unexpectedly!  Backtrace:\n",
-    };
-
-    /* XXX This should really be in a glibc header somewhere... */
-    extern const char *const sys_sigabbrev[NSIG];
-
-    signal(signum, SIG_DFL); /* back to default */
-
-    if (signum == 0) {
-        i = write(STDERR_FILENO, errmsgs[2], strlen(errmsgs[2]));
-    } else {
-        i = write(STDERR_FILENO, errmsgs[0], strlen(errmsgs[0]));
-        i = write(STDERR_FILENO, sys_sigabbrev[signum],
-                strlen(sys_sigabbrev[signum]));
-        i = write(STDERR_FILENO, errmsgs[1], strlen(errmsgs[1]));
-    }
-
-    i = backtrace (array, 30);
-    backtrace_symbols_fd(array, i, STDERR_FILENO);
-    _exit(1);
-}
-
-void initExitHandler(void)
-{
-    if (expected_exit)
-        return;
-
-    initSegvHandler(0);
-}
-
-static void setupBacktrace(void)
-{
-    void *array;
-
-    signal(SIGSEGV, initSegvHandler);
-    signal(SIGABRT, initSegvHandler);
-    atexit(initExitHandler);
-
-    /* Turns out, there's an initializer at the top of backtrace() that
-     * (on some arches) calls dlopen(). dlopen(), unsurprisingly, calls
-     * malloc(). So, call backtrace() early in signal handler setup so
-     * we can later safely call it from the signal handler itself. */
-    backtrace(&array, 1);
-}
-
-int main(int argc, char **argv) {
-    pid_t installpid, childpid;
-    int waitStatus;
-    int fd = -1;
-    int doShutdown =0;
-    reboot_action shutdown_method = HALT;
-    int isSerial = 0;
-    char * console = NULL;
-    int doKill = 1;
-    char * argvc[15];
-    char ** argvp = argvc;
-    char twelve = 12;
-    struct serial_struct si;
-    int i, disable_keys;
-
-    if (!strncmp(basename(argv[0]), "poweroff", 8)) {
-        printf("Running poweroff...\n");
-        fd = getInitPid();
-        if (fd > 0)
-            kill(fd, SIGUSR2);
-        doExit(0);
-    } else if (!strncmp(basename(argv[0]), "halt", 4)) {
-        printf("Running halt...\n");
-        fd = getInitPid();
-        if (fd > 0)
-            kill(fd, SIGUSR1);
-        doExit(0);
-    } else if (!strncmp(basename(argv[0]), "reboot", 6)) {
-        printf("Running reboot...\n");
-        fd = getInitPid();
-        if (fd > 0)
-            kill(fd, SIGINT);
-        doExit(0);
-    }
-
-    /* turn off screen blanking */
-    printstr("\033[9;0]");
-    printstr("\033[8]");
-
-    umask(022);
-
-    /* set up signal handler */
-    setupBacktrace();
-
-    printstr("\nGreetings.\n");
-
-    printf("anaconda installer init version %s starting\n", VERSION);
-
-    printf("mounting /proc filesystem... "); 
-    if (mount("/proc", "/proc", "proc", 0, NULL))
-        fatal_error(1);
-    printf("done\n");
-
-    printf("creating /dev filesystem... "); 
-    if (mount("/dev", "/dev", "tmpfs", 0, NULL))
-        fatal_error(1);
-    createDevices();
-    printf("done\n");
-    printf("starting udev...");
-    if ((childpid = fork()) == 0) {
-        execl("/sbin/udevd", "/sbin/udevd", "--daemon", NULL);
-        exit(1);
-    }
-    
-    /* wait at least until the udevd process that we forked exits */
-    do {
-        pid_t retpid;
-        int waitstatus;
-
-        retpid = wait(&waitstatus);
-        if (retpid == -1) {
-            if (errno == EINTR)
-                continue;
-            /* if the child exited before we called waitpid, we can get
-             * ECHILD without anything really being wrong; we just lost
-             * the race.*/
-            if (errno == ECHILD)
-                break;
-            printf("init: error waiting on udevd: %m\n");
-            exit(1);
-        } else if ((retpid == childpid) && WIFEXITED(waitstatus)) {
-            break;
-        }
-    } while (1);
-    
-    if (fork() == 0) {
-        execl("/sbin/udevadm", "udevadm", "control", "--env=ANACONDA=1", NULL);
-        exit(1);
-    }
-    printf("done\n");
-
-    printf("mounting /dev/pts (unix98 pty) filesystem... "); 
-    if (mount("/dev/pts", "/dev/pts", "devpts", 0, NULL))
-        fatal_error(1);
-    printf("done\n");
-
-    printf("mounting /sys filesystem... "); 
-    if (mount("/sys", "/sys", "sysfs", 0, NULL))
-        fatal_error(1);
-    printf("done\n");
-
-    /* these args are only for testing from commandline */
-    for (i = 1; i < argc; i++) {
-        if (!strcmp (argv[i], "serial")) {
-            isSerial = 1;
-            break;
-        }
-    }
-
-    doKill = getKillPolicy();
-
-#if !defined(__s390__) && !defined(__s390x__)
-    static struct termios orig_cmode;
-    struct termios cmode, mode;
-    int cfd;
-    
-    cfd =  open("/dev/console", O_RDONLY);
-    tcgetattr(cfd,&orig_cmode);
-    close(cfd);
-
-    cmode = orig_cmode;
-    cmode.c_lflag &= (~ECHO);
-
-    cfd = open("/dev/console", O_WRONLY);
-    tcsetattr(cfd,TCSANOW,&cmode);
-    close(cfd);
-
-    /* handle weird consoles */
-#if defined(__powerpc__)
-    char * consoles[] = { "/dev/hvc0", /* hvc for JS20 */
-
-                          "/dev/hvsi0", "/dev/hvsi1",
-                          "/dev/hvsi2", /* hvsi for POWER5 */
-                          NULL };
-#elif defined (__ia64__)
-    char * consoles[] = { "/dev/ttySG0", "/dev/xvc0", "/dev/hvc0", NULL };
-#elif defined (__i386__) || defined (__x86_64__)
-    char * consoles[] = { "/dev/xvc0", "/dev/hvc0", NULL };
-#else
-    char * consoles[] = { NULL };
-#endif
-    for (i = 0; consoles[i] != NULL; i++) {
-        if ((fd = open(consoles[i], O_RDWR)) >= 0 && !tcgetattr(fd, &mode) && !termcmp(&cmode, &mode)) {
-            printf("anaconda installer init version %s using %s as console\n",
-                   VERSION, consoles[i]);
-            isSerial = 3;
-            console = strdup(consoles[i]);
-            break;
-        }
-        close(fd);
-    }
-
-    cfd = open("/dev/console", O_WRONLY);
-    tcsetattr(cfd,TCSANOW,&orig_cmode);
-    close(cfd); 
-
-    if ((fd < 0) && (ioctl (0, TIOCLINUX, &twelve) < 0)) {
-        isSerial = 2;
-
-        if (ioctl(0, TIOCGSERIAL, &si) == -1) {
-            isSerial = 0;
-        }
-    }
-
-    if (isSerial && (isSerial != 3)) {
-        char *device = "/dev/ttyS0";
-
-        printf("anaconda installer init version %s using a serial console\n", 
-               VERSION);
-
-        if (isSerial == 2)
-            device = "/dev/console";
-        fd = open(device, O_RDWR, 0);
-        if (fd < 0)
-            device = "/dev/tts/0";
-
-        if (fd < 0) {
-            printf("failed to open %s\n", device);
-            fatal_error(1);
-        }
-
-        setupTerminal(fd);
-    } else if (isSerial == 3) {
-        setupTerminal(fd);
-    } else if (fd < 0)  {
-        fd = open("/dev/tty1", O_RDWR, 0);
-        if (fd < 0)
-            fd = open("/dev/vc/1", O_RDWR, 0);
-
-        if (fd < 0) {
-            printf("failed to open /dev/tty1 and /dev/vc/1");
-            fatal_error(1);
-        }
-    }
-
-    setsid();
-    if (ioctl(0, TIOCSCTTY, NULL)) {
-        printf("could not set new controlling tty\n");
-    }
-
-    dup2(fd, 0);
-    dup2(fd, 1);
-    dup2(fd, 2);
-    if (fd > 2)
-        close(fd);
-#else
-    dup2(0, 1);
-    dup2(0, 2);
-#endif
-
-    /* disable Ctrl+Z, Ctrl+C, etc ... but not in rescue mode */
-    disable_keys = 1;
-    if (argc > 1)
-        if (strstr(argv[1], "rescue"))
-            disable_keys = 0;
-
-    if (disable_keys) {
-        tcgetattr(0, &ts);
-        ts.c_iflag &= ~BRKINT;
-        ts.c_iflag |= IGNBRK;
-        ts.c_iflag &= ~ISIG;
-        tcsetattr(0, TCSANOW, &ts);
-    }
-
-    int ret;
-    ret = sethostname("localhost.localdomain", 21);
-    /* the default domainname (as of 2.0.35) is "(none)", which confuses 
-     glibc */
-    ret = setdomainname("", 0);
-
-    printf("trying to remount root filesystem read write... ");
-    if (mount("/", "/", "ext2", MS_REMOUNT | MS_MGC_VAL, NULL)) {
-        fatal_error(1);
-    }
-    printf("done\n");
-
-    /* we want our /tmp to be tmpfs, but we also want to let people hack
-     * their initrds to add things like a ks.cfg, so this has to be a little
-     * tricky */
-    rename("/tmp", "/oldtmp");
-    mkdir("/tmp", 0755);
-
-    printf("mounting /tmp as tmpfs... ");
-    if (mount("none", "/tmp", "tmpfs", 0, "size=250m"))
-        fatal_error(1);
-    printf("done\n");
-
-    copyDirectory("/oldtmp", "/tmp", copyErrorFn, copyErrorFn);
-    unlink("/oldtmp");
-
-    /* Now we have some /tmp space set up, and /etc and /dev point to
-       it. We should be in pretty good shape. */
-    startSyslog();
-
-    /* write out a pid file */
-    if ((fd = open("/var/run/init.pid", O_WRONLY|O_CREAT, 0644)) > 0) {
-        char * buf = malloc(10);
-        int ret;
-
-        snprintf(buf, 9, "%d", getpid());
-        ret = write(fd, buf, strlen(buf));
-        close(fd);
-        free(buf);
-    } else {
-        printf("unable to write init.pid (%d): %m\n", errno);
-        sleep(2);
-    }
-
-    /* D-Bus */
-    if (fork() == 0) {
-        execl("/sbin/dbus-uuidgen", "/sbin/dbus-uuidgen", "--ensure", NULL);
-        doExit(1);
-    }
-
-    if (fork() == 0) {
-        execl("/sbin/dbus-daemon", "/sbin/dbus-daemon", "--system", NULL);
-        doExit(1);
-    }
-
-    sleep(2);
-
-    /* Go into normal init mode - keep going, and then do a orderly shutdown
-       when:
-
-       1) /bin/install exits
-       2) we receive a SIGHUP 
-    */
-
-    printf("running install...\n"); 
-
-    setsid();
-
-    if (!(installpid = fork())) {
-        /* child */
-        *argvp++ = "/sbin/loader";
-
-        if (isSerial == 3) {
-            *argvp++ = "--virtpconsole";
-            *argvp++ = console;
-        }
-
-        *argvp++ = NULL;
-
-        printf("running %s\n", argvc[0]);
-        execve(argvc[0], argvc, env);
-
-        shutDown(1, HALT);
-    }
-
-    /* signal handlers for halt/poweroff */
-    signal(SIGUSR1, sigUsr1Handler);
-    signal(SIGUSR2, sigUsr2Handler);
-
-    /* set up the ctrl+alt+delete handler to kill our pid, not pid 1 */
-    signal(SIGINT, sigintHandler);
-    if ((fd = open("/proc/sys/kernel/cad_pid", O_WRONLY)) != -1) {
-        char buf[7];
-        size_t count;
-        sprintf(buf, "%d", getpid());
-        count = write(fd, buf, strlen(buf));
-        close(fd);
-        /* if we succeeded in writing our pid, turn off the hard reboot
-           ctrl-alt-del handler */
-        if (count == strlen(buf) &&
-            (fd = open("/proc/sys/kernel/ctrl-alt-del", O_WRONLY)) != -1) {
-            int ret;
-
-            ret = write(fd, "0", 1);
-            close(fd);
-        }
-    }
-    
-    while (!doShutdown) {
-        pid_t childpid;
-        childpid = wait(&waitStatus);
-
-        if (childpid == installpid) {
-            doShutdown = 1;
-            ioctl(0, VT_ACTIVATE, 1);
-        }
-    }
-
-    if (!WIFEXITED(waitStatus) ||
-        (WIFEXITED(waitStatus) && WEXITSTATUS(waitStatus))) {
-        shutdown_method = DELAYED_REBOOT;
-        printf("install exited abnormally [%d/%d] ", WIFEXITED(waitStatus),
-                                                     WEXITSTATUS(waitStatus));
-        if (WIFSIGNALED(waitStatus)) {
-            printf("-- received signal %d", WTERMSIG(waitStatus));
-        }
-        printf("\n");
-    } else {
-        shutdown_method = REBOOT;
-    }
-
-    shutDown(doKill, shutdown_method);
-
-    return 0;
-}
-
-/* vim:tw=78:ts=4:et:sw=4
- */
diff --git a/loader/init.h b/loader/init.h
deleted file mode 100644
index e1e5b70..0000000
--- a/loader/init.h
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * init.h
- *
- * Copyright (C) 2009  Red Hat, Inc.  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 as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * 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, see <http://www.gnu.org/licenses/>.
- */
-#ifndef INIT_H
-#define INIT_H
-
-typedef enum {
-	REBOOT,
-	POWEROFF,
-	HALT,
-        /* gives user a chance to read the trace before scrolling the text out
-           with disk unmounting and termination info */
-        DELAYED_REBOOT
-} reboot_action;
-
-#endif /* INIT_H */
diff --git a/loader/kbd.c b/loader/kbd.c
deleted file mode 100644
index b94f920..0000000
--- a/loader/kbd.c
+++ /dev/null
@@ -1,164 +0,0 @@
-/*
- * kbd.c - keyboard handling
- *
- * Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002  Red Hat, Inc.
- * 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 as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * 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, see <http://www.gnu.org/licenses/>.
- *
- * Author(s): Erik Troan <ewt@xxxxxxxxxx>
- *            Matt Wilson <msw@xxxxxxxxxx>
- *            Michael Fulbright <msf@xxxxxxxxxx>
- *            Jeremy Katz <katzj@xxxxxxxxxx>
- */
-
-#include <alloca.h>
-#include <errno.h>
-#include <newt.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "loader.h"
-#include "loadermisc.h"
-#include "lang.h"
-#include "windows.h"
-
-#include "../isys/stubs.h"
-#include "../isys/lang.h"
-#include "../isys/log.h"
-
-/* boot flags */
-extern uint64_t flags;
-
-int chooseKeyboard(struct loaderData_s * loaderData, char ** kbdtypep) {
-    int num = -1;
-    int rc;
-    gzFile f;
-    struct kmapHeader hdr;
-    struct kmapInfo * infoTable;
-    struct langInfo * languages;
-    int numLanguages;
-    char ** kbds;
-    char buf[16384]; 			/* I hope this is big enough */
-    int i;
-    char * defkbd = loaderData->kbd ? loaderData->kbd : NULL;
-    char *lang;
-
-#if defined(__s390__) || defined(__s390x__)
-    return LOADER_NOOP;
-#endif
-
-    if (FL_SERIAL (flags) || FL_VIRTPCONSOLE(flags)) return LOADER_NOOP;
-
-    numLanguages = getLangInfo(&languages);
-
-    lang = getenv("LANG");
-    if (!lang)
-       lang = loaderData->lang;
-
-    if (!defkbd && lang) {
-	for (i = 0; i < numLanguages; i++) {
-	    if (!strncmp(languages[i].lc_all, lang, 2)) {
-		defkbd = languages[i].keyboard;
-		break;
-	    }
-	}
-    }
-
-    if (!defkbd)
-	defkbd = "us";
-
-    f = gunzip_open("/etc/keymaps.gz");
-    if (!f) {
-	errorWindow("cannot open /etc/keymaps.gz: %s");
-	return LOADER_ERROR;
-    }
-
-    if (gunzip_read(f, &hdr, sizeof(hdr)) != sizeof(hdr)) {
-	errorWindow("failed to read keymaps header: %s");
-	gunzip_close(f);
-	return LOADER_ERROR;
-    }
-
-    logMessage(INFO, "%d keymaps are available", hdr.numEntries);
-
-    i = hdr.numEntries * sizeof(*infoTable);
-    infoTable = alloca(i);
-    if (gunzip_read(f, infoTable, i) != i) {
-	errorWindow("failed to read keymap information: %s");
-	gunzip_close(f);
-	return LOADER_ERROR;
-    }
-
-    if (num == -1 ) {
-	kbds = alloca(sizeof(*kbds) * (hdr.numEntries + 1));
-	for (i = 0; i < hdr.numEntries; i++)  {
-	    kbds[i] = infoTable[i].name;
-	}
-
-	kbds[i] = NULL;
-	qsort(kbds, i, sizeof(*kbds), simpleStringCmp);
-
-	for (i = 0; i < hdr.numEntries; i++) 
-	    if (!strcmp(kbds[i], defkbd)) 
-		num = i;
-
-	rc = newtWinMenu(_("Keyboard Type"), 
-			_("What type of keyboard do you have?"),
-		        40, 5, 5, 8, kbds, &num, _("OK"), _("Back"), NULL);
-	if (rc == 2) return LOADER_BACK;
-
-	/* num needs to index the right keyboard infoTable */
-	for (i = 0; i < hdr.numEntries; i++)
-	    if (!strcmp(kbds[num], infoTable[i].name)) break;
-	num = i;
-    }
-
-    rc = 0;
-
-    for (i = 0; i < num; i++) {
-	if (gunzip_read(f, buf, infoTable[i].size) != infoTable[i].size) {
-	    logMessage(ERROR, "error reading %d bytes from file: %m",
-		       infoTable[i].size);
-	    gunzip_close(f);
-	    rc = LOADER_ERROR;
-	}
-    }
-
-    if (!rc) rc = loadKeymap(f);
-
-    /* normalize the error condition */
-    /* MSWFIXME - do we want to warn the user that setting the
-       keyboard didn't work?
-    */
-    if (rc != 0)
-	rc = LOADER_ERROR;
-    else
-        gunzip_close(f);
-
-    loaderData->kbd = strdup(infoTable[num].name);
-
-    return rc;
-}
-
-void setKickstartKeyboard(struct loaderData_s * loaderData, int argc, 
-                          char ** argv) {
-    if (argc < 2) {
-        logMessage(ERROR, "no argument passed to keyboard kickstart command");
-        return;
-    }
-
-    loaderData->kbd = argv[1];
-    loaderData->kbd_set = 1;
-}
diff --git a/loader/kbd.h b/loader/kbd.h
deleted file mode 100644
index 26c7111..0000000
--- a/loader/kbd.h
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * kbd.h
- *
- * Copyright (C) 2007  Red Hat, Inc.  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 as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * 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, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef H_KBD
-#define H_KBD
-
-int chooseKeyboard(struct loaderData_s * loaderData, char ** kbdtypep);
-void setKickstartKeyboard(struct loaderData_s * loaderData, int argc, 
-                          char ** argv);
-
-#endif
diff --git a/loader/keymaps-i386 b/loader/keymaps-i386
deleted file mode 100644
index 93f2e58d10c66c2586ad2f42deccdecaec16b177..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001

literal 12173
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
V7~sRTFNEiTfZ~fQc(x<}`9D*L!)E{h

diff --git a/loader/keymaps-ppc b/loader/keymaps-ppc
deleted file mode 100644
index 914f4bfd6a36a0b42c8fb5f61284a4c15ee26b8d..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001

literal 12871
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

diff --git a/loader/keymaps-x86_64 b/loader/keymaps-x86_64
deleted file mode 100644
index 93f2e58d10c66c2586ad2f42deccdecaec16b177..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001

literal 12173
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
V7~sRTFNEiTfZ~fQc(x<}`9D*L!)E{h

diff --git a/loader/kickstart.c b/loader/kickstart.c
deleted file mode 100644
index 26c4aab..0000000
--- a/loader/kickstart.c
+++ /dev/null
@@ -1,559 +0,0 @@
-/*
- * kickstart.c - kickstart file handling
- *
- * Copyright (C) 1999, 2000, 2001, 2002, 2003  Red Hat, Inc.
- * 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 as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * 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, see <http://www.gnu.org/licenses/>.
- *
- * Author(s): Erik Troan <ewt@xxxxxxxxxx>
- *            Matt Wilson <msw@xxxxxxxxxx>
- *            Michael Fulbright <msf@xxxxxxxxxx>
- *            Jeremy Katz <katzj@xxxxxxxxxx>
- */
-
-#include <alloca.h>
-#include <ctype.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <newt.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/stat.h>
-#include <unistd.h>
-#include <glib.h>
-
-#include "loader.h"
-#include "loadermisc.h"
-#include "lang.h"
-#include "kickstart.h"
-#include "modules.h"
-
-#include "kbd.h"
-#include "driverdisk.h"
-#include "net.h"
-#include "method.h"
-
-#include "nfsinstall.h"
-#include "urlinstall.h"
-#include "cdinstall.h"
-#include "hdinstall.h"
-
-#include "../isys/imount.h"
-#include "../isys/isys.h"
-#include "../isys/log.h"
-
-/* boot flags */
-extern uint64_t flags;
-
-struct ksCommandNames {
-    int code;
-    char * name;
-    void (*setupData) (struct loaderData_s *loaderData,
-                       int argc, char ** argv);
-} ;
-
-struct ksCommand {
-    int code, argc;
-    char ** argv;
-};
-
-static void setTextMode(struct loaderData_s * loaderData, int argc, 
-                        char ** argv);
-static void setGraphicalMode(struct loaderData_s * loaderData, int argc, 
-                             char ** argv);
-static void setCmdlineMode(struct loaderData_s * loaderData, int argc, 
-                           char ** argv);
-static void setSELinux(struct loaderData_s * loaderData, int argc, 
-                       char ** argv);
-static void setPowerOff(struct loaderData_s * loaderData, int argc, 
-                        char ** argv);
-static void setHalt(struct loaderData_s * loaderData, int argc, 
-                    char ** argv);
-static void setShutdown(struct loaderData_s * loaderData, int argc, 
-                        char ** argv);
-static void setMediaCheck(struct loaderData_s * loaderData, int argc, 
-                          char ** argv);
-static void setUpdates(struct loaderData_s * loaderData, int argc,
-                       char ** argv);
-static void setVnc(struct loaderData_s * loaderData, int argc,
-                       char ** argv);
-
-struct ksCommandNames ksTable[] = {
-    { KS_CMD_NFS, "nfs", setKickstartNfs },
-    { KS_CMD_CDROM, "cdrom", setKickstartCD },
-    { KS_CMD_HD, "harddrive", setKickstartHD },
-    { KS_CMD_TEXT, "text", setTextMode },
-    { KS_CMD_GRAPHICAL, "graphical", setGraphicalMode },
-    { KS_CMD_URL, "url", setKickstartUrl },
-    { KS_CMD_NETWORK, "network", setKickstartNetwork },
-    { KS_CMD_KEYBOARD, "keyboard", setKickstartKeyboard },
-    { KS_CMD_LANG, "lang", setKickstartLanguage },
-    { KS_CMD_DD, "driverdisk", useKickstartDD },
-    { KS_CMD_DEVICE, "device", loadKickstartModule },
-    { KS_CMD_CMDLINE, "cmdline", setCmdlineMode },
-    { KS_CMD_SELINUX, "selinux", setSELinux },
-    { KS_CMD_POWEROFF, "poweroff", setPowerOff },
-    { KS_CMD_HALT, "halt", setHalt },
-    { KS_CMD_SHUTDOWN, "shutdown", setShutdown },
-    { KS_CMD_MEDIACHECK, "mediacheck", setMediaCheck },
-    { KS_CMD_UPDATES, "updates", setUpdates },
-    { KS_CMD_VNC, "vnc", setVnc },
-    { KS_CMD_NONE, NULL, NULL }
-};
-
-struct ksCommand * commands = NULL;
-int numCommands = 0;
-
-int ksReadCommands(char * cmdFile) {
-    int fd;
-    char * buf;
-    struct stat sb;
-    char * start, * end, * chptr;
-    char oldch;
-    int line = 0;
-    gint argc = 0;
-    gchar **argv = NULL;
-    GError *optErr = NULL;
-    int inSection = 0; /* in a section such as %post, %pre or %packages */
-    struct ksCommandNames * cmd;
-    int commandsAlloced = 5;
-
-    if ((fd = open(cmdFile, O_RDONLY)) < 0) {
-        startNewt();
-        newtWinMessage(_("Kickstart Error"), _("OK"),
-                       _("Error opening kickstart file %s: %m"),
-                       cmdFile);
-        return LOADER_ERROR;
-    }
-
-    fstat(fd, &sb);
-    buf = alloca(sb.st_size + 1);
-    if (read(fd, buf, sb.st_size) != sb.st_size) {
-        startNewt();
-        newtWinMessage(_("Kickstart Error"), _("OK"),
-                       _("Error reading contents of kickstart file %s: %m"),
-                       cmdFile);
-        close(fd);
-        return LOADER_ERROR;
-    }
-
-    close(fd);
-
-    buf[sb.st_size] = '\0';
-
-    commands = malloc(sizeof(*commands) * commandsAlloced);
-
-    start = buf;
-    while (*start && !inSection) {
-        line++;
-        if (!(end = strchr(start, '\n')))
-            end = start + strlen(start);
-
-        oldch = *end;
-        *end = '\0';
-
-        while (*start && isspace(*start)) start++;
-
-        chptr = end - 1;
-        while (chptr > start && isspace(*chptr)) chptr--;
-        
-        if (isspace(*chptr)) 
-            *chptr = '\0';
-        else
-            *(chptr + 1) = '\0';
-
-        if (!*start || *start == '#' || !strncmp(start, "%include", 8)) {
-            /* keep parsing the file */
-        } else if (*start == '%') {
-            /* assumed - anything starting with %something is a section */
-            inSection = 1;
-        } else if  (*chptr == '\\') {
-            /* JKFIXME: this should be handled better, but at least we 
-             * won't segfault now */
-        } else {
-            if (!g_shell_parse_argv(start, &argc, &argv, &optErr) && argc) {
-                newtWinMessage(_("Kickstart Error"), _("OK"),
-                               _("Error in %s on line %d of kickstart "
-                                 "file %s."), argv[0], line, cmdFile);
-                g_error_free(optErr);
-            } else if (!argc) {
-                newtWinMessage(_("Kickstart Error"), _("OK"),
-                               _("Missing options on line %d of kickstart "
-                                 "file %s."), line, cmdFile);
-            } else {
-                for (cmd = ksTable; cmd->name; cmd++)
-                    if (!strcmp(cmd->name, argv[0])) break;
-                
-                if (cmd->name) {
-                    if (numCommands == commandsAlloced) {
-                        commandsAlloced += 5;
-                        commands = realloc(commands,
-                                           sizeof(*commands) * commandsAlloced);
-                    }
-                    
-                    commands[numCommands].code = cmd->code;
-                    commands[numCommands].argc = argc;
-                    commands[numCommands].argv = argv;
-                    numCommands++;
-                }
-            }
-        }
-        
-        if (oldch)
-            start = end + 1;
-        else
-            start = end;
-    }
-    
-    return 0;
-}
-
-
-int ksHasCommand(int cmd) {
-    int i;
-
-    for(i = 0; i < numCommands; i++)
-	if (commands[i].code == cmd) return 1;
-
-    return 0;
-}
-
-int ksGetCommand(int cmd, char ** last, int * argc, char *** argv) {
-    int i = 0;
-    
-    if (last) {
-        for (i = 0; i < numCommands; i++) {
-            if (commands[i].argv == last) break;
-        }
-        
-        i++;
-    }
-
-    for (; i < numCommands; i++) {    
-        if (commands[i].code == cmd) {
-            if (argv) *argv = commands[i].argv;
-            if (argc) *argc = commands[i].argc;
-            return 0;
-        }
-    }
-    
-    return 1;
-}
-
-int kickstartFromRemovable(char *kssrc) {
-    struct device ** devices;
-    char *p, *kspath;
-    int i, rc;
-
-    logMessage(INFO, "doing kickstart from removable media");
-    devices = getDevices(DEVICE_DISK);
-    /* usb can take some time to settle, even with the various hacks we
-     * have in place. some systems use portable USB CD-ROM drives, try to
-     * make sure there really isn't one before bailing. */
-    for (i = 0; !devices && i < 10; ++i) {
-        logMessage(INFO, "sleeping to wait for a USB disk");
-        sleep(2);
-        devices = getDevices(DEVICE_DISK);
-    }
-    if (!devices) {
-        logMessage(ERROR, "no disks");
-        return 1;
-    }
-
-    for (i = 0; devices[i]; i++) {
-        if (devices[i]->priv.removable == 1) {
-            logMessage(INFO, "first removable media is %s", devices[i]->device);
-            break;
-        }
-    }
-
-    if (!devices[i] || (devices[i]->priv.removable == 0)) {
-        logMessage(ERROR, "no removable devices");
-        return 1;
-    }
-
-    /* format is floppy:[/path/to/ks.cfg] */
-    kspath = "";
-    p = strchr(kssrc, ':');
-    if (p)
-	kspath = p + 1;
-
-    if (!p || strlen(kspath) < 1)
-	kspath = "/ks.cfg";
-
-    if ((rc=getKickstartFromBlockDevice(devices[i]->device, kspath))) {
-	if (rc == 3) {
-	    startNewt();
-	    newtWinMessage(_("Error"), _("OK"),
-			   _("Cannot find ks.cfg on removable media."));
-	}
-	return 1;
-    }
-
-    return 0;
-}
-
-
-/* given a device name (w/o '/dev' on it), try to get ks file */
-/* Error codes: 
-      1 - could not create device node
-      2 - could not mount device as ext2, vfat, or iso9660
-      3 - kickstart file named path not there
-*/
-int getKickstartFromBlockDevice(char *device, char *path) {
-    return getFileFromBlockDevice(device, path, "/tmp/ks.cfg");
-}
-
-static char *newKickstartLocation(const char *origLocation) {
-    const char *location;
-    char *retval = NULL;
-    newtComponent f, okay, cancel, answer, locationEntry;
-    newtGrid grid, buttons;
-
-    startNewt();
-
-    locationEntry = newtEntry(-1, -1, NULL, 60, &location, NEWT_FLAG_SCROLL);
-    newtEntrySet(locationEntry, origLocation, 1);
-
-    /* button bar at the bottom of the window */
-    buttons = newtButtonBar(_("OK"), &okay, _("Cancel"), &cancel, NULL);
-
-    grid = newtCreateGrid(1, 3);
-
-    newtGridSetField(grid, 0, 0, NEWT_GRID_COMPONENT,
-                     newtTextboxReflowed(-1, -1, _("Unable to download the kickstart file.  Please modify the kickstart parameter below or press Cancel to proceed as an interactive installation."), 60, 0, 0, 0),
-                     0, 0, 0, 0, NEWT_ANCHOR_LEFT, 0);
-    newtGridSetField(grid, 0, 1, NEWT_GRID_COMPONENT, locationEntry,
-                     0, 1, 0, 0, NEWT_ANCHOR_LEFT, 0);
-    newtGridSetField(grid, 0, 2, NEWT_GRID_SUBGRID, buttons,
-                     0, 1, 0, 0, 0, NEWT_GRID_FLAG_GROWX);
-
-    f = newtForm(NULL, NULL, 0);
-    newtGridAddComponentsToForm(grid, f, 1);
-    newtGridWrappedWindow(grid, _("Error downloading kickstart file"));
-    newtGridFree(grid, 1);
-
-    /* run the form */
-    answer = newtRunForm(f);
-
-    if (answer != cancel)
-        retval = strdup(location);
-
-    newtFormDestroy(f);
-    newtPopWindow();
-
-    return retval;
-}
-
-int isKickstartFileRemote(char *ksFile) {
-    char *location = NULL;
-
-    if (ksFile == NULL) {
-        return 0;
-    }
-
-    if (!strcmp(ksFile, "ks")) {
-       return 1;
-    } else if (!strncmp(ksFile, "ks=", 3)) {
-        location = ksFile + 3;
-    }
-
-    if (!strncmp(location, "http", 4) ||
-        !strncmp(location, "ftp://";, 6) ||
-        !strncmp(location, "nfs:", 4)) {
-        return 1;
-    } else {
-        return 0;
-    }
-}
-
-void getKickstartFile(struct loaderData_s *loaderData) {
-    char *c;
-    int rc = 1;
-
-    /* Chop off the parameter name, if given. */
-    if (!strncmp(loaderData->ksFile, "ks=", 3))
-        c = loaderData->ksFile+3;
-    else
-        c = loaderData->ksFile;
-
-    while (rc != 0) {
-        if (!strncmp(c, "ks", 2)) {
-            rc = kickstartFromNfs(NULL, loaderData);
-            loaderData->ksFile = strdup("/tmp/ks.cfg");
-        } else if (!strncmp(c, "http", 4) || !strncmp(c, "ftp://";, 6)) {
-            rc = kickstartFromUrl(c, loaderData);
-            loaderData->ksFile = strdup("/tmp/ks.cfg");
-        } else if (!strncmp(c, "nfs:", 4)) {
-            rc = kickstartFromNfs(c+4, loaderData);
-            loaderData->ksFile = strdup("/tmp/ks.cfg");
-        } else if (!strncmp(c, "floppy", 6)) {
-            rc = kickstartFromRemovable(c);
-            loaderData->ksFile = strdup("/tmp/ks.cfg");
-        } else if (!strncmp(c, "hd:", 3)) {
-            rc = kickstartFromHD(c);
-            loaderData->ksFile = strdup("/tmp/ks.cfg");
-        } else if (!strncmp(c, "bd:", 3)) {
-            rc = kickstartFromBD(c);
-            loaderData->ksFile = strdup("/tmp/ks.cfg");
-        } else if (!strncmp(c, "cdrom", 5)) {
-            rc = kickstartFromCD(c);
-            loaderData->ksFile = strdup("/tmp/ks.cfg");
-        } else if (!strncmp(c, "file:", 5)) {
-            loaderData->ksFile = c+5;
-            break;
-        }
-
-        if (rc != 0) {
-            char *newLocation;
-
-            if (!strcmp(c, "ks"))
-                newLocation = newKickstartLocation("");
-            else
-                newLocation = newKickstartLocation(c);
-
-            if (loaderData->ksFile != NULL)
-                free(loaderData->ksFile);
-
-            if (newLocation != NULL) {
-               loaderData->ksFile = strdup(newLocation);
-               free(newLocation);
-               return getKickstartFile(loaderData);
-            }
-            else
-               return;
-        }
-    }
-
-    flags |= LOADER_FLAGS_KICKSTART;
-    return;
-}
-
-static void setVnc(struct loaderData_s * loaderData, int argc,
-                   char ** argv) {
-    logMessage(INFO, "kickstart forcing graphical mode over vnc");
-    flags |= LOADER_FLAGS_GRAPHICAL | LOADER_FLAGS_EARLY_NETWORKING;
-    return;
-}
-
-static void setUpdates(struct loaderData_s * loaderData, int argc,
-                       char ** argv) {
-   if (argc == 1)
-      flags |= LOADER_FLAGS_UPDATES;
-   else if (argc == 2)
-      loaderData->updatessrc = strdup(argv[1]);
-   else
-      logMessage(WARNING, "updates command given with incorrect arguments");
-}
-
-static void setTextMode(struct loaderData_s * loaderData, int argc, 
-                        char ** argv) {
-    logMessage(INFO, "kickstart forcing text mode");
-    flags |= LOADER_FLAGS_TEXT;
-    return;
-}
-
-static void setGraphicalMode(struct loaderData_s * loaderData, int argc, 
-                        char ** argv) {
-    logMessage(INFO, "kickstart forcing graphical mode");
-    flags |= LOADER_FLAGS_GRAPHICAL;
-    return;
-}
-
-static void setCmdlineMode(struct loaderData_s * loaderData, int argc, 
-                           char ** argv) {
-    logMessage(INFO, "kickstart forcing cmdline mode");
-    flags |= LOADER_FLAGS_CMDLINE;
-    return;
-}
-
-static void setSELinux(struct loaderData_s * loaderData, int argc, 
-                       char ** argv) {
-    flags |= LOADER_FLAGS_SELINUX;
-    return;
-}
-
-static void setPowerOff(struct loaderData_s * loaderData, int argc, 
-                        char ** argv) {
-    if (!FL_NOKILL(flags))
-        flags |= LOADER_FLAGS_POWEROFF;
-    return;
-}
-
-static void setHalt(struct loaderData_s * loaderData, int argc, 
-                    char ** argv) {
-    if (!FL_NOKILL(flags))
-        flags |= LOADER_FLAGS_HALT;
-    return;
-}
-
-static void setShutdown(struct loaderData_s * loaderData, int argc, 
-                    char ** argv) {
-    gint eject = 0, reboot = 0, halt = 0, poweroff = 0;
-    GOptionContext *optCon = g_option_context_new(NULL);
-    GError *optErr = NULL;
-    GOptionEntry ksOptions[] = {
-        { "eject", 'e', 0, G_OPTION_ARG_INT, &eject, NULL, NULL },
-        { "reboot", 'r', 0, G_OPTION_ARG_INT, &reboot, NULL, NULL },
-        { "halt", 'h', 0, G_OPTION_ARG_INT, &halt, NULL, NULL },
-        { "poweroff", 'p', 0, G_OPTION_ARG_INT, &poweroff, NULL, NULL },
-        { NULL },
-    };
-
-    g_option_context_set_help_enabled(optCon, FALSE);
-    g_option_context_add_main_entries(optCon, ksOptions, NULL);
-
-    if (!g_option_context_parse(optCon, &argc, &argv, &optErr)) {
-        startNewt();
-        newtWinMessage(_("Kickstart Error"), _("OK"),
-                       _("Bad argument to shutdown kickstart method "
-                         "command: %s"), optErr->message);
-        g_error_free(optErr);
-        g_option_context_free(optCon);
-        return;
-    }
-
-    g_option_context_free(optCon);
-
-    if (FL_NOKILL(flags)) {
-        flags |= LOADER_FLAGS_HALT;
-    } else  {
-        if (poweroff)
-            flags |= LOADER_FLAGS_POWEROFF;
-        if ((!poweroff && !reboot) || (halt))
-            flags |= LOADER_FLAGS_HALT;
-    }
-}
-
-static void setMediaCheck(struct loaderData_s * loaderData, int argc, 
-                          char ** argv) {
-    flags |= LOADER_FLAGS_MEDIACHECK;
-    return;
-}
-
-void runKickstart(struct loaderData_s * loaderData) {
-    struct ksCommandNames * cmd;
-    int argc;
-    char ** argv;
-
-    logMessage(INFO, "setting up kickstart");
-    for (cmd = ksTable; cmd->name; cmd++) {
-        if ((!ksGetCommand(cmd->code, NULL, &argc, &argv)) && cmd->setupData) {
-            cmd->setupData(loaderData, argc, argv);
-        }
-    }
-}
-
-/* vim:set sw=4 sts=4 et: */
diff --git a/loader/kickstart.h b/loader/kickstart.h
deleted file mode 100644
index 574026b..0000000
--- a/loader/kickstart.h
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * kickstart.h
- *
- * Copyright (C) 2007  Red Hat, Inc.  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 as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * 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, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef H_KICKSTART
-
-#include "loader.h"
-
-#define KS_CMD_NONE	    0
-#define KS_CMD_NFS	    1
-#define KS_CMD_CDROM	    2
-#define KS_CMD_HD	    3
-#define KS_CMD_URL	    4
-#define KS_CMD_NETWORK      5
-#define KS_CMD_TEXT         6
-#define KS_CMD_KEYBOARD     7
-#define KS_CMD_LANG         8
-#define KS_CMD_DD           9
-#define KS_CMD_DEVICE      10
-#define KS_CMD_CMDLINE     11
-#define KS_CMD_GRAPHICAL   12
-#define KS_CMD_SELINUX     13
-#define KS_CMD_POWEROFF    14
-#define KS_CMD_HALT        15
-#define KS_CMD_SHUTDOWN    16
-#define KS_CMD_MEDIACHECK  17
-#define KS_CMD_UPDATES     18
-#define KS_CMD_VNC         19
-
-int ksReadCommands(char * cmdFile);
-int ksGetCommand(int cmd, char ** last, int * argc, char *** argv);
-int ksHasCommand(int cmd);
-
-int isKickstartFileRemote(char *ksFile);
-void getKickstartFile(struct loaderData_s * loaderData);
-void runKickstart(struct loaderData_s * loaderData);
-int getKickstartFromBlockDevice(char *device, char *path);
-
-#endif
diff --git a/loader/lang.c b/loader/lang.c
deleted file mode 100644
index 31749fc..0000000
--- a/loader/lang.c
+++ /dev/null
@@ -1,399 +0,0 @@
-/*
- * lang.c - determines language, handles translations
- *
- * Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003  Red Hat, Inc.
- * 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 as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * 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, see <http://www.gnu.org/licenses/>.
- *
- * Author(s): Erik Troan <ewt@xxxxxxxxxx>
- *            Matt Wilson <msw@xxxxxxxxxx>
- *            Michael Fulbright <msf@xxxxxxxxxx>
- *            Jeremy Katz <katzj@xxxxxxxxxx>
- */
-
-#include <alloca.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <netinet/in.h>
-#include <newt.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/ioctl.h>
-#include <unistd.h>
-#include <wchar.h>
-
-#include "loader.h"
-#include "lang.h"
-#include "loadermisc.h"
-#include "windows.h"
-
-#include "../isys/stubs.h"
-#include "../isys/cpio.h"
-#include "../isys/lang.h"
-#include "../isys/isys.h"
-#include "../isys/log.h"
-
-/* boot flags */
-extern uint64_t flags;
-
-struct aString {
-    unsigned int hash;
-    short length;
-    char * str;
-} ;
-
-struct aString * strings = NULL;
-int numStrings = 0, allocedStrings = 0;
-
-static int english = 0;
-
-static char * topLineWelcome = N_("Welcome to %s for %s");
-static char * topLineWelcomeRescue = N_("Welcome to %s for %s - Rescue Mode");
-static char * bottomHelpLine = N_("  <Tab>/<Alt-Tab> between elements  | <Space> selects | <F12> next screen ");
-
-static int aStringCmp(const void * a, const void * b) {
-    const struct aString * first = a;
-    const struct aString * second = b;
-
-    if (first->hash < second->hash)
-        return -1;
-    else if (first->hash == second->hash)
-        return 0;
-
-    return 1;
-}
-
-char * translateString(char * str) {
-    unsigned int sum = 0, xor = 0;
-    int len = 0;
-    char * chptr;
-    struct aString * match;
-    struct aString key;
-
-    for (chptr = str; *chptr; chptr++) {
-        sum += *chptr;
-        xor ^= *chptr;
-        len++;
-    }
-
-    key.hash = (sum << 16) | ((xor & 0xFF) << 8) | (len & 0xFF);
-    match = bsearch(&key, strings, numStrings, sizeof(*strings), aStringCmp);
-    if (!match)
-        return str;
-
-    return match->str;
-}
-
-static struct langInfo * languages = NULL;
-static int numLanguages = 0;
-
-static void loadLanguageList(void) {
-    char * file = "/etc/lang-table";
-    FILE * f;
-    char line[256];
-    char name[256], key[256], font[256], code[256],
-        keyboard[256], timezone[256];
-    int lineNum = 0;
-
-    wcwidth(0);
-    f = fopen(file, "r");
-    if (!f) {
-        newtWinMessage(_("Error"), _("OK"), "cannot open %s: %m", file);
-        return;
-    }
-
-    while (fgets(line, sizeof(line), f)) {
-        lineNum++;
-        languages = realloc(languages, sizeof(*languages) * (numLanguages + 1));
-        if (sscanf(line, "%[^\t]\t%[^\t]\t%[^\t]\t%[^\t]\t%[^\t]\t%[^\t]\n",
-                   name, key, font, code, keyboard, timezone) != 6) {
-            printf("bad line %d in lang-table", lineNum);
-            logMessage(WARNING, "bad line %d in lang-table", lineNum);
-        } else {
-            languages[numLanguages].lang = strdup(name);
-            languages[numLanguages].key = strdup(key);
-            languages[numLanguages].font = strdup(font);
-            languages[numLanguages].lc_all = strdup(code);
-            languages[numLanguages++].keyboard = strdup(keyboard);
-        }
-    }
-    fclose(f);
-}
-
-int getLangInfo(struct langInfo ** langs) {
-    if (!languages)
-        loadLanguageList();
-
-    *langs = languages;
-    return numLanguages;
-}
-
-void loadLanguage (char * file) {
-    char filename[200];
-    gzFile stream;
-    int fd, hash, rc;
-    char * key = getenv("LANGKEY");
-
-    if (strings) {
-	free(strings), strings = NULL;
-	numStrings = allocedStrings = 0;
-    }
-    
-    /* english requires no files */
-    if (!strcmp(key, "en"))
-        return;
-
-    if (!file) {
-        file = filename;
-        sprintf(filename, "/etc/loader.tr");
-    }
-
-    stream = gunzip_open(file);
-
-    if (!stream) {
-        newtWinMessage("Error", "OK", "Translation for %s is not available.  "
-                       "The Installation will proceed in English.", key);
-        return ;
-    }
-    
-    sprintf(filename, "%s.tr", key);
-
-    rc = installCpioFile(stream, filename, "/tmp/translation", 1);
-    gunzip_close(stream);
-
-    if (rc || access("/tmp/translation", R_OK)) {
-        newtWinMessage("Error", "OK", "Cannot get translation file %s.\n", 
-                        filename);
-        return;
-    }
-    
-    fd = open("/tmp/translation", O_RDONLY);
-    if (fd < 0) {
-        newtWinMessage("Error", "OK", "Failed to open /tmp/translation: %m\n");
-        return;
-    }
-
-    while (read(fd, &hash, 4) == 4) {
-        if (allocedStrings == numStrings) {
-            allocedStrings += 10;
-            strings = realloc(strings, sizeof(*strings) * allocedStrings);
-        }
-
-        strings[numStrings].hash = ntohl(hash);
-        rc = read(fd, &strings[numStrings].length, 2);
-        strings[numStrings].length = ntohs(strings[numStrings].length);
-        strings[numStrings].str = malloc(strings[numStrings].length + 1);
-        rc = read(fd, strings[numStrings].str, strings[numStrings].length);
-        strings[numStrings].str[strings[numStrings].length] = '\0';
-        numStrings++;
-    }
-
-    close(fd);
-    unlink("/tmp/translation");
-
-    qsort(strings, numStrings, sizeof(*strings), aStringCmp);
-}
-
-
-/* give the index of the language to set to -- sets the appropriate
- * lang variables if we have a font.
- *
- * ASSUMPTION: languages exists
- */
-static void setLangEnv (int i) {
-    if (i > numLanguages)
-        return;
-
-    if (strcmp(languages[i].font, "latarcyrheb-sun16"))
-        return;
-    logMessage(INFO, "setting language to %s", languages[i].lc_all);
-
-    setenv("LANG", languages[i].lc_all, 1);
-    setenv("LANGKEY", languages[i].key, 1);
-    setenv("LINGUAS", languages[i].lang, 1);
-    loadLanguage (NULL);
-}
-
-/* choice is the index of the chosen language in languages */
-static int setupLanguage(int choice, int forced) {
-    char * buf;
-    int i;
-
-    logMessage(DEBUGLVL, "going to set language to %s", languages[choice].lc_all);
-    /* load the language only if it is displayable.  if they're using
-     * a serial console or iSeries vioconsole, we hope it's smart enough */
-    if ((strcmp(languages[choice].font, "latarcyrheb-sun16") && !FL_SERIAL(flags) && 
-         !FL_VIRTPCONSOLE(flags) && !isVioConsole())) {
-        if (forced == 1) return 0;
-
-	newtWinMessage("Language Unavailable", "OK", 
-		       "%s display is unavailable in text mode.  The "
-		       "installation will continue in English until the "
-		       "display of %s is possible.", languages[choice].lang,
-		       languages[choice].lang);
-        setLangEnv(english);
-	return 0;
-    }
-    
-    setLangEnv (choice);
-    isysLoadFont();
-
-    /* clear out top line */
-    buf = alloca(81); /* reserve one byte for \0 */
-    for (i=0; i < 80; i++)
-	buf[i] = ' ';
-    buf[80] = 0; /* and set the \0 */
-    newtDrawRootText(0, 0, buf);
-
-    char *fmt = FL_RESCUE(flags) ? _(topLineWelcomeRescue) : _(topLineWelcome);
-    checked_asprintf(&buf, fmt, getProductName(), getProductArch());
-
-    newtDrawRootText(0, 0, buf);
-    free(buf);
-    newtPopHelpLine();
-    newtPushHelpLine(_(bottomHelpLine));
-
-    return 0;
-
-}
-
-/* this is pretty simple.  we want to break down the language specifier
- * into its short form (eg, en_US)
- */
-static char * getLangShortForm(char * oldLang) {
-    char * lang;
-    char * c;
-    
-    lang = strdup(oldLang);
-
-    c = strchr(lang, '@');
-    if (c) {
-        *c = '\0';
-    }
-
-    c = strchr(lang, '.');
-    if (c) {
-        *c = '\0';
-    }
-
-    return lang;
-}
-
-/* return the nick of a language -- eg en_US -> en */
-static char * getLangNick(char * oldLang) {
-    char * lang;
-    char * c;
-    
-    lang = strdup(oldLang);
-
-    c = strchr(lang, '_');
-    if (c) {
-        *c = '\0';
-    }
-
-    return lang;
-}
-
-int setLanguage (char * key, int forced) {
-    int i;
-
-    if (!languages) loadLanguageList();
-
-    for (i = 0; i < numLanguages; i++) {
-        if (!strcmp(languages[i].lc_all, key)) {
-            return setupLanguage(i, forced | !FL_KICKSTART(flags));
-        }
-    }
-
-    /* we didn't specify anything that's exactly in the lang-table.  check
-     * against short forms and nicks */
-    for (i = 0; i < numLanguages; i++) {
-        if (!strcmp(getLangShortForm(languages[i].lc_all), key)) {
-            return setupLanguage(i, forced | !FL_KICKSTART(flags));
-        }
-    }
-
-    for (i = 0; i < numLanguages; i++) {
-        if (!strcmp(getLangNick(languages[i].lc_all), key)) {
-            return setupLanguage(i, forced | !FL_KICKSTART(flags));
-        }
-    }
-
-    logMessage(ERROR, "unable to set to requested language %s", key);
-    return -1;
-}
-
-int chooseLanguage(char ** lang) {
-    int choice = 0;
-    char ** langs;
-    int i;
-    int current = -1;
-    char * currentLangName = getenv("LANG");
-    int numLangs = 0;
-    char * langPicked;
-
-    if (!languages) loadLanguageList();
-
-    langs = alloca(sizeof(*langs) * (numLanguages + 1)); 
-
-    for (i = 0; i < numLanguages; i++) {
-        if (!strncmp(languages[i].key, "en", 2))
-            english = numLangs;
-        if (currentLangName &&
-            !strcmp(languages[i].lang, currentLangName))
-            current = numLangs;
-
-        langs[numLangs++] = languages[i].lang;
-    }
-
-    langs[numLangs] = NULL;
-
-    if (current >= 0)
-        choice = current;
-    else
-        choice = english;
-
-    if (!FL_CMDLINE(flags))
-        newtWinMenu(_("Choose a Language"),
-                    _("What language would you like to use during the "
-                      "installation process?"), 40, 5, 5, 8,
-                    langs, &choice, _("OK"), NULL);
-
-    langPicked = langs[choice];
-    for (i = 0; i < numLanguages; i++) {
-        if (!strcmp(langPicked, languages[i].lang)) {
-            *lang = languages[i].lc_all;
-            choice = i;
-            break;
-        }
-    }
-
-    /* this can't happen */
-    if (i == numLanguages) abort();
-
-    return setupLanguage(choice, 0);
-}
-
-void setKickstartLanguage(struct loaderData_s * loaderData, int argc, 
-                          char ** argv) {
-    if (argc < 2) {
-        logMessage(ERROR, "no argument passed to lang kickstart command");
-        return;
-    }
-
-    loaderData->lang = argv[1];
-    loaderData->lang_set = 1;
-}
diff --git a/loader/lang.h b/loader/lang.h
deleted file mode 100644
index 965f5a0..0000000
--- a/loader/lang.h
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * lang.h
- *
- * Copyright (C) 2007  Red Hat, Inc.  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 as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * 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, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef _LANG_H_
-#define _LANG_H_
-
-#include "loader.h"
-
-#define _(x) translateString (x)
-#define N_(foo) (foo)
-
-struct langInfo {
-    char * lang, * key, * font, * lc_all, * keyboard;
-} ;
-
-
-int chooseLanguage(char ** lang);
-char * translateString(char * str);
-int setLanguage (char * key, int forced);
-int getLangInfo(struct langInfo **langs);
-
-void setKickstartLanguage(struct loaderData_s * loaderData, int argc, 
-                          char ** argv);
-
-#endif /* _LANG_H_ */
diff --git a/loader/linuxrc.s390 b/loader/linuxrc.s390
deleted file mode 100644
index 814dd32..0000000
--- a/loader/linuxrc.s390
+++ /dev/null
@@ -1,3118 +0,0 @@
-#! /bin/bash
-
-# linuxrc.s390: init process of Red Hat's installer initrd for s390(x)
-# Copyright (C) 2000-2004 by
-#        Bernhard Rosenkraenzer <bero@xxxxxxxxxx>
-#        Oliver Paukstadt <opaukstadt@xxxxxxxxxxxx>
-#        Karsten Hopp <karsten@xxxxxxxxx>
-#        Florian La Roche <laroche@xxxxxxxxxx>
-#        Nils Philippsen <nils@xxxxxxxxx>
-#        Helge Deller <hdeller@xxxxxxxxx>
-#        David Sainty <dsainty@xxxxxxxxxx>
-# Copyright (C) IBM Corp. 2008,2009
-#        Author: Steffen Maier <maier@xxxxxxxxxx>
-#
-#    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; either version 2 of the License, or
-#    (at your option) any later version.
-#
-#    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
-#
-
-# prerequisites of this script to run inside the installer initrd:
-# - udevadm and udevd need to be there
-# - have /etc/udev/udev.conf with at least one comment line as content
-# - if necessary, have udev rules
-# - lsznet.raw and znetcontrolunits from s390utils-base in /lib/s390-tools
-# - pack kernel modules and module-init-tools (no longer use busybox for that)
-# - "multi on" in /etc/host.conf [RH bugs 486457,486461,483244]
-
-# TODOs:
-# - make sure driver modules get loaded automatically
-# - udev rule for lcs/ctcm vs. cu3088
-
-# debug: set -x
-
-if [ "${0##*/}" = "reboot" ]; then
-    kill -USR2 1
-elif [ "${0##*/}" = "halt" ]; then
-    kill -USR1 1
-fi
-
-VERSION=1.2
-
-export TEXTDOMAIN=s390installer
-export TEXTDOMAINDIR=/usr/lib/locale
-
-# helper function to execute command in arguments and print command on stdout
-function debug() {
-    # uncomment the following echo "$*" to enable debug output
-    #echo "$*"
-    $*
-}
-
-# FIXME: maybe change to "$$" for production use, in case it wouldn't be init
-declare -r INITPID="1"
-
-unset testing
-[ "$$" != "$INITPID" ] && testing="1"
-# uncomment the following test="1" to never execute sensitive commands
-#testing="1"
-
-if [ "$RUNKS" = "0" ]; then
-    RUNKS=""
-fi
-
-# ping command to use to test host availability (for gateway & dns servers)
-PINGOPTS="-c 3 -w 30"
-PING="ping $PINGOPTS"
-PING6="ping6 $PINGOPTS"
-
-# helper function to disable commands while running outside the initrd
-function tv() {
-    if [ -z "$testing" ]; then
-        $*
-    else
-        return 0
-    fi
-}
-
-function checkipv6()
-{
-    local ip=$1
-    [ -z "$ip" ] && return 1
-    /sbin/ipcalc -c -6 "$ip" >/dev/null 2>&1
-    return $?
-}
-
-function checkipv4()
-{
-    local ip=$1
-    [ -z "$ip" ] && return 1
-    /sbin/ipcalc -c -4 "$ip" >/dev/null 2>&1
-    return $?
-}
-
-function doshutdown()
-{
-    echo $"about to exec shutdown"
-    exec /sbin/shutdown
-    exit 0
-}
-
-function doreboot()
-{
-    if [ -e "/sys/firmware/reipl" ]; then
-        read REIPL_TYPE < /sys/firmware/reipl/reipl_type
-        echo "reipl_type=$REIPL_TYPE"
-        pushd /sys/firmware/reipl/$REIPL_TYPE >/dev/null 2>&1
-        for i in *; do
-            echo "$i=`cat $i`"
-        done
-        popd >/dev/null 2>&1
-    fi
-
-    echo $"about to exec shutdown -r"
-    exec /sbin/shutdown -r
-    exit 0
-}
-
-function sysecho () {
-    file=$1
-    shift
-    local i=1
-    while [ $i -le 10 ] ; do
-        if [ ! -f "$file" ]; then
-            sleep 1
-            i=$((i+1))
-        else
-            break
-        fi
-    done
-    [ -f "$file" ] && echo $* > $file
-}
-
-function dasd_settle() {
-    local dasd_status=/sys/bus/ccw/devices/$1/status
-    if [ ! -f $dasd_status ]; then
-        return 1
-    fi
-    local i=1
-    while [ $i -le 30 ] ; do
-        local status
-        read status < $dasd_status
-        case $status in
-            online|unformatted)
-                return 0 ;;
-            *)
-                sleep 0.1
-                i=$((i+1)) ;;
-        esac
-    done
-    return 1
-}
-
-function dasd_settle_all() {
-    for dasdccw in $(cut -d '(' -f 1 /proc/dasd/devices) ; do
-        if ! dasd_settle $dasdccw ; then
-            echo $"Could not access DASD $dasdccw in time"
-            return 1
-        fi
-    done
-    return 0
-}
-
-function startinetd()
-{
-    echo
-    echo $"Starting sshd to allow login over the network."
-    if [ -z "$testing" ]; then
-        echo $"Welcome to the anaconda install environment $VERSION for $S390ARCH" > /etc/issue.net
-        echo $"Welcome to the anaconda install environment $VERSION for $S390ARCH" > /etc/motd
-        echo >> /etc/motd
-    fi # testing
-
-    /sbin/sshd -f /etc/ssh/sshd_config.anaconda
-    if [ -z "$RUNKS" ]; then
-        echo
-        echo $"Connect now to $IPADDR and log in as user install to start the installation."
-        echo $"E.g. using: ssh -x install@$IPADDR"
-        echo $"You may log in as the root user to start an interactive shell."
-        read
-        while : ; do
-            /bin/sh --login
-            [ $? = 0 ] || break
-        done
-    fi
-}
-
-# prints a canonocalized device bus ID for a given devno of any format
-function canonicalize_devno()
-{
-    case ${#1} in
-        3) echo "0.0.0${1}" ;;
-        4) echo "0.0.${1}" ;;
-        *) echo "${1}" ;;
-    esac
-    return 0
-}
-
-# read file from CMS and write it to /tmp
-function readcmsfile() # $1=dasdport $2=filename
-{
-    local dev
-    if [ $# -ne 2 ]; then return; fi
-    # precondition: udevd created dasda block device node
-    if ! sysecho /proc/cio_ignore "free $1"; then
-        echo $"DASD $1 could not be cleared from device blacklist"
-        return 1
-    fi
-    # /proc/cio_ignore won't block on freeing devices until resensing
-    # has been completed, so wait until the udev event queue depletes
-    # (without udevadm settle we could wait 2 seconds unconditionally)
-    #debug ls -laF /dev/.udev
-    udevadm settle
-    # even though the device might now be online, some of its
-    # sysfs attributes might not yet be available
-    sleep 1
-    # precondition: dasd_eckd_mod driver incl. dependencies loaded,
-    #               dasd_mod must be loaded without setting any DASD online
-    dev=$(canonicalize_devno $1)
-    if ! sysecho /sys/bus/ccw/devices/$dev/online 1; then
-        echo $"DASD $dev could not be set online"
-        return 1
-    fi
-    udevadm settle
-    if ! dasd_settle $dev ; then
-        echo $"Could not access DASD $dev in time"
-        return 1
-    fi
-    udevadm settle
-    if ! cmsfscat -d /dev/dasda -a $2 > /tmp/$2; then
-        echo $"Could not read conf file $2 on CMS DASD $1."
-    fi
-    if ! sysecho /sys/bus/ccw/devices/$dev/online 0; then
-        echo $"DASD $dev could not be set offline again"
-        return 1
-    fi
-    udevadm settle
-    # consequences of no more module unload: loader can no longer
-    # use DASD module option to online DASDs and set other DASD parameters!
-}
-
-# adaption of the same function in init.c (udevd gets started later)
-function createDevices()
-{
-    awk '{ printf("mknod /dev/%s %s %s %s\n", $1, $2, $3, $4);
-      printf("chmod %s /dev/%s\n", $5, $1);
-      printf("chown %s /dev/%s\n", $6, $1);
-    }' <<EOF | sh
-console c 5 1 600 root:root
-null c 1 3 666 root:root
-zero c 1 5 666 root:root
-mem c 1 1 600 root:root
-ptmx c 5 2 666 root:root
-tty  c 5 0 666 root:root
-tty0 c 4 0 600 root:tty
-tty1 c 4 1 600 root:tty
-random c 1 8 644 root:root
-urandom c 1 9 644 root:root
-rtc c 10 135 644 root:root
-EOF
-    # tty handling is different from init.c since s390 does not have all
-    for i in 2 3 4 5 6 7 8 9 ; do
-        ln -s console /dev/tty$i
-    done
-    mkdir /dev/pts
-    ln -s /proc/self/fd /dev/fd
-}
-
-# approximately the main() function of init.c
-function init_main() {
-    S390ARCH=$(uname -m)
-    if [ "$S390ARCH" = "s390" ]; then
-        export S390ARCH="S/390"
-    else
-        export S390ARCH="zSeries"
-    fi
-
-    echo
-    echo $"Starting the $S390ARCH initrd to configure networking. Version is $VERSION"
-
-    # set up env vars as we do in init.c
-    if [ $(uname -m) = "s390x" ]; then
-        LD_LIBRARY_PATH=/lib64:/usr/lib64:/usr/X11R6/lib64:/usr/kerberos/lib64:/lib:/usr/lib:/usr/X11R6/lib:/usr/kerberos/lib
-    else
-        LD_LIBRARY_PATH=/lib:/usr/lib:/usr/X11R6/lib:/usr/kerberos/lib
-    fi
-    export LD_LIBRARY_PATH
-
-    PATH="$PATH:/usr/bin:/bin:/sbin:/usr/sbin:/mnt/sysimage/bin:/mnt/sysimage/usr/bin:/mnt/sysimage/usr/sbin:/mnt/sysimage/sbin:/mnt/sysimage/usr/X11R6/bin"
-    export PATH
-    HOME=/
-    export HOME
-    PYTHONPATH=/tmp/updates
-    export PYTHONPATH
-
-    if [ -z "$testing" ]; then
-
-        mount -t proc none /proc
-
-        mount -t tmpfs none /dev
-        createDevices
-        # udevd req'd by udevadm settle (/dev/.udev/queue)
-        # in readcmsfile, dialog_network_table, semantic_check_subchannels.
-        # (important: start udevd at the right time, e.g. after setup of /dev)
-        echo $"Starting udev..."
-        udevd --daemon
-        # debug: udevadm control --log-priority=debug
-
-        udevadm control --env=ANACONDA=1
-
-        mount -t devpts /dev/pts /dev/pts
-        mount -t sysfs none /sys
-
-        # remount root fs rw
-        mount /dev/root /  -o remount,rw
-
-        # limit output on 3270 console
-        # (console_loglevel of 4 is just right to not get driver info,
-        #  e.g. from qeth, since that would mix up with the user dialog)
-        echo "4 4 1 7" > /proc/sys/kernel/printk
-
-        # make /tmp/ramfs
-        mount -t ramfs none /tmp
-
-        ifconfig lo 127.0.0.1 netmask 255.0.0.0
-        route add -host 127.0.0.1 dev lo
-
-        echo -e "127.0.0.1\tlocalhost.localdomain localhost localhost4 localhost4.localdomain4" > /etc/hosts
-        echo -e     "::1\t\tlocalhost.localdomain localhost localhost6 localhost6.localdomain6" >> /etc/hosts
-
-        /sbin/dbus-uuidgen --ensure &
-        [ $? != 0 ] && echo "error on calling /sbin/dbus-uuidgen --ensure"
-        /sbin/dbus-daemon --system &
-        [ $? != 0 ] && echo "error on calling /sbin/dbus-daemon --system"
-
-    fi # testing
-}
-
-# trigger udev to automatically load device drivers
-function udev_setup() {
-    if [ -z "$testing" ]; then
-       # debug: udevadm monitor &
-       udevadm trigger
-       udevadm settle
-    fi # testing
-}
-
-# from here on accesses to sysfs try to follow
-# linux/Documentation/sysfs-rules.txt
-
-### lsznet.raw integration
-
-declare -a nettable
-
-function read_lsznet_output() {
-    count=0
-    local line
-    while read line; do
-        nettable[$count]="$line"
-        count=$((count + 1))
-    # using the more sophisticated process substitution instead of temp file
-    # requires the symlink /dev/fd -> /proc/self/fd => createDevices
-    done < <(/lib/s390-tools/lsznet.raw)
-}
-
-function print_nettable() {
-    local fmtstring="%3s %-14s %-7s %-5s %-4s %-6s %-7s %s\n"
-    printf "$fmtstring" \
-        "NUM" "CARD" "CU" "CHPID" "TYPE" "DRIVER" "IF" "DEVICES"
-    local i
-    for ((i=0; i < count; i++)); do
-        local item cutype chp chpidtype devdrv devname chlist cardtype
-        read item cutype chp chpidtype devdrv devname chlist cardtype <<< ${nettable[$i]}
-        printf "$fmtstring" \
-            $item "$cardtype" $cutype $chp "$chpidtype" $devdrv $devname $chlist
-    done
-}
-
-function clear_screen() {
-    # FIXME: find a way to clear screen despite 3215 line mode terminal
-    echo
-}
-
-function dialog_network_table() {
-    while : ; do
-        echo $"Scanning for available network devices..."
-        # This may take a long time so we show "progress":
-        #( while true; do echo -n "."; sleep 1; done ) &
-        #local childpid=$!
-        read_lsznet_output
-        #kill $childpid
-        #echo
-        echo $"Autodetection found ${count} devices."
-        # count==0: there might still be a blacklist the user wants to clear.
-        # do not flood user with long list if there are many devices
-        if [ "$count" -le 15 ]; then
-            # Show list
-            answer=s
-        else # [ $count -gt 15 ]
-            echo
-            while : ; do
-                echo $"s) show all, m) manual config:"
-                local answer
-                read answer
-                case $answer in
-                    s|m) break ;;
-                esac
-            done
-        fi
-        [ "$answer" = "m" ] && break
-        # show network table to select network hardware configuration from
-        if [ "$count" -gt 0 ]; then
-            clear_screen
-            print_nettable
-            echo
-        fi
-        # account for possibly ignored common I/O devices
-        # cio_wc_bytes is NOT local so it can be re-used outside this function
-        cio_wc_bytes=0
-        local cio_wc_filename cio_wc_foo
-        if [ -f /proc/cio_ignore ]; then
-            local cio_wc=$(wc -c /proc/cio_ignore)
-            read cio_wc_bytes cio_wc_filename cio_wc_foo <<< "$cio_wc"
-            if [ "$cio_wc_bytes" != "0" ]; then
-                echo $"Note: There is a device blacklist active! (Clearing might take long)"
-                #cat /proc/cio_ignore | tr '\n' ','
-                #echo
-            else
-                if [ "$count" -eq 0 ]; then
-                    # count==0 AND no device blacklist => manual mode
-                    echo $"Entering manual configuration mode."
-                    break
-                fi
-            fi
-        fi
-        # selection dialog
-        while : ; do
-            [ "$count" -gt 0 ] && echo -n $"<num>) use config, "
-            [ "$cio_wc_bytes" != "0" ] && echo -n $"c) clear blacklist, "
-            echo $"m) manual config, r) rescan, s) shell:"
-            local choice
-            read choice
-            [ -z "$choice" ] && continue
-            if [ "$choice" = "s" ]; then
-                echo $"Enter 'exit' at the shell prompt to get back to the installation dialog."
-                /bin/bash
-                continue 2
-            fi
-            [ "$choice" = "m" ] && break
-            [ "$choice" = "r" ] && continue 2
-            [ "$cio_wc_bytes" != "0" -a "$choice" = "c" ] && break
-            [[ "$choice" =~ ^[[:digit:]]+$ ]]
-            case $? in
-                0)
-                    # string matched the pattern
-                    [ "$choice" -ge 1 -a "$choice" -le "$count"  ] && break
-                    ;;
-                1)
-                    # string did not match the pattern
-                    continue
-                    ;;
-                2)
-                    echo "l.$LINENO: syntax error in regex of match operator =~, code needs to be fixed" 1>&2
-                    ;;
-                *)
-                    echo "l.$LINENO: unexpected return code of regex match operator =~, code needs to be fixed" 1>&2
-                    ;;
-            esac
-        done
-        if [ "$choice" = "c" ]; then
-            echo $"Clearing device blacklist..."
-            if sysecho /proc/cio_ignore "free all"; then
-                cio_wc_bytes=0
-                # /proc/cio_ignore won't block on freeing devices
-                # until resensing has been completed, so wait until
-                # the udev event queue depletes.
-                # This may take a long time so we show "progress":
-                #( while true; do echo -n "."; sleep 3; done ) &
-                #local childpid=$!
-                #debug ls -laF /dev/.udev
-                udevadm settle
-                # (virtual) CTC/A takes some more time to appear in sysfs
-                # FIXME: how long to wait? 3 seconds seems to be enough.
-                sleep 3
-                #kill $childpid
-                #echo
-                continue
-            else
-                echo $"Device blacklist could not be cleared"
-            fi
-        fi
-        [ "$choice" = "m" ] && break
-        # finally extract config info from selected item
-        # array nettable starts at index zero, user input starts at index one
-        choice=$((choice - 1))
-        local item cutype chp chpidtype devdrv devname chlist cardtype
-        read item cutype chp chpidtype devdrv devname chlist cardtype <<< ${nettable[$choice]}
-        # $NETTYPE happens to be exactly the network driver name
-        if [ "$devdrv" = "ctcm" ]; then
-            NETTYPE="ctc"
-        else
-            NETTYPE=$devdrv
-        fi
-        SUBCHANNELS=$chlist
-        break
-    done
-    echo
-}
-
-declare -r PREFIXFORMAT=[[:xdigit:]]*
-declare -r SSIDFORMAT=[0-3]
-declare -r BUSIDFORMAT=[[:xdigit:]][[:xdigit:]][[:xdigit:]][[:xdigit:]]
-declare -r IDFORMAT=$PREFIXFORMAT.$SSIDFORMAT.$BUSIDFORMAT
-declare -r SUBCHANNEL_TYPE_IO=0
-
-. /lib/s390-tools/znetcontrolunits
-
-function cardtype2cleartext() {
-    local cardtype=$1
-    case $cardtype in
-        OSD_10GIG)        echo "OSA card in OSD mode, 10 Gigabit Ethernet" ;;
-        OSD_1000)         echo "OSA card in OSD mode, Gigabit Ethernet" ;;
-        OSD_100)          echo "OSA card in OSD mode, Fast Ethernet" ;;
-        OSD_GbE_LANE)     echo "OSA card in OSD mode, Gigabit Ethernet, LAN Emulation" ;;
-        OSD_FE_LANE)      echo "OSA card in OSD mode, Fast Ethernet, LAN Emulation" ;;
-        OSD_TR_LANE)      echo "OSA card in OSD mode, Token Ring, LAN Emulation" ;;
-        OSD_ATM_LANE)     echo "OSA card in OSD mode, ATM, LAN Emulation" ;;
-        OSD_Express)      echo "OSA card in OSD mode, unknown link type" ;;
-        HSTR)             echo "OSA card in OSD mode, High Speed Token Ring" ;;
-        OSN)              echo "OSA for NCP, ESCON/CDLC bridge" ;;
-        HiperSockets)     echo "HiperSockets with CHPID type IQD" ;;
-        "GuestLAN QDIO")  echo "GuestLAN based on OSA (QDIO)" ;;
-        "GuestLAN Hiper") echo "GuestLAN based on HiperSockets" ;;
-        unknown)          echo "other" ;;
-        *) echo "unknown"
-            echo "l.$LINENO: found unknown card_type, code needs to be fixed" 1>&2
-            ;;
-    esac
-}
-
-# returns true iff running under z/VM
-function isVM() {
-    local cpu_version=$(cat /proc/cpuinfo |grep "^processor " | head -n1 | sed 's/.*version = \([[:xdigit:]][[:xdigit:]]\).*/\1/' | tr '[:lower:]' '[:upper:]')
-    if [ "$cpu_version" = "FF" ]; then
-        return 0
-    else
-        return 1
-    fi
-}
-
-# watch out: potential error message as side effect
-function isLayer2Default() {
-    # Read default from sysfs because according to device
-    # drivers book there are differences in the default between
-    # OSA (l2), hipersockets (l3).
-    # This only works here in installer where nobody has overwritten
-    # the default setting with another custom value already!
-    if [ ! -f /sys/devices/${NETTYPE}/$SCH_R_DEVBUSID/layer2 ]; then
-        echo $"Could not read layer mode from sysfs"
-        return 1
-    fi
-    local layer2
-    read layer2 < /sys/devices/${NETTYPE}/$SCH_R_DEVBUSID/layer2
-    if [ "$layer2" = "1" ]; then
-        return 0
-    else
-        return 1
-    fi
-}
-
-# returns true iff either LAYER2 has been set to 1 or is the default
-# watch out: potential error message as side effect
-function isLayer2() {
-    case "x$LAYER2" in
-        x0) return 1 ;; # layer 3
-        x1) return 0 ;; # layer 2
-        x)  # LAYER2 is unset or empty => qeth driver default applies.
-            isLayer2Default
-            return $?
-            ;;
-        *) echo "l.$LINENO: unknown value \"$LAYER2\" for LAYER2, code needs to be fixed" 1>&2
-            return 2 ;;
-    esac
-}
-
-# returns true iff qeth device $SCH_R_DEVBUSID
-# is capable of supporting IPv6
-# watch out: potential error message as side effect
-function ipv6_capable() {
-    [ "$NETTYPE" = "qeth" ] || return 1
-    case $cardtype in
-        OSD_10GIG|OSD_1000|OSD_100|OSD_Express|HiperSockets|"GuestLAN QDIO")
-            return 0 ;;
-        OSD_GbE_LANE|OSD_FE_LANE|OSD_TR_LANE|OSD_ATM_LANE) return 1 ;;
-        HSTR|OSN|unknown) return 1 ;;
-        "GuestLAN Hiper") return 1 ;;
-        *) echo $"Unknown card_type to determine IPv6 support"
-            return 1 ;;
-    esac
-}
-
-# sets device online _and_ retrieves DEVICE at the same time
-function set_device_online() {
-    echo $"Activating network device..."
-    local sysnettype
-    case "${NETTYPE}" in
-        qeth|lcs) sysnettype=${NETTYPE} ;;
-        ctc) sysnettype=ctcm ;;
-    esac
-    if ! [ -f /sys/devices/${sysnettype}/$SCH_R_DEVBUSID/online ]; then
-        echo $"Sysfs path to set device online does not exist."
-        return 1
-    fi
-    if ! sysecho /sys/devices/${sysnettype}/$SCH_R_DEVBUSID/online "1"; then
-        echo $"Could not set device ($SUBCHANNELS) online"
-        return 1
-    fi
-    udevadm settle
-    local i=1
-    while : ; do
-        local online
-        read online < /sys/devices/${sysnettype}/$SCH_R_DEVBUSID/online
-        [ "$online" == "1" ] && break
-        sleep 1
-        i=$((i+1))
-        if [ "$i" -gt 10 ]; then
-            echo $"Could not set device ($SUBCHANNELS) online within timeout"
-            return 1
-        fi
-    done
-    if [ "$NETTYPE" = "lcs" -o "$NETTYPE" = "ctc" ]; then
-        # KH FIXME: Workaround for missing sysfs interface
-        #   DEVICE=$(cat /sys/devices/lcs/${SUBCHANNELS//,*/}/if_name)
-        # replaced with flexible solution:
-        # https://bugzilla.redhat.com/show_bug.cgi?id=204803#c9
-        # "sys/bus/ccwgroup/devices/${SUBCHANNEL}/net\:*
-        # for lcs after setting online"
-        if [ ! -h /sys/devices/${sysnettype}/$SCH_R_DEVBUSID/net:* ]; then
-            echo $"Device $SUBCHANNELS does not have required sysfs attribute 'net:*'"
-            return 1
-        fi
-        DEVICE=$(echo /sys/devices/${sysnettype}/$SCH_R_DEVBUSID/net:*)
-        DEVICE=${DEVICE//*:/}
-        if [ "$DEVICE" = "" ]; then
-            echo $"Could not get device name for $SUBCHANNELS"
-            return 1
-        fi
-    else # qeth
-        if [ ! -f /sys/devices/qeth/$SCH_R_DEVBUSID/if_name ]; then
-            echo $"Device $SUBCHANNELS does not have required sysfs attribute 'if_name'"
-            return 1
-        fi
-        # (device needs to be online to read if_name from sysfs attribute!)
-        read DEVICE < /sys/devices/qeth/$SCH_R_DEVBUSID/if_name
-        if [ "$DEVICE" = "" ]; then
-            echo $"Could not get device name for $SUBCHANNELS"
-            return 1
-        fi
-        if [ -f /sys/devices/qeth/$SCH_R_DEVBUSID/card_type ]; then
-            read cardtype < /sys/devices/qeth/$SCH_R_DEVBUSID/card_type
-            #debug echo "$cardtype"
-            # device is now online and link type will be known
-            echo -n $"Detected: "
-            cardtype2cleartext "$cardtype"
-        else
-            echo $"Could not read qeth network card type from sysfs."
-        fi
-    fi
-}
-
-# sets device up and blocks until device appears to be up
-function set_device_up() {
-    if [ -z "$DEVICE" ]; then
-        echo $"Could not determine interface name to bring up device $SUBCHANNELS"
-        return 1
-    fi
-    # Device does not come up fast enough to use "ip" to configure, so block.
-    # While OSA come up themselves after setting online,
-    # e.g. HiperSockets won't => set them up explicitly for the following check
-    debug ip link set up $DEVICE
-    local i=1
-    while : ; do
-        local tst=$(ip -o link show up dev $DEVICE)
-        [ -n "$tst" ] && break
-        sleep 1
-        i=$((i+1))
-        if [ "$i" -gt 10 ]; then
-            echo $"Could not bring up device $DEVICE within timeout"
-            return 1
-        fi
-    done
-    return 0
-}
-
-function syntax_check_domainname() {
-    # - match against regex adopted from RFC1035,sec.2.3.1 or RFC1034,sec.3.5
-    #   (Internationalized Domain Names in Applications (IDNA) [RFC4690]
-    #    have to be entered after encoding by punycode [RFC3492])
-    [[ "$1" =~ ^[[:alpha:]]([[:alnum:]-]{0,61}[[:alnum:]])?(\.[[:alpha:]]([[:alnum:]-]{0,61}[[:alnum:]])?)*$ ]]
-    case $? in
-        0)
-            # string matched the pattern
-            return 0
-            ;;
-        1)
-            # string did not match the pattern
-            echo "$2"
-            ;;
-        2)
-            echo "l.$LINENO: syntax error in regex of match operator =~, code needs to be fixed" 1>&2
-            ;;
-        *)
-            echo "l.$LINENO: unexpected return code of regex match operator =~, code needs to be fixed" 1>&2
-            ;;
-    esac
-    return 1
-}
-
-function modprobe_alias() {
-    if [ ":$NETTYPE" = ":ctc" ]; then
-        echo "alias $DEVICE ctcm" >> /tmp/modprobe.conf
-    else
-        echo "alias $DEVICE $NETTYPE" >> /tmp/modprobe.conf
-    fi
-    if [ $? -ne 0 ]; then
-        echo $"Could not append alias for network device $DEVICE to modprobe.conf"
-        return 1
-    fi
-    return 0
-}
-
-function disable_ipv6_autoconf() {
-    sysctl -w net.ipv6.conf.all.accept_ra=0 > /dev/null
-    sysctl -w net.ipv6.conf.all.accept_redirects=0 > /dev/null
-    sysctl -w net.ipv6.conf.all.autoconf=0 > /dev/null
-    sysctl -w net.ipv6.conf.default.accept_ra=0 > /dev/null
-    sysctl -w net.ipv6.conf.default.accept_redirects=0 > /dev/null
-    sysctl -w net.ipv6.conf.default.autoconf=0 > /dev/null
-}
-
-function configure_ipv6_address() {
-    # device needs to be online
-    # arp flag needs to be on for ipv6 over osa because of ndisc.
-    # happens automatically by the driver. do NOT mess with default setting.
-    #NO#debug ip link set dev $DEVICE arp on
-    if ! debug ip -6 address add $IPADDR/$NETMASK dev $DEVICE; then
-        echo $"Could net set IPv6 address $IPADDR/$NETMASK for device $DEVICE"
-        return 1
-    fi
-    # network route has been set by above "ip address add" already
-    # take care of MTU, which is bundled with ifconfig in the other IPv4 cases
-    if [ -n "$MMTU" ]; then
-        if ! debug ip link set $DEVICE $MMTU; then
-            echo $"Could net set maximum transfer unit ($MMTU) for device $DEVICE"
-            return 1
-        fi
-    fi
-    return 0
-}
-
-function configure_ipv4_address() {
-    # it's IPv4 and we can make use of ipcalc for better usability
-    if ipcalc -bmnp $ipcalc_arg > /tmp/ipcalc.$$.out 2> /dev/null; then
-        . /tmp/ipcalc.$$.out
-    else
-        echo $"Could not calculate network address and broadcast address from"
-        echo $" IPv4 address $IPADDR and netmask $NETMASK"
-        return 1
-    fi
-    rm /tmp/ipcalc.$$.out
-    # device needs to be online
-    if ! debug ifconfig $DEVICE $IPADDR $MMTU netmask $NETMASK broadcast $BROADCAST; then
-        echo $"Could not set IPv4 address $IPADDR for device $DEVICE"
-        echo $" with network mask $NETMASK and broadcast address $BROADCAST"
-        [ -n "$MMTU" ] && echo $" and maximum transfer unit: $MMTU"
-        return 1
-    fi
-    # This network route is already there after ifconfig!
-    #if ! debug route add -net $NETWORK netmask $NETMASK dev $DEVICE; then
-    #    echo $"Could not add network route to $NETWORK/$NETMASK on device $DEVICE"
-    #    return 1
-    #fi
-    return 0
-}
-
-function handle_mtu() {
-    # don't ask for MTU, but use it if it has been set in the .parm file
-    # don't overwrite MMTU if it has been set for CTC
-    [ -n "$MTU" -a -z "$MMTU" ] && MMTU="mtu $MTU"
-}
-
-function rollback_config() {
-    # each transaction to roll back may fail, if previous setup has not
-    # made progress that far to reach a certain transation
-    # => error output is misleading and should be avoided
-    [ -n "$DEVICE" ] && tv ip -4 route flush default dev $DEVICE
-    [ -n "$DEVICE" ] && tv ip -6 route flush default dev $DEVICE
-    # address flush seems to be effective for all address families
-    [ -n "$DEVICE" ] && ip address flush dev $DEVICE
-    if [ -n "$NETTYPE" ]; then
-        if [ -n "$SCH_R_DEVBUSID" ]; then
-            local sysnettype
-            case "${NETTYPE}" in
-                qeth|lcs) sysnettype=${NETTYPE} ;;
-                ctcm) sysnettype=ctcm ;;
-            esac
-            [ -f /sys/devices/${sysnettype}/$SCH_R_DEVBUSID/online ] && \
-                sysecho /sys/devices/${sysnettype}/$SCH_R_DEVBUSID/online "0"
-            udevadm settle
-            [ -f /sys/devices/${sysnettype}/$SCH_R_DEVBUSID/ungroup ] && \
-                sysecho /sys/devices/${sysnettype}/$SCH_R_DEVBUSID/ungroup "1"
-            udevadm settle
-        fi
-    fi
-    [ -z "$mtu_was_set" ] && unset MTU
-    [ -z "$mmtu_was_set" ] && unset MMTU
-    [ -z "$vswitch_was_set" ] && unset VSWITCH
-    # prevent possible reuse of an old DEVICE on restarting dialog
-    unset DEVICE
-    # set activated DASDs offline again
-    local dasd
-    while read dasd < /proc/dasd/devices; do
-        dasd=${dasd%%(*}
-        sysecho /sys/bus/ccw/devices/$dasd/online 0
-    done
-    udevadm settle
-}
-
-### workflow helper functions
-
-# workflow ideas:
-# - setting/applying single configuration steps right away save us explicit
-#   syntactical & semantic checks PLUS we get direct feedback on error
-# - check error level of forked external programs and react on errors
-
-unset reenter
-unset redoitem
-unset interaction_happened
-
-function reenter() {
-    [ -z "$reenter" ] && return 1
-    # reenter menu should only be shown if NOT redoing item
-    if [ -n "$redoitem" ]; then
-        # unset redoitem # wrong => do NOT do this here
-        return 1
-    fi
-    return 0
-}
-
-function reenter_menu() {
-    local oldvalue=$1
-    interaction_happened="yes"
-    # unsetting input here is not sufficient, since reenter_menu
-    # is not called for predefined parameters
-    # which then might get assigned a previous old input of another parameter!
-    #unset input
-    reenter || return 0
-    # don't present reenter menu for empty parameters
-    # (currently ignoring parameters that are allowed to be empty!)
-    # this could be improved by checking if variable has been set/defined
-    #[ -z "$1" ] && return 0
-    while : ; do
-        if [ -n "$helptext" ]; then
-            echo $"0) default is previous \"$oldvalue\", 1) new value, ?) help"
-        else
-            echo $"0) default is previous \"$oldvalue\", 1) new value"
-        fi
-        # uncoded alternative: 2) skip parameter
-        local answer
-        read answer
-        [ -z "$answer" ] && return 1
-        case $answer in
-            0) return 1 ;;
-            1)  # Deciding to enter new value gets user out of reenter-mode
-                # temporarily for this parameter.
-                # To put it differently: redoing does NOT present old values.
-                redoitem="yes"
-                echo -n $"new value: "
-                return 0
-                ;;
-            "?") input="?"
-                return 1
-                ;;
-        esac
-    done
-}
-
-function workflow_item_menu() {
-    local noredo=$1
-    # default is to continue if running kickstart to prevent interaction
-    [ -n "$RUNKS" ] && return 0
-    interaction_happened="yes"
-    while : ; do
-        unset redoitem
-        if [ "$noredo" = "noredo" ]; then
-            echo $"1) continue, 2) restart dialog, 3) halt, 4) shell"
-        else
-            echo $"0) redo this parameter, 1) continue, 2) restart dialog, 3) halt, 4) shell"
-        fi
-        local answer
-        read answer
-        case $answer in
-            0) [ "$noredo" = "noredo" ] && continue
-                redoitem="yes"
-                continue 2
-                ;;
-            1) return 0 ;; # can be used to break at caller on ignore
-            2) reenter="yes"
-                rollback_config
-                continue 3
-                ;;
-            3) tv doshutdown
-                exit 0
-                ;;
-            4) echo $"Enter 'exit' at the shell prompt to get back to the installation dialog."
-                /bin/bash
-                if [ "$noredo" != "noredo" ] && [ -n "$question_prefix" ]; then
-                    $question_prefix
-                    echo
-                fi
-                ;; # stay in workflow item menu
-        esac
-    done
-}
-
-# input variables: PARMNAME, question_prefix, question_choices,
-#                  "options" ...
-# output variables: $question_prefix, $helptext
-# modifies: the variable named $PARMNAME, $OPTIND
-function ask() {
-    [ $# -lt 3 ] && echo "l.$LINENO: too few arguments (<3), please fix calling code." 1>&2
-    local PARMNAME=$1
-    shift
-    question_prefix=$1
-    shift
-    local question_choices=$1
-    shift
-    local exception
-    local syntax_check
-    unset helptext
-    local handle
-    local finish
-    local optname
-    OPTIND=1
-    while getopts ":e:s:h:c:f:" optname; do
-        case $optname in
-            e) exception=$OPTARG ;;
-            s) syntax_check=$OPTARG ;;
-            h) helptext=$OPTARG ;;
-            c) handle=$OPTARG ;;
-            f) finish=$OPTARG ;;
-            "?") ;; # ignore invalid option
-            :) echo "l.$LINENO: Missing parameter to option -$OPTARG" 1>&2 ;;
-        esac
-    done
-    while : ; do
-        unset input
-        local input
-        # actually ask question if one of the following is true:
-        # - $PARMNAME parameter has not been set yet, e.g. not in parm file
-        # - on 2nd and further attempts, i.e. redoing the parameter
-        # - on having restarted the whole dialog
-        # describing the same from another viewpoint:
-        # - if $PARMNAME has been set, try to check syntax and apply
-        # - on redo, $PARMNAME has been set and reenter is false,
-        #   but still ask question again
-        # - on reenter, $PARMNAME might have been set, but still ask question
-        if [ -z "${!PARMNAME}" -o -n "$redoitem" -o -n "$reenter" ]; then
-            # one empty line to separate parameter questions from each other
-            echo
-            $question_prefix
-            if reenter; then
-                echo
-            else
-                $question_choices
-            fi
-            # on reenter, give choice between old value and entering new one
-            reenter_menu ${!PARMNAME} && read input \
-                && [ "$input" != "?" ] && eval ${PARMNAME}=\$input
-            # escaping the $ in the RHS of the eval statement makes it safe
-        fi
-        if [ -n "$helptext" ] && [ "$input" = "?" ]; then
-            $helptext
-            continue
-        fi
-        # optional: default or exceptional handling
-        [ -n "$exception" ] && $exception
-        if [ -n "$syntax_check" -a -z "$handle" ]; then
-            # some parameters have only syntax check (and deferred config):
-            if $syntax_check; then
-                break
-            else
-                workflow_item_menu && break
-            fi
-        elif [ -n "$syntax_check" -a -n "$handle" ]; then
-            # most common parameters have syntax and configuration:
-            # user might still continue on syntax error
-            $syntax_check || workflow_item_menu
-            # optional: actual configuration
-            if $handle; then
-                # parmname has been configured successfully
-                break
-            else
-                # user might still continue on configuration failure
-                workflow_item_menu && break
-            fi
-        elif [ -n "$finish" ]; then
-            # few parameters need special handling done by their own function:
-            $finish
-        else
-            echo $"Unsupported calling of ask function, please fix calling code"
-        fi
-    done # PARMNAME
-    # disable potential temporary redoing-mode during reenter-mode
-    unset redoitem
-}
-
-### NETTYPE
-
-function syntax_check_nettype() {
-    # - NETTYPE \in {qeth,lcs,ctc}
-    [[ "$NETTYPE" =~ (^qeth$)|(^lcs$)|(^ctc$) ]]
-    case $? in
-        0)
-            # string matched the pattern
-            return 0
-            ;;
-        1)
-            # string did not match the pattern
-            ;;
-        2)
-            echo "l.$LINENO: syntax error in regex of match operator =~, code needs to be fixed" 1>&2
-            ;;
-        *)
-            echo "l.$LINENO: unexpected return code of regex match operator =~, code needs to be fixed" 1>&2
-            ;;
-    esac
-    echo $"Incorrect format or value for network type (NETTYPE): $NETTYPE"
-    return 1
-}
-
-function question_prefix_nettype() {
-    echo -n $"Network type"
-}
-
-function question_choices_nettype() {
-    echo $" (qeth, lcs, ctc, ? for help). Default is qeth:"
-}
-
-function helptext_nettype() {
-    echo $" Help text for network type:"
-    echo $"  qeth: OSA-Express Fast Ethernet, Gigabit Ethernet (including 1000Base-T),"
-    echo $"        High Speed Token Ring, Hipersockets, and ATM (running Ethernet LAN emulation)"
-    echo $"        features in QDIO mode."
-    echo $"        [default]"
-    echo $"  lcs:  OSA-2 Ethernet/Token Ring, OSA-Express Fast Ethernet in non-QDIO mode,"
-    echo $"        OSA-Express High Speed Token Ring in non-QDIO mode and Gigabit Ethernet"
-    echo $"        in non-QDIO mode."
-    echo $"  ctc:  Deprecated, useful for migration."
-}
-
-function exception_nettype() {
-    # - default is qeth since it should be common
-    if [ -z "$NETTYPE" ]; then
-        NETTYPE=qeth
-        break
-    fi
-}
-
-function finish_nettype() {
-    if syntax_check_nettype; then
-        break
-    else
-        # necessary parts which would otherwise be done by workflow_item_menu
-        interaction_happened="yes"
-        redoitem="yes"
-    fi
-}
-
-function do_nettype() {
-    ask NETTYPE \
-        question_prefix_nettype question_choices_nettype \
-        -h helptext_nettype -e exception_nettype -f finish_nettype
-}
-
-### CHANDEV
-
-function do_chandev() {
-    echo
-    echo $"The CHANDEV variable isn't used anymore, please update your "
-    echo $".parm or the .conf file to use NETTYPE, SUBCHANNELS, etc. instead."
-    echo
-}
-
-### SUBCHANNELS
-
-function syntax_check_subchannels() {
-    SUBCHANNELS=$(echo $SUBCHANNELS | tr ABCDEF abcdef)
-    # - make subchannel question dependent on NETTYPE (2 vs. 3 subchannels)
-    if [ "$NETTYPE" = "qeth" ]; then
-        # - match against regex, depending on qeth
-        [[ "$SUBCHANNELS" =~ ^[[:xdigit:]]+\.[0-3]\.[[:xdigit:]]{4},[[:xdigit:]]+\.[0-3]\.[[:xdigit:]]{4},[[:xdigit:]]+\.[0-3]\.[[:xdigit:]]{4}$ ]]
-    else
-        # - match against regex, depending on lcs/ctc
-        [[ "$SUBCHANNELS" =~ ^[[:xdigit:]]+\.[0-3]\.[[:xdigit:]]{4},[[:xdigit:]]+\.[0-3]\.[[:xdigit:]]{4}$ ]]
-    fi
-    case $? in
-        0)
-            # string matched the pattern
-            return 0
-            ;;
-        1)
-            # string did not match the pattern
-            echo $"Incorrect format for channels (SUBCHANNELS): $SUBCHANNELS"
-            ;;
-        2)
-            echo "l.$LINENO: syntax error in regex of match operator =~, code needs to be fixed" 1>&2
-            ;;
-        *)
-            echo "l.$LINENO: unexpected return code of regex match operator =~, code needs to be fixed" 1>&2
-            ;;
-    esac
-    return 1
-}
-
-function semantic_check_subchannels() {
-    local subch_count
-    if [ "$NETTYPE" = "qeth" ]; then
-        subch_count=3
-    else
-        subch_count=2
-    fi
-    # done: make subchannel handling more robust by not relying on REMATCH
-    local -a subch_array
-    IFS=,
-    read -a subch_array <<< "indexzero,$SUBCHANNELS"
-    unset IFS
-    local i
-    local all_subch_good=0
-    for ((i=1; i <= $subch_count; i++)); do
-        local devbusid=${subch_array[$i]}
-        # remember first subchannel for potential undo of ccwgroup
-        # (via /sys/devices/qeth/$SCH_R_DEVBUSID/ungroup)
-        [ "$i" -eq 1 ] && SCH_R_DEVBUSID=$devbusid
-        local prefix ssid devno foo
-        IFS=.
-        read prefix ssid devno foo <<< "$devbusid"
-        unset IFS
-        local dev_p=$(echo /sys/devices/css$prefix/$IDFORMAT/$devbusid)
-        # - check for existence of devnos in sysfs
-        if [ ! -d "$dev_p" -a "$cio_wc_bytes" != "0" ]; then
-            # - try to free from /proc/cio_ignore if they don't exist
-            echo $"Device $devbusid not present, trying to clear from blacklist and resense..."
-            if sysecho /proc/cio_ignore "free $devbusid"; then
-                # /proc/cio_ignore won't block on freeing devices
-                # until resensing has been completed, so wait until
-                # the udev event queue depletes (without udevadm settle we
-                # could wait 2 seconds unconditionally)
-                #debug ls -laF /dev/.udev
-                udevadm settle
-                # even though the device might now be online, some of its
-                # sysfs attributes (e.g. cutype) might not yet be available
-                sleep 1
-            else
-                echo $"Device $devbusid could not be cleared from device blacklist"
-            fi
-        fi
-        # reevaluate since globbing might not have worked before device existed
-        dev_p=$(echo /sys/devices/css$prefix/$IDFORMAT/$devbusid)
-        if [ ! -d "$dev_p" ]; then
-            echo $"Device $devbusid does not exist"
-            all_subch_good=1
-            continue
-        fi
-        # devno does exist now
-        local subch_p=${dev_p%/*}
-        local subch=${subch_p##*/}
-        # filter definitely unusable subchannels ...
-        # - check for subchannel type I/O
-        if [ -f $subch_p/type ]; then
-            local type
-            read type < $subch_p/type
-            if [ "$type" != "$SUBCHANNEL_TYPE_IO" ]; then
-                echo $"Channel $subch (device $devbusid) is not of type I/O"
-                all_subch_good=1
-                continue
-            fi
-        fi
-        # - check for correct CU type/model, depending on qeth/lcs/ctc
-        if [ ! -f $dev_p/cutype ]; then
-            echo $"Device $devbusid does not have required sysfs attribute 'cutype'"
-            all_subch_good=1
-            continue
-        fi
-        local cutype
-        read cutype < $dev_p/cutype
-        if search_cu $cutype; then
-            local driver
-            if [ "$NETTYPE" = "ctc" ]; then
-                driver="ctcm"
-            else
-                driver=$NETTYPE
-            fi
-            if [ "${CU_DEVDRV[$cu_idx]}" != "$driver" ]; then
-                echo $"Device $devbusid has control unit type $cutype,"
-                echo $" which does not match your selected network type $NETTYPE"
-                all_subch_good=1
-                continue
-            fi
-        else
-            echo $"Device $devbusid has control unit type $cutype which is unknown"
-            all_subch_good=1
-            continue
-        fi
-        # read CHPIDs information about subchannels
-        if [ ! -f $subch_p/chpids ]; then
-            echo $"Channel $subch (device $devbusid) does not have required sysfs attribute 'chpids'"
-            all_subch_good=1
-            continue
-        fi
-        local chpid_list
-        read chpid_list < $subch_p/chpids
-        local -a chpids
-        read -a chpids <<< "$chpid_list"
-        if [ ${#chpids[@]} -ne 8 ]; then
-            echo $"sysfs reported ${#chpids[@]} CHPIDs instead of expected 8, code needs fix"
-        fi
-        if [ ! -f $subch_p/pimpampom ]; then
-            echo $"Channel $subch (device $devbusid) does not have required sysfs attribute 'pimpampom'"
-            all_subch_good=1
-            continue
-        fi
-        local pim pam pom foo
-        read pim pam pom foo < $subch_p/pimpampom
-        local pimchpidZ=""
-        for ((chp=0; chp < 8; chp++)); do
-            local mask=$((0x80 >> chp))
-            if (( 0x$pim & $mask )); then
-                pimchpidZ=${pimchpidZ}${chpids[chp]}
-            else
-                pimchpidZ=${pimchpidZ}"ZZ"
-            fi
-        done
-        local pimchpids=${pimchpidZ//ZZ/}
-        if [ "x$pimchpids" == "x" ]; then
-            echo $"Channel $subch (device $devbusid) does not have any installed channel path"
-            all_subch_good=1
-            continue
-        fi
-        # compare parts of different subchannels for required matches
-        if [ "$i" -eq 1 ]; then
-            # remember parts of first subchannel for comparison
-            local sch_r_prefix=$prefix
-            local sch_r_ssid=$ssid
-            local sch_r_devno=$devno
-            local sch_r_pimchipidZ=$pimchpidZ
-            local sch_r_cutype=$cutype
-        else
-            local comparison=0
-            # $sch_r_... might be empty if first channel was wrong
-            # => be sure to quote all variable accesses in test statements.
-            # - all subchannels must be of same CU type/model
-            if [ "$cutype" != "$sch_r_cutype" ]; then
-                echo $"Device $devbusid does not have the same control unit type as device $SCH_R_DEVBUSID"
-                comparison=1
-            fi
-            # - all subchannels must have same CHPIDs
-            if [ "$pimchpidZ" != "$sch_r_pimchipidZ" ]; then
-                echo $"Device $devbusid does not have the same CHPIDs as device $SCH_R_DEVBUSID"
-                comparison=1
-            fi
-            # - all subchannels should have same prefix & ssid ?
-            if [ "$prefix" != "$sch_r_prefix" \
-                -o "$ssid" != "$sch_r_ssid" ]; then
-                echo $"Device $devbusid does not have the same prefix and subchannel set ID as device $SCH_R_DEVBUSID"
-                comparison=1
-            fi
-            if [ "$i" -eq 2 ]; then
-                local sch_w_devbusid=$devbusid
-                local sch_w_devno=$devno
-                # TODO: not true for CTCM => relax
-                # - write_devbusid == read_devbusid+1
-                if [ $((0x$devno)) -ne $((0x$sch_r_devno + 1)) ]; then
-                    echo $"Device bus ID of write channel (dev $devbusid) must be one larger than"
-                    echo $" that of read channel (dev $SCH_R_DEVBUSID)"
-                    comparison=1
-                fi
-            elif [ "$i" -eq 3 ]; then
-                # check data subchannel unequal to read/write subchannel
-                # (also seems to be handled by ccwgroup kernel subsystem)
-                if [ "$devbusid" = "$sch_w_devbusid" \
-                    -o "$devbusid" = "$SCH_R_DEVBUSID" ]; then
-                    echo $"Device bus ID of data channel (dev $devbusid) must be different to that of"
-                    echo $" read channel ($SCH_R_DEVBUSID) and write channel ($sch_w_devbusid)"
-                    comparison=1
-                fi
-            fi
-            if [ "$comparison" != 0 ]; then
-                all_subch_good=1
-                continue
-            fi
-        fi
-        # filter potentially good subchannels ...
-        if [ -h $dev_p/group_device ]; then
-            echo $"Device $devbusid is already in a ccwgroup and thus unavailable"
-            all_subch_good=1
-            continue
-        fi
-        if [ ! -f $dev_p/online ]; then
-            echo $"Device $devbusid does not have required sysfs attribute 'online'"
-            all_subch_good=1
-            continue
-        fi
-        local online
-        read online < $dev_p/online
-        if [ "$online" = "1" ]; then
-            echo $"Device $devbusid is already in use and thus unavailable"
-            all_subch_good=1
-            continue
-        fi
-        # - check availability
-        if [ ! -f $dev_p/availability ]; then
-            echo $"Device $devbusid does not have required sysfs attribute 'availability'"
-            all_subch_good=1
-            continue
-        fi
-        local availability
-        read availability < $dev_p/availability
-        if [ "$availability" != "good" ]; then
-            echo $"Device $devbusid is not available but '$availiability'"
-            all_subch_good=1
-            continue
-        fi
-
-    done # for ((i=1; i <= $subch_count; i++))
-    if [ "$all_subch_good" = "0" ]; then
-        return 0
-    fi
-    return 1
-}
-
-function handle_subchannels() {
-    # - try to establish ccwgroup right here and fail out on error
-    local driver
-    if [ "$NETTYPE" = "ctc" ]; then
-        driver="ctcm"
-    else
-        driver=$NETTYPE
-    fi
-    if sysecho /sys/bus/ccwgroup/drivers/${driver}/group "$SUBCHANNELS"; then
-        udevadm settle
-        case "$NETTYPE" in
-            qeth)
-                # Just preliminary card_type info until device goes online!
-                # In fact it seems enough to separate OSA from HiperSockets.
-                if [ -f /sys/devices/qeth/$SCH_R_DEVBUSID/card_type ]; then
-                    read cardtype < /sys/devices/qeth/$SCH_R_DEVBUSID/card_type
-                else
-                    echo $"Could not read qeth network card type from sysfs."
-                fi
-                ;;
-            ctc|lcs)
-                if [ -f /sys/devices/$driver/$SCH_R_DEVBUSID/type ]; then
-                    local type
-                    read type < /sys/devices/$driver/$SCH_R_DEVBUSID/type
-                    [ "$type" = "CTC/A" ] && \
-                        type="channel-to-channel adapter (CTC/A)"
-                    echo $"Detected: $type"
-                else
-                    echo $"Could not read ctc network card type from sysfs."
-                fi
-                ;;
-        esac
-        return 0
-    else
-        echo $"Channels $SUBCHANNELS could not be grouped"
-    fi
-    return 1
-}
-
-function question_prefix_subchannels() {
-    if [ "$NETTYPE" = "qeth" ]; then
-        echo -n $"Read,write,data channel"
-    else
-        echo -n $"Read,write channel"
-    fi
-}
-
-function question_choices_subchannels() {
-    if [ "$NETTYPE" = "qeth" ]; then
-        echo $" (e.g. 0.0.0300,0.0.0301,0.0.0302 or ? for help)."
-    else
-        echo $" (e.g. 0.0.0600,0.0.0601 or ? for help)"
-    fi
-}
-
-function helptext_subchannels() {
-    if [ "$NETTYPE" = "qeth" ]; then
-        echo $" Help text for qeth channels:"
-        echo $"  Enter the device bus ID of your CCW devices."
-        echo $"  QETH needs three channels for read, write, and data,"
-        echo $"  e.g. 0.0.0300,0.0.0301,0.0.0302"
-    else
-        echo $" Help text for lcs/ctc channels:"
-        echo $"  Enter the device bus ID of your CCW devices."
-        echo $"  CTC/ESCON and LCS need two channels for read and write,"
-        echo $"  e.g. 0.0.0600,0.0.0601 will configure the CTC or ESCON interface"
-        echo $"  with the channels 0x600 and 0x601"
-    fi
-}
-
-function finish_subchannels() {
-    syntax_check_subchannels || workflow_item_menu
-    # continuing on syntax error is doomed to fail,
-    # since handle_subchannels relies on the regex-based strict parsing
-    # in syntax_check_subchannels which does not match anything then
-    # news: relaxed by splitting semantic check and actual handling
-    semantic_check_subchannels || workflow_item_menu
-    if handle_subchannels; then
-        break
-    else
-        workflow_item_menu && break
-    fi
-}
-
-function do_subchannels() {
-    ask SUBCHANNELS \
-        question_prefix_subchannels question_choices_subchannels \
-        -h helptext_subchannels -f finish_subchannels
-}
-
-### PORTNAME (qeth)
-
-function syntax_check_portname() {
-    # - 1-8 characters, we convert it to upper case
-    PORTNAME=$(echo $PORTNAME | tr '[:lower:]' '[:upper:]')
-    local portname_len=${#PORTNAME}
-    if [ "$portname_len" -ge 1 -a "$portname_len" -le 8 ]; then
-        return 0
-    fi
-    echo $"Incorrect string length [1..8] for portname (PORTNAME): $PORTNAME"
-    return 1
-}
-
-function handle_portname() {
-    [ -n "$PORTNAME" ] || return 0
-    # - try to set portname right here w/ error handling
-    if sysecho /sys/devices/${NETTYPE}/$SCH_R_DEVBUSID/portname "$PORTNAME"; then
-        return 0
-    else
-        echo $"Portname '$PORTNAME' could not be configured for $SUBCHANNELS"
-    fi
-    return 1
-}
-
-function hint_portname() {
-    if [ -f /sys/devices/${NETTYPE}/$SCH_R_DEVBUSID/portname ]; then
-        local pname_hint
-        read pname_hint < /sys/devices/${NETTYPE}/$SCH_R_DEVBUSID/portname
-        if [ "$pname_hint" = "no portname required" ]; then
-            echo $"  * Your configuration does not require a portname. *"
-        fi
-    fi
-}
-
-function question_prefix_portname(){
-    echo -n $"Portname"
-}
-
-function question_choices_portname(){
-    echo $" (1..8 characters, or ? for help). Default is no portname:"
-}
-
-function helptext_portname(){
-    echo $" Help text for portname:"
-    # updated text describing when portname is obsolete;
-    # taken from:
-    # SA22-7935-09, Open Systems Adapter-Express Customer's
-    #   Guide and Reference, 10th ed. May 2008, IBM, p.17f.
-    # SC33-8411-00, Device Drivers, Features, and Commands,
-    #   1st ed. May 2008, IBM, p.116.
-    echo $"  Portname of the OSA-Express feature in QDIO mode and z/VM Guest LAN."
-    echo $"  This parameter is optional with:"
-    echo $"   - z/VM 4.4.0 or z/VM 4.3.0 with APARs VM63308 and PQ73878"
-    echo $"   - z800, z900 with >= Driver 3G - EC stream J11204, MCL032 (OSA level 3.33)"
-    echo $"   - z890, z990, z9, z10 mainframes"
-    hint_portname
-    echo $"  If portname is used, all operating systems sharing port must use same name."
-    echo $"  Input empty string if you don't want to enter a portname. [default]"
-}
-
-function exception_portname(){
-    [ -z "$PORTNAME" ] && break
-}
-
-function do_portname() {
-    ask PORTNAME \
-        question_prefix_portname question_choices_portname \
-        -h helptext_portname \
-        -e exception_portname -s syntax_check_portname -c handle_portname
-}
-
-### PORTNO (qeth)
-
-function syntax_check_qeth_portno() {
-    case $PORTNO in
-        0|1)
-            return 0
-            ;;
-    esac
-    echo $"Incorrect format or value for relative port number (PORTNO): $PORTNO"
-    return 1
-}
-
-function handle_qeth_portno() {
-    if sysecho /sys/devices/qeth/$SCH_R_DEVBUSID/portno "$PORTNO"; then
-        return 0
-    fi
-    echo $"Could not configure relative port number $PORTNO for $SUBCHANNELS"
-    return 1
-}
-
-function question_prefix_portno() {
-    echo -n $"Relative port number for OSA"
-}
-
-function question_choices_portno() {
-    echo $" (0, 1, or ? for help). Default is 0:"
-}
-
-function helptext_portno() {
-    echo $" Help text for relative port number for OSA with 2 ports per CHPID:"
-    echo $"  This applies to:"
-    echo $"   - OSA-Express3 Gigabit Ethernet on z10 systems"
-    echo $"   - OSA-Express ATM on zSeries 800 and 900 systems"
-    echo $"  0 for relative port number 0 [default]"
-    echo $"  1 for relative port number 1"
-    echo $"  Input empty string to not modify the default configuration."
-}
-
-function exception_portno() {
-    # Writing portno of e.g. hipersockets device fails.
-    # Therefore, do not configure on empty default value.
-    [ -z "$PORTNO" ] && break
-}
-
-function do_portno() {
-    ask PORTNO \
-        question_prefix_portno question_choices_portno \
-        -h helptext_portno -e exception_portno \
-        -s syntax_check_qeth_portno -c handle_qeth_portno
-}
-
-### LAYER2
-
-function syntax_check_layer2() {
-    # - $LAYER2 \in {0,1}
-    case $LAYER2 in
-        0|1)
-            return 0
-            ;;
-    esac
-    echo $"Incorrect format or value for layer2 mode (LAYER2): $LAYER2"
-    return 1
-}
-
-function handle_layer2() {
-    [ "$NETTYPE" == "qeth" ] || return 0
-    [ -n "$LAYER2" ] || return 0
-    # - try to set layer2 mode right here w/ error handling
-    if sysecho /sys/devices/${NETTYPE}/$SCH_R_DEVBUSID/layer2 "$LAYER2"; then
-        return 0
-    else
-        echo $"Layer2 mode '$LAYER2' could not be configured for $SUBCHANNELS"
-    fi
-    return 1
-}
-
-function question_prefix_layer2() {
-    echo -n $"Layer mode"
-}
-
-function question_choices_layer2() {
-    echo -n $" (0 for layer3, 1 for layer2, or ? for help)."
-    if [ "$isLayer2Default" = "yes" ]; then
-        echo $" Default is 1:"
-    else
-        echo $" Default is 0:"
-    fi
-}
-
-function helptext_layer2() {
-    echo $" Help text for OSA mode of operation: layer 2 vs. layer 3"
-    if [ "$isLayer2Default" = "yes" ]; then
-        echo $"  0 for layer 3 mode (may not work with dhcp, tcpdump, etc.)"
-        echo $"  1 for layer 2 mode [default]"
-    else
-        echo $"  0 for layer 3 mode [default] (may not work with dhcp, tcpdump, etc.)"
-        echo $"  1 for layer 2 mode"
-    fi
-}
-
-function exception_layer2() {
-    if [ -z "$LAYER2" ]; then
-        isLayer2Default && LAYER2=1 || LAYER2=0
-        # do not break, always apply, default may differ from online layer mode
-        #break
-    fi
-}
-
-function do_layer2() {
-    isLayer2Default && isLayer2Default=yes || isLayer2Default=no
-    ask LAYER2 \
-        question_prefix_layer2 question_choices_layer2 \
-        -h helptext_layer2 -e exception_layer2 \
-        -s syntax_check_layer2 -c handle_layer2
-}
-
-### MACADDR
-
-function syntax_check_macaddr() {
-    # - match against regex
-    [[ "$MACADDR" =~ ^[[:xdigit:]][[:xdigit:]]:[[:xdigit:]][[:xdigit:]]:[[:xdigit:]][[:xdigit:]]:[[:xdigit:]][[:xdigit:]]:[[:xdigit:]][[:xdigit:]]:[[:xdigit:]][[:xdigit:]]$ ]]
-    case $? in
-        0)
-            # string matched the pattern
-            return 0
-            ;;
-        1)
-            # string did not match the pattern
-            echo $"Incorrect format for mac address (MACADDR): $MACADDR"
-            ;;
-        2)
-            echo "l.$LINENO: syntax error in regex of match operator =~, code needs to be fixed" 1>&2
-            ;;
-        *)
-            echo "l.$LINENO: unexpected return code of regex match operator =~, code needs to be fixed" 1>&2
-            ;;
-    esac
-    return 1
-}
-
-function handle_macaddr() {
-    # - try to set macaddr right here w/ error handlg.
-    # device needs to be online
-    if debug ifconfig $DEVICE hw ether $MACADDR; then
-        return 0
-    fi
-    echo $"MAC address $MACADDR could not be configured for"
-    echo $" $SUBCHANNELS (network device $DEVICE)"
-    return 1
-}
-
-function question_prefix_macaddr() {
-    echo -n $"Unique MAC address"
-}
-
-function question_choices_macaddr() {
-    macaddr_default=$(ifconfig $DEVICE | grep 'HWaddr' | sed 's/.*HWaddr \([[:xdigit:]][[:xdigit:]]:[[:xdigit:]][[:xdigit:]]:[[:xdigit:]][[:xdigit:]]:[[:xdigit:]][[:xdigit:]]:[[:xdigit:]][[:xdigit:]]:[[:xdigit:]][[:xdigit:]]\).*/\1/')
-    echo $" (e.g. 02:00:00:00:00:00, ? for help). Default is $macaddr_default:"
-}
-
-function helptext_macaddr() {
-    echo $" Help text for MAC address:"
-    if [ -z "${cardtype//OSD_*/}" ]; then
-        echo $"  For real OSA in layer 2 mode, a random MAC address is automatically assigned."
-    else
-        echo $"  If connecting to a layer 2 VSWITCH, a MAC address is automatically assigned."
-    fi
-    echo $"  You may accept the automatic MAC address with an empty input. [default]"
-    echo $"  If the automatic address is not unique, please provide a MAC address."
-    [ -z "${cardtype//OSD_*/}" ] && \
-        echo $"  For real OSA, the provided address must be different from that of the OSA."
-    echo $"  You may override the automatic MAC address with non-empty input."
-    echo $"  An example MAC address would be: 02:00:00:00:00:00"
-}
-
-function exception_macaddr() {
-    if [ -z "$MACADDR" ]; then
-        if [ -z "${cardtype//OSD_*/}" ]; then
-            # keep random default MAC address of real OSA,
-            # so the OSA comes up with the same MAC each time in the future
-            MACADDR=$macaddr_default
-        else
-            # virtual OSA in layer2 is GuestLAN or VSWITCH
-            VSWITCH=1
-        fi
-        break
-    fi
-}
-
-function do_macaddr() {
-    ask MACADDR \
-        question_prefix_macaddr question_choices_macaddr \
-        -h helptext_macaddr -e exception_macaddr \
-        -s syntax_check_macaddr -c handle_macaddr
-}
-
-### CTCPROT
-
-function syntax_check_ctcprot() {
-    case "x$CTCPROT" in
-        x|x0)
-            unset CTCPROT
-            return 0
-            ;;
-        x1|x3)
-            return 0
-            ;;
-        x2)
-            echo $"CTC tty's are not usable for this installation (CTCPROT)"
-            ;;
-        *)
-            echo $"Incorrect format or value for CTC protocol (CTCPROT): $CTCPROT"
-            ;;
-    esac
-    return 1
-}
-
-function handle_ctcprot() {
-    [ -n "$CTCPROT" ] || return 0
-    if sysecho /sys/devices/ctcm/${SCH_R_DEVBUSID}/protocol "$CTCPROT"; then
-        return 0
-    fi
-    echo $"Could not configure CTC protocol $CTCPROT for $SUBCHANNELS"
-    return 1
-}
-
-function question_prefix_ctcprot() {
-    echo -n $"CTC protocol"
-}
-
-function question_choices_ctcprot() {
-    echo $" (0, 1, 3, or ? for help). Default is 0:"
-}
-
-function helptext_ctcprot() {
-    echo $" Help text for CTC protocol:"
-    echo $"  Protocol which should be used for the CTC interface"
-    echo $"  0 for compatibility with p.e. VM TCP service machine [default]"
-    echo $"  1 for enhanced package checking for Linux peers"
-    echo $"  3 for compatibility with OS/390 or z/OS peers"
-}
-
-function do_ctcprot() {
-    ask CTCPROT \
-        question_prefix_ctcprot question_choices_ctcprot \
-        -h helptext_ctcprot -s syntax_check_ctcprot -c handle_ctcprot
-}
-
-### PORTNAME (LCS portno)
-
-function syntax_check_lcs_portno() {
-    [[ "$PORTNAME" =~ ^[[:digit:]]+$ ]]
-    case $? in
-        0)
-            # string matched the pattern
-            return 0
-            ;;
-        1)
-            # string did not match the pattern
-            ;;
-        2)
-            echo "l.$LINENO: syntax error in regex of match operator =~, code needs to be fixed" 1>&2
-            ;;
-        *)
-            echo "l.$LINENO: unexpected return code of regex match operator =~, code needs to be fixed" 1>&2
-            ;;
-    esac
-    echo $"Incorrect format for LCS port number (PORTNAME): $PORTNAME"
-    return 1
-}
-
-function handle_lcs_portno() {
-    [ -n "$PORTNAME" ] || return 0
-    if sysecho /sys/devices/lcs/$SCH_R_DEVBUSID/portno "$PORTNAME"; then
-        return 0
-    fi
-    echo $"Could not configure relative port number $PORTNAME for $SUBCHANNELS"
-    return 1
-}
-
-function question_prefix_lcs_portno() {
-    echo -n $"Relative port number of your LCS device"
-}
-
-function question_choices_lcs_portno() {
-    echo $" (number or ? for help). Default is 0:"
-}
-
-function helptext_lcs_portno() {
-    echo $" Help text for relative port number of LCS device:"
-    echo $"  Required for OSA-Express ATM cards only."
-}
-
-function exception_lcs_portno() {
-    [ -z "$PORTNAME" ] && break
-}
-
-function do_lcs_portno() {
-    # LCS portno and QETH portname share the parameter variable PORTNAME.
-    # For compatibility with existing parm files we keep this scheme.
-    ask PORTNAME \
-        question_prefix_lcs_portno question_choices_lcs_portno \
-        -e exception_lcs_portno \
-        -h helptext_lcs_portno -s syntax_check_lcs_portno -c handle_lcs_portno
-}
-
-### HOSTNAME
-
-function syntax_check_hostname() {
-    syntax_check_domainname "$HOSTNAME" "Incorrect format for hostname (HOSTNAME): $HOSTNAME"
-}
-
-function handle_hostname() {
-    if ! hostname $HOSTNAME; then
-        echo $"Could not configure hostname $HOSTNAME"
-        return 1
-    fi
-    return 0
-}
-
-function question_prefix_hostname() {
-    echo -n $"Hostname of your new Linux guest"
-}
-
-function question_choices_hostname() {
-    echo $" (FQDN e.g. s390.redhat.com or ? for help):"
-}
-
-function helptext_hostname() {
-    echo $" Help text for hostname:"
-    echo $"  Enter the full qualified domain name of your host."
-}
-
-function do_hostname() {
-    ask HOSTNAME \
-        question_prefix_hostname question_choices_hostname \
-        -h helptext_hostname -s syntax_check_hostname -c handle_hostname
-}
-
-### IPADDR
-
-function syntax_check_ipaddr() {
-    unset ipv4
-    unset ipv6
-    if checkipv4 $IPADDR; then
-        ipv4="yes"
-        return 0
-    elif [ "$ipv6_capable" = "yes" ] && checkipv6 $IPADDR; then
-        ipv6="yes"
-        return 0
-    fi
-    echo $"Incorrect format for IP address (IPADDR): $IPADDR"
-    return 1
-}
-
-function question_prefix_ipaddr() {
-    echo -n $"IPv4 address"
-    [ "$ipv6_capable" = "yes" ] && echo -n $" / IPv6 addr."
-}
-
-function question_choices_ipaddr() {
-    echo -n $" (e.g. 10.0.0.2"
-    [ "$ipv6_capable" = "yes" ] && echo -n $" / 2001:0DB8::"
-    echo $" or ? for help)"
-}
-
-function helptext_ipaddr() {
-    echo $" Help text for IP address:"
-    echo $"  Enter a valid IPv4 address of your new Linux guest (e.g. 10.0.0.2)"
-    if [ "$ipv6_capable" = "yes" ]; then
-        echo $"  or alternatively a valid IPv6 address without CIDR prefix (e.g. 2001:0DB8::)"
-        echo $"  IPv6 is supported on:"
-        echo $"   - Ethernet interfaces of the OSA-Express adapter running in QDIO mode."
-        echo $"   - HiperSockets interfaces"
-        echo $"   - z/VM guest LAN interfaces running in QDIO mode."
-        echo $"  IPv6 is not supported on HiperSockets guest LAN, OSA-Express Token Ring, ATM."
-    fi
-}
-
-function do_ipaddr() {
-    ipv6_capable && ipv6_capable=yes || ipv6_capable=no
-    ask IPADDR \
-        question_prefix_ipaddr question_choices_ipaddr \
-        -h helptext_ipaddr -s syntax_check_ipaddr
-    if [ "$ipv6" ]; then
-       # qeth_l3 would load ipv6 automatically but not qeth_l2
-       modprobe ipv6
-       tv disable_ipv6_autoconf
-    fi
-
-    # no handling/configuring of IPADDR yet, since more parameters needed
-}
-
-### NETMASK (IPv4)
-
-function syntax_check_netmask_v4() {
-    # also support CIDR prefix
-    if [[ "$NETMASK" =~ ^[[:digit:]]+$ ]]; then
-        if [ "$NETMASK" -ge 1 -a "$NETMASK" -le 32 ]; then
-            ipcalc_arg="$IPADDR/$NETMASK"
-            return 0
-        fi
-        echo $"Incorrect value for network prefix [1..32] (NETMASK): $NETMASK"
-        return 1
-    elif checkipv4 $NETMASK; then
-        ipcalc_arg="$IPADDR $NETMASK"
-        return 0
-    fi
-    echo $"Incorrect format or value for network mask (NETMASK): $NETMASK"
-    return 1
-}
-
-function question_prefix_netmask() {
-    echo -n $"IPv4 netmask or CIDR prefix"
-}
-
-function hint_netmask_v4() {
-    # default based on class a/b/c address
-    local a b c d
-    IFS=.
-    read a b c d <<< "$IPADDR"
-    unset IFS
-    local ip=$(( ( a << 24 ) + ( b << 16 ) + ( c << 8 ) + ( d ) ))
-    # <<EOF convince syntax highlighter that above shifts are no here documents
-    if   [ $(( ip & 0x80000000 )) -eq $(( 0x00000000 )) ]; then
-        # class a
-        echo "255.0.0.0"
-    elif [ $(( ip & 0xC0000000 )) -eq $(( 0x80000000 )) ]; then
-        # class b
-        echo "255.255.0.0"
-    elif [ $(( ip & 0xE0000000 )) -eq $(( 0xC0000000 )) ]; then
-        # class c
-        echo "255.255.255.0"
-    else
-        # some other class that should not be used as host address
-        return 1
-    fi
-    return 0
-}
-
-function question_choices_netmask() {
-    echo -n $" (e.g. 255.255.255.0 or 1..32 or ? for help)"
-    local default=$(hint_netmask_v4)
-    if [ -n "$default" ]; then
-        echo $". Default is $default:"
-    else
-        echo $":"
-        echo $"The IP address you entered previously should probably not be used for a host."
-    fi
-}
-
-function helptext_netmask() {
-    echo $" Help text for IPv4 netmask or CIDR prefix:"
-    echo $"  Enter a valid IPv4 netmask or CIDR prefix (e.g. 255.255.255.0 or 1..32)"
-    local default=$(hint_netmask_v4)
-    if [ -n "$default" ]; then
-        echo $"  Default is $default"
-    else
-        echo $"The IP address you entered previously should probably not be used for a host."
-    fi
-}
-
-function exception_netmask() {
-    if [ -z "$NETMASK" ]; then
-        NETMASK=$(hint_netmask_v4)
-    fi
-}
-
-function do_netmask() {
-    ask NETMASK \
-        question_prefix_netmask question_choices_netmask \
-        -h helptext_netmask \
-        -s syntax_check_netmask_v4 -e exception_netmask
-    # no handling/configuring of NETMASK yet, since more parameters needed
-}
-
-### NETWORK
-
-function do_network() {
-    echo
-    echo $"The NETWORK parameter isn't used anymore and will be ignored."
-    echo $" It is sufficient to specify IPADDR and NETMASK."
-    echo
-}
-
-### BROADCAST
-
-function do_broadcast() {
-    echo
-    echo $"The BROADCAST parameter isn't used anymore and will be ignored."
-    echo $" It is sufficient to specify IPADDR and NETMASK."
-    echo
-}
-
-### NETMASK (IPv6)
-
-function syntax_check_prefix_v6() {
-    if [[ "$NETMASK" =~ ^[[:digit:]]+$ ]]; then
-        if [ "$NETMASK" -ge 1 -a "$NETMASK" -le 128 ]; then
-            return 0
-        fi
-    fi
-    echo $"Incorrect value for network prefix [1..128] (NETMASK): $NETMASK"
-    return 1
-}
-
-function question_prefix_netmask_v6() {
-    echo -n $"CIDR prefix for the IPv6 address"
-}
-
-function question_choices_netmask_v6() {
-    echo $" (1..128):"
-}
-
-function do_netmask_v6() {
-    ask NETMASK \
-        question_prefix_netmask_v6 question_choices_netmask_v6 \
-        -s syntax_check_prefix_v6
-    # no handling/configuring of NETMASK yet, since more parameters needed
-}
-
-### GATEWAY (IPv4)
-
-function configure_ipv4_gateway() {
-    # FIXME:
-    # - Strictly speaking we should first check reachability of gateway
-    #   and then configure the gateway route.
-    #   This would require a new intermediate workflow_item step
-    #   so that the user might continue despite unreachable gateway.
-    # done: Only adding default route might add multiple undesired default
-    # routes on redoing the parameter item, so delete default route
-    # before adding a new one.
-    ip -4 route del default dev $DEVICE >& /dev/null
-    [ -z "$GATEWAY" ] && return 0
-    if ! tv route add default gw $GATEWAY dev $DEVICE; then
-        echo $"Could net set default route on device $DEVICE via gateway $GATEWAY"
-        return 1
-    fi
-    # BH FIXME: Workaround for manual MACADDR, need ping to update arp table
-    echo $"Trying to reach gateway $GATEWAY..."
-    if [ "$NETTYPE" = "ctc" ]; then
-        # (virtual) CTC(/A) seems to need some time to get functional
-        local i=1
-        while : ; do
-            $PING $GATEWAY >& /dev/null && break
-            i=$((i+1))
-            if [ "$i" -gt 3 ]; then
-                echo $"Could not reach gateway $GATEWAY within timeout"
-                return 1
-            fi
-        done
-    else
-        if ! $PING $GATEWAY >& /dev/null; then
-            echo $"Could not reach your default gateway $GATEWAY"
-            return 1
-        fi
-    fi
-    return 0
-}
-
-function hint_ipv4_gateway() {
-    # - provide default suggestion based on network,
-    #   for a class C network this would be either .1 or .254 at the end
-    local a b c d
-    IFS=.
-    read a b c d <<< "$NETWORK"
-    unset IFS
-    local ip=$(( ( a << 24 ) + ( b << 16 ) + ( c << 8 ) + ( d ) ))
-    # <<EOF convince syntax highlighter that above shifts are no here documents
-    local lo=$(( ip | 1 ))
-    local lo_a=$(( (lo & 0xFF000000) >> 24 ))
-    local lo_b=$(( (lo & 0x00FF0000) >> 16 ))
-    local lo_c=$(( (lo & 0x0000FF00) >> 8 ))
-    local lo_d=$(( (lo & 0x000000FF) ))
-    local hi=$(( ip | ( (2**(32 - PREFIX)) - 1 ) ))
-    local hi_a=$(( (hi & 0xFF000000) >> 24 ))
-    local hi_b=$(( (hi & 0x00FF0000) >> 16 ))
-    local hi_c=$(( (hi & 0x0000FF00) >> 8 ))
-    local hi_d=$(( (hi & 0x000000FE) ))
-    echo $"  Depending on your network design patterns, the default gateway"
-    echo $"   might be $lo_a.$lo_b.$lo_c.$lo_d or $hi_a.$hi_b.$hi_c.$hi_d"
-}
-
-function question_prefix_gateway() {
-    echo -n $"IPv4 address of your default gateway"
-}
-
-function question_choices_gateway() {
-    echo $" or ? for help:"
-}
-
-function helptext_gateway() {
-    echo $" Help text for IPv4 default gateway:"
-    echo $"  For HiperSockets with internal traffic only you may want to leave this empty"
-    echo $"  and choose continue afterwards to go on without gateway."
-    hint_ipv4_gateway
-}
-
-function finish_gateway() {
-    if ! checkipv4 $GATEWAY; then
-        # above checkipv4 is silent, so make up for syntax error
-        echo $"Incorrect format for IPv4 address of gateway (GATEWAY): $GATEWAY"
-        workflow_item_menu
-    fi
-    if configure_ipv4_gateway; then
-        break
-    else
-        workflow_item_menu && break
-    fi
-}
-
-# FIXME: allow empty/no gateway?
-
-function do_gateway() {
-    ask GATEWAY \
-        question_prefix_gateway question_choices_gateway \
-        -h helptext_gateway -f finish_gateway
-}
-
-### GATEWAY (IPv6)
-
-function configure_ipv6_gateway() {
-    # FIXME:
-    # - Strictly speaking we should first check reachability of gateway
-    #   and then configure the gateway route.
-    #   This would require a new intermediate workflow_item step
-    #   so that the user might continue despite unreachable gateway.
-    # done: Only adding default route might add multiple undesired default
-    # routes on redoing the parameter item, so delete default route
-    # before adding a new one.
-    ip -6 route del default dev $DEVICE >& /dev/null
-    [ -z "$GATEWAY" ] && return 0
-    # IPv6 http://www.ibiblio.org/pub/Linux/docs/HOWTO/other-formats/html_single/Linux+IPv6-HOWTO.html#AEN1147
-    #       ip -6 route add ::/0 dev $DEVICE via $GATEWAY
-    # (Could also be learned by autoconfiguration on the link:
-    #  after IP address setup and device up,
-    #   see if default route has been learned
-    #   ip -6 route show | grep ^default
-    #  However, we currently use manual IPv6 configuration only.)
-    if ! debug ip -6 route add ::/0 dev $DEVICE via $GATEWAY; then
-        echo $"Could net set default route on device $DEVICE"
-        echo $" via gateway $GATEWAY"
-        return 1
-    fi
-    # BH FIXME: Workaround for manual MACADDR, need ping to update arp table
-    echo $"Trying to reach gateway $GATEWAY..."
-    if ! $PING6 $GATEWAY >& /dev/null; then
-        echo $"Could not reach your default gateway $GATEWAY"
-        return 1
-    fi
-    return 0
-}
-
-function question_prefix_gateway_v6() {
-    echo -n $"IPv6 address of your default gateway"
-}
-
-function question_choices_gateway_v6() {
-    echo $":"
-}
-
-function helptext_gateway_v6() {
-    echo $" Help text for IPv6 default gateway:"
-    echo $"  For HiperSockets with internal traffic only you may want to leave this empty"
-    echo $"  and choose continue afterwards to go on without gateway."
-}
-
-function finish_gateway_v6() {
-    if ! checkipv6 $GATEWAY; then
-        # above checkipv6 is silent, so make up for syntax error
-        echo $"Incorrect format for IPv6 address of gateway (GATEWAY): $GATEWAY"
-        workflow_item_menu
-    fi
-    if configure_ipv6_gateway; then
-        break
-    else
-        workflow_item_menu && break
-    fi
-}
-
-# FIXME: allow empty/no gateway?
-
-function do_gateway_v6() {
-    ask GATEWAY \
-        question_prefix_gateway_v6 question_choices_gateway_v6 \
-        -h helptext_gateway_v6 -f finish_gateway_v6
-}
-
-### GATEWAY (IPv4, point-to-point)
-
-function configure_ipv4_ptp() {
-    # device needs to be online
-    if debug ifconfig $DEVICE $IPADDR $MMTU pointopoint $GATEWAY; then
-        configure_ipv4_gateway
-        return $?
-    fi
-    echo $"Could not set IPv4 address $IPADDR for device $DEVICE"
-    echo $" to peer $GATEWAY"
-    [ -n "$MMTU" ] && echo $" and maximum transfer unit: $MMTU"
-    return 1
-}
-
-function question_prefix_ptp_gateway() {
-    echo -n $"IPv4 address of your point-to-point partner"
-}
-
-function question_choices_ptp_gateway() {
-    echo $" or ? for help:"
-    # no hinting possible here
-}
-
-function helptext_ptp_gateway() {
-    echo $" Help text for point-to-point partner:"
-    echo $"  IPv4 address of your CTC or ESCON point-to-point partner."
-}
-
-function finish_ptp_gateway() {
-    if checkipv4 $GATEWAY; then
-        if [ "$GATEWAY" = "$IPADDR" ]; then
-            echo $"IPv4 address of partner should probably be different from the guest's address"
-            workflow_item_menu && break
-        else
-            break
-        fi
-    else
-        # above checkipv4 is silent, so make up for syntax error
-        echo $"Incorrect format for IPv4 address of partner (GATEWAY): $GATEWAY"
-        workflow_item_menu && break
-    fi
-    # too early to actually configure gateway
-}
-
-function do_ptp_gateway() {
-    ask GATEWAY \
-        question_prefix_ptp_gateway question_choices_ptp_gateway \
-        -h helptext_ptp_gateway -f finish_ptp_gateway
-}
-
-### DNS
-
-function syntax_check_dns() {
-    if [ -z "$DNS" ]; then
-        echo $"You might encounter problems without a nameserver, especially with FTP installs"
-        return 1
-    fi
-    local dnsitem
-    local allgood="yes"
-    if [ "$ipv6" ]; then
-        while read dnsitem; do
-            if ! checkipv6 $dnsitem; then
-                echo $"Not a valid IPv6 address for DNS server: $dnsitem"
-                allgood="no"
-            fi
-        done < <(echo $DNS | sed 's/,/\n/g')
-    else
-         while read dnsitem; do
-           if ! checkipv4 $dnsitem; then
-                echo $"Not a valid IPv4 address for DNS server: $dnsitem"
-                allgood="no"
-            fi
-         done < <(echo $DNS | sed 's/:/\n/g')
-    fi
-    if [ "$allgood" = "yes" ]; then
-        return 0
-    else
-        return 1
-    fi
-}
-
-function handle_dns() {
-    # - foreach DNS try if server is reachable by one ping
-    [ -z "$DNS" ] && return 0
-    local dnsitem
-    local allgood="yes"
-    echo $"Trying to reach DNS servers..."
-    if [ "$ipv6" ]; then
-        while read dnsitem; do
-            if ! $PING6 $dnsitem >& /dev/null; then
-                echo $"Could not ping DNS server (might still serve DNS requests): $dnsitem"
-                allgood="no"
-                # this should not be a hard failure since some network
-                # environments may prevent pings to DNS servers
-                # => prevent workflow_item_menu in kickstart mode
-            fi
-        done < <(echo $DNS | sed 's/,/\n/g')
-    else
-        while read dnsitem; do
-            # Some network environment may prevent a DNS server from being
-            # reachable by ping, so it would make sense to use nslookup.
-            # However, nslookup fails with "Resolver Error 0 (no error)"
-            # at this stage of the setup progress => not useful
-            if ! $PING $dnsitem >& /dev/null; then
-                echo $"Could not ping DNS server: $dnsitem"
-#                if nslookup $dnsitem $dnsitem >& /dev/null; then
-#                    echo $" but could resolve DNS server with itself: $dnsitem"
-#                else
-#                    echo $"Could not resolve DNS server with itself: $dnsitem"
-#                    allgood="no"
-#                fi
-#            elif ! nslookup $dnsitem $dnsitem >& /dev/null; then
-#                echo $"Could not resolve DNS server with itself: $dnsitem"
-                allgood="no"
-            fi
-        done < <(echo $DNS | sed 's/:/\n/g')
-    fi
-    if [ "$allgood" = "yes" ]; then
-        return 0
-    else
-        return 1
-    fi
-}
-
-function question_prefix_dns() {
-    if [ "$ipv6" ]; then
-        echo -n $"IPv6 addresses of DNS servers"
-    else
-        echo -n $"IPv4 addresses of DNS servers"
-    fi
-}
-
-function question_choices_dns() {
-    if [ "$ipv6" ]; then
-        echo $" (separated by commas ',' or ? for help):"
-    else
-        echo $" (separated by colons ':' or ? for help):"
-    fi
-}
-
-function helptext_dns() {
-    echo $" Help text for DNS servers:"
-    if [ "$ipv6" ]; then
-        echo $"  Enter IPv6 addresses of DNS servers separated by commas ','"
-    else
-        echo $"  Enter IPv4 addresses of DNS servers separated by colons ':'"
-    fi
-    echo $"  Default are no DNS servers at all."
-    echo $"  However, you might encounter problems without a nameserver,"
-    echo $"   especially with FTP installs."
-    if [ "$ipv6" ]; then
-        echo $"  An example with 2 servers would be: 2001:0DB8::42,2001:0DB8::BE:AF"
-    else
-        echo $"  An example with 2 servers would be: 10.0.0.250:10.1.1.1"
-    fi
-}
-
-function do_dns() {
-    ask DNS \
-        question_prefix_dns question_choices_dns \
-        -h helptext_dns -s syntax_check_dns -c handle_dns
-}
-
-### SEARCHDNS
-
-function syntax_check_searchdns() {
-    [ -z "$SEARCHDNS" ] && return 0
-    local dnsitem
-    local allgood="yes"
-    while read dnsitem; do
-        syntax_check_domainname "$dnsitem" $"Not a valid DNS search domain: $dnsitem" || allgood="no"
-    done < <(echo $SEARCHDNS | sed 's/:/\n/g')
-    if [ "$allgood" = "yes" ]; then
-        return 0
-    else
-        return 1
-    fi
-}
-
-function question_prefix_searchdns() {
-    echo -n $"DNS search domains"
-}
-
-function question_choices_searchdns() {
-    echo $" (separated by colons ':' or ? for help):"
-}
-
-function helptext_searchdns() {
-    echo $" Help text for DNS search domains:"
-    echo $"  Enter search domains according to hostname syntax separated by colons."
-    echo $"  Default are no DNS search domains at all."
-    echo $"  An example would be: subdomain.domain.com:domain.com"
-}
-
-function do_searchdns() {
-    ask SEARCHDNS \
-        question_prefix_searchdns question_choices_searchdns \
-        -h helptext_searchdns -s syntax_check_searchdns
-}
-
-### DASD
-
-function parse_dasd() {
-    local handle
-    [ "$1" = "-h" ] && handle=yes || unset handle
-    local dasditem
-    local allgood="yes"
-    local cio_wc=$(wc -c /proc/cio_ignore)
-    read cio_wc_bytes cio_wc_filename cio_wc_foo <<< "$cio_wc"
-    if [ "$handle" = "yes" -a "$cio_wc_bytes" != "0" ]; then
-        echo $"Trying to clear specified DASDs from device blacklist..."
-        mkdir -p /etc/modprobe.d
-        echo "options dasd_mod dasd=$DASD" > /etc/modprobe.d/dasd_mod.conf
-        if ! dasd_cio_free; then
-            echo $"Not all specified DASDs could be detected within timeout."
-            allgood="no"
-        fi
-    fi
-    while read dasditem; do
-        unset range features range lo hi rangegood \
-            attrs devno lodevno hidevno devbusid sys
-        case $dasditem in
-            autodetect)
-                [ -z "$handle" ] && continue
-                cio_wc=$(wc -c /proc/cio_ignore)
-                read cio_wc_bytes cio_wc_filename cio_wc_foo <<< "$cio_wc"
-                # above we only freed the devices specified in $DASD,
-                # so there might still be other DASDs in the blacklist
-                if [ "$cio_wc_bytes" != "0" ]; then
-                    echo $"Note: There is a device blacklist active! Only activating visible DASDs."
-                fi
-                local sys
-                while read sys; do
-                    if ! sysecho $sys/online 1; then
-                        echo $"Could not set DASD ${sys##*/} online"
-                    fi
-                done < <(find /sys/bus/ccw/drivers/dasd-eckd/ -name "*.?.????" 2>/dev/null;\
-                    find /sys/bus/ccw/drivers/dasd-fba/ -name "*.?.????" 2>/dev/null)
-                ;;
-            probeonly|nopav|nofcx)
-                if [ -z "$handle" ]; then
-                    echo $"DASD option $dasditem not supported by installer"
-                fi
-                ;;
-            "") continue ;; # empty range
-            *)  local range features rangegood="yes"
-                IFS='('
-                read range features <<< "$dasditem"
-                unset IFS
-                # parse: dev OR dev'-'dev
-                local lo=${range%%-*}
-                [[ "$lo" =~ (^[[:xdigit:]]+\.[0-3]\.[[:xdigit:]]{4}$)|(^[[:xdigit:]]{3,4}$) ]]
-                case $? in
-                    0)  # string matched the pattern
-                        lo=$(canonicalize_devno $lo) ;;
-                    1)  # string did not match the pattern
-                        rangegood="no"
-                        if [ -z "$handle" ]; then
-                            echo $"Incorrect format for lower bound of DASD range $range: $lo"
-                            allgood="no"
-                        fi
-                        ;;
-                    2)  echo "l.$LINENO: syntax error in regex of match operator =~, code needs to be fixed" 1>&2 ;;
-                    *)  echo "l.$LINENO: unexpected return code of regex match operator =~, code needs to be fixed" 1>&2 ;;
-                esac
-                if [ "${range//*-*/}" = "" ]; then
-                    local hi=${range##*-}
-                    [[ "$hi" =~ (^[[:xdigit:]]+\.[0-3]\.[[:xdigit:]]{4}$)|(^[[:xdigit:]]{3,4}$) ]]
-                    case $? in
-                        0)  # string matched the pattern
-                            hi=$(canonicalize_devno $hi)
-                            if [ "${lo%.*}" != "${hi%.*}" ]; then
-                                echo $"Prefixes of DASD range $range do not match: ${lo%.*} != ${hi%.*}"
-                                rangegood="no"
-                                allgood="no"
-                            fi
-                            ;;
-                        1)  # string did not match the pattern
-                            rangegood="no"
-                            if [ -z "$handle" ]; then
-                                echo $"Incorrect format for upper bound of DASD range $range: $hi"
-                                allgood="no"
-                            fi
-                            ;;
-                        2)  echo "l.$LINENO: syntax error in regex of match operator =~, code needs to be fixed" 1>&2 ;;
-                        *)  echo "l.$LINENO: unexpected return code of regex match operator =~, code needs to be fixed" 1>&2 ;;
-                    esac
-                fi
-                if [ "${features//*)/}" != "" ]; then
-                    if [ -z "$handle" ]; then
-                        echo $"Missing closing parenthesis at features of DASD range $range: ($features"
-                        allgood="no"
-                    fi
-                fi
-                local attrs=""
-                if [ -n "$features" ]; then
-                    features="${features%)}"
-                    while read feature; do
-                        case $feature in
-                            ro) attrs=$attrs" readonly" ;;
-                            diag) attrs=$attrs" use_diag" ;;
-                            erplog|failfast) attrs=$attrs" "$feature ;;
-                            *) if [ -z "$handle" ]; then
-                                   echo $"Unknown DASD feature for device range $range: $feature"
-                                   allgood="no"
-                               fi
-                               ;;
-                        esac
-                    done < <(echo $features | sed 's/:/\n/g')
-                fi
-                [ "$rangegood" = "yes" ] || continue
-                [ "$handle" = "yes" ] || continue
-                # now apply $attrs and set DASDs $lo to $hi online
-                [ -z "$hi" ] && hi=$lo
-                local devno lodevno=$((0x${lo##*.})) hidevno=$((0x${hi##*.}))
-                for ((devno=$lodevno; $devno <= $hidevno; ++devno)); do
-                    local devbusid=$(printf "%s.%04x" ${lo%.*} $devno)
-                    local sys="/sys/bus/ccw/devices/"$devbusid
-                    for attr in $attrs; do
-                        if [ "$attr" = "use_diag" ]; then
-                            # diag discipline cannot be auto-loaded
-                            modprobe dasd_diag_mod
-                        fi
-                        if [ ! -f $sys/$attr ]; then
-                            echo $"DASD $devbusid does not provide attribute $attr"
-                            continue
-                        fi
-                        if ! sysecho $sys/$attr 1; then
-                            echo $"Could not set attribute $attr for DASD $devbusid"
-                        fi
-                    done
-                    if [ ! -f $sys/online ]; then
-                        echo $"DASD $devbusid not found"
-                        continue
-                    fi
-                    if ! sysecho $sys/online 1; then
-                        echo $"Could not set DASD $devbusid online"
-                    fi
-                done
-                ;;
-        esac
-    done < <(echo $DASD | sed 's/,/\n/g')
-    if [ "$handle" = "yes" ]; then
-        udevadm settle
-        dasd_settle_all || return 1
-        echo $"Activated DASDs:"
-        cat /proc/dasd/devices | sed -e 's/ at ([^)]*) is//' -e 's/ at/,/'
-    fi
-    if [ "$allgood" = "yes" ]; then
-        return 0
-    else
-        return 1
-    fi
-}
-
-function syntax_check_dasd() {
-    parse_dasd
-    return $?
-}
-
-function handle_dasd() {
-    parse_dasd -h
-    return $?
-}
-
-function question_prefix_dasd() {
-    echo -n $"DASD range"
-}
-
-function question_choices_dasd() {
-    echo $" (e.g. 200-203,205 or ? for help). Default is autoprobing:"
-}
-
-function helptext_dasd() {
-    echo $" Help text for DASD range:"
-    echo $"  Comma separated list of ranges of device bus IDs."
-    echo $"  Default is autoprobing (not recommended)."
-    echo $"  Examples would be: 200-203 or 200,201,202,203 or 0.0.0200-0.0.0203,0.0.0205"
-}
-
-function exception_dasd() {
-    [ -z "$DASD" ] && DASD="autodetect"
-}
-
-function do_dasd() {
-    ask DASD \
-        question_prefix_dasd question_choices_dasd \
-        -h helptext_dasd -e exception_dasd -s syntax_check_dasd -c handle_dasd
-}
-
-### FCP
-
-function syntax_check_fcp() {
-    local allgood="yes"
-    local i
-    for i in ${!FCP_*}; do
-        local -a fcp
-        local devno wwpn lun
-        read -a fcp <<< "${!i}"
-        case ${#fcp[@]} in
-            3)
-                devno=${fcp[0]}
-                wwpn=${fcp[1]}
-                lun=${fcp[2]}
-                ;;
-            5)
-                devno=${fcp[0]}
-                wwpn=${fcp[2]}
-                lun=${fcp[4]}
-                echo $"Deprecated number of FCP arguments (5 instead of 3): "
-                echo $" $i=\"${!i}\""
-                echo $" should instead be: "
-                echo $" $i=\"$devno $wwpn $lun\""
-                ;;
-            *)
-                echo $"Unsupported number of FCP arguments (${#fcp[@]} instead of 3) in:"
-                echo $" $i=\"${!i}\""
-                allgood="no"
-                continue
-                ;;
-        esac
-        [[ "$devno" =~ (^[[:xdigit:]]+\.[0-3]\.[[:xdigit:]]{4}$)|(^[[:xdigit:]]{3,4}$) ]]
-        case $? in
-            0)  ;; # string matched the pattern
-            1)  # string did not match the pattern
-                echo $"Incorrect format for FCP device $devno in:"
-                echo $" $i=\"${!i}\""
-                allgood="no"
-                ;;
-            2)
-                echo "l.$LINENO: syntax error in regex of match operator =~, code needs to be fixed" 1>&2
-                ;;
-            *)
-                echo "l.$LINENO: unexpected return code of regex match operator =~, code needs to be fixed" 1>&2
-                ;;
-        esac
-        # zfcp.py:class ZFCPDevice would also accept WWPN without leading 0x
-        [[ "$wwpn" =~ ^0x[[:xdigit:]]{16}$ ]]
-        case $? in
-            0)  ;; # string matched the pattern
-            1)  # string did not match the pattern
-                echo $"Incorrect format for FCP WWPN $wwpn in:"
-                echo $" $i=\"${!i}\""
-                allgood="no"
-                ;;
-            2)  echo "l.$LINENO: syntax error in regex of match operator =~, code needs to be fixed" 1>&2 ;;
-            *)  echo "l.$LINENO: unexpected return code of regex match operator =~, code needs to be fixed" 1>&2 ;;
-        esac
-        # zfcp.py:class ZFCPDevice would also accept LUN without leading 0x
-        # zfcp.py:class ZFCPDevice would also accept 16 bit LUN and pads with 0
-        [[ "$lun" =~ ^0x[[:xdigit:]]{8}0{8}$ ]]
-        case $? in
-            0)  ;; # string matched the pattern
-            1)  # string did not match the pattern
-                echo $"Incorrect format for FCP LUN $lun in:"
-                echo $" $i=\"${!i}\""
-                allgood="no"
-                ;;
-            2)
-                echo "l.$LINENO: syntax error in regex of match operator =~, code needs to be fixed" 1>&2
-                ;;
-            *)
-                echo "l.$LINENO: unexpected return code of regex match operator =~, code needs to be fixed" 1>&2
-                ;;
-        esac
-    done
-    if [ "$allgood" = "yes" ]; then
-        return 0
-    else
-        return 1
-    fi
-}
-
-###
-
-function show_parms() {
-    # The only issue with this stateless approach to showing parameters based
-    # on their content being non-empty is, that parameters with defaults
-    # such as LAYER2, (PORTNAME,) CTCPROT, PORTNO (,MACADDR) won't be shown
-    # if the user just hit enter, so the parm file would be "incomplete".
-    # However this is not easy to fix in here, since it would require the
-    # inter-parameter dependenies coded below in the main part, e.g. an
-    # empty LAYER2 should only be printed with default value if $NETTYPE=qeth.
-    # For the time being, at least the parameters LAYER2, PORTNAME, and CTCPROT
-    # only get asked on being empty if not running in kickstart mode.
-    cat << EOF
-NETTYPE=$NETTYPE
-IPADDR=$IPADDR
-NETMASK=$NETMASK
-GATEWAY=$GATEWAY
-HOSTNAME=$HOSTNAME
-EOF
-    [ "$SUBCHANNELS" ] && echo "SUBCHANNELS=$SUBCHANNELS"
-    [ "$LAYER2" ] && echo "LAYER2=$LAYER2"
-    [ "$VSWITCH" ] && echo "VSWITCH=$VSWITCH"
-    [ "$MACADDR" ] && echo "MACADDR=$MACADDR"
-    [ "$PORTNAME" ] && echo "PORTNAME=$PORTNAME"
-    [ "$PORTNO" ] && echo "PORTNO=$PORTNO"
-    [ "$PEERID" ] && echo "PEERID=$PEERID"
-    [ "$CTCPROT" ] && echo "CTCPROT=$CTCPROT"
-    if [ -n "$mmtu_was_set" ]; then
-        echo "MMTU=\"$MMTU\""
-    elif [ -n "$mtu_was_set" ]; then
-        echo "MTU=$MTU"
-    fi
-    [ "$DNS" ] && echo "DNS=$DNS"
-    [ "$SEARCHDNS" ] && echo "SEARCHDNS=$SEARCHDNS"
-    [ "$DASD" ] && echo "DASD=$DASD"
-}
-
-function final_check() {
-    # final check && break
-    if [ -z "$interaction_happened" ]; then
-        # if parm file was good enough just continue without interaction
-        break
-        return 0
-    fi
-    while : ; do
-        # optionally consider "continue" as default
-        # but then again the user may inadvertently continue
-        echo
-        echo $"c) continue, p) parm file/configuration, n) network state, r) restart, s) shell"
-        local answer
-        read answer
-        case $answer in
-            c) return 0 ;;
-            p) echo
-                show_parms ;;
-            n) # show interfaces and routing table
-                ifconfig -a
-                if [ "$ipv6" ]; then
-                    #route -n -A inet6
-                    # the following produces more compact output for 80 columns
-                    ip -6 route show | grep -v "^unreachable "
-                else
-                    route -n
-                fi
-                ;;
-            d) # show active DASDs with some useful details
-                echo $"Activated DASDs:"
-                cat /proc/dasd/devices|sed -e 's/ at ([^)]*) is//' -e 's/ at/,/'
-                ;;
-            r) break ;;
-            s) echo $"Enter 'exit' at the shell prompt to get back to the installation dialog."
-                /bin/bash
-                ;;
-    esac
-    done
-    return 1
-}
-
-### MAIN ###
-
-init_main
-udev_setup
-
-# Parse configuration
-if [ -n "$CMSDASD" -a -n "$CMSCONFFILE" ]; then
-    readcmsfile $CMSDASD $CMSCONFFILE
-    source /tmp/$CMSCONFFILE #2>/dev/null
-fi
-
-if [ -r /sys/firmware/ipl/ipl_type ]; then
-    #local ipl_type
-    read ipl_type < /sys/firmware/ipl/ipl_type
-    if [ "$ipl_type" = "fcp" ]; then
-        while : ; do
-            echo $"Your IPL device is set to FCP."
-            echo $"Would you like to perform a CD-ROM/DVD-ROM installation? (y/n)"
-            #local do_cd_install
-            read do_cd_install
-            case $do_cd_install in
-                y|Y|[Yy][Ee][Ss])
-                    # precondition: zfcp driver incl. dependencies loaded
-                    #local CD_DEVICE WWPN LUN
-                    read CD_DEVICE < /sys/firmware/ipl/device
-                    read WWPN < /sys/firmware/ipl/wwpn
-                    read LUN < /sys/firmware/ipl/lun
-                    if sysecho /proc/cio_ignore "free $CD_DEVICE"; then
-                        udevadm settle
-                        # even though device might now be online, some of its
-                        # sysfs attributes might not yet be available
-                        sleep 1
-                    else
-                        echo $"Device $CD_DEVICE could not be cleared from device blacklist"
-                    fi
-                    sysecho /sys/bus/ccw/drivers/zfcp/$CD_DEVICE/online 1 \
-                        || echo $"Could not set FCP device $CD_DEVICE online"
-                    udevadm settle
-                    # port (WWPN) appears automatically
-                    sysecho /sys/bus/ccw/drivers/zfcp/$CD_DEVICE/$WWPN/unit_add $LUN \
-                        || echo $"Could not add LUN $LUN at WWPN $WWPN on FCP device $CD_DEVICE"
-                    udevadm settle
-                    break
-                    ;;
-                n|N|[Nn][Oo])
-                    break
-                    ;;
-                *)
-                    echo
-                    echo $"*** INVALID ANSWER: $do_cd_install"
-                    echo
-                    unset do_cd_install
-                    ;;
-            esac
-        done
-    fi
-fi
-
-# Perform a network installation
-
-[ -n "$MTU" ] && mtu_was_set=$MTU
-[ -n "$MMTU" ] && mmtu_was_set=$MMTU
-[ -n "$VSWITCH" ] && vswitch_was_set=$VSWITCH
-
-[ -n "$CHANDEV" ] && do_chandev
-[ -n "$NETWORK" ] && do_network
-[ -n "$BROADCAST" ] && do_broadcast
-
-# [ -z "${cardtype//OSD_*/}" ] can be used to check for real OSA
-
-# Check for missing parameters, prompt for them if necessary
-while : ; do
-
-    # do not show list of possible network device configurations, if:
-    # - running unattended install with kickstart
-    # - relevant parameters have already been specified in parm file
-    #   (a possible optimization would be matching those parms to table entry)
-    # - dialog has not been restarted
-    [ -n "$reenter" \
-        -o -z "$RUNKS" -a \( -z "$NETTYPE" -o -z "$SUBCHANNELS" \) ] && \
-        dialog_network_table
-    if isVM; then
-        echo $"* NOTE: To enter default or empty values press enter twice. *"
-    fi
-    do_nettype
-
-    # precondition: driver (qeth/lcs/ctcm) loaded incl. dependencies
-    do_subchannels
-    if [ "$NETTYPE" = "qeth" ]; then
-        [ -z "$reenter" -a -n "$RUNKS" -a -z "$PORTNAME" ] || \
-            [ -n "${cardtype//OSD_*/}" ] || do_portname
-        # See also https://bugzilla.redhat.com/show_bug.cgi?id=439461
-        #
-        # If running in kickstart mode (unattended), we assume no
-        # interaction and the user won't get asked for PORTNO.
-        # Otherwise the user will be asked for PORTNO.
-        # If the user specified PORTNO in parm/conf file, PORTNO gets
-        # respected (or the user will be asked if it was wrong).
-        if [ -f /sys/devices/qeth/$SCH_R_DEVBUSID/portno ]; then
-            # driver support exists since RHEL5.2
-            [ -z "$reenter" -a -n "$RUNKS" -a -z "$PORTNO" ] || \
-                [ -n "${cardtype//OSD_*/}" ] || do_portno
-        fi
-        do_layer2
-        # set device online to know the device name
-        # and to know if it's OSD/HiperSockets/GuestLAN BUT do not
-        # try to ifconfig the device up since that requires
-        # setting the mac address before (if applicable).
-        set_device_online || workflow_item_menu noredo
-        # MAC address handling is not part of
-        # https://bugzilla.redhat.com/show_bug.cgi?id=233376
-        # Instead the additions come from
-        # https://bugzilla.redhat.com/show_bug.cgi?id=248049
-        # The new parms VSWITCH and MACADDR are described in
-        # the RHEL 5.1 release notes.
-        if isLayer2; then
-            if [ -z "$VSWITCH" -o "$VSWITCH" == 0 ]; then
-                do_macaddr
-            fi
-        fi
-    elif [ "$NETTYPE" = "ctc" ]; then
-        [ -z "$reenter" -a -n "$RUNKS" -a -z "$CTCPROT" ] || do_ctcprot
-        set_device_online || workflow_item_menu noredo
-    elif [ "$NETTYPE" = "lcs" ]; then
-        [ -n "$RUNKS" -a -z "$PORTNAME" ] && PORTNAME=0
-        do_lcs_portno
-        set_device_online || workflow_item_menu noredo
-    fi
-
-    # device needs to be up before configuring with ifconfig/ip in
-    # configure_ipv6_address/configure_ipv4_address/configure_ipv4_address
-    set_device_up || workflow_item_menu noredo
-
-    [ "$HOSTNAME" = "(none)" ] && unset HOSTNAME
-    do_hostname
-
-    # Note: The workflow_item_menu does a rollback_config on restart
-    # dialog, i.e. hardware config has been reset and it is impossible to
-    # only restart halfway at IPADDR.
-    do_ipaddr
-    if [ "$ipv6" ]; then
-        # this branch is all IPv6 and at the same time also NETTYPE==qeth
-        do_netmask_v6
-        handle_mtu
-        configure_ipv6_address || workflow_item_menu noredo
-        do_gateway_v6
-    else
-        # Consider IPv4 as default, even for unknown IP versions
-        # due to invalid input for IPADDR ignored by the user previously
-        # (neither ipv6 nor ipv4 is set).
-        # Otherwise we would skip things like NETMASK or GATEWAY
-        # and jump forward to DNS which is probably not what we want.
-        if [ "$NETTYPE" = "qeth" ] || [ "$NETTYPE" = "lcs" ]; then
-            do_netmask
-            handle_mtu
-            configure_ipv4_address || workflow_item_menu noredo
-            do_gateway
-        else  # ctc0
-            if [ -z "$NETMASK" ]; then
-                # If the user did not supply netmask, we add the right one.
-                # Netmask MUST be present,
-                # or pumpSetupInterface() blows routes.
-                NETMASK="255.255.255.255"
-            fi
-            # don't ask for MTU, but use it if set in the parm file
-            # don't overwrite MMTU if it has been set for CTC
-            [ "$NETTYPE" = "ctc" -a -z "$MTU" -a -z "$MMTU" ] && \
-                MMTU="mtu 1500"
-            do_ptp_gateway
-            configure_ipv4_ptp || workflow_item_menu noredo
-        fi
-    fi
-
-    modprobe_alias
-    do_dns
-    [ -n "$DNS" ] && do_searchdns
-
-    do_dasd
-
-    echo $"Initial configuration completed."
-    final_check && break
-    rollback_config
-    reenter="yes"
-
-done # outer dialog loop
-
-if [ -z "$testing" ]; then
-
-    # convert to space-separated lists
-    if [ -n "$SEARCHDNS" ]; then
-        SEARCHDNS=$(echo $SEARCHDNS |sed -e 's/:/ /g')
-        for i in "$SEARCHDNS"; do echo "search $i"; done >> /etc/resolv.conf
-    fi
-    if [ -n "$DNS" ]; then
-        if [ "$ipv6" ]; then
-            RESOLVDNS=$(echo $DNS |sed -e 's/,/ /g')
-        else
-            RESOLVDNS=$(echo $DNS |sed -e 's/:/ /g')
-        fi
-        for i in $RESOLVDNS; do echo "nameserver $i"; done >> /etc/resolv.conf
-    fi
-
-    # make sure we have an /etc/hosts file (originally required for telnetd)
-    if [ ! -z "$HOSTNAME" -a ! -z "$IPADDR" ]; then
-        echo -e "$IPADDR\t$HOSTNAME $(echo $HOSTNAME | cut -d '.' -f 1)" >> /etc/hosts
-    fi
-
-fi # testing
-
-# syntax check to give user early feedback on parameters provided in parm file
-# (he probably won't notice the logs written by anaconda later on)
-syntax_check_fcp
-# currently we ignore failed syntax checks since FCP parms are non-interactive
-for i in ${!FCP_*}; do
-    echo "${!i}" >> /tmp/fcpconfig
-done
-# cio_ignore handling for FCP should happen when the content of /tmp/fcpconfig
-# will actually be processed which is in anaconda's zfcp.py ZFCP::readConfig()
-
-# TODO/FIXME: also need to pass IPv6 decision to loader/anaconda
-#    [ "$ipv6" ] && echo "IPV6=yes"
-
-# transfer options into install environment
-cat > /tmp/install.cfg << EOF
-LANG="$LANG"
-S390ARCH="$S390ARCH"
-TEXTDOMAIN="$TEXTDOMAIN"
-TEXTDOMAINDIR="$TEXTDOMAINDIR"
-PORTNAME="$PORTNAME"
-HOSTNAME="$HOSTNAME"
-DEVICE="$DEVICE"
-NETTYPE="$NETTYPE"
-IPADDR="$IPADDR"
-GATEWAY="$GATEWAY"
-MTU="$MTU"
-NETWORK="$NETWORK"
-NETMASK="$NETMASK"
-BROADCAST="$BROADCAST"
-SEARCHDNS="$SEARCHDNS"
-PEERID="$PEERID"
-SUBCHANNELS="$SUBCHANNELS"
-ONBOOT="yes"
-CTCPROT="$CTCPROT"
-EOF
-if [ "$ipv6" ]; then
-    DNS1=$(echo $DNS | cut -d ',' -f 1)
-    echo DNS=\"$DNS1\" >> /tmp/install.cfg
-    echo DNS1=\"$DNS1\" >> /tmp/install.cfg
-    echo DNS2=\"$(echo $DNS | cut -d ',' -f 2)\" >> /tmp/install.cfg
-else
-    DNS1=$(echo $DNS | cut -d ':' -f 1)
-    echo DNS=\"$DNS1\" >> /tmp/install.cfg
-    echo DNS1=\"$DNS1\" >> /tmp/install.cfg
-    echo DNS2=\"$(echo $DNS | cut -d ':' -f 2)\" >> /tmp/install.cfg
-fi
-cat >> /tmp/install.cfg << EOF
-export LANG PORTNAME S390ARCH TEXTDOMAIN TEXTDOMAINDIR
-export HOSTNAME DEVICE NETTYPE IPADDR GATEWAY MTU
-export NETWORK NETMASK BROADCAST DNS DNS1 DNS2 SEARCHDNS
-export PEERID ONBOOT SUBCHANNELS CTCPROT
-EOF
-# immediately read it in again to export these into the shell below
-. /tmp/install.cfg
-if [ -z "$testing" ]; then
-    cat /tmp/install.cfg >> /etc/profile
-fi # testing
-
-NETSCRIPTS="/etc/sysconfig/network-scripts"
-IFCFGFILE="$NETSCRIPTS/ifcfg-$DEVICE"
-if [ ! -d "$NETSCRIPTS" ]; then
-    mkdir -p $NETSCRIPTS
-fi
-
-# to please NetworkManager on startup in loader before loader reconfigures net
-cat > /etc/sysconfig/network << EOF
-HOSTNAME=$HOSTNAME
-EOF
-
-cat > $IFCFGFILE << EOF
-DEVICE=$DEVICE
-ONBOOT=yes
-BOOTPROTO=static
-GATEWAY=$GATEWAY
-BROADCAST=$BROADCAST
-MTU=$MTU
-SUBCHANNELS=$SUBCHANNELS
-EOF
-if [ "$ipv6" ]; then
-    cat >> $IFCFGFILE << EOF
-IPV6INIT=yes
-IPV6_AUTOCONF=no
-IPV6ADDR=$IPADDR/$NETMASK
-IPV6_DEFAULTGW=$GATEWAY
-EOF
-    # FIXME: /etc/sysconfig/network:IPV6_DEFAULTGW=$GATEWAY
-    #        /etc/sysconfig/network:NETWORKING_IPV6=yes
-else
-    cat >> $IFCFGFILE << EOF
-IPADDR=$IPADDR
-NETMASK=$NETMASK
-EOF
-fi
-[ "$DNS1" != "" ] && echo "DNS1=$DNS1" >> $IFCFGFILE
-[ "$DNS2" != "" ] && echo "DNS2=$DNS2" >> $IFCFGFILE
-# colons in SEARCHDNS already replaced with spaces above for /etc/resolv.conf
-[ "$SEARCHDNS" != "" ] && echo "DOMAIN=\"$SEARCHDNS\"" >> $IFCFGFILE
-[ "$NETTYPE" != "" ] && echo "NETTYPE=$NETTYPE" >> $IFCFGFILE
-[ "$PEERID" != "" ] && echo "PEERID=$PEERID" >> $IFCFGFILE
-[ "$PORTNAME" != "" ] && echo "PORTNAME=$PORTNAME" >> $IFCFGFILE
-[ "$CTCPROT" != "" ] && echo "CTCPROT=$CTCPROT" >> $IFCFGFILE
-[ "$MACADDR" != "" ] && echo "MACADDR=$MACADDR" >> $IFCFGFILE
-optstr=""
-for option in LAYER2 PORTNO; do
-    [ -z "${!option}" ] && continue
-    [ -n "$optstr" ] && optstr=${optstr}" "
-    optstr=${optstr}$(echo ${option} | tr [[:upper:]] [[:lower:]])"="${!option}
-done
-# write single quotes since network.py removes double quotes but we need quotes
-echo "OPTIONS='$optstr'" >> $IFCFGFILE
-unset option
-unset optstr
-
-if [ -z "$testing" ]; then
-
-    # so that the vars get propagated into the sshd shells
-    mkdir /.ssh
-    cat >> /.ssh/environment <<EOF
-LD_LIBRARY_PATH=$LD_LIBRARY_PATH
-PATH=$PATH
-HOME=$HOME
-PYTHONPATH=$PYTHONPATH
-EOF
-
-    cat >> /etc/profile <<EOF
-LD_LIBRARY_PATH=$LD_LIBRARY_PATH
-PATH=$PATH
-HOME=$HOME
-PYTHONPATH=$PYTHONPATH
-export LD_LIBRARY_PATH PATH HOME PYTHONPATH
-EOF
-
-    if [ -n "$DISPLAY" ]; then
-        echo "export DISPLAY=$DISPLAY" >> /etc/profile
-    fi
-
-    # I'm tired of typing this out...
-    echo "loader" >> /.bash_history
-
-    echo -n $$ > /var/run/init.pid
-
-    # shutdown (halt) on SIGUSR1
-    trap doshutdown SIGUSR1
-    # reboot on SIGUSR2
-    trap doreboot SIGUSR2
-
-    startinetd
-
-    if [ -n "$RUNKS" ]; then
-        /sbin/loader
-    fi
-
-    doshutdown
-
-fi # testing
-
-# ;;; Local Variables: ***
-# ;;; mode: sh ***
-# ;;; end: ***
diff --git a/loader/loader.c b/loader/loader.c
deleted file mode 100644
index 84fd116..0000000
--- a/loader/loader.c
+++ /dev/null
@@ -1,2378 +0,0 @@
-/*
- * loader.c
- *
- * This is the installer loader.  Its job is to somehow load the rest
- * of the installer into memory and run it.  This may require setting
- * up some devices and networking, etc. The main point of this code is
- * to stay SMALL! Remember that, live by that, and learn to like it.
- *
- * Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
- * 2006, 2007  Red Hat, Inc.  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 as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * 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, see <http://www.gnu.org/licenses/>.
- *
- * Author(s): Erik Troan <ewt@xxxxxxxxxx>
- *            Matt Wilson <msw@xxxxxxxxxx>
- *            Michael Fulbright <msf@xxxxxxxxxx>
- *            Jeremy Katz <katzj@xxxxxxxxxx>
- */
-
-#include <ctype.h>
-#include <errno.h>
-#include <execinfo.h>
-#include <fcntl.h>
-#include <newt.h>
-#include <signal.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <strings.h>
-#include <unistd.h>
-#include <stdint.h>
-#include <dirent.h>
-#include <arpa/inet.h>
-
-#include <sys/ioctl.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <sys/stat.h>
-#include <sys/wait.h>
-#include <sys/utsname.h>
-
-#include <linux/fb.h>
-#include <linux/serial.h>
-#include <linux/vt.h>
-
-#include <glib.h>
-
-#ifdef USE_MTRACE
-#include <mcheck.h>
-#endif
-
-#include "copy.h"
-#include "getparts.h"
-#include "loader.h"
-#include "loadermisc.h" /* JKFIXME: functions here should be split out */
-#include "lang.h"
-#include "fwloader.h"
-#include "kbd.h"
-#include "kickstart.h"
-#include "windows.h"
-
-/* module stuff */
-#include "modules.h"
-#include "moduleinfo.h"
-
-#include "driverdisk.h"
-
-/* hardware stuff */
-#include "hardware.h"
-
-/* install method stuff */
-#include "method.h"
-#include "cdinstall.h"
-#include "nfsinstall.h"
-#include "hdinstall.h"
-#include "urls.h"
-#include "urlinstall.h"
-
-#include "net.h"
-#include "telnetd.h"
-
-#include <selinux/selinux.h>
-#include "selinux.h"
-
-#include "../isys/imount.h"
-#include "../isys/isys.h"
-#include "../isys/stubs.h"
-#include "../isys/lang.h"
-#include "../isys/eddsupport.h"
-#include "../isys/log.h"
-
-/* maximum number of extra arguments that can be passed to the second stage */
-#define MAX_EXTRA_ARGS 128
-static char * extraArgs[MAX_EXTRA_ARGS];
-static int hasGraphicalOverride();
-
-static int newtRunning = 0;
-
-/* boot flags -- we need these in a lot of places */
-uint64_t flags = LOADER_FLAGS_SELINUX;
-
-#ifdef INCLUDE_LOCAL
-#include "cdinstall.h"
-#include "hdinstall.h"
-#endif
-#ifdef INCLUDE_NETWORK
-#include "nfsinstall.h"
-#include "urlinstall.h"
-#endif
-
-int num_link_checks = 5;
-int post_link_sleep = 0;
-
-static pid_t init_pid = 1;
-static int init_sig = SIGUSR1; /* default to shutdown=halt */
-static const char *LANG_DEFAULT = "en_US.UTF-8";
-
-static struct installMethod installMethods[] = {
-    { N_("Local CD/DVD"), 0, DEVICE_CDROM, mountCdromImage },
-    { N_("Hard drive"), 0, DEVICE_DISK, mountHardDrive },
-    { N_("NFS directory"), 1, DEVICE_NETWORK, mountNfsImage },
-    { "URL", 1, DEVICE_NETWORK, mountUrlImage },
-};
-static int numMethods = sizeof(installMethods) / sizeof(struct installMethod);
-
-static int expected_exit = 0;
-
-void doExit(int result)
-{
-    expected_exit = 1;
-    exit(result);
-}
-
-void doSuspend(void) {
-    newtFinished();
-    doExit(1);
-}
-
-void doShell(void) {
-    pid_t child;
-    int status;
-
-    newtSuspend();
-    child = fork();
-
-    if (child == 0) {
-        if (execl("/sbin/bash", "/sbin/bash", "-i", NULL) == -1) {
-            logMessage(ERROR, "%s (%d): %m", __func__, __LINE__);
-            _exit(1);
-        }
-    } else if (child == -1) {
-        logMessage(ERROR, "%s (%d): %m", __func__, __LINE__);
-        newtResume();
-    } else {
-        if (waitpid(child, &status, 0) == -1) {
-            logMessage(ERROR, "%s (%d): %m", __func__, __LINE__);
-        }
-
-        newtResume();
-    }
-}
-
-void doGdbserver(struct loaderData_s *loaderData) {
-    int child, fd;
-    char *pid;
-    iface_t iface;
-
-    /* If gdbserver is found, go ahead and run it on the loader process now
-     * before anything bad happens.
-     */
-    if (loaderData->gdbServer && !access("/usr/bin/gdbserver", X_OK)) {
-        pid_t loaderPid = getpid();
-        iface_init_iface_t(&iface);
-
-        if (kickstartNetworkUp(loaderData, &iface)) {
-            logMessage(ERROR, "can't run gdbserver due to no network");
-            return;
-        }
-
-        checked_asprintf(&pid, "%d", loaderPid);
-
-        if (!(child = fork())) {
-            logMessage(INFO, "starting gdbserver: %s %s %s %s",
-                       "/usr/bin/gdbserver", "--attach", loaderData->gdbServer,
-                       pid);
-
-            fd = open("/dev/null", O_RDONLY);
-            close(STDIN_FILENO);
-            dup2(fd, STDIN_FILENO);
-            close(fd);
-            fd = open("/dev/null", O_WRONLY);
-            close(STDOUT_FILENO);
-            dup2(fd, STDOUT_FILENO);
-            close(STDERR_FILENO);
-            dup2(fd, STDERR_FILENO);
-            close(fd);
-
-            if (execl("/usr/bin/gdbserver", "/usr/bin/gdbserver", "--attach",
-                      loaderData->gdbServer, pid, NULL) == -1)
-                logMessage(ERROR, "error running gdbserver: %m");
-
-            _exit(1);
-        }
-    }
-}
-
-void startNewt(void) {
-    if (!newtRunning) {
-        char *buf;
-        char *arch = getProductArch();
-        checked_asprintf(&buf, _("Welcome to %s for %s"), getProductName(), arch);
-
-        /*
-         * Because currently initrd.img only has got the default English locale
-         * support, pretend for newtInit() it is actually the used LANG so Newt
-         * knows how to compute character widths etc. 
-         */
-        char *lang = getenv("LANG");
-        if (lang) {
-            lang = strdup(lang);
-        }
-        setenv("LANG", LANG_DEFAULT, 1);
-        newtInit();
-        unsetenv("LANG");
-        /* restore the original LANG value */
-        if (lang) {
-            setenv("LANG", lang, 1);
-            free(lang);
-        }
-
-        newtCls();
-        newtDrawRootText(0, 0, buf);
-        free(buf);
-        
-        newtPushHelpLine(_("  <Tab>/<Alt-Tab> between elements  | <Space> selects | <F12> next screen "));
-        
-        newtRunning = 1;
-        if (!access("/bin/sh",  X_OK)) 
-            newtSetSuspendCallback((void *) doShell, NULL);
-    }
-}
-
-void stopNewt(void) {
-    if (newtRunning) newtFinished();
-    newtRunning = 0;
-}
-
-static gchar *productName = NULL;
-static gchar *productPath = NULL;
-static gchar *productArch = NULL;
-
-static void initProductInfo(void) {
-    gchar *contents = NULL;
-    gchar **lines = NULL, **stamp = NULL;
-    GError *fileErr = NULL;
-
-    if (!g_file_get_contents("/.buildstamp", &contents, NULL, &fileErr)) {
-        logMessage(ERROR, "error reading .buildstamp: %s", fileErr->message);
-        g_error_free(fileErr);
-        productName = g_strdup("anaconda");
-        productArch = g_strdup("unknown architecture");
-        productPath = g_strdup("anaconda");
-        return;
-    }
-
-    /* .buildstamp uses the first 3 lines in this format:
-     *     STAMP.productArch
-     *     productName
-     *     productPath
-     */
-    lines = g_strsplit(contents, "\n", 0);
-    g_free(contents);
-
-    if ((lines != NULL) && (g_strv_length(lines) >= 3)) {
-        /* STAMP.productArch */
-        stamp = g_strsplit(lines[0], ".", 0);
-
-        if ((stamp != NULL) && (g_strv_length(stamp) == 2)) {
-            productArch = g_strdup(stamp[1]);
-        } else {
-            productArch = g_strdup("unknown architecture");
-        }
-
-        if (stamp) {
-            g_strfreev(stamp);
-        }
-
-        productName = g_strdup(lines[1]);
-        productPath = g_strdup(lines[2]);
-    } else {
-        productName = g_strdup("anaconda");
-        productArch = g_strdup("unknown architecture");
-        productPath = g_strdup("anaconda");
-    }
-
-    if (lines) {
-        g_strfreev(lines);
-    }
-
-    return;
-}
-
-char * getProductName(void) {
-    if (!productName) {
-       initProductInfo();
-    }
-    return productName;
-}
-
-char * getProductArch(void) {
-    if (!productArch) {
-       initProductInfo();
-    }
-    return productArch;
-}
-
-char * getProductPath(void) {
-    if (!productPath) {
-       initProductInfo();
-    }
-    return productPath;
-}
-
-void initializeConsole() {
-    /* enable UTF-8 console */
-    setenv("LANG", LANG_DEFAULT, 1);
-    printf("\033%%G");
-    fflush(stdout);
-
-    isysLoadFont();
-    isysSetUnicodeKeymap();
-}
-
-/* fbcon is buggy and resets our color palette if we allocate a terminal
- * after initializing it, so we initialize 9 of them before we need them.
- * If it doesn't work, the user gets to suffer through having an ugly palette,
- * but things are still usable. */
-static void initializeTtys(void) {
-    int fd, n;
-    char dev[] = "/dev/ttyX";
-
-    for (n = 9; n > 0; n--) {
-	sprintf(dev, "/dev/tty%d", n);
-	mknod(dev, 0600 | S_IFCHR, makedev(4, n));
-	fd = open(dev, O_RDWR|O_NOCTTY);
-	if (fd >= 0) {
-	    ioctl(fd, VT_ACTIVATE, n);
-	    if (n == 1)
-		ioctl(fd, VT_WAITACTIVE, n);
-	    close(fd);
-	} else
-	    logMessage(ERROR, "failed to initialize %s", dev);
-    }
-}
-
-static void spawnShell(void) {
-    pid_t pid;
-
-    if (FL_SERIAL(flags) || FL_NOSHELL(flags)) {
-        logMessage(INFO, "not spawning a shell");
-        return;
-    } else if (access("/bin/sh",  X_OK))  {
-        logMessage(ERROR, "cannot open shell - /bin/sh doesn't exist");
-        return;
-    }
-
-    if (!(pid = fork())) {
-	int fd;
-
-    	fd = open("/dev/tty2", O_RDWR|O_NOCTTY);
-    	if (fd < 0) {
-            logMessage(ERROR, "cannot open /dev/tty2 -- no shell will be provided");
-	    return;
-	}
-
-        dup2(fd, 0);
-        dup2(fd, 1);
-        dup2(fd, 2);
-        
-        close(fd);
-        setsid();
-
-	/* enable UTF-8 console */
-	printf("\033%%G");
-	fflush(stdout);
-	isysLoadFont();
-	
-        if (ioctl(0, TIOCSCTTY, NULL)) {
-            logMessage(ERROR, "could not set new controlling tty");
-        }
-        
-        signal(SIGINT, SIG_DFL);
-        signal(SIGTSTP, SIG_DFL);
-
-        if (!access("/tmp/updates/pyrc.py", R_OK|X_OK))
-            setenv("PYTHONSTARTUP", "/tmp/updates/pyrc.py", 1);
-        else if (!access("/usr/share/anaconda/pyrc.py", R_OK|X_OK))
-            setenv("PYTHONSTARTUP", "/usr/share/anaconda/pyrc.py", 1);
-        setenv("LD_LIBRARY_PATH", LIBPATH, 1);
-        setenv("LANG", "C", 1);
-        
-        if (execl("/bin/sh", "-/bin/sh", NULL) == -1) {
-            logMessage(CRITICAL, "exec of /bin/sh failed: %m");
-            exit(1);
-        }
-    }
-
-    return;
-}
-
-
-static void copyWarnFn (char *msg) {
-   logMessage(WARNING, msg);
-}
-
-static void copyErrorFn (char *msg) {
-   newtWinMessage(_("Error"), _("OK"), _(msg));
-}
-
-void loadUpdates(struct loaderData_s *loaderData) {
-    char *device = NULL, *part = NULL, *buf;
-    char **devNames = NULL;
-    enum { UPD_DEVICE, UPD_PART, UPD_PROMPT, UPD_LOAD, UPD_DONE } stage = UPD_DEVICE;
-    int rc, num = 0;
-    int dir = 1;
-
-    while (stage != UPD_DONE) {
-        switch (stage) {
-        case UPD_DEVICE: {
-            rc = getRemovableDevices(&devNames);
-            if (rc == 0)
-                return;
-
-            /* we don't need to ask which to use if they only have one */
-            if (rc == 1) {
-                device = strdup(devNames[0]);
-                free(devNames);
-                devNames = NULL;
-                if (dir == -1)
-                    return;
-
-                stage = UPD_PART;
-                break;
-            }
-            dir = 1;
-
-            startNewt();
-            rc = newtWinMenu(_("Update Disk Source"),
-                             _("You have multiple devices which could serve "
-                               "as sources for an update disk.  Which would "
-                               "you like to use?"), 40, 10, 10,
-                             rc < 6 ? rc : 6, devNames,
-                             &num, _("OK"), _("Cancel"), NULL);
-
-            if (rc == 2) {
-                free(devNames);
-                devNames = NULL;
-                return;
-            }
-
-            device = strdup(devNames[num]);
-            free(devNames);
-            devNames = NULL;
-            stage = UPD_PART;
-        }
-
-        case UPD_PART: {
-            char ** part_list = getPartitionsList(device);
-            int nump = 0, num = 0;
-
-            if (part != NULL) {
-                free(part);
-                part = NULL;
-            }
-
-            if ((nump = lenPartitionsList(part_list)) == 0) {
-                if (dir == -1) {
-                    stage = UPD_DEVICE;
-                } else {
-                    checked_asprintf(&part, "/dev/%s", device);
-                    stage = UPD_PROMPT;
-                }
-
-                break;
-            }
-            dir = 1;
-
-            startNewt();
-            rc = newtWinMenu(_("Update Disk Source"),
-                             _("There are multiple partitions on this device "
-                               "which could contain the update disk image.  "
-                               "Which would you like to use?"), 40, 10, 10,
-                             nump < 6 ? nump : 6, part_list, &num, _("OK"),
-                             _("Back"), NULL);
-
-            if (rc == 2) {
-                freePartitionsList(part_list);
-                stage = UPD_DEVICE;
-                dir = -1;
-                break;
-            }
-
-            part = strdup(part_list[num]);
-            stage = UPD_LOAD;
-        }
-
-        case UPD_PROMPT:
-            checked_asprintf(&buf, _("Insert your updates disk into %s and "
-                                     "press \"OK\" to continue."), part);
-
-            rc = newtWinChoice(_("Updates Disk"), _("OK"), _("Back"), buf);
-            free(buf);
-            buf = NULL;
-
-            if (rc == 2) {
-                stage = UPD_PART;
-                dir = -1;
-                break;
-            }
-
-            stage = UPD_LOAD;
-            break;
-
-        case UPD_LOAD:
-            logMessage(INFO, "UPDATES device is %s", part);
-
-            if (doPwMount(part, "/tmp/update-disk", "auto", "ro", NULL)) {
-                newtWinMessage(_("Error"), _("OK"),
-                               _("Failed to mount updates disk"));
-                stage = UPD_PROMPT;
-                break;
-            } else {
-                /* Copy everything to /tmp/updates so we can unmount the disk  */
-                winStatus(40, 3, _("Updates"), _("Reading anaconda updates"));
-                if (!copyDirectory("/tmp/update-disk", "/tmp/updates", copyWarnFn,
-                                   copyErrorFn)) {
-                    dir = 1;
-                    stage = UPD_DONE;
-                }
-
-                newtPopWindow();
-                umount("/tmp/update-disk");
-            }
-
-        case UPD_DONE:
-            break;
-        }
-    }
-
-    return;
-}
-
-static char *newUpdatesLocation(const char *origLocation) {
-    const char *location;
-    char *retval = NULL;
-    newtComponent f, okay, cancel, answer, locationEntry;
-    newtGrid grid, buttons;
-
-    startNewt();
-
-    locationEntry = newtEntry(-1, -1, NULL, 60, &location, NEWT_FLAG_SCROLL);
-    newtEntrySet(locationEntry, origLocation, 1);
-
-    /* button bar at the bottom of the window */
-    buttons = newtButtonBar(_("OK"), &okay, _("Cancel"), &cancel, NULL);
-
-    grid = newtCreateGrid(1, 3);
-
-    newtGridSetField(grid, 0, 0, NEWT_GRID_COMPONENT,
-                     newtTextboxReflowed(-1, -1, _("Unable to download the updates image.  Please modify the updates location below or press Cancel to proceed without updates.."), 60, 0, 0, 0),
-                     0, 0, 0, 0, NEWT_ANCHOR_LEFT, 0);
-    newtGridSetField(grid, 0, 1, NEWT_GRID_COMPONENT, locationEntry,
-                     0, 1, 0, 0, NEWT_ANCHOR_LEFT, 0);
-    newtGridSetField(grid, 0, 2, NEWT_GRID_SUBGRID, buttons,
-                     0, 1, 0, 0, 0, NEWT_GRID_FLAG_GROWX);
-
-    f = newtForm(NULL, NULL, 0);
-    newtGridAddComponentsToForm(grid, f, 1);
-    newtGridWrappedWindow(grid, _("Error downloading updates image"));
-    newtGridFree(grid, 1);
-
-    /* run the form */
-    answer = newtRunForm(f);
-
-    if (answer != cancel)
-        retval = strdup(location);
-
-    newtFormDestroy(f);
-    newtPopWindow();
-
-    return retval;
-}
-
-static int loadUpdatesFromRemote(char * url, struct loaderData_s * loaderData) {
-    int rc = getFileFromUrl(url, "/tmp/updates.img", loaderData);
-
-    if (rc != 0) {
-        char *newLocation = newUpdatesLocation(url);
-
-        if (!newLocation)
-           return rc;
-        else
-           return loadUpdatesFromRemote(newLocation, loaderData);
-    }
-
-    copyUpdatesImg("/tmp/updates.img");
-    unlink("/tmp/updates.img");
-    return 0;
-}
-
-static void writeVNCPasswordFile(char *pfile, char *password) {
-    FILE *f;
-
-    f = fopen(pfile, "w+");
-    fprintf(f, "%s\n", password);
-    fclose(f);
-}
-
-/* read information from /etc/sysconfig/network-scripts/ifcfg-$INTERFACE
- * (written by linuxrc), the linuxrc mess should be firing up NM too
- */
-static void readNetInfo(struct loaderData_s ** ld) {
-    struct loaderData_s * loaderData = *ld;
-    char *cfgfile = NULL;
-    gchar *contents = NULL;
-    gchar **lines = NULL, **line = NULL;
-    GError *e = NULL;
-
-    /* when this function is called, the DEVICE environment variable
-     * contains the device name whose ifcfg file we want to read
-     */
-    if (!getenv("DEVICE")) {
-        return;
-    }
-
-    checked_asprintf(&cfgfile, "/etc/sysconfig/network-scripts/ifcfg-%s",
-                     getenv("DEVICE"));
-
-    /* make sure everything is NULL before we begin copying info */
-    loaderData->ipv4 = NULL;
-    loaderData->netmask = NULL;
-    loaderData->gateway = NULL;
-    loaderData->dns = NULL;
-    loaderData->peerid = NULL;
-    loaderData->subchannels = NULL;
-    loaderData->portname = NULL;
-    loaderData->nettype = NULL;
-    loaderData->ctcprot = NULL;
-    loaderData->layer2 = NULL;
-    loaderData->portno = NULL;
-    loaderData->macaddr = NULL;
-#ifdef ENABLE_IPV6
-    loaderData->ipv6 = NULL;
-    loaderData->gateway6 = NULL;
-#endif
-
-    /*
-     * The ifcfg file is written out by /sbin/init on s390x (which is
-     * really the linuxrc.s390 script).  It's a shell-sourcable file with
-     * various system settings needing for the system instance.
-     *
-     * The goal of this function is to read in only the network settings
-     * and populate the loaderData structure.
-     */
-    if (!g_file_get_contents(cfgfile, &contents, NULL, &e)) {
-        logMessage(ERROR, "error reading %s: %s", cfgfile, e->message);
-        g_error_free(e);
-        return;
-    }
-
-    line = lines = g_strsplit(contents, "\n", 0);
-    g_free(contents);
-
-    while (*line != NULL) {
-        gchar *tmp = g_strdup(*line);
-        gchar **pair = NULL;
-
-        if (!strstr(tmp, "=")) {
-            g_free(tmp);
-            line++;
-            continue;
-        }
-
-        tmp = g_strstrip(tmp);
-        pair = g_strsplit(tmp, "=", 0);
-
-        if (g_strv_length(pair) == 2) {
-            gchar *val = g_shell_unquote(pair[1], &e);
-
-            if (e != NULL) {
-                logMessage(WARNING,
-                           "error reading %s from %s (line=%s): %s",
-                           pair[0], cfgfile, tmp, e->message);
-                g_error_free(e);
-            } else {
-                if (!g_strcmp0(pair[0], "IPADDR")) {
-                    loaderData->ipv4 = strdup(val);
-                } else if (!g_strcmp0(pair[0], "NETMASK")) {
-                    loaderData->netmask = strdup(val);
-                } else if (!g_strcmp0(pair[0], "GATEWAY")) {
-                    loaderData->gateway = strdup(val);
-                } else if (!g_strcmp0(pair[0], "DNS")) {
-                    loaderData->dns = strdup(val);
-                } else if (!g_strcmp0(pair[0], "MTU")) {
-                    errno = 0;
-                    loaderData->mtu = strtol(val, NULL, 10);
-
-                    if ((errno == ERANGE && (loaderData->mtu == LONG_MIN ||
-                                             loaderData->mtu == LONG_MAX)) ||
-                        (errno != 0 && loaderData->mtu == 0)) {
-                        logMessage(ERROR, "%s: %d: %m", __func__, __LINE__);
-                        abort();
-                    }
-                } else if (!g_strcmp0(pair[0], "PEERID")) {
-                    loaderData->peerid = strdup(val);
-                } else if (!g_strcmp0(pair[0], "SUBCHANNELS")) {
-                    loaderData->subchannels = strdup(val);
-                } else if (!g_strcmp0(pair[0], "PORTNAME")) {
-                    loaderData->portname = strdup(val);
-                } else if (!g_strcmp0(pair[0], "NETTYPE")) {
-                    loaderData->nettype = strdup(val);
-                } else if (!g_strcmp0(pair[0], "CTCPROT")) {
-                    loaderData->ctcprot = strdup(val);
-                } else if (!g_strcmp0(pair[0], "LAYER2")) {
-                    loaderData->layer2 = strdup(val);
-                } else if (!g_strcmp0(pair[0], "PORTNO")) {
-                    loaderData->portno = strdup(val);
-                } else if (!g_strcmp0(pair[0], "MACADDR")) {
-                    loaderData->macaddr = strdup(val);
-                } else if (!g_strcmp0(pair[0], "HOSTNAME")) {
-                    loaderData->hostname = strdup(val);
-                }
-            }
-
-            g_free(val);
-        }
-
-        g_strfreev(pair);
-        g_free(tmp);
-        line++;
-    }
-
-    if (loaderData->ipv4 && loaderData->netmask) {
-        flags |= LOADER_FLAGS_HAVE_CMSCONF;
-    }
-
-    free(cfgfile);
-    g_strfreev(lines);
-    return;
-}
-
-/* parse anaconda or pxelinux-style ip= arguments
- * pxelinux format: ip=<client-ip>:<boot-server-ip>:<gw-ip>:<netmask>
- * anaconda format: ip=<client-ip> netmask=<netmask> gateway=<gw-ip>
-*/
-static void parseCmdLineIp(struct loaderData_s * loaderData, char *argv)
-{
-    /* Detect pxelinux */
-    if (strstr(argv, ":") != NULL) {
-        char *start, *end;
-
-        /* IP */
-        start = argv + 3;
-        end = strstr(start, ":");
-        loaderData->ipv4 = strndup(start, end-start);
-        loaderData->ipinfo_set = 1;
-
-        /* Boot server */
-        if (end + 1 == '\0')
-            return;
-        start = end + 1;
-        end = strstr(start, ":");
-        if (end == NULL)
-            return;
-
-        /* Gateway */
-        if (end + 1 == '\0')
-            return;
-        start = end + 1;
-        end = strstr(start, ":");
-        if (end == NULL) {
-            loaderData->gateway = strdup (start);
-            return;
-        } else {
-            loaderData->gateway = strndup(start, end-start);
-        }
-
-        /* Netmask */
-        if (end + 1 == '\0')
-            return;
-        start = end + 1;
-        loaderData->netmask = strdup(start);
-    } else {
-        loaderData->ipv4 = strdup(argv + 3);
-        loaderData->ipinfo_set = 1;
-    }
-
-    if (loaderData->ipinfo_set)
-        flags |= LOADER_FLAGS_IP_PARAM;
-}
-
-#ifdef ENABLE_IPV6
-/*
- * parse anaconda ipv6= arguments
- */
-static void parseCmdLineIpv6(struct loaderData_s * loaderData, char *argv)
-{
-    /* right now we only accept ipv6= arguments equal to:
-     *     dhcp     DHCPv6 call
-     *     auto     RFC 2461 neighbor discovery
-     */
-    loaderData->ipv6 = NULL;
-
-    if (!strncasecmp(argv, "ipv6=dhcp", 9)) {
-        loaderData->ipv6 = strdup("dhcp");
-    } else if (!strncasecmp(argv, "ipv6=auto", 9)) {
-        loaderData->ipv6 = strdup("auto");
-    }
-
-    if (loaderData->ipv6 != NULL) {
-        loaderData->ipv6info_set = 1;
-        flags |= LOADER_FLAGS_IPV6_PARAM;
-    }
-
-    return;
-}
-#endif
-
-static long argToLong(char *arg, int offset) {
-    long retval;
-
-    errno = 0;
-
-    retval = strtol(arg+offset, NULL, 10);
-    if ((errno == ERANGE && (retval == LONG_MIN || retval == LONG_MAX)) ||
-        (errno != 0 && retval == 0)) {
-        logMessage(ERROR, "%s: %d: %m", __func__, __LINE__);
-        abort();
-    }
-
-    return retval;
-}
-
-/* parses /proc/cmdline for any arguments which are important to us.  
- * NOTE: in test mode, can specify a cmdline with --cmdline
- */
-static void parseCmdLineFlags(struct loaderData_s * loaderData,
-                              char * cmdLine) {
-    int fd;
-    char buf[1024];
-    int len;
-    gint argc = 0;
-    gchar **argv = NULL;
-    GError *optErr = NULL;
-    int numExtraArgs = 0;
-    int i;
-    char *front;
-
-    /* we want to default to graphical and allow override with 'text' */
-    flags |= LOADER_FLAGS_GRAPHICAL;
-
-    /* if we have any explicit cmdline (probably test mode), we don't want
-     * to parse /proc/cmdline */
-    if (!cmdLine) {
-        if ((fd = open("/proc/cmdline", O_RDONLY)) < 0) return;
-        len = read(fd, buf, sizeof(buf) - 1);
-        close(fd);
-        if (len <= 0) {
-            logMessage(INFO, "kernel command line was empty");
-            return;
-        }
-        
-        buf[len] = '\0';
-        cmdLine = buf;
-    }
-
-    logMessage(INFO, "kernel command line: %s", cmdLine);
-    
-    if (!g_shell_parse_argv(cmdLine, &argc, &argv, &optErr)) {
-        g_error_free(optErr);
-        return;
-    }
-
-    for (i=0; i < argc; i++) {
-        if (!strcasecmp(argv[i], "askmethod"))
-            flags |= LOADER_FLAGS_ASKMETHOD;
-        else if (!strcasecmp(argv[i], "asknetwork"))
-            flags |= LOADER_FLAGS_ASKNETWORK;
-        else if (!strcasecmp(argv[i], "noshell"))
-            flags |= LOADER_FLAGS_NOSHELL;
-        else if (!strcasecmp(argv[i], "nokill"))
-            flags |= LOADER_FLAGS_NOKILL;
-        else if (!strcasecmp(argv[i], "mediacheck"))
-            flags |= LOADER_FLAGS_MEDIACHECK;
-        else if (!strcasecmp(argv[i], "allowwireless"))
-            flags |= LOADER_FLAGS_ALLOW_WIRELESS;
-        else if (!strcasecmp(argv[i], "telnet"))
-            flags |= LOADER_FLAGS_TELNETD;
-        else if (!strcasecmp(argv[i], "noprobe"))
-            flags |= LOADER_FLAGS_NOPROBE;
-        else if (!strcasecmp(argv[i], "text")) {
-            logMessage(INFO, "text mode forced from cmdline");
-            flags |= LOADER_FLAGS_TEXT;
-            flags &= ~LOADER_FLAGS_GRAPHICAL;
-        }
-        else if (!strcasecmp(argv[i], "graphical")) {
-            logMessage(INFO, "graphical mode forced from cmdline");
-            flags |= LOADER_FLAGS_GRAPHICAL;
-        } else if (!strcasecmp(argv[i], "cmdline")) {
-            logMessage(INFO, "cmdline mode forced from cmdline");
-            flags |= LOADER_FLAGS_CMDLINE;
-        } else if (!strncasecmp(argv[i], "updates=", 8))
-            loaderData->updatessrc = strdup(argv[i] + 8);
-        else if (!strncasecmp(argv[i], "updates", 7))
-            flags |= LOADER_FLAGS_UPDATES;
-        else if (!strncasecmp(argv[i], "dogtail=", 8))
-            loaderData->dogtailurl = strdup(argv[i] + 8);
-        else if (!strncasecmp(argv[i], "dd=", 3) || 
-                 !strncasecmp(argv[i], "driverdisk=", 11)) {
-            loaderData->ddsrc = strdup(argv[i] + 
-                                       (argv[i][1] == 'r' ? 11 : 3));
-        }
-        else if (!strcasecmp(argv[i], "dd") || 
-                 !strcasecmp(argv[i], "driverdisk"))
-            flags |= LOADER_FLAGS_MODDISK;
-        else if (!strcasecmp(argv[i], "dlabel=on"))
-            flags |= LOADER_FLAGS_AUTOMODDISK;
-        else if (!strcasecmp(argv[i], "dlabel=off"))
-            flags &= ~LOADER_FLAGS_AUTOMODDISK;
-        else if (!strcasecmp(argv[i], "rescue"))
-            flags |= LOADER_FLAGS_RESCUE;
-        else if (!strcasecmp(argv[i], "nopass"))
-            flags |= LOADER_FLAGS_NOPASS;
-        else if (!strcasecmp(argv[i], "serial")) 
-            flags |= LOADER_FLAGS_SERIAL;
-        else if (!strcasecmp(argv[i], "noipv4"))
-            flags |= LOADER_FLAGS_NOIPV4;
-#ifdef ENABLE_IPV6
-        else if (!strcasecmp(argv[i], "noipv6"))
-            flags |= LOADER_FLAGS_NOIPV6;
-#endif
-        else if (!strcasecmp(argv[i], "kssendmac"))
-            flags |= LOADER_FLAGS_KICKSTART_SEND_MAC;
-        else if (!strcasecmp(argv[i], "kssendsn"))
-            flags |= LOADER_FLAGS_KICKSTART_SEND_SERIAL;
-        /* deprecated hardware bits */
-        else if (!strcasecmp(argv[i], "nousbstorage"))
-            mlAddBlacklist("usb-storage");
-        else if (!strcasecmp(argv[i], "nousb")) {
-            mlAddBlacklist("ehci-hcd");
-            mlAddBlacklist("ohci-hcd");
-            mlAddBlacklist("uhci-hcd");
-        } else if (!strcasecmp(argv[i], "nofirewire"))
-            mlAddBlacklist("firewire-ohci");
-        else if (!strncasecmp(argv[i], "loglevel=", 9)) {
-            if (!strcasecmp(argv[i]+9, "debug")) {
-                loaderData->logLevel = strdup(argv[i]+9);
-                setLogLevel(DEBUGLVL);
-            }
-            else if (!strcasecmp(argv[i]+9, "info")) {
-                loaderData->logLevel = strdup(argv[i]+9);
-                setLogLevel(INFO);
-            }
-            else if (!strcasecmp(argv[i]+9, "warning")) {
-                loaderData->logLevel = strdup(argv[i]+9);
-                setLogLevel(WARNING);
-            }
-            else if (!strcasecmp(argv[i]+9, "error")) {
-                loaderData->logLevel = strdup(argv[i]+9);
-                setLogLevel(ERROR);
-            }
-            else if (!strcasecmp(argv[i]+9, "critical")) {
-                loaderData->logLevel = strdup(argv[i]+9);
-                setLogLevel(CRITICAL);
-            }
-        }
-        else if (!strncasecmp(argv[i], "ksdevice=", 9)) {
-            loaderData->netDev = strdup(argv[i] + 9);
-            loaderData->netDev_set = 1;
-        }
-        else if (!strncmp(argv[i], "BOOTIF=", 7)) {
-            /* +10 so that we skip over the leading 01- */
-            loaderData->bootIf = strdup(argv[i] + 10);
-
-            /* scan the BOOTIF value and replace '-' with ':' */
-            front = loaderData->bootIf;
-            if (front) {
-                while (*front != '\0') {
-                    if (*front == '-')
-                        *front = ':';
-                    front++;
-                }
-            }
-
-            loaderData->bootIf_set = 1;
-        } else if (!strncasecmp(argv[i], "dhcpclass=", 10)) {
-            loaderData->netCls = strdup(argv[i] + 10);
-            loaderData->netCls_set = 1;
-        }
-        else if (!strcasecmp(argv[i], "ks") || !strncasecmp(argv[i], "ks=", 3))
-            loaderData->ksFile = strdup(argv[i]);
-        else if (!strncasecmp(argv[i], "display=", 8))
-            setenv("DISPLAY", argv[i] + 8, 1);
-        else if ((!strncasecmp(argv[i], "lang=", 5)) && 
-                 (strlen(argv[i]) > 5))  {
-            loaderData->lang = strdup(argv[i] + 5);
-            loaderData->lang_set = 1;
-        }
-        else if (!strncasecmp(argv[i], "keymap=", 7) &&
-                   (strlen(argv[i]) > 7)) {
-            loaderData->kbd = strdup(argv[i] + 7);
-            loaderData->kbd_set = 1;
-        }
-        else if (!strncasecmp(argv[i], "method=", 7)) {
-            logMessage(WARNING, "method= is deprecated.  Please use repo= instead.");
-            loaderData->instRepo = strdup(argv[i] + 7);
-        }
-        else if (!strncasecmp(argv[i], "repo=", 5))
-            loaderData->instRepo = strdup(argv[i] + 5);
-        else if (!strncasecmp(argv[i], "stage2=", 7))
-            setStage2LocFromCmdline(argv[i] + 7, loaderData);
-        else if (!strncasecmp(argv[i], "hostname=", 9))
-            loaderData->hostname = strdup(argv[i] + 9);
-        else if (!strncasecmp(argv[i], "ip=", 3))
-            parseCmdLineIp(loaderData, argv[i]);
-#ifdef ENABLE_IPV6
-        else if (!strncasecmp(argv[i], "ipv6=", 5))
-            parseCmdLineIpv6(loaderData, argv[i]);
-#endif
-        else if (!strncasecmp(argv[i], "netmask=", 8))
-            loaderData->netmask = strdup(argv[i] + 8);
-        else if (!strncasecmp(argv[i], "gateway=", 8))
-            loaderData->gateway = strdup(argv[i] + 8);
-        else if (!strncasecmp(argv[i], "dns=", 4))
-            loaderData->dns = strdup(argv[i] + 4);
-        else if (!strncasecmp(argv[i], "ethtool=", 8))
-            loaderData->ethtool = strdup(argv[i] + 8);
-        else if (!strncasecmp(argv[i], "essid=", 6))
-            loaderData->essid = strdup(argv[i] + 6);
-        else if (!strncasecmp(argv[i], "mtu=", 4))
-            loaderData->mtu = argToLong(argv[i], 4);
-        else if (!strncasecmp(argv[i], "wepkey=", 7))
-            loaderData->wepkey = strdup(argv[i] + 7);
-        else if (!strncasecmp(argv[i], "linksleep=", 10))
-            num_link_checks = argToLong(argv[i], 10);
-        else if (!strncasecmp(argv[i], "nicdelay=", 9))
-            post_link_sleep = argToLong(argv[i], 9);
-        else if (!strncasecmp(argv[i], "dhcptimeout=", 12))
-            loaderData->dhcpTimeout = argToLong(argv[i], 12);
-        else if (!strncasecmp(argv[i], "selinux=0", 9))
-            flags &= ~LOADER_FLAGS_SELINUX;
-        else if (!strncasecmp(argv[i], "selinux", 7))
-            flags |= LOADER_FLAGS_SELINUX;
-        else if (!strncasecmp(argv[i], "gdb=", 4))
-            loaderData->gdbServer = strdup(argv[i] + 4);
-        else if (!strncasecmp(argv[i], "proxy=", 6))
-            splitProxyParam(argv[i]+6, &loaderData->proxyUser,
-                            &loaderData->proxyPassword, &loaderData->proxy);
-        else if (numExtraArgs < (MAX_EXTRA_ARGS - 1)) {
-            /* go through and append args we just want to pass on to */
-            /* the anaconda script, but don't want to represent as a */
-            /* LOADER_FLAGS_XXX since loader doesn't care about these */
-            /* particular options.                                   */
-            /* do vncpassword case first */
-            if (!strncasecmp(argv[i], "vncpassword=", 12)) {
-                writeVNCPasswordFile("/tmp/vncpassword.dat", argv[i]+12);
-            }
-            else if (!strncasecmp(argv[i], "resolution=", 11) ||
-                     !strncasecmp(argv[i], "nomount", 7) ||
-                     !strncasecmp(argv[i], "vnc", 3) ||
-                     !strncasecmp(argv[i], "vncconnect=", 11) ||
-                     !strncasecmp(argv[i], "headless", 8) ||
-                     !strncasecmp(argv[i], "usefbx", 6) ||
-                     !strncasecmp(argv[i], "mpath", 6) ||
-                     !strncasecmp(argv[i], "nompath", 8) ||
-                     !strncasecmp(argv[i], "dmraid", 6) ||
-                     !strncasecmp(argv[i], "nodmraid", 8) ||
-                     !strncasecmp(argv[i], "xdriver=", 8) ||
-                     !strncasecmp(argv[i], "vesa", 4) ||
-                     !strncasecmp(argv[i], "syslog=", 7)) { 
-
-                /* vnc implies graphical */
-                if (!strncasecmp(argv[i], "vnc", 3)) {
-                    logMessage(INFO, "vnc forced graphical mode from cmdline");
-                    flags |= LOADER_FLAGS_GRAPHICAL;
-                }
-
-                /* the following things require networking to be configured
-                 * by loader, so an active connection is ready once we get
-                 * to anaconda
-                 */
-                if (!strncasecmp(argv[i], "syslog", 6) ||
-                    !strncasecmp(argv[i], "vnc", 3)) {
-                    logMessage(INFO, "early networking required for %s",
-                               argv[i]);
-                    flags |= LOADER_FLAGS_EARLY_NETWORKING;
-                }
-                if (isKickstartFileRemote(loaderData->ksFile)) {
-                    logMessage(INFO, "early networking required for remote kickstart configuration");
-                    flags |= LOADER_FLAGS_EARLY_NETWORKING;
-                }
-
-                if (!strncasecmp(argv[i], "vesa", 4)) {
-                    checked_asprintf(&extraArgs[numExtraArgs],
-                                     "--xdriver=vesa");
-
-                    logMessage(WARNING, "\"vesa\" command line argument is deprecated.  use \"xdriver=vesa\".");
-                } else {
-                    checked_asprintf(&extraArgs[numExtraArgs],"--%s",
-                                     argv[i]);
-                }
-
-                numExtraArgs += 1;
-
-                if (numExtraArgs > (MAX_EXTRA_ARGS - 2)) {
-                     logMessage(WARNING, "Too many command line arguments (max "
-                                "allowed is %d), rest will be dropped.",
-                                MAX_EXTRA_ARGS);
-                }
-            }
-        }
-    }
-
-    readNetInfo(&loaderData);
-
-    /* NULL terminates the array of extra args */
-    extraArgs[numExtraArgs] = NULL;
-
-    return;
-}
-
-/* make sure they have enough ram */
-static void checkForRam(void) {
-    if (totalMemory() < MIN_RAM) {
-        char *buf;
-
-        checked_asprintf(&buf, _("You do not have enough RAM to install %s "
-                                 "on this machine."), getProductName());
-
-        startNewt();
-        newtWinMessage(_("Error"), _("OK"), buf);
-        free(buf);
-        stopNewt();
-        doExit(0);
-    }
-}
-
-static int haveDeviceOfType(int type) {
-    struct device ** devices;
-
-    devices = getDevices(type);
-    if (devices) {
-        return 1;
-    }
-    return 0;
-}
-
-static char *doLoaderMain(struct loaderData_s *loaderData,
-                          moduleInfoSet modInfo) {
-    enum { STEP_LANG, STEP_KBD, STEP_METHOD, STEP_DRIVER,
-           STEP_DRIVERDISK, STEP_NETWORK, STEP_IFACE,
-           STEP_IP, STEP_STAGE2, STEP_DONE } step;
-
-    char *url = NULL, *ret = NULL, *devName = NULL, *kbdtype = NULL;
-    static iface_t iface;
-    int i, rc = LOADER_NOOP, dir = 1;
-    int needsNetwork = 0, class = -1;
-    int skipMethodDialog = 0, skipLangKbd = 0;
-
-    char *installNames[10];
-    int numValidMethods = 0;
-    int validMethods[10];
-
-    for (i = 0; i < numMethods; i++, numValidMethods++) {
-        installNames[numValidMethods] = installMethods[i].name;
-        validMethods[numValidMethods] = i;
-    }
-    installNames[numValidMethods] = NULL;
-
-    /* Before anything else, see if there's a CD/DVD with a stage2 image on
-     * it.  However if stage2= was given, use that value as an override here.
-     * That will also then bypass any method selection UI in loader.
-     */
-    if (!FL_ASKMETHOD(flags)) {
-        url = findAnacondaCD("/mnt/stage2");
-        if (url) {
-            setStage2LocFromCmdline(url, loaderData);
-            skipMethodDialog = 1;
-
-            logMessage(INFO, "Detected stage 2 image on CD (url: %s)", url);
-            winStatus(50, 3, _("Media Detected"),
-                      _("Found local installation media"), 0);
-            sleep(3);
-            newtPopWindow();
-
-            skipLangKbd = 1;
-            flags |= LOADER_FLAGS_NOPASS;
-        } else if (!loaderData->stage2Data && loaderData->instRepo) {
-            /* If no CD/DVD with a stage2 image was found and we were given a
-             * repo=/method= parameter, try to piece together a valid setting
-             * for the stage2= parameter based on that.
-             */
-            char *tmp;
-
-            checked_asprintf(&tmp, "%s/images/install.img",
-                             loaderData->instRepo);
-
-            logMessage(INFO, "no stage2= given, assuming %s", tmp);
-            setStage2LocFromCmdline(tmp, loaderData);
-            free(tmp);
-
-            /* If we had to infer a stage2= location, but the repo= parameter
-             * we based this guess on was wrong, we need to correct the typo
-             * in both places.  Unfortunately we can't really know what the
-             * user meant, so the best we can do is take the results of
-             * running stage2= through the UI and chop off any /images/whatever
-             * path that's at the end of it.
-             */
-            loaderData->inferredStage2 = 1;
-            if (loaderData->method != -1) {
-                skipMethodDialog = 1;
-            }
-        } else if (loaderData->stage2Data) {
-            skipMethodDialog = 1;
-        }
-    } else {
-        /* Needed because they have already been set when parsing cmdline.
-         * (Leaks a little.)
-         */
-        loaderData->method = -1;
-        loaderData->stage2Data = NULL;
-    }
-
-    i = 0;
-    step = STEP_LANG;
-
-    while (step != STEP_DONE) {
-        switch(step) {
-            case STEP_LANG: {
-                if (loaderData->lang && (loaderData->lang_set == 1))
-                    setLanguage(loaderData->lang, 1);
-                else if (FL_RESCUE(flags) || !skipLangKbd)
-                    chooseLanguage(&loaderData->lang);
-
-                step = STEP_KBD;
-                dir = 1;
-                break;
-            }
-
-            case STEP_KBD: {
-                if (loaderData->kbd && (loaderData->kbd_set == 1)) {
-                    /* JKFIXME: this is broken -- we should tell of the 
-                     * failure; best by pulling code out in kbd.c to use */
-                    if (isysLoadKeymap(loaderData->kbd)) {
-                        logMessage(WARNING, "requested keymap %s is not valid, asking",
-                                   loaderData->kbd);
-                        loaderData->kbd = NULL;
-                        loaderData->kbd_set = 0;
-                        break;
-                    }
-                    rc = LOADER_NOOP;
-                } else if (FL_RESCUE(flags) || !skipLangKbd) {
-                    /* JKFIXME: should handle kbdtype, too probably... but it 
-                     * just matters for sparc */
-                    if (!FL_CMDLINE(flags))
-                        rc = chooseKeyboard(loaderData, &kbdtype);
-                    else
-                       rc = LOADER_NOOP;
-                } else {
-                    step = STEP_METHOD;
-                    dir = 1;
-                }
-
-                if (rc == LOADER_NOOP) {
-                    if (dir == -1)
-                        step = STEP_LANG;
-                    else
-                        step = STEP_METHOD;
-
-                    break;
-                }
-
-                if (rc == LOADER_BACK) {
-                    step = STEP_LANG;
-                    dir = -1;
-                } else {
-                    step = STEP_METHOD;
-                    dir = 1;
-                }
-
-                break;
-            }
-
-            case STEP_METHOD: {
-                if (loaderData->method != -1)
-                    skipMethodDialog = 1;
-                else if (FL_CMDLINE(flags)) {
-                    fprintf(stderr, "No method given for cmdline mode, aborting\n");
-                    doExit(EXIT_FAILURE);
-                }
-
-                /* If we already found a stage2 image, skip the prompt. */
-                if (skipMethodDialog) {
-                    if (dir == 1)
-                        rc = 1;
-                    else
-                        rc = -1;
-                } else {
-                    /* we need to set these each time through so that we get
-                     * updated for language changes (#83672) */
-                    for (i = 0; i < numMethods; i++) {
-                        installNames[i] = _(installMethods[i].name);
-                    }
-                    installNames[i] = NULL;
-
-                    rc = newtWinMenu(FL_RESCUE(flags) ? _("Rescue Method") :
-                                     _("Installation Method"),
-                                     FL_RESCUE(flags) ?
-                                     _("What type of media contains the rescue "
-                                       "image?") :
-                                     _("What type of media contains the installation "
-                                       "image?"),
-                                     30, 10, 20, 6, installNames, &loaderData->method,
-                                     _("OK"), _("Back"), NULL);
-                    if (rc == 2) {
-                        loaderData->method = -1;
-                    }
-                }
-
-                if (rc && (rc != 1)) {
-                    step = STEP_KBD;
-                    dir = -1;
-                } else {
-                    class = installMethods[validMethods[loaderData->method]].type;
-                    step = STEP_DRIVER;
-                    dir = 1;
-                }
-                break;
-            }
-
-            case STEP_DRIVER: {
-                if ((FL_EARLY_NETWORKING(flags) && haveDeviceOfType(DEVICE_NETWORK)) ||
-                    (class == -1 || haveDeviceOfType(class))) {
-                    step = STEP_NETWORK;
-                    dir = 1;
-                    class = -1;
-                    break;
-                }
-
-                if (skipLangKbd) {
-                    skipLangKbd = 0;
-                    step = STEP_KBD;
-                    break;
-                }
-
-                rc = newtWinTernary(_("No driver found"), _("Select driver"),
-                                    _("Use a driver disk"), _("Back"),
-                                    _("Unable to find any devices of the type "
-                                      "needed for this installation type.  "
-                                      "Would you like to manually select your "
-                                      "driver or use a driver disk?"));
-                if (rc == 2) {
-                    step = STEP_DRIVERDISK;
-                    dir = 1;
-                    break;
-                } else if (rc == 3) {
-                    step = STEP_METHOD;
-                    loaderData->method = -1;
-                    dir = -1;
-                    break;
-                }
-
-                chooseManualDriver(installMethods[validMethods[loaderData->method]].type,
-                                   loaderData);
-                /* it doesn't really matter what we return here; we just want
-                 * to reprobe and make sure we have the driver */
-                step = STEP_DRIVER;
-                break;
-            }
-
-            case STEP_DRIVERDISK: {
-                if (skipLangKbd) {
-                    skipLangKbd = 0;
-                    step = STEP_KBD;
-                    break;
-                }
-
-                rc = loadDriverFromMedia(class, loaderData, 0, 0, NULL);
-                if (rc == LOADER_BACK) {
-                    step = STEP_DRIVER;
-                    dir = -1;
-                    break;
-                }
-
-                /* need to come back to driver so that we can ensure that we found
-                 * the right kind of driver after loading the driver disk */
-                step = STEP_DRIVER;
-                break;
-            }
-
-            case STEP_NETWORK: {
-                if (((installMethods[validMethods[loaderData->method]].type !=
-                       DEVICE_NETWORK) && (!hasGraphicalOverride()) &&
-                      !FL_ASKNETWORK(flags) &&
-                      !FL_EARLY_NETWORKING(flags)) ||
-                     (is_nm_connected())) {
-                    needsNetwork = 0;
-                    if (dir == 1) 
-                        step = STEP_STAGE2;
-                    else if (dir == -1)
-                        step = STEP_METHOD;
-                    break;
-                }
-
-                needsNetwork = 1;
-                if (!haveDeviceOfType(DEVICE_NETWORK)) {
-                    class = DEVICE_NETWORK;
-                    step = STEP_DRIVER;
-                    break;
-                }
-                logMessage(INFO, "need to set up networking");
-
-                memset(&iface, 0, sizeof(iface));
-
-                /* fall through to interface selection */
-            }
-
-            case STEP_IFACE: {
-                logMessage(INFO, "going to pick interface");
-
-                /* skip configureTCPIP() screen for kickstart (#260621) */
-                if (loaderData->ksFile)
-                    flags |= LOADER_FLAGS_IS_KICKSTART;
-
-                if (FL_HAVE_CMSCONF(flags)) {
-                    loaderData->ipinfo_set = 1;
-#ifdef ENABLE_IPV6
-                    loaderData->ipv6info_set = 1;
-#endif
-                }
-
-                rc = chooseNetworkInterface(loaderData);
-                if ((rc == LOADER_BACK) || (rc == LOADER_ERROR) ||
-                    ((dir == -1) && (rc == LOADER_NOOP))) {
-                    /* don't skip method dialog iff we don't have url from ks or boot params */
-                    if (!loaderData->stage2Data) {
-                        loaderData->method = -1;
-                    }
-                    step = STEP_METHOD;
-                    dir = -1;
-                    break;
-                }
-
-                devName = loaderData->netDev;
-                strcpy(iface.device, devName);
-
-                /* continue to ip config */
-                step = STEP_IP;
-                dir = 1;
-                break;
-            }
-
-            case STEP_IP: {
-                if (!needsNetwork || dir == -1) {
-                    step = STEP_METHOD; /* only hit going back */
-                    break;
-                }
-
-                if ((ret = malloc(INET6_ADDRSTRLEN+1)) == NULL) {
-                    logMessage(ERROR, "malloc failure for ret in STEP_IP");
-                    doExit(EXIT_FAILURE);
-                }
-
-                logMessage(INFO, "going to do getNetConfig");
-
-                /* s390 provides all config info by way of the CMS conf file */
-                if (FL_HAVE_CMSCONF(flags)) {
-                    loaderData->ipinfo_set = 1;
-#ifdef ENABLE_IPV6
-                    loaderData->ipv6info_set = 1;
-#endif
-                }
-
-                /* populate netDev based on any kickstart data */
-                setupIfaceStruct(&iface, loaderData);
-                rc = readNetConfig(devName, &iface, loaderData->netCls, loaderData->method);
-
-                /* set the hostname if we have that */
-                if (loaderData->hostname) {
-                    if (sethostname(loaderData->hostname,
-                                    strlen(loaderData->hostname))) {
-                        logMessage(ERROR, "error setting hostname to %s",
-                                   loaderData->hostname);
-                    }
-                }
-
-                free(ret);
-                ret = NULL;
-
-                if ((rc == LOADER_BACK) ||
-                    ((dir == -1) && (rc == LOADER_NOOP))) {
-                    needsNetwork = 1;
-                    step = STEP_IFACE;
-                    dir = -1;
-                    break;
-                }
-                /* retry */
-                if (rc == LOADER_ERROR) {
-                    needsNetwork = 1;
-                    break;
-                }
-
-                writeEnabledNetInfo(&iface);
-                step = STEP_STAGE2;
-                dir = 1;
-                break;
-            }
-
-            case STEP_STAGE2: {
-                if (url) {
-                    logMessage(INFO, "stage2 url is %s", url);
-                    return url;
-                }
-
-                logMessage(INFO, "starting STEP_STAGE2");
-                url = installMethods[validMethods[loaderData->method]].mountImage(
-                                          installMethods + validMethods[loaderData->method],
-                                          "/mnt/stage2", loaderData);
-                if (!url) {
-                    step = STEP_IP;
-                    loaderData->ipinfo_set = 0;
-#ifdef ENABLE_IPV6
-                    loaderData->ipv6info_set = 0;
-#endif
-                    loaderData->method = -1;
-                    skipMethodDialog = 0;
-                    dir = -1;
-                } else {
-                    logMessage(INFO, "got stage2 at url %s", url);
-                    step = STEP_DONE;
-                    dir = 1;
-
-                    if (loaderData->invalidRepoParam) {
-                        char *newInstRepo;
-
-                        /* Doesn't contain /images?  Let's not even try. */
-                        if (strstr(url, "/images") == NULL)
-                            break;
-                        
-                        checked_asprintf(&newInstRepo, "%.*s",
-                                         (int) (strstr(url, "/images")-url), url);
-
-                        free(loaderData->instRepo);
-                        loaderData->instRepo = newInstRepo;
-                        logMessage(INFO, "reset repo= parameter to %s",
-                                   loaderData->instRepo);
-                    }
-                }
-
-                break;
-            }
-
-            case STEP_DONE:
-                break;
-        }
-    }
-
-    return url;
-}
-static int manualDeviceCheck(struct loaderData_s *loaderData) {
-    char ** devices;
-    int i, j, rc, num = 0;
-    unsigned int width = 40;
-    char * buf;
-
-    do {
-        /* FIXME */
-        devices = malloc(1 * sizeof(*devices));
-        j = 0;
-        devices[j] = NULL;
-
-        if (width > 70)
-            width = 70;
-
-        if (j > 0) {
-            buf = _("The following devices have been found on your system.");
-        } else {
-            buf = _("No device drivers have been loaded for your system.  "
-                    "Would you like to load any now?");
-        }
-
-        rc = newtWinMenu(_("Devices"), buf, width, 10, 20, 
-                         (j > 6) ? 6 : j, devices, &num, _("Done"), 
-                         _("Add Device"), NULL);
-
-        /* no leaky */
-        for (i = 0; i < j; i++)
-            free(devices[j]);
-        free(devices);
-
-        if (rc != 2)
-            break;
-
-        chooseManualDriver(DEVICE_ANY, loaderData);
-    } while (1);
-    return 0;
-}
-
-/* JKFIXME: I don't really like this, but at least it isolates the ifdefs */
-/* Either move dirname to %s_old or unlink depending on arch (unlink on all
- * !s390{,x} arches).  symlink to /mnt/runtime/dirname.  dirname *MUST* start
- * with a '/' */
-static void migrate_runtime_directory(char * dirname) {
-    char * runtimedir;
-    int ret;
-
-    checked_asprintf(&runtimedir, "/mnt/runtime%s", dirname);
-
-    if (!access(runtimedir, X_OK)) {
-        if (unlink(dirname) == -1) {
-            char * olddir;
-            
-            checked_asprintf(&olddir, "%s_old", dirname);
-
-            ret = rename(dirname, olddir);
-            free(olddir);
-        }
-        ret = symlink(runtimedir, dirname);
-    }
-    free(runtimedir);
-}
-
-
-static int hasGraphicalOverride() {
-    int i;
-
-    if (getenv("DISPLAY"))
-        return 1;
-
-    for (i = 0; extraArgs[i] != NULL; i++) {
-        if (!strncasecmp(extraArgs[i], "--vnc", 5))
-            return 1;
-    }
-    return 0;
-}
-
-void loaderSegvHandler(int signum) {
-    void *array[30];
-    size_t i;
-    const char const * const errmsgs[] = {
-        "loader received SIG",
-        "!  Backtrace:\n",
-        "Loader exited unexpectedly!  Backtrace:\n",
-    };
-
-    /* XXX This should really be in a glibc header somewhere... */
-    extern const char *const sys_sigabbrev[NSIG];
-
-    signal(signum, SIG_DFL); /* back to default */
-
-    newtFinished();
-    if (signum == 0) {
-        i = write(STDERR_FILENO, errmsgs[2], strlen(errmsgs[2]));
-    } else {
-        i = write(STDERR_FILENO, errmsgs[0], strlen(errmsgs[0]));
-        i = write(STDERR_FILENO, sys_sigabbrev[signum],
-                strlen(sys_sigabbrev[signum]));
-        i = write(STDERR_FILENO, errmsgs[1], strlen(errmsgs[1]));
-    }
-
-    i = backtrace (array, 30);
-    backtrace_symbols_fd(array, i, STDERR_FILENO);
-    _exit(1);
-}
-
-void loaderExitHandler(void)
-{
-    if (expected_exit)
-        return;
-
-    loaderSegvHandler(0);    
-}
-
-static void setupBacktrace(void)
-{
-    void *array;
-
-    signal(SIGSEGV, loaderSegvHandler);
-    signal(SIGABRT, loaderSegvHandler);
-    atexit(loaderExitHandler);
-
-    /* Turns out, there's an initializer at the top of backtrace() that
-     * (on some arches) calls dlopen(). dlopen(), unsurprisingly, calls
-     * malloc(). So, call backtrace() early in signal handler setup so
-     * we can later safely call it from the signal handler itself. */
-    backtrace(&array, 1);
-}
-
-void loaderUsrXHandler(int signum) {
-    logMessage(INFO, "Remembering signal %d\n", signum);
-    init_sig = signum;
-}
-
-static int anaconda_trace_init(void) {
-#ifdef USE_MTRACE
-    setenv("MALLOC_TRACE","/malloc",1);
-    mtrace();
-#endif
-    /* We have to do this before we init bogl(), which doLoaderMain will do
-     * when setting fonts for different languages.  It's also best if this
-     * is well before we might take a SEGV, so they'll go to tty8 */
-    initializeTtys();
-
-    /* set up signal handler */
-    setupBacktrace();
-
-    return 0;
-}
-
-static void add_to_path_env(const char *env, const char *val)
-{
-    char *oldenv, *newenv;
-
-    oldenv = getenv(env);
-    if (oldenv) {
-        checked_asprintf(&newenv, "%s:%s", val, oldenv);
-
-        oldenv = strdupa(newenv);
-        free(newenv);
-        newenv = oldenv;
-    } else {
-        newenv = strdupa(val);
-    }
-
-    setenv(env, newenv, 1);
-}
-
-static void loadScsiDhModules(void)
-{
-    struct utsname utsname;
-    char *modules = NULL;
-    char *tmp = NULL;
-    struct dirent *ent = NULL;
-
-    uname(&utsname);
-    checked_asprintf(&tmp,
-        "/lib/modules/%s/kernel/drivers/scsi/device_handler", utsname.release);
-
-    DIR *dir = opendir(tmp);
-    free(tmp);
-    if (!dir)
-        return;
-
-    int fd = dirfd(dir);
-    while ((ent = readdir(dir)) != NULL) {
-        struct stat sb;
-
-        if (fstatat(fd, ent->d_name, &sb, 0) < 0)
-            continue;
-
-        size_t len = strlen(ent->d_name) - 3;
-        if (strcmp(ent->d_name+len, ".ko"))
-            continue;
-
-        if (S_ISREG(sb.st_mode)) {
-            char modname[len+1];
-            strncpy(modname, ent->d_name, len);
-	    modname[len] = '\0';
-
-            if (modules && modules[0]) {
-                checked_asprintf(&tmp, "%s:%s", modules, modname);
-            } else {
-                checked_asprintf(&tmp, "%s", modname);
-            }
-
-            free(modules);
-            modules = tmp;
-        }
-    }
-    closedir(dir);
-
-    mlLoadModuleSet(modules);
-    free(modules);
-}
-
-int main(int argc, char ** argv) {
-    int rc, ret, pid, status;
-
-    struct stat sb;
-    struct serial_struct si;
-    char * arg;
-    FILE *f;
-
-    char twelve = 12;
-
-    moduleInfoSet modInfo;
-    iface_t iface;
-
-    char *url = NULL;
-
-    char ** argptr, ** tmparg;
-    char * anacondaArgs[50];
-
-    struct loaderData_s loaderData;
-
-    char *path, *fmt;
-    GSList *dd, *dditer;
-    GTree *moduleState;
-
-    gchar *cmdLine = NULL, *ksFile = NULL, *virtpcon = NULL;
-    gboolean mediacheck = FALSE;
-    gchar **remaining = NULL;
-    GOptionContext *optCon = g_option_context_new(NULL);
-    GError *optErr = NULL;
-    GOptionEntry optionTable[] = {
-        { "cmdline", 0, 0, G_OPTION_ARG_STRING, &cmdLine, NULL, NULL },
-        { "ksfile", 0, 0, G_OPTION_ARG_STRING, &ksFile, NULL, NULL },
-        { "mediacheck", 0, 0, G_OPTION_ARG_NONE, &mediacheck, NULL, NULL },
-        { "virtpconsole", 0, 0, G_OPTION_ARG_STRING, &virtpcon, NULL, NULL },
-        { G_OPTION_REMAINING, 0, 0, G_OPTION_ARG_STRING_ARRAY, &remaining,
-          NULL, NULL },
-        { NULL },
-    };
-
-    /* get init PID if we have it */
-    if ((f = fopen("/var/run/init.pid", "r")) != NULL) {
-        char linebuf[256];
-
-        while (fgets(linebuf, sizeof(linebuf), f) != NULL) {
-            errno = 0;
-            init_pid = strtol(linebuf, NULL, 10);
-            if (errno == EINVAL || errno == ERANGE) {
-                logMessage(ERROR, "%s (%d): %m", __func__, __LINE__);
-                init_pid = 1;
-            }
-        }
-
-        fclose(f);
-    }
-
-    signal(SIGUSR1, loaderUsrXHandler);
-    signal(SIGUSR2, loaderUsrXHandler);
-
-    /* Make sure sort order is right. */
-    setenv ("LC_COLLATE", "C", 1);	
-
-    /* Very first thing, set up tracebacks and debug features. */
-    rc = anaconda_trace_init();
-
-    /* now we parse command line options */
-    g_option_context_set_help_enabled(optCon, FALSE);
-    g_option_context_add_main_entries(optCon, optionTable, NULL);
-
-    if (!g_option_context_parse(optCon, &argc, &argv, &optErr)) {
-        fprintf(stderr, "bad option: %s\n", optErr->message);
-        g_error_free(optErr);
-        g_option_context_free(optCon);
-        doExit(1);
-    }
-
-    g_option_context_free(optCon);
-
-    if (remaining) {
-        fprintf(stderr, "unexpected argument: %s\n", remaining[0]);
-        g_strfreev(remaining);
-        doExit(1);
-    }
-
-    g_strfreev(remaining);
-
-    if (!access("/var/run/loader.run", R_OK)) {
-        printf(_("loader has already been run.  Starting shell.\n"));
-        execl("/bin/sh", "-/bin/sh", NULL);
-        doExit(0);
-    }
-
-    f = fopen("/var/run/loader.run", "w+");
-    fprintf(f, "%d\n", getpid());
-    fclose(f);
-
-    /* The fstat checks disallows serial console if we're running through
-       a pty. This is handy for Japanese. */
-    fstat(0, &sb);
-    if (major(sb.st_rdev) != 3 && major(sb.st_rdev) != 136 && 
-        (virtpcon == NULL)){
-        if ((ioctl (0, TIOCLINUX, &twelve) < 0) && 
-            (ioctl(0, TIOCGSERIAL, &si) != -1))
-            flags |= LOADER_FLAGS_SERIAL;
-    }
-
-    if (mediacheck) flags |= LOADER_FLAGS_MEDIACHECK;
-    if (ksFile) flags |= LOADER_FLAGS_KICKSTART;
-    if (virtpcon) flags |= LOADER_FLAGS_VIRTPCONSOLE;
-
-    /* uncomment to send mac address in ks=http:/ header by default*/
-    flags |= LOADER_FLAGS_KICKSTART_SEND_MAC;
-
-    /* JKFIXME: I do NOT like this... it also looks kind of bogus */
-#if defined(__s390__) || defined(__s390x__)
-    flags |= LOADER_FLAGS_NOSHELL;
-#endif
-
-    openLog();
-    
-    /* XXX if RHEL, enable the AUTODD feature by default,
-     * but we should come with more general way how to control this */
-    if (!strncmp(getProductName(), "Red Hat", 7)) {
-        flags |= LOADER_FLAGS_AUTOMODDISK;
-    }
-
-    memset(&loaderData, 0, sizeof(loaderData));
-    loaderData.method = -1;
-    loaderData.fw_loader_pid = -1;
-    loaderData.fw_search_pathz_len = -1;
-    loaderData.dhcpTimeout = -1;
-
-    extraArgs[0] = NULL;
-    parseCmdLineFlags(&loaderData, cmdLine);
-
-    logMessage(INFO, "anaconda version %s on %s starting", VERSION, getProductArch());
-
-    if ((FL_SERIAL(flags) || FL_VIRTPCONSOLE(flags)) && 
-        !hasGraphicalOverride()) {
-        logMessage(INFO, "text mode forced due to serial/virtpconsole");
-        flags |= LOADER_FLAGS_TEXT;
-    }
-    set_fw_search_path(&loaderData, "/firmware:/lib/firmware");
-    start_fw_loader(&loaderData);
-
-    arg = "/lib/modules/module-info";
-    modInfo = newModuleInfoSet();
-    if (readModuleInfo(arg, modInfo, NULL, 0)) {
-        fprintf(stderr, "failed to read %s\n", arg);
-        sleep(5);
-        stop_fw_loader(&loaderData);
-        doExit(1);
-    }
-    initializeConsole();
-
-    checkForRam();
-
-    /* iSeries vio console users will be ssh'ing in to the primary
-       partition, so use a terminal type that is appripriate */
-    if (isVioConsole())
-        setenv("TERM", "vt100", 1);
-
-    mlLoadModuleSet("cramfs:squashfs:iscsi_tcp");
-
-    loadScsiDhModules();
-
-#if !defined(__s390__) && !defined(__s390x__)
-    mlLoadModuleSet("floppy:edd:pcspkr:iscsi_ibft");
-#endif
-
-#ifdef ENABLE_IPV6
-    if (!FL_NOIPV6(flags))
-        mlLoadModule("ipv6", NULL);
-#endif
-
-    /* now let's do some initial hardware-type setup */
-#if defined(__powerpc__)
-    mlLoadModule("spufs", NULL);
-#endif
-
-    if (loaderData.lang && (loaderData.lang_set == 1)) {
-        setLanguage(loaderData.lang, 1);
-    }
-
-    /* FIXME: this is a bit of a hack */
-    loaderData.modInfo = modInfo;
-
-    /* If there is /.rundepmod file present, rerun depmod */
-    if (!access("/.rundepmod", R_OK)){
-        if (system("depmod -a")) {
-            /* this is not really fatal error, it might still work, log it */
-            logMessage(ERROR, "Error running depmod -a for initrd overlay");
-        }
-    }
-
-    /* this allows us to do an early load of modules specified on the
-     * command line to allow automating the load order of modules so that
-     * eg, certain scsi controllers are definitely first.
-     * FIXME: this syntax is likely to change in a future release
-     *        but is done as a quick hack for the present.
-     */
-    if (!mlInitModuleConfig()) {
-        logMessage(ERROR, "unable to initialize kernel module loading");
-        abort();
-    }
-
-    earlyModuleLoad(0);
-
-    /* Save list of preloaded modules so we can restore the state */
-    moduleState = mlSaveModuleState();
-
-    /* Load all known devices */
-    busProbe(FL_NOPROBE(flags));
-
-    if (FL_AUTOMODDISK(flags)) {
-        /* Load all autodetected DDs */
-        logMessage(INFO, "Trying to detect vendor driver discs");
-        dd = findDriverDiskByLabel();
-        dditer = dd;
-        while(dditer) {
-            /* load the DD */
-            if (loadDriverDiskFromPartition(&loaderData, (char*)(dditer->data))) {
-                logMessage(ERROR, "Automatic driver disk loader failed for %s.", (char*)(dditer->data));
-            }
-            else {
-                logMessage(INFO, "Automatic driver disk loader succeeded for %s.", (char*)(dditer->data));
-
-                /* Unload all devices and load them again to use the updated modules */
-                mlRestoreModuleState(moduleState);
-                busProbe(0);
-            }
-            
-            /* clean the device record */
-            free((char*)(dditer->data));
-            dditer->data = NULL;
-
-            /* next DD */
-            dditer = g_slist_next(dditer);
-        }
-        g_slist_free(dd);
-    }
-
-    if (FL_MODDISK(flags)) {
-        startNewt();
-        loadDriverDisks(DEVICE_ANY, &loaderData, moduleState);
-    }
-
-    if (!access("/dd.img", R_OK)) {
-        logMessage(INFO, "found /dd.img, loading drivers");
-        getDDFromSource(&loaderData, "path:/dd.img", moduleState);
-    }
-    
-    /* Reset depmod & modprobe to normal mode and get the rest of drivers*/
-    mlFreeModuleState(moduleState);
-    busProbe(FL_NOPROBE(flags));
-
-    /* Disable all network interfaces in NetworkManager by default */
-#if !defined(__s390__) && !defined(__s390x__)
-    int i;
-
-    if ((i = writeDisabledNetInfo()) != 0) {
-        logMessage(ERROR, "writeDisabledNetInfo failure: %d", i);
-    }
-#endif
-
-    /* Start NetworkManager now so it's always available to talk to. */
-    if (iface_start_NetworkManager())
-        logMessage(INFO, "failed to start NetworkManager");
-
-    if (!FL_CMDLINE(flags))
-        startNewt();
-
-    /* can't run gdbserver until after network modules are loaded */
-    doGdbserver(&loaderData);
-
-    /* JKFIXME: we'd really like to do this before the busprobe, but then
-     * we won't have network devices available (and that's the only thing
-     * we support with this right now */
-    if (loaderData.ddsrc != NULL) {
-        getDDFromSource(&loaderData, loaderData.ddsrc, NULL);
-    }
-
-    /* JKFIXME: loaderData->ksFile is set to the arg from the command line,
-     * and then getKickstartFile() changes it and sets FL_KICKSTART.  
-     * kind of weird. */
-    if (loaderData.ksFile || ksFile) {
-        logMessage(INFO, "getting kickstart file");
-
-        if (!ksFile)
-            getKickstartFile(&loaderData);
-        if (FL_KICKSTART(flags) && 
-            (ksReadCommands((ksFile)?ksFile:loaderData.ksFile)!=LOADER_ERROR)) {
-            runKickstart(&loaderData);
-        }
-    }
-
-    if (FL_EARLY_NETWORKING(flags)) {
-        kickstartNetworkUp(&loaderData, &iface);
-    }
-
-    if (FL_TELNETD(flags))
-        startTelnetd(&loaderData);
-
-    url = doLoaderMain(&loaderData, modInfo);
-
-    /* unlink dirs and link to the ones in /mnt/runtime */
-    migrate_runtime_directory("/usr");
-    migrate_runtime_directory("/lib");
-    migrate_runtime_directory("/lib64");
-    ret = symlink("/mnt/runtime/etc/selinux", "/etc/selinux");
-    copyDirectory("/mnt/runtime/etc","/etc", NULL, copyErrorFn);
-    copyDirectory("/mnt/runtime/var","/var", NULL, copyErrorFn);
-
-    /* now load SELinux policy before exec'ing anaconda and the shell
-     * (if we're using SELinux) */
-    if (FL_SELINUX(flags)) {
-        if (mount("/selinux", "/selinux", "selinuxfs", 0, NULL)) {
-            logMessage(ERROR, "failed to mount /selinux: %m, disabling SELinux");
-            flags &= ~LOADER_FLAGS_SELINUX;
-        } else {
-            if (loadpolicy() == 0) {
-                setexeccon(ANACONDA_CONTEXT);
-            } else {
-                logMessage(ERROR, "failed to load policy, disabling SELinux");
-                flags &= ~LOADER_FLAGS_SELINUX;
-            }
-        }
-    }
-
-    logMessage(INFO, "getting ready to spawn shell now");
-
-    spawnShell();  /* we can attach gdb now :-) */
-
-    if (FL_NOPROBE(flags) && !loaderData.ksFile) {
-        startNewt();
-        manualDeviceCheck(&loaderData);
-    }
-
-    if (loaderData.updatessrc)
-        loadUpdatesFromRemote(loaderData.updatessrc, &loaderData);
-    else if (FL_UPDATES(flags))
-        loadUpdates(&loaderData);
-
-    /* make sure /tmp/updates exists so that magic in anaconda to */
-    /* symlink rhpl/ will work                                    */
-    if (access("/tmp/updates", F_OK))
-        mkdirChain("/tmp/updates");
-
-    add_fw_search_dir(&loaderData, "/tmp/updates/firmware");
-    add_fw_search_dir(&loaderData, "/tmp/product/firmware");
-
-    add_to_path_env("PYTHONPATH", "/tmp/updates");
-    add_to_path_env("PYTHONPATH", "/tmp/updates/iw");
-    add_to_path_env("PYTHONPATH", "/tmp/updates/textw");
-    add_to_path_env("PYTHONPATH", "/tmp/product");
-    add_to_path_env("LD_LIBRARY_PATH", "/tmp/updates");
-    add_to_path_env("LD_LIBRARY_PATH", "/tmp/product");
-    add_to_path_env("PATH", "/tmp/updates");
-    add_to_path_env("PATH", "/tmp/product");
-
-    stop_fw_loader(&loaderData);
-    start_fw_loader(&loaderData);
-
-    mlLoadModuleSet("raid0:raid1:raid5:raid6:raid456:raid10:linear:dm-mod:dm-zero:dm-mirror:dm-snapshot:dm-multipath:dm-round-robin:dm-crypt:cbc:sha256:lrw:xts");
-
-    if (!access("/mnt/runtime/usr/lib/libunicode-lite.so.1", R_OK))
-        setenv("LD_PRELOAD", "/mnt/runtime/usr/lib/libunicode-lite.so.1", 1);
-    if (!access("/mnt/runtime/usr/lib64/libunicode-lite.so.1", R_OK))
-        setenv("LD_PRELOAD", "/mnt/runtime/usr/lib64/libunicode-lite.so.1", 1);
-
-    argptr = anacondaArgs;
-
-    path = getenv("PATH");
-    while (path && path[0]) {
-        int n = strcspn(path, ":");
-        char c, *binpath;
-
-        c = path[n];
-        path[n] = '\0';
-        checked_asprintf(&binpath, "%s/anaconda", path);
-        path[n] = c;
-
-        if (!access(binpath, X_OK)) {
-            *argptr++ = strdupa(binpath);
-            free(binpath);
-            break;
-        }
-        free(binpath);
-        path += n + 1;
-    }
-
-    logMessage(INFO, "Running anaconda script %s", *(argptr-1));
-
-    *argptr++ = "--stage2";
-    if (strncmp(url, "ftp:", 4)) {
-        *argptr++ = url;
-    } else {
-        int fd, ret;
-
-        fd = open("/tmp/ftp-stage2", O_CREAT | O_TRUNC | O_RDWR, 0600);
-        ret = write(fd, url, strlen(url));
-        ret = write(fd, "\r", 1);
-        close(fd);
-        *argptr++ = "@/tmp/ftp-stage2";
-    }
-
-    /* add extra args - this potentially munges extraArgs */
-    tmparg = extraArgs;
-    while (*tmparg) {
-        char *idx;
-
-        logMessage(DEBUGLVL, "adding extraArg %s", *tmparg);
-        idx = strchr(*tmparg, '=');
-        if (idx &&  ((idx-*tmparg) < strlen(*tmparg))) {
-            *idx = '\0';
-            *argptr++ = *tmparg;
-            *argptr++ = idx+1;
-        } else {
-            *argptr++ = *tmparg;
-        }
-
-        tmparg++;
-    }
-
-    if (FL_AUTOMODDISK(flags))
-        *argptr++ = "--dlabel";
-
-    if (FL_NOIPV4(flags))
-        *argptr++ = "--noipv4";
-
-#ifdef ENABLE_IPV6
-    if (FL_NOIPV6(flags))
-        *argptr++ = "--noipv6";
-#endif
-
-#if defined(__s390__) || defined(__s390x__)
-    *argptr++ = "--headless";
-#endif
-
-    if (FL_KICKSTART(flags)) {
-        *argptr++ = "--kickstart";
-        *argptr++ = loaderData.ksFile;
-    }
-
-    if (FL_SERIAL(flags))
-        *argptr++ = "--serial";
-
-    if (FL_RESCUE(flags)) {
-        *argptr++ = "--rescue";
-    } else {
-        if (FL_TEXT(flags))
-            *argptr++ = "-T";
-        else if (FL_GRAPHICAL(flags))
-            *argptr++ = "--graphical";
-        if (FL_CMDLINE(flags))
-            *argptr++ = "-C";
-        if (!FL_SELINUX(flags))
-            *argptr++ = "--noselinux";
-        else if (FL_SELINUX(flags))
-            *argptr++ = "--selinux";
-
-        if (FL_VIRTPCONSOLE(flags)) {
-            *argptr++ = "--virtpconsole";
-            *argptr++ = virtpcon;
-        }
-
-        if (loaderData.updatessrc && FL_UPDATES(flags)) {
-            *argptr++ = "--updates";
-            *argptr++ = loaderData.updatessrc;
-        }
-
-        if (loaderData.dogtailurl) {
-            *argptr++ = "--dogtail";
-            *argptr++ = loaderData.dogtailurl;
-        }
-
-        if ((loaderData.lang) && !FL_NOPASS(flags)) {
-            *argptr++ = "--lang";
-            *argptr++ = loaderData.lang;
-        }
-
-        if ((loaderData.kbd) && !FL_NOPASS(flags)) {
-            *argptr++ = "--keymap";
-            *argptr++ = loaderData.kbd;
-        }
-
-        if (loaderData.logLevel) {
-            *argptr++ = "--loglevel";
-            *argptr++ = loaderData.logLevel;
-        }
-
-        if (loaderData.instRepo) {
-           *argptr++ = "--repo";
-            if (strncmp(loaderData.instRepo, "ftp:", 4)) {
-                *argptr++ = loaderData.instRepo;
-            } else {
-                int fd, ret;
-
-                fd = open("/tmp/ftp-repo", O_CREAT | O_TRUNC | O_RDWR, 0600);
-                ret = write(fd, loaderData.instRepo, strlen(loaderData.instRepo));
-                ret = write(fd, "\r", 1);
-                close(fd);
-                *argptr++ = "@/tmp/ftp-repo";
-            }
-        }
-
-        if (loaderData.proxy && strcmp("", loaderData.proxy)) {
-            *argptr++ = "--proxy";
-
-            *argptr++ = strdup(loaderData.proxy);
-
-            if (loaderData.proxyUser && strcmp(loaderData.proxyUser, "")) {
-                int fd, ret;
-
-                fd = open("/tmp/proxy", O_CREAT|O_TRUNC|O_RDWR, 0600);
-                ret = write(fd, loaderData.proxyUser, strlen(loaderData.proxyUser));
-                ret = write(fd, "\r\n", 2);
-
-                if (loaderData.proxyPassword && strcmp(loaderData.proxyPassword, "")) {
-                    ret = write(fd, loaderData.proxyPassword, strlen(loaderData.proxyPassword));
-                    ret = write(fd, "\r\n", 2);
-                }
-
-                close(fd);
-
-                *argptr++ = "--proxyAuth";
-                *argptr++ = "/tmp/proxy";
-            }
-        }
-    }
-    
-    *argptr = NULL;
-    
-    stopNewt();
-    closeLog();
-
-    if (FL_RESCUE(flags)) {
-        fmt = _("Running anaconda %s, the %s rescue mode - please wait.\n");
-    } else {
-        fmt = _("Running anaconda %s, the %s system installer - please wait.\n");
-    }
-    printf(fmt, VERSION, getProductName());
-
-    if (!(pid = fork())) {
-        if (execv(anacondaArgs[0], anacondaArgs) == -1) {
-           fprintf(stderr,"exec of anaconda failed: %m\n");
-           doExit(1);
-        }
-    }
-
-    waitpid(pid, &status, 0);
-
-    if (!WIFEXITED(status) || (WIFEXITED(status) && WEXITSTATUS(status))) {
-        rc = 1;
-    } else {
-        rc = 0;
-    }
-
-    if ((rc == 0) && (FL_POWEROFF(flags) || FL_HALT(flags))) {
-        if (!(pid = fork())) {
-            char * cmd = (FL_POWEROFF(flags) ? strdup("/sbin/poweroff") :
-                          strdup("/sbin/halt"));
-            if (execl(cmd, cmd, NULL) == -1) {
-                fprintf(stderr, "exec of poweroff failed: %m\n");
-                doExit(1);
-            }
-        }
-        waitpid(pid, &status, 0);
-    }
-
-    stop_fw_loader(&loaderData);
-#if defined(__s390__) || defined(__s390x__)
-    /* at the latest possibility signal init=linuxrc.s390 to reboot/halt */
-    logMessage(INFO, "Sending signal %d to process %d\n",
-               init_sig, init_pid);
-    kill(init_pid, init_sig);
-#endif
-    doExit(rc);
-
-    doExit(1);
-}
-
-/* vim:set sw=4 sts=4 et: */
diff --git a/loader/loader.h b/loader/loader.h
deleted file mode 100644
index c64c475..0000000
--- a/loader/loader.h
+++ /dev/null
@@ -1,193 +0,0 @@
-/*
- * loader.h
- *
- * Copyright (C) 2007  Red Hat, Inc.  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 as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * 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, see <http://www.gnu.org/licenses/>.
- */
-
-#include <stdint.h>
-
-#ifndef LOADER_H
-#define LOADER_H
-
-#define LOADER_OK 0
-#define LOADER_BACK 1
-#define LOADER_NOOP 2
-#define LOADER_ERROR -1
-
-/* #0 unused */
-/* #1 unused */
-#define LOADER_FLAGS_TEXT               (((uint64_t) 1) << 2)
-#define LOADER_FLAGS_RESCUE             (((uint64_t) 1) << 3)
-#define LOADER_FLAGS_KICKSTART          (((uint64_t) 1) << 4)
-#define LOADER_FLAGS_KICKSTART_SEND_MAC (((uint64_t) 1) << 5)
-#define LOADER_FLAGS_POWEROFF           (((uint64_t) 1) << 6)
-#define LOADER_FLAGS_NOPROBE              (((uint64_t) 1) << 7)
-#define LOADER_FLAGS_MODDISK            (((uint64_t) 1) << 8)
-#define LOADER_FLAGS_EARLY_NETWORKING   (((uint64_t) 1) << 9)
-#define LOADER_FLAGS_SERIAL             (((uint64_t) 1) << 10)
-#define LOADER_FLAGS_UPDATES            (((uint64_t) 1) << 11)
-#define LOADER_FLAGS_KSFILE             (((uint64_t) 1) << 12)
-#define LOADER_FLAGS_HALT               (((uint64_t) 1) << 13)
-#define LOADER_FLAGS_SELINUX            (((uint64_t) 1) << 14)
-#define LOADER_FLAGS_VIRTPCONSOLE       (((uint64_t) 1) << 15)
-/* #16 unused */
-#define LOADER_FLAGS_NOSHELL            (((uint64_t) 1) << 17)
-/* #18 unused */
-#define LOADER_FLAGS_TELNETD            (((uint64_t) 1) << 19)
-#define LOADER_FLAGS_NOPASS             (((uint64_t) 1) << 20)
-/* #21 unused */
-#define LOADER_FLAGS_MEDIACHECK         (((uint64_t) 1) << 22)
-/* #23 unused */
-#define LOADER_FLAGS_ASKMETHOD          (((uint64_t) 1) << 24)
-#define LOADER_FLAGS_ASKNETWORK         (((uint64_t) 1) << 25)
-/* #26 unused */
-/* #27 unused */
-#define LOADER_FLAGS_CMDLINE            (((uint64_t) 1) << 28)
-#define LOADER_FLAGS_GRAPHICAL          (((uint64_t) 1) << 29)
-#define LOADER_FLAGS_NOIPV4             (((uint64_t) 1) << 31)
-#ifdef ENABLE_IPV6
-#define LOADER_FLAGS_NOIPV6             (((uint64_t) 1) << 32)
-#endif
-#define LOADER_FLAGS_IP_PARAM           (((uint64_t) 1) << 33)
-#ifdef ENABLE_IPV6
-#define LOADER_FLAGS_IPV6_PARAM         (((uint64_t) 1) << 34)
-#endif
-#define LOADER_FLAGS_IS_KICKSTART       (((uint64_t) 1) << 35)
-#define LOADER_FLAGS_ALLOW_WIRELESS     (((uint64_t) 1) << 36)
-#define LOADER_FLAGS_HAVE_CMSCONF       (((uint64_t) 1) << 37)
-#define LOADER_FLAGS_NOKILL		(((uint64_t) 1) << 38)
-#define LOADER_FLAGS_KICKSTART_SEND_SERIAL   (((uint64_t) 1) << 39)
-#define LOADER_FLAGS_AUTOMODDISK        (((uint64_t) 1) << 40)
-
-#define FL_TEXT(a)               ((a) & LOADER_FLAGS_TEXT)
-#define FL_RESCUE(a)             ((a) & LOADER_FLAGS_RESCUE)
-#define FL_KICKSTART(a)          ((a) & LOADER_FLAGS_KICKSTART)
-#define FL_KICKSTART_SEND_MAC(a) ((a) & LOADER_FLAGS_KICKSTART_SEND_MAC)
-#define FL_POWEROFF(a)           ((a) & LOADER_FLAGS_POWEROFF)
-#define FL_NOPROBE(a)            ((a) & LOADER_FLAGS_NOPROBE)
-#define FL_MODDISK(a)            ((a) & LOADER_FLAGS_MODDISK)
-#define FL_EARLY_NETWORKING(a)   ((a) & LOADER_FLAGS_EARLY_NETWORKING)
-#define FL_SERIAL(a)             ((a) & LOADER_FLAGS_SERIAL)
-#define FL_UPDATES(a)            ((a) & LOADER_FLAGS_UPDATES)
-#define FL_KSFILE(a)             ((a) & LOADER_FLAGS_KSFILE)
-#define FL_NOSHELL(a)            ((a) & LOADER_FLAGS_NOSHELL)
-#define FL_TELNETD(a)            ((a) & LOADER_FLAGS_TELNETD)
-#define FL_NOPASS(a)             ((a) & LOADER_FLAGS_NOPASS)
-#define FL_MEDIACHECK(a)         ((a) & LOADER_FLAGS_MEDIACHECK)
-#define FL_ASKMETHOD(a)          ((a) & LOADER_FLAGS_ASKMETHOD)
-#define FL_GRAPHICAL(a)          ((a) & LOADER_FLAGS_GRAPHICAL)
-#define FL_CMDLINE(a)            ((a) & LOADER_FLAGS_CMDLINE)
-#define FL_HALT(a)               ((a) & LOADER_FLAGS_HALT)
-#define FL_SELINUX(a)            ((a) & LOADER_FLAGS_SELINUX)
-#define FL_VIRTPCONSOLE(a)       ((a) & LOADER_FLAGS_VIRTPCONSOLE)
-#define FL_ASKNETWORK(a)         ((a) & LOADER_FLAGS_ASKNETWORK)
-#define FL_NOIPV4(a)             ((a) & LOADER_FLAGS_NOIPV4)
-#ifdef ENABLE_IPV6
-#define FL_NOIPV6(a)             ((a) & LOADER_FLAGS_NOIPV6)
-#endif
-#define FL_IP_PARAM(a)           ((a) & LOADER_FLAGS_IP_PARAM)
-#ifdef ENABLE_IPV6
-#define FL_IPV6_PARAM(a)         ((a) & LOADER_FLAGS_IPV6_PARAM)
-#endif
-#define FL_IS_KICKSTART(a)       ((a) & LOADER_FLAGS_IS_KICKSTART)
-#define FL_ALLOW_WIRELESS(a)     ((a) & LOADER_FLAGS_ALLOW_WIRELESS)
-#define FL_HAVE_CMSCONF(a)       ((a) & LOADER_FLAGS_HAVE_CMSCONF)
-#define FL_NOKILL(a)		 ((a) & LOADER_FLAGS_NOKILL)
-#define FL_KICKSTART_SEND_SERIAL(a) ((a) & LOADER_FLAGS_KICKSTART_SEND_SERIAL)
-#define FL_AUTOMODDISK(a)        ((a) & LOADER_FLAGS_AUTOMODDISK)
-
-void doExit(int) __attribute__ ((noreturn));
-void startNewt(void);
-void stopNewt(void);
-char * getProductName(void);
-char * getProductPath(void);
-char * getProductArch(void);
-
-#include "moduleinfo.h"
-#include "../isys/devices.h"
-/* JKFIXME: I don't like all of the _set attribs, but without them,
- * we can't tell if it was explicitly set by kickstart/cmdline or 
- * if we just got it going through the install.   */
-struct loaderData_s {
-    char * lang;
-    int lang_set;
-    char * kbd;
-    int kbd_set;
-    char * netDev;
-    int netDev_set;
-    char * bootIf;
-    int bootIf_set;
-    char * netCls;
-    int netCls_set;
-    char *ipv4, *netmask, *gateway, *dns, *hostname, *peerid, *ethtool, *subchannels, *portname, *essid, *wepkey, *nettype, *ctcprot, *layer2, *portno, *macaddr;
-#ifdef ENABLE_IPV6
-    char *ipv6;
-    int ipv6info_set;
-    char *gateway6;
-#endif
-    int mtu;
-    int noDns;
-    int dhcpTimeout;
-    int ipinfo_set;
-    char * ksFile;
-    int method;
-    char * ddsrc;
-    void * stage2Data;
-    char * logLevel;
-    char * updatessrc;
-    char * dogtailurl;
-    char * gdbServer;
-    char * instRepo;
-
-    pid_t fw_loader_pid;
-    char *fw_search_pathz;
-    size_t fw_search_pathz_len;
-
-    moduleInfoSet modInfo;
-
-    int inferredStage2, invalidRepoParam;
-
-    /* Proxy info needs to be in the loaderData so we can get these
-     * settings off the command line, too.
-     */
-    char *proxy;
-    char *proxyUser;
-    char *proxyPassword;
-};
-
-/* 64 bit platforms, definitions courtesy of glib */
-#if defined (__x86_64__) || defined(__ia64__) || defined(__alpha__) || defined(__powerpc64__) || defined(__s390x__) || (defined(__sparc__) && defined(__arch64__))
-#define POINTER_TO_INT(p)  ((int) (long) (p))
-#define INT_TO_POINTER(i)  ((void *) (long) (i))
-#else
-#define POINTER_TO_INT(p)  ((int) (p))
-#define INT_TO_POINTER(i)  ((void *) (i))
-#endif
-
-/* library paths */
-#if defined(__x86_64__) || defined(__s390x__) || defined(__powerpc64__)
-#define LIBPATH "/lib64:/usr/lib64:/usr/X11R6/lib64:/usr/kerberos/lib64:/mnt/usr/lib64:/mnt/sysimage/lib64:/mnt/sysimage/usr/lib64"
-#else
-#define LIBPATH "/lib:/usr/lib:/usr/X11R6/lib:/usr/kerberos/lib:/mnt/usr/lib:/mnt/sysimage/lib:/mnt/sysimage/usr/lib"
-#endif
-
-#define checked_asprintf(...)                                       \
-    if (asprintf( __VA_ARGS__ ) == -1) {                            \
-        logMessage(CRITICAL, "%s: %d: %m", __func__, __LINE__);     \
-        abort();                                                    \
-    }
-
-#endif
diff --git a/loader/loadermisc.c b/loader/loadermisc.c
deleted file mode 100644
index 64e80a2..0000000
--- a/loader/loadermisc.c
+++ /dev/null
@@ -1,150 +0,0 @@
-/*
- * loadermisc.c - miscellaneous loader functions that don't seem to fit
- * anywhere else (yet)  (was misc.c)
- * JKFIXME: need to break out into reasonable files based on function
- *
- * Copyright (C) 1999, 2000, 2001, 2002  Red Hat, Inc.  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 as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * 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, see <http://www.gnu.org/licenses/>.
- *
- * Author(s): Erik Troan <ewt@xxxxxxxxxx>
- *            Matt Wilson <msw@xxxxxxxxxx>
- *            Michael Fulbright <msf@xxxxxxxxxx>
- *            Jeremy Katz <katzj@xxxxxxxxxx>
- */
-
-#include <ctype.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <string.h>
-#include <unistd.h>
-#include <stdarg.h>
-#include <stdlib.h>
-
-#include "../isys/log.h"
-
-#include "windows.h"
-
-int copyFileFd(int infd, char * dest, progressCB pbcb,
-               struct progressCBdata *data, long long total) {
-    int outfd;
-    char buf[4096];
-    int i;
-    int rc = 0;
-    long long count = 0;
-
-    outfd = open(dest, O_CREAT | O_RDWR, 0666);
-
-    if (outfd < 0) {
-        logMessage(ERROR, "failed to open %s: %m", dest);
-        return 1;
-    }
-
-    while ((i = read(infd, buf, sizeof(buf))) > 0) {
-        if (write(outfd, buf, i) != i) {
-            rc = 1;
-            break;
-        }
-
-        count += i;
-
-        if (pbcb && data && total) {
-            pbcb(data, count, total);
-        }
-    }
-
-    close(outfd);
-
-    return rc;
-}
-
-int copyFile(char * source, char * dest) {
-    int infd = -1;
-    int rc;
-
-    infd = open(source, O_RDONLY);
-
-    if (infd < 0) {
-        logMessage(ERROR, "failed to open %s: %m", source);
-        return 1;
-    }
-
-    rc = copyFileFd(infd, dest, NULL, NULL, 0);
-
-    close(infd);
-
-    return rc;
-}
-
-int simpleStringCmp(const void * a, const void * b) {
-    const char * first = *((const char **) a);
-    const char * second = *((const char **) b);
-
-    return strverscmp(first, second);
-}
-
-/* look for available memory.  note: won't ever report more than the 
- * 900 megs or so supported by the -BOOT kernel due to not using e820 */
-int totalMemory(void) {
-    int fd;
-    int bytesRead;
-    char buf[4096];
-    char * chptr, * start;
-    int total = 0;
-
-    fd = open("/proc/meminfo", O_RDONLY);
-    if (fd < 0) {
-        logMessage(ERROR, "failed to open /proc/meminfo: %m");
-        return 0;
-    }
-
-    bytesRead = read(fd, buf, sizeof(buf) - 1);
-    if (bytesRead < 0) {
-        logMessage(ERROR, "failed to read from /proc/meminfo: %m");
-        close(fd);
-        return 0;
-    }
-
-    close(fd);
-    buf[bytesRead] = '\0';
-
-    chptr = buf;
-    while (*chptr && !total) {
-        if (strncmp(chptr, "MemTotal:", 9)) {
-            chptr++;
-            continue;
-        }
-
-        start = ++chptr ;
-        while (*chptr && *chptr != '\n') chptr++;
-
-        *chptr = '\0';
-
-        while (!isdigit(*start) && *start) start++;
-        if (!*start) {
-            logMessage(WARNING, "no number appears after MemTotal tag");
-            return 0;
-        }
-
-        chptr = start;
-        while (*chptr && isdigit(*chptr)) {
-            total = (total * 10) + (*chptr - '0');
-            chptr++;
-        }
-    }
-
-    logMessage(INFO, "%d kB are available", total);
-
-    return total;
-}
diff --git a/loader/loadermisc.h b/loader/loadermisc.h
deleted file mode 100644
index 23ebf4a..0000000
--- a/loader/loadermisc.h
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * loadermisc.h
- *
- * Copyright (C) 2007  Red Hat, Inc.  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 as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * 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, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef H_LOADER_MISC_H
-#define H_LOADER_MISC_H
-#include <stdio.h>
-#include <stdarg.h>
-
-#include "windows.h"
-
-int copyFile(char * source, char * dest);
-int copyFileFd(int infd, char * dest, progressCB pbcb,
-               struct progressCBdata *data, long long total);
-int simpleStringCmp(const void * a, const void * b);
-int totalMemory(void);
-
-#endif
diff --git a/loader/mediacheck.c b/loader/mediacheck.c
deleted file mode 100644
index 4bec1c8..0000000
--- a/loader/mediacheck.c
+++ /dev/null
@@ -1,115 +0,0 @@
-/*
- * simple program to check implanted md5sum in an iso 9660 image
- *
- * Copyright (C) 2001, 2005  Red Hat, Inc.  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 as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * 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, see <http://www.gnu.org/licenses/>.
- *
- * Author(s): Michael Fulbright <msf@xxxxxxxxxx>
- *            Dustin Kirkland <dustin.kirkland@xxxxxxxxx>
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <string.h>
-#include <newt.h>
-#include <libcheckisomd5.h>
-
-#include "../isys/log.h"
-
-#include "lang.h"
-#include "windows.h"
-
-int doMediaCheck(char *file, char *descr) {
-    struct progressCBdata data;
-    newtComponent t, f, scale, label;
-    int rc;
-    int dlen;
-    int llen;
-    char tmpstr[1024];
-
-    if (access(file, R_OK) < 0) {
-	newtWinMessage(_("Error"), _("OK"), _("Unable to find install image "
-					      "%s"), file);
-	return -1;
-    }
-
-    if (descr)
-	snprintf(tmpstr, sizeof(tmpstr), _("Checking \"%s\"."), descr);
-    else
-	snprintf(tmpstr, sizeof(tmpstr), _("Checking media."));
-
-    dlen = strlen(tmpstr);
-    if (dlen > 65)
-	dlen = 65;
-
-    newtCenteredWindow(dlen+8, 6, _("Media Check"));
-    t = newtTextbox(1, 1, dlen+4, 3, NEWT_TEXTBOX_WRAP);
-
-    newtTextboxSetText(t, tmpstr);
-    llen = strlen(tmpstr);
-
-    label = newtLabel(llen+1, 1, "-");
-    f = newtForm(NULL, NULL, 0);
-    newtFormAddComponent(f, t);
-    scale = newtScale(3, 3, dlen, 100);
-    newtFormAddComponent(f, scale);
-
-    newtDrawForm(f);
-    newtRefresh();
-
-    data.scale = scale;
-    data.label = label;
-
-    rc = mediaCheckFile(file, progressCallback, &data);
-
-    newtFormDestroy(f);
-    newtPopWindow();
-
-    if (rc == ISOMD5SUM_CHECK_NOT_FOUND) {
-	logMessage(WARNING, "mediacheck: %s (%s) has no checksum info", file, descr);
-	newtWinMessage(_("Error"), _("OK"),
-		       _("Unable to find the checksum in the "
-			 "image.  This probably "
-			 "means the disc was created without adding the "
-			 "checksum."));
-    } else if (rc == ISOMD5SUM_FILE_NOT_FOUND) {
-        logMessage(WARNING, "mediacheck: %s (%s) open failed", file, descr);
-        newtWinMessage(_("Error"), _("OK"),
-                       _("Unable to open the image."));
-    } else if (rc == ISOMD5SUM_CHECK_FAILED) {
-        logMessage(ERROR, "mediacheck: %s (%s) FAILED", file, descr);
-        newtWinMessage(_("Error"), _("OK"),
-                       _("The image which was just tested has errors. "
-                         "This could be due to a "
-                         "corrupt download or a bad disc.  "
-                         "If applicable, please clean the disc "
-                         "and try again.  If this test continues to fail you "
-                         "should not continue the install."));
-    } else if (rc == ISOMD5SUM_CHECK_PASSED) {
-        logMessage(INFO, "mediacheck: %s (%s) PASSED", file, descr);
-        newtWinMessage(_("Success"), _("OK"),
-                       _("The image which was just tested was successfully "
-                         "verified.  It should be OK to install from this "
-                         "media.  Note that not all media/drive errors can "
-                         "be detected by the media check."));
-    }
-
-
-    return rc;
-}
diff --git a/loader/mediacheck.h b/loader/mediacheck.h
deleted file mode 100644
index ab2f887..0000000
--- a/loader/mediacheck.h
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * mediacheck.h
- *
- * Copyright (C) 2007  Red Hat, Inc.  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 as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * 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, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef MEDIACHECK_H
-#define MEDIACHECK_H
-
-int doMediaCheck(char *file, char *descr);
-
-#endif
diff --git a/loader/method.c b/loader/method.c
deleted file mode 100644
index 3ca669f..0000000
--- a/loader/method.c
+++ /dev/null
@@ -1,570 +0,0 @@
-/*
- * method.c - generic install method setup functions
- *
- * Copyright (C) 2002  Red Hat, Inc.  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 as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * 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, see <http://www.gnu.org/licenses/>.
- *
- * Author(s): Erik Troan <ewt@xxxxxxxxxx>
- *            Matt Wilson <msw@xxxxxxxxxx>
- *            Michael Fulbright <msf@xxxxxxxxxx>
- *            Jeremy Katz <katzj@xxxxxxxxxx>
- */
-
-#include <ctype.h>
-#include <dirent.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <inttypes.h>
-#include <libgen.h>
-#include <newt.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/ioctl.h>
-#include <sys/mount.h>
-#include <sys/stat.h>
-#include <sys/types.h>
-#include <unistd.h>
-#include <libgen.h>
-
-#include "copy.h"
-#include "loader.h"
-#include "loadermisc.h"
-#include "lang.h"
-#include "mediacheck.h"
-#include "method.h"
-
-#include "../isys/imount.h"
-#include "../isys/isys.h"
-#include "../isys/cpio.h"
-#include "../isys/log.h"
-
-#include "devt.h"
-
-#include "nfsinstall.h"
-#include "hdinstall.h"
-#include "urlinstall.h"
-
-/* boot flags */
-extern uint64_t flags;
-
-static void stripTrailingSlash(char *path) {
-    size_t len = strlen(path);
-
-    if (len == 0)
-        return;
-    if (path[len-1] == '/')
-        path[len-1] = '\0';
-}
-
-int umountLoopback(char * mntpoint, char * device) {
-    int loopfd;
-
-    umount(mntpoint);
-
-    logMessage(INFO, "umounting loopback %s %s", mntpoint, device);
-
-    loopfd = open(device, O_RDONLY);
-
-    if (ioctl(loopfd, LOOP_CLR_FD, 0) == -1)
-        logMessage(ERROR, "LOOP_CLR_FD failed for %s %s: %m", mntpoint, device);
-
-    close(loopfd);
-
-    return 0;
-}
-
-int mountLoopback(char *fsystem, char *mntpoint, char *device) {
-    char *opts, *err = NULL;
-
-    if (device == NULL) {
-        logMessage(ERROR, "no loopback device given");
-        return LOADER_ERROR;
-    }
-
-    if (access(fsystem, F_OK) != 0) {
-       logMessage(ERROR, "file %s is not accessible", fsystem);
-       return LOADER_ERROR;
-    }
-
-    checked_asprintf(&opts, "ro,loop=%s", device);
-
-    if (doPwMount(fsystem, mntpoint, "auto", opts, &err)) {
-        logMessage(ERROR, "failed to mount loopback device %s on %s as %s: %s",
-                   device, mntpoint, fsystem, err);
-        return LOADER_ERROR;
-    }
-
-    logMessage(INFO, "mounted loopback device %s on %s as %s", mntpoint, device, fsystem);
-
-    return 0;
-}
-
-/* returns the *absolute* path (malloced) to the #1 iso image */
-/* get timestamp and description of ISO image from stamp file */
-/* returns 0 on success, -1 otherwise                         */
-int readStampFileFromIso(char *file, char **timestamp, char **releasedescr) {
-    DIR * dir;
-    FILE *f;
-    struct dirent * ent;
-    struct stat sb;
-    char *stampfile;
-    char *descr, *tstamp;
-    char tmpstr[1024];
-    int  filetype;
-    int  rc;
-
-    lstat(file, &sb);
-    if (S_ISBLK(sb.st_mode)) {
-	filetype = 1;
-	if (doPwMount(file, "/tmp/testmnt", "iso9660", "ro", NULL)) {
-	    logMessage(ERROR, "Failed to mount device %s to get description",
-                       file);
-	    return -1;
-	}
-    } else if (S_ISREG(sb.st_mode)) {
-	filetype = 2;
-	if (mountLoopback(file, "/tmp/testmnt", "/dev/loop6")) {
-	    logMessage(ERROR, "Failed to mount iso %s to get description",
-                       file);
-	    return -1;
-	}
-    } else {
-	    logMessage(ERROR, "Unknown type of file %s to get description",
-                       file);
-	    return -1;
-    }
-
-    if (!(dir = opendir("/tmp/testmnt"))) {
-	umount("/tmp/testmnt");
-	if (filetype == 2)
-	    umountLoopback("/tmp/testmnt", "/dev/loop6");
-	return -1;
-    }
-
-    errno = 0;
-    stampfile = NULL;
-    while ((ent = readdir(dir))) {
-	if (!strncmp(ent->d_name, ".discinfo", 9)) {
-	    stampfile = strdup(".discinfo");
-	    break;
-	}
-    }
-
-    closedir(dir);
-    descr = NULL;
-    tstamp = NULL;
-    if (stampfile) {
-	snprintf(tmpstr, sizeof(tmpstr), "/tmp/testmnt/%s", stampfile);
-	f = fopen(tmpstr, "r");
-	if (f) {
-	    char *tmpptr;
-
-	    /* readtime stamp line */
-	    tmpptr = fgets(tmpstr, sizeof(tmpstr), f);
-	    
-	    if (tmpptr)
-		tstamp = strdup(tmpstr);
-
-	    /* now read OS description line */
-	    if (tmpptr)
-		tmpptr = fgets(tmpstr, sizeof(tmpstr), f);
-
-	    if (tmpptr)
-		descr = strdup(tmpstr);
-
-	    /* skip over arch */
-	    if (tmpptr)
-		tmpptr = fgets(tmpstr, sizeof(tmpstr), f);
-
-	    /* now get the CD number */
-	    if (tmpptr) {
-		unsigned int len;
-		char *p, *newstr;
-
-		tmpptr = fgets(tmpstr, sizeof(tmpstr), f);
-		
-		/* nuke newline from end of descr, stick number on end*/
-		for (p=descr+strlen(descr); p != descr && !isspace(*p); p--);
-
-		*p = '\0';
-		len = strlen(descr) + strlen(tmpstr) + 10;
-		newstr = malloc(len);
-		strncpy(newstr, descr, len-1);
-		strncat(newstr, " ", len-1);
-
-		/* is this a DVD or not?  If disc id has commas, like */
-		/* "1,2,3", its a DVD                                 */
-		if (strchr(tmpstr, ','))
-		    strncat(newstr, "DVD\n", len-1);
-		else {
-		    strncat(newstr, "disc ", len-1);
-		    strncat(newstr, tmpstr, len-1);
-		}
-
-		free(descr);
-		descr = newstr;
-	    }
-
-	    fclose(f);
-	}
-    }
-
-    free(stampfile);
-
-    umount("/tmp/testmnt");
-    if (filetype == 2)
-	umountLoopback("/tmp/testmnt", "/dev/loop6");
-
-    if (descr != NULL && tstamp != NULL) {
-	descr[strlen(descr)-1] = '\0';
-	*releasedescr = descr;
-
-	tstamp[strlen(tstamp)-1] = '\0';
-	*timestamp = tstamp;
-
-	rc = 0;
-    } else {
-	rc = 1;
-    }	
-
-    return rc;
-}
-
-/* XXX this ignores "location", which should be fixed
- *
- * Given a starting isoFile, will offer choice to mediacheck it and
- * all other ISO images in the same directory with the same stamp
- */
-void queryIsoMediaCheck(char *isoFile) {
-    DIR * dir;
-    struct dirent * ent;
-    char *isoDir;
-    char isoImage[1024];
-    char tmpmessage[1024];
-    char *master_timestamp;
-    char *tmpstr;
-    int rc, first;
-
-    /* dont bother to test in automated installs */
-    if (FL_KICKSTART(flags) && !FL_MEDIACHECK(flags))
-	return;
-
-    /* if they did not specify to mediacheck explicitely then return */
-    if (!FL_MEDIACHECK(flags))
-	return;
-
-    /* check that file is actually an iso */
-    if (!fileIsIso(isoFile))
-	return;
-
-    /* get stamp of isoFile, free descr since we dont care */
-    readStampFileFromIso(isoFile, &master_timestamp, &tmpstr);
-    free(tmpstr);
-    
-    /* get base path from isoFile */
-    tmpstr = strdup(isoFile);
-    isoDir = strdup(dirname(tmpstr));
-    free(tmpstr);
-
-    logMessage(DEBUGLVL, "isoFile = %s", isoFile);
-    logMessage(DEBUGLVL, "isoDir  = %s", isoDir);
-    logMessage(DEBUGLVL, "Master Timestemp = %s", master_timestamp);
-
-    if (!(dir = opendir(isoDir))) {
-	newtWinMessage(_("Error"), _("OK"), 
-		       _("Failed to read directory %s: %m"),
-		       isoDir);
-	free(isoDir);
-	free(master_timestamp);
-	return;
-    }
-
-    /* Walk through the directories looking for a CD images. */
-    errno = 0;
-    first = 0;
-    while (1) {
-	char *nextname;
-	char *tdescr, *tstamp;
-
-	if (first) {
-	    first = 1;
-	    nextname = isoFile;
-	} else {
-	    ent = readdir(dir);
-	    if (!ent)
-		break;
-
-	    nextname = ent->d_name;
-	}
-
-	/* synthesize name of iso from isoDir and file entry */
-	snprintf(isoImage, sizeof(isoImage), "%s/%s", isoDir, nextname);
-
-	/* see if this is an iso image */
-	if (!fileIsIso(isoImage)) {
-	    errno = 0;
-	    continue;
-	}
-
-	/* see if its part of the current CD set */
-	readStampFileFromIso(isoImage, &tstamp, &tdescr);
-	if (strcmp(tstamp, master_timestamp)) {
-	    errno = 0;
-	    continue;
-	}
-	    
-	/* found a valid candidate, proceed */
-	snprintf(tmpmessage, sizeof(tmpmessage),
-		 _("Would you like to perform a checksum "
-		   "test of the ISO image:\n\n   %s?"), isoImage);
-
-	rc = newtWinChoice(_("Checksum Test"), _("Test"), _("Skip"),
-			   tmpmessage);
-
-	if (rc == 2) {
-	    logMessage(INFO, "mediacheck: skipped checking of %s", isoImage);
-	    if (tdescr)
-		free(tdescr);
-	    continue;
-	} else {
-	    doMediaCheck(isoImage, tdescr);
-	    if (tdescr)
-		free(tdescr);
-
-	    continue;
-	}
-    }
-
-    free(isoDir);
-    free(master_timestamp);
-    closedir(dir);
-}
-
-static void copyWarnFn (char *msg) {
-   logMessage(WARNING, msg);
-}
-
-static void copyErrorFn (char *msg) {
-   newtWinMessage(_("Error"), _("OK"), _(msg));
-}
-
-/* 
- * unpack a gzipped cpio ball into a tree rooted at rootDir
- * returns 0 on success, 1 on failure
- */
-int unpackCpioBall(char * ballPath, char * rootDir) {
-    gzFile fd;
-    char *buf, *cwd;
-    int rc = 1;
-
-    if (access(ballPath, R_OK))
-        return 1;
-
-    if (access(rootDir, R_OK))
-        mkdirChain(rootDir);
-
-    buf = (char *)malloc(PATH_MAX);
-    cwd = getcwd(buf, PATH_MAX);
-    if ((rc = chdir(rootDir)) == 0) {
-        fd = gunzip_open(ballPath);
-        if (fd) {
-            if (!installCpioFile(fd, NULL, NULL, 0)) {
-                logMessage(INFO, "copied contents of %s into %s", ballPath,
-                           rootDir);
-                rc = chdir(cwd);
-                return 0;
-            }
-            gunzip_close(fd);
-        }
-        rc = chdir(cwd);
-    }
-
-    return 1;
-}
-
-void copyUpdatesImg(char * path) {
-    if (!access(path, R_OK)) {
-        if (!mountLoopback(path, "/tmp/update-disk", "/dev/loop7")) {
-            copyDirectory("/tmp/update-disk", "/tmp/updates", copyWarnFn,
-                          copyErrorFn);
-            umountLoopback("/tmp/update-disk", "/dev/loop7");
-            unlink("/tmp/update-disk");
-        } else {
-            unpackCpioBall(path, "/tmp/updates");
-        }
-    }
-}
-
-void copyProductImg(char * path) {
-    if (!access(path, R_OK)) {
-        if (!mountLoopback(path, "/tmp/product-disk", "/dev/loop7")) {
-            copyDirectory("/tmp/product-disk", "/tmp/product", copyWarnFn,
-                          copyErrorFn);
-            umountLoopback("/tmp/product-disk", "/dev/loop7");
-            unlink("/tmp/product-disk");
-        }
-    }
-}
-
-/** Bind the uncompressed second stage to /mnt/runtime.
- *
- * return 0 on success, 1 on failure to mount.
- */
-int mountStage2Direct(char *stage2Path) {
-    if (access(stage2Path, R_OK)) {
-        return 1;
-    }
-
-    char *target = "/mnt/runtime";
-    char *error = NULL;
-    if (doBindMount(stage2Path, target, &error)) {
-        logMessage(ERROR, "failed to bind %s to %s: %s",
-                   stage2Path, target, error);
-        free(error);
-        return 1;
-    }
-    logMessage(INFO, "successfully bound %s to %s", stage2Path, target);
-    return 0;
-}
-
-/* mount a second stage, verify the stamp file, copy updates 
- * Returns 0 on success, 1 on failure to mount, -1 on bad stamp */
-int mountStage2(char *stage2path) {
-    if (access(stage2path, R_OK)) {
-        return 1;
-    }
-
-    if (mountLoopback(stage2path, "/mnt/runtime", "/dev/loop0")) {
-        return 1;
-    }
-
-    return 0;
-}
-
-
-/* copies a second stage from fd to dest and mounts on mntpoint */
-int copyFileAndLoopbackMount(int fd, char * dest, char * device, char * mntpoint,
-                             progressCB pbcb, struct progressCBdata *data,
-                             long long total) {
-    int rc;
-    struct stat sb;
-
-    rc = copyFileFd(fd, dest, pbcb, data, total);
-    stat(dest, &sb);
-    logMessage(DEBUGLVL, "copied %" PRId64 " bytes to %s (%s)", sb.st_size, dest, 
-               ((rc) ? " incomplete" : "complete"));
-    
-    if (rc) {
-	/* just to make sure */
-	unlink(dest);
-	return 1;
-    }
-
-    if (mountLoopback(dest, mntpoint, device)) {
-        /* JKFIXME: this used to be fatal, but that seems unfriendly */
-        logMessage(ERROR, "Error mounting %s on %s: %m", device, mntpoint);
-        return 1;
-    }
-
-    return 0;
-}
-
-/* given a device name (w/o '/dev' on it), try to get a file */
-/* Error codes: 
-      1 - could not create device node
-      2 - could not mount device as ext2, vfat, or iso9660
-      3 - file named path not there
-*/
-int getFileFromBlockDevice(char *device, char *path, char * dest) {
-    int rc, i;
-    char file[4096];
-
-    logMessage(INFO, "getFileFromBlockDevice(%s, %s)", device, path);
-
-    /* some USB thumb drives and hard drives are slow to initialize */
-    /* retry up to 5 times or 31 seconds */
-    rc = doPwMount(device, "/tmp/mnt", "auto", "ro", NULL);
-    for (i = 0; mountMightSucceedLater(rc) && i < 5; ++i) {
-        logMessage(INFO, "sleeping to wait for USB storage devices");
-        sleep(1 << i);
-        rc = doPwMount(device, "/tmp/mnt", "auto", "ro", NULL);
-        logMessage(ERROR, "error code: %d", rc);
-    }
-    if (rc) {
-        logMessage(ERROR, "failed to mount /dev/%s: %m", device);
-        return 2;
-    }
-
-    snprintf(file, sizeof(file), "/tmp/mnt/%s", path);
-    logMessage(INFO, "Searching for file on path %s", file);
-    
-    if (access(file, R_OK)) {
-	rc = 3;
-    } else {
-	copyFile(file, dest);
-	rc = 0;
-	logMessage(INFO, "file copied to %s", dest);
-    }    
-
-    umount("/tmp/mnt");
-    unlink("/tmp/mnt");
-    return rc;
-}
-
-void setStage2LocFromCmdline(char * arg, struct loaderData_s * ld) {
-    if (!strncmp(arg, "nfs:", 4)) {
-        ld->method = METHOD_NFS;
-        ld->stage2Data = calloc(sizeof(struct nfsInstallData *), 1);
-
-        parseNfsHostPathOpts(arg + 4,
-          &(((struct nfsInstallData *)ld->stage2Data)->host),
-          &(((struct nfsInstallData *)ld->stage2Data)->directory),
-          &(((struct nfsInstallData *)ld->stage2Data)->mountOpts));
-        stripTrailingSlash(((struct nfsInstallData *)ld->stage2Data)->directory);
-    } else if (!strncmp(arg, "nfsiso:", 7)) {
-        ld->method = METHOD_NFS;
-        ld->stage2Data = calloc(sizeof(struct nfsInstallData *), 1);
-
-        parseNfsHostPathOpts(arg + 7,
-          &(((struct nfsInstallData *)ld->stage2Data)->host),
-          &(((struct nfsInstallData *)ld->stage2Data)->directory),
-          &(((struct nfsInstallData *)ld->stage2Data)->mountOpts));
-    } else if (!strncmp(arg, "ftp:", 4) ||
-               !strncmp(arg, "http", 4)) {
-        ld->method = METHOD_URL;
-        ld->stage2Data = calloc(sizeof(struct urlInstallData *), 1);
-        ((urlInstallData *)ld->stage2Data)->url = strdup(arg);
-    } else if (!strncmp(arg, "cdrom:", 6)) {
-        ld->method = METHOD_CDROM;
-    } else if (!strncmp(arg, "harddrive:", 10) ||
-               !strncmp(arg, "hd:", 3)) {
-        size_t offset;
-
-	arg += strcspn(arg, ":");
-	if (!*arg || !*(arg+1))
-	    return;
-	arg += 1;
-        offset = strcspn(arg, ":");
-
-        ld->method = METHOD_HD;
-        ld->stage2Data = calloc(sizeof(struct hdInstallData *), 1);
-        ((struct hdInstallData *)ld->stage2Data)->partition = strndup(arg, offset);
-	arg += offset;
-	if (*arg && *(arg+1))
-            ((struct hdInstallData *)ld->stage2Data)->directory = strdup(arg+1);
-        else
-            ((struct hdInstallData *)ld->stage2Data)->directory = NULL;
-    }
-}
diff --git a/loader/method.h b/loader/method.h
deleted file mode 100644
index cabd1c2..0000000
--- a/loader/method.h
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * method.h
- *
- * Copyright (C) 2007  Red Hat, Inc.  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 as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * 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, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef H_METHOD
-#define H_METHOD
-
-#include "loader.h"
-#include "windows.h"
-
-/* method identifiers, needs to match struct installMethod order in loader.c */
-enum {
-    METHOD_CDROM,
-    METHOD_HD,
-    METHOD_NFS,
-    METHOD_URL
-};
-
-struct installMethod {
-    char * name;
-    int network;
-    enum deviceType type;
-    char * (*mountImage)(struct installMethod * method,
-                         char * location, struct loaderData_s * loaderData);
-};
-
-int umountLoopback(char * mntpoint, char * device);
-int mountLoopback(char * fsystem, char * mntpoint, char * device);
-
-int readStampFileFromIso(char *file, char **descr, char **timestamp);
-void queryIsoMediaCheck(char * isoDir);
-
-int mountStage2(char *stage2path);
-int mountStage2Direct(char *stage2path);
-int copyFileAndLoopbackMount(int fd, char *dest, char *device, char *mntpoint,
-                             progressCB pbcb, struct progressCBdata *data, long long total);
-int getFileFromBlockDevice(char *device, char *path, char * dest);
-
-int unpackCpioBall(char * ballPath, char * rootDir);
-void copyUpdatesImg(char * path);
-void copyProductImg(char * path);
-
-void setStage2LocFromCmdline(char * arg, struct loaderData_s * ld);
-
-#endif
diff --git a/loader/mkctype.c b/loader/mkctype.c
deleted file mode 100644
index 12eaba0..0000000
--- a/loader/mkctype.c
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * mkctype.c
- *
- * Copyright (C) 2007  Red Hat, Inc.  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 as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * 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, see <http://www.gnu.org/licenses/>.
- */
-
-#include <ctype.h>
-#include <stdio.h>
-
-#if __GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ > 2)
-# define __ctype_b (*__ctype_b_loc())
-# define __ctype_tolower (*__ctype_tolower_loc())
-# define __ctype_toupper (*__ctype_toupper_loc())
-#endif
-
-int main(int argc, char ** argv) {
-    int i;
-
-    printf("#include <sys/types.h>\n\n");
-
-    printf("static const unsigned short int __ctype_b_internal[] = {");
-
-    for (i = -128; i < 256; i++) {
-	if (!(i % 8)) {
-	    printf("\n");
-	}
-
-	printf("\t0x%x,", __ctype_b[i]);
-    }
-
-    printf("\n};\n\n");
-    printf("const unsigned short int * __ctype_b = __ctype_b_internal + 128;\n\n");
-
-    printf("const int __ctype_toupper_internal[] = {");
-    for (i = -128; i < 256; i++) {
-	if (!(i % 8)) {
-	    printf("\n");
-	}
-
-	printf("\t0x%x,", __ctype_toupper[i]);
-    }
-
-    printf("\n};\n\n");
-    printf("const int * __ctype_toupper = __ctype_toupper_internal + 128;\n\n");
-
-    printf("const int __ctype_tolower_internal[] = {");
-    for (i = -128; i < 256; i++) {
-	if (!(i % 8)) {
-	    printf("\n");
-	}
-
-	printf("\t0x%x,", __ctype_tolower[i]);
-    }
-
-    printf("\n};\n\n");
-    printf("const int * __ctype_tolower = __ctype_tolower_internal + 128;\n\n");
-
-    printf ("const unsigned short int **__ctype_b_loc (void) { return &__ctype_b; }\n");
-    printf ("const int **__ctype_toupper_loc (void) { return &__ctype_toupper; }\n");
-    printf ("const int **__ctype_tolower_loc (void) { return &__ctype_tolower; }\n\n");
-
-    return 0;
-};
diff --git a/loader/moduleinfo.c b/loader/moduleinfo.c
deleted file mode 100644
index 2e0ab77..0000000
--- a/loader/moduleinfo.c
+++ /dev/null
@@ -1,276 +0,0 @@
-/*
- * moduleinfo.c - module info functionality
- *
- * Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002  Red Hat, Inc.
- * 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 as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * 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, see <http://www.gnu.org/licenses/>.
- *
- * Author(s): Erik Troan <ewt@xxxxxxxxxx>
- *            Matt Wilson <msw@xxxxxxxxxx>
- */
-
-#include <alloca.h>
-#include <ctype.h>
-#include <fcntl.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/stat.h>
-#include <unistd.h>
-
-#include <stdio.h>
-
-#include "moduleinfo.h"
-
-struct moduleInfo * getModuleList(moduleInfoSet mis, 
-                                  enum driverMajor major) {
-    struct moduleInfo * miList, * next;
-    int i;
-
-    next = miList = malloc(sizeof(*miList) * mis->numModules + 1);
-    for (i = 0; i < mis->numModules; i++) {
-        if (mis->moduleList[i].major == major || major == DRIVER_NONE) {
-            *next = mis->moduleList[i];
-            next++;
-        }
-    }
-
-    if (next == miList) {
-        free(next);
-        return NULL;
-    }
-
-    next->moduleName = NULL;
-    next++;
-
-    miList = realloc(miList, sizeof(*miList) * (next - miList));
-    return miList;
-}
-
-struct moduleInfo * findModuleInfo(moduleInfoSet mis, 
-                                   const char * moduleName) {
-    int i;
-    struct moduleInfo * found = NULL;
-
-    for (i = 0; i < mis->numModules; i++) {
-        if (!strcmp(moduleName, mis->moduleList[i].moduleName)) {
-            if (!found)
-                found = mis->moduleList + i;
-            else if (found->locationID && !mis->moduleList[i].locationID)
-                ;
-            else
-                found = mis->moduleList + i;
-        }
-    }
-
-    return found;
-}
-
-moduleInfoSet newModuleInfoSet(void) {
-    return calloc(sizeof(struct moduleInfoSet_s), 1);
-}
-
-/* filename: file to read module-info from
- * mis: moduleInfoSet
- * location: moduleBallLocation struct describing the location of 
- *           these modules.  (may be NULL)
- * override: 1 if modules from this module ball should override old ones
- *           of the same name.
- */
-int readModuleInfo(const char * filename, moduleInfoSet mis, 
-                   void * location, int override) {
-    int fd, isIndented;
-    char * buf, * start, * next = NULL, * chptr;
-    struct stat sb;
-    char oldch;
-    struct moduleInfo * nextModule;
-    int modulesAlloced;
-    int i;
-    int found = 0, skipModule = 0;
-
-    fd = open(filename, O_RDONLY);
-    if (fd < 0) return -1;
- 
-    fstat(fd, &sb);
-    buf = alloca(sb.st_size + 1);
-    i = read(fd, buf, sb.st_size);
-    buf[sb.st_size] = '\0';
-    close(fd);
-
-    if (i != sb.st_size)
-        return -1;
-
-    nextModule = NULL;
-    modulesAlloced = mis->numModules;
-
-    if (strncmp(buf, "Version 0\n", 10)) return -1;
-
-    start = buf + 10;
-    while (start && *start) {
-        chptr = strchr(start, '\n');
-        if (chptr) {
-            /* slice and dice */
-            next = chptr + 1;
-        } else {
-            chptr += strlen(start) - 1;
-        }
-
-        chptr--;
-        while (isspace(*chptr)) chptr--;
-        chptr++;
-        *chptr = '\0';
-
-        isIndented = 0;
-        if (isspace(*start)) {
-            while (isspace(*start) && *start != '\n') start++;
-            isIndented = 1;
-        }
-
-        if (*start != '\n' && *start && *start != '#') {
-            if (!isIndented) {
-                if (nextModule && nextModule->moduleName &&
-                    nextModule == (mis->moduleList + mis->numModules)) {
-                        mis->numModules++; 
-                }
-
-                if (mis->numModules == modulesAlloced) {
-                    modulesAlloced += 5;
-                    mis->moduleList = realloc(mis->moduleList,
-                        modulesAlloced * sizeof(*mis->moduleList));
-                }
-
-                nextModule = NULL;
-                found = 0;
-                skipModule = 0;
-                for (i = 0; i < mis->numModules; i++) {
-                    if (!strcmp(mis->moduleList[i].moduleName, start)) {
-                        if (override) 
-                            nextModule = mis->moduleList + i;
-                        else
-                            skipModule = 1;
-                        found = 1;
-                        break;
-                    }
-                }
-
-                if (!found && !nextModule) {
-                    nextModule = mis->moduleList + mis->numModules;
-
-                    nextModule->moduleName = strdup(start);
-                } 
-
-                if (nextModule) {
-                    nextModule->major = DRIVER_NONE;
-                    nextModule->minor = DRIVER_MINOR_NONE;
-                    nextModule->description = NULL;
-                    nextModule->flags = 0;
-                    nextModule->args = NULL;
-                    nextModule->numArgs = 0;
-                    nextModule->locationID = location;
-                }
-            } else if (!nextModule && skipModule) {
-                /* we're skipping this one (not overriding), do nothing */
-            } else if (!nextModule && skipModule) {
-                /* ACK! syntax error */
-                fprintf(stderr, "module-info syntax error in %s\n", filename);
-                return 1;
-            } else if (nextModule->major == DRIVER_NONE) {
-                chptr = start + strlen(start) - 1;
-                while (!isspace(*chptr) && chptr > start) chptr--;
-                if (chptr != start) chptr++;
-
-                if (!strcmp(chptr, "eth")) {
-                    nextModule->major = DRIVER_NET;
-                    nextModule->minor = DRIVER_MINOR_ETHERNET;
-                } else if (!strcmp(chptr, "tr")) {
-                    nextModule->major = DRIVER_NET;
-                    nextModule->minor = DRIVER_MINOR_TR;
-                } else if (!strcmp(chptr, "scsi_hostadapter") ||
-                           !strcmp(chptr, "scsi")) {
-                    nextModule->major = DRIVER_SCSI;
-                } else if (!strcmp(chptr, "pcmcia")) {
-                    nextModule->major = DRIVER_PCMCIA;
-                } else if (!strcmp(chptr, "fs")) {
-                    nextModule->major = DRIVER_FS;
-                } else if (!strcmp(chptr, "cdrom")) {
-                    nextModule->major = DRIVER_CDROM;
-                } else if (!strcmp(chptr, "ide")) {
-                    nextModule->major = DRIVER_IDE;
-                } else {
-                    nextModule->major = DRIVER_OTHER;
-                }
-            } else if (!nextModule->description) {
-                chptr = start + strlen(start) - 1;
-                if (*start == '"' && *chptr == '"') {
-                    start++;
-                    *chptr = '\0';
-                    nextModule->description = strdup(start);
-                }
-            } else {
-                nextModule->args = realloc(nextModule->args,
-                        sizeof(*nextModule->args) * (nextModule->numArgs + 1));
-                chptr = start;
-                while (!isspace(*chptr) && *chptr) chptr++;
-                if (*chptr) {
-                    oldch = *chptr;
-                    *chptr = '\0';
-                    nextModule->args[nextModule->numArgs].arg = strdup(start);
-
-                    start = chptr + 1;
-                    while (*start && isspace(*start)) start++;
-
-                    if (*start == '"') {
-                        start++;
-                        chptr = strchr(start, '"');
-                        if (chptr) {
-                            *chptr = '\0';
-                            nextModule->args[nextModule->numArgs].description = 
-                                strdup(start);
-                            nextModule->numArgs++;
-                        }
-                    }
-                }
-            }
-        }
-
-        start = next;
-    }
-
-    /* do we need to add in this last module? */
-    if (nextModule && ((nextModule - mis->moduleList) == mis->numModules))
-        mis->numModules++;
-
-    return 0;
-}
-
-void freeModuleInfoSet(moduleInfoSet mis) {
-    int i, j;
-
-    for (i = 0; i < mis->numModules; i++) {
-        if (mis->moduleList[i].moduleName) 
-            free(mis->moduleList[i].moduleName);
-
-        if (mis->moduleList[i].description) 
-            free(mis->moduleList[i].description);
-
-        for (j = 0; i < mis->moduleList[i].numArgs; j++) {
-            if (mis->moduleList[i].args[j].arg) 
-                free(mis->moduleList[i].args[j].arg) ;
-            if (mis->moduleList[i].args[j].description) 
-                free(mis->moduleList[i].args[j].description) ;
-        }
-    }
-
-    free(mis);
-}
diff --git a/loader/moduleinfo.h b/loader/moduleinfo.h
deleted file mode 100644
index 72f6d71..0000000
--- a/loader/moduleinfo.h
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- * moduleinfo.h
- *
- * Copyright (C) 2007  Red Hat, Inc.  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 as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * 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, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef MODULEINFO_H
-#define MODULEINFO_H
-
-enum driverMajor { DRIVER_NONE = 0, DRIVER_SCSI, DRIVER_NET, DRIVER_CDROM,
-		   DRIVER_PCMCIA, DRIVER_FS, DRIVER_IDE, DRIVER_OTHER = 1000,
-                   DRIVER_ANY = 5000 };
-enum driverMinor { DRIVER_MINOR_NONE = 0, DRIVER_MINOR_ETHERNET,
-		   DRIVER_MINOR_TR };
-
-struct moduleArg {
-    char * arg;
-    char * description;
-};
-
-#define MI_FLAG_NOMISCARGS	(1 << 0)
-
-struct moduleInfo {
-    char * moduleName;
-    char * description;
-    enum driverMajor major;
-    enum driverMinor minor;
-    int numArgs;
-    struct moduleArg * args;
-    int flags;
-    void * locationID;
-};
-
-struct moduleInfoSet_s {
-    struct moduleInfo * moduleList;
-    int numModules;
-};
-
-struct moduleBallLocation {
-    char * path; /* path to module ball that this driver is from. if NULL,
-                  * implies /modules/modules.cgz */
-    char * title; /* title used for driver disk -- may be NULL */
-    int version;  /* module ball version, used to determine layout */
-};
-#define CURRENT_MODBALLVER 1
-
-/* valid moduleball versions
- * 0: old single-arch module ball, modules are in uname.release
- * 1: multi-arch, modules are in uname.release/arch
- */
-
-typedef struct moduleInfoSet_s * moduleInfoSet;
-
-moduleInfoSet newModuleInfoSet(void);
-void freeModuleInfoSet(moduleInfoSet mis);
-int readModuleInfo(const char * filename, moduleInfoSet mis, void * path, int override);
-struct moduleInfo * findModuleInfo(moduleInfoSet mis, 
-				   const char * moduleName);
-
-/* NULL moduleName indicates the end of the list; the list must be freed() */
-struct moduleInfo * getModuleList(moduleInfoSet mis, 
-				  enum driverMajor major);
-
-
-#endif
diff --git a/loader/modules.c b/loader/modules.c
deleted file mode 100644
index 89f956c..0000000
--- a/loader/modules.c
+++ /dev/null
@@ -1,530 +0,0 @@
-/*
- * modules.c - module loading functionality
- *
- * Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007,
- *               2008, 2009  Red Hat, Inc.
- * 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 as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * 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, see <http://www.gnu.org/licenses/>.
- *
- * Author(s): Erik Troan <ewt@xxxxxxxxxx>
- *            Matt Wilson <msw@xxxxxxxxxx>
- *            Michael Fulbright <msf@xxxxxxxxxx>
- *            Jeremy Katz <katzj@xxxxxxxxxx>
- *            David Cantrell <dcantrell@xxxxxxxxxx>
- */
-#include <ctype.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <newt.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <sys/mman.h>
-#include <sys/stat.h>
-#include <sys/types.h>
-#include <sys/utsname.h>
-#include <sys/wait.h>
-#include <unistd.h>
-#include <glib.h>
-#include <glib/gprintf.h>
-#include <assert.h>
-
-#include "../isys/log.h"
-
-#include "loader.h"
-#include "modules.h"
-#include "windows.h"
-
-/* boot flags */
-extern uint64_t flags;
-
-static GSList *modopts = NULL;
-static GSList *blacklist = NULL;
-
-static gboolean _isValidModule(gchar *module) {
-    gint fd = -1, i = 0;
-    gchar *path = NULL, *buf = NULL, *modname = NULL;
-    gchar *ends[] = { ".ko.gz:", ".ko:", NULL };
-    struct utsname utsbuf;
-    struct stat sbuf;
-
-    if (uname(&utsbuf) == -1) {
-        logMessage(ERROR, "%s (%d): %m", __func__, __LINE__);
-        return FALSE;
-    }
-
-    if (asprintf(&path, "/lib/modules/%s/modules.dep", utsbuf.release) == -1) {
-        logMessage(ERROR, "%s (%d): %m", __func__, __LINE__);
-        return FALSE;
-    }
-
-    if (stat(path, &sbuf) == -1) {
-        logMessage(ERROR, "%s (%d): %m", __func__, __LINE__);
-        free(path);
-        return FALSE;
-    }
-
-    if ((fd = open(path, O_RDONLY)) == -1) {
-        logMessage(ERROR, "%s (%d): %m", __func__, __LINE__);
-        free(path);
-        return FALSE;
-    } else {
-        free(path);
-    }
-
-    buf = mmap(0, sbuf.st_size, PROT_READ, MAP_SHARED, fd, 0);
-    if (!buf || buf == MAP_FAILED) {
-        close(fd);
-        return FALSE;
-    }
-
-    close(fd);
-
-    while (ends[i] != NULL) {
-        if (asprintf(&modname, "/%s%s", module, ends[i]) == -1) {
-            logMessage(ERROR, "%s (%d): %m", __func__, __LINE__);
-            return FALSE;
-        }
-
-        if (g_strstr_len(buf, -1, modname) != NULL) {
-            munmap(buf, sbuf.st_size);
-            free(modname);
-            return TRUE;
-        }
-
-        free(modname);
-        modname = NULL;
-        i++;
-    }
-
-    munmap(buf, sbuf.st_size);
-    return FALSE;
-}
-
-static void _addOption(const gchar *module, const gchar *option) {
-    gboolean found = FALSE;
-    GSList *iterator = modopts;
-    module_t *modopt = NULL;
-    gchar *tmpopt = g_strdup(option);
-
-    while (iterator != NULL) {
-        modopt = (module_t *) iterator->data;
-
-        if (!strncmp(modopt->name, module, strlen(modopt->name))) {
-            found = TRUE;
-            break;
-        }
-
-        iterator = g_slist_next(iterator);
-    }
-
-    if (found) {
-        modopt->options = g_slist_append(modopt->options, tmpopt);
-    } else {
-        if ((modopt = g_malloc0(sizeof(module_t))) == NULL) {
-            logMessage(ERROR, "%s (%d): %m", __func__, __LINE__);
-            abort();
-        }
-
-        modopt->name = g_strdup(module);
-        modopt->options = NULL;
-        modopt->options = g_slist_append(modopt->options, tmpopt);
-        modopts = g_slist_append(modopts, modopt);
-    }
-
-    return;
-}
-
-static gboolean _writeModulesConf(gchar *conf) {
-    gint fd = -1, rc = 0, len = 0;
-    GSList *iterator = modopts;
-    GString *buf = g_string_new("# Module options and blacklists written by anaconda\n");
-
-    if (conf == NULL) {
-        /* XXX: should this use mkstemp() ? */
-        conf = "/tmp/modprobe.conf";
-    }
-
-    if ((fd = open(conf, O_WRONLY | O_CREAT, 0644)) == -1) {
-        logMessage(ERROR, "error opening to %s: %m", conf);
-        return FALSE;
-    }
-
-    while (iterator != NULL) {
-        module_t *modopt = iterator->data;
-        GSList *optiterator = modopt->options;
-        g_string_append_printf(buf, "options %s", modopt->name);
-
-        while (optiterator != NULL) {
-            gchar *option = (gchar *) optiterator->data;
-            g_string_append_printf(buf, " %s", option);
-            optiterator = g_slist_next(optiterator);
-        }
-
-        g_string_append(buf, "\n");
-        iterator = g_slist_next(iterator);
-    }
-
-    iterator = blacklist;
-
-    while (iterator != NULL) {
-        gchar *module = (gchar *) iterator->data;
-        g_string_append_printf(buf, "blacklist %s\n", module);
-        iterator = g_slist_next(iterator);
-    }
-
-    len = buf->len;
-    rc = write(fd, buf->str, len);
-    close(fd);
-    g_string_free(buf, TRUE);
-
-    return (rc == len);
-}
-
-static gboolean _doLoadModule(const gchar *module, gchar **args) {
-    gint child;
-    gint status;
-
-    if (!(child = fork())) {
-        gint i, rc;
-        gchar **argv = NULL;
-        gint fd = -1;
-
-        if ((argv = g_malloc0(3 * sizeof(*argv))) == NULL) {
-            logMessage(ERROR, "%s (%d): %m", __func__, __LINE__);
-            abort();
-        }
-
-        if ((fd = open("/dev/tty3", O_RDWR)) == -1) {
-            logMessage(ERROR, "%s (%d): %m", __func__, __LINE__);
-        } else {
-            dup2(fd, 0);
-            dup2(fd, 1);
-            dup2(fd, 2);
-            close(fd);
-        }
-
-        argv[0] = "/sbin/modprobe";
-        argv[1] = g_strdup(module);
-        argv[2] = NULL;
-
-        if (args) {
-            for (i = 0; args[i] ; i++) {
-                _addOption(module, args[i]);
-            }
-            _writeModulesConf(MODULES_CONF);
-        }
-
-        rc = execv("/sbin/modprobe", argv);
-        g_strfreev(argv);
-        _exit(rc);
-    }
-
-    waitpid(child, &status, 0);
-
-    if (!WIFEXITED(status) || (WIFEXITED(status) && WEXITSTATUS(status))) {
-        return TRUE;
-    } else {
-        return FALSE;
-    }
-}
-
-gboolean mlInitModuleConfig(void) {
-    gint i = 0;
-    gchar *cmdline = NULL;
-    gchar **options = NULL;
-    GError *readErr = NULL;
-
-    /* read module options out of /proc/cmdline and into a structure */
-    if (!g_file_get_contents("/proc/cmdline", &cmdline, NULL, &readErr)) {
-        logMessage(ERROR, "unable to read /proc/cmdline: %s", readErr->message);
-        g_error_free(readErr);
-        return _writeModulesConf(MODULES_CONF);
-    }
-
-    cmdline = g_strchomp(cmdline);
-    options = g_strsplit(cmdline, " ", 0);
-    g_free(cmdline);
-
-    if (options == NULL) {
-        return _writeModulesConf(MODULES_CONF);
-    }
-
-    while (options[i] != NULL) {
-        gchar *tmpmod = NULL;
-        gchar **fields = NULL;
-
-        if (g_strstr_len(options[i], -1, "=") == NULL) {
-            i++;
-            continue;
-        }
-
-        if (!strncmp(options[i], "blacklist=", 10)) {
-            if ((fields = g_strsplit(options[i], "=", 0)) != NULL) {
-                if (g_strv_length(fields) == 2) {
-                    tmpmod = g_strdup(fields[1]);
-                    blacklist = g_slist_append(blacklist, tmpmod);
-                }
-            }
-        } else if ((fields = g_strsplit(options[i], ".", 0)) != NULL) {
-            if (g_strv_length(fields) == 2) {
-                if (_isValidModule(fields[0])) {
-                    _addOption(fields[0], fields[1]);
-                }
-            }
-        }
-
-        if (fields != NULL) {
-            g_strfreev(fields);
-        }
-
-        i++;
-    }
-
-    if (options != NULL) {
-        g_strfreev(options);
-    }
-
-    return _writeModulesConf(MODULES_CONF);
-}
-
-/* load a module with a given list of arguments */
-gboolean mlLoadModule(const gchar *module, gchar **args) {
-    return _doLoadModule(module, args);
-}
-
-/* loads a : separated list of modules */
-gboolean mlLoadModuleSet(const gchar *modNames) {
-    gchar **mods = NULL, **iterator = NULL;
-    gboolean rc = FALSE;
-
-    if (modNames == NULL) {
-        return FALSE;
-    }
-
-    if ((mods = g_strsplit(modNames, ":", 0)) != NULL) {
-        iterator = mods;
-
-        while (*iterator != NULL) {
-            rc |= _doLoadModule(*iterator, NULL);
-            iterator++;
-        }
-    } else {
-        return FALSE;
-    }
-
-    g_strfreev(mods);
-    return rc;
-}
-
-gboolean mlAddBlacklist(gchar *module) {
-    gchar *tmpmod = NULL;
-
-    if (module == NULL) {
-        return FALSE;
-    }
-
-    tmpmod = g_strdup(module);
-    blacklist = g_slist_append(blacklist, tmpmod);
-    return _writeModulesConf(MODULES_CONF);
-}
-
-gboolean mlRemoveBlacklist(gchar *module) {
-    GSList *iterator = blacklist;
-
-    if (module == NULL) {
-        return FALSE;
-    }
-
-    while (iterator != NULL) {
-        if (!strcmp((gchar *) iterator->data, module)) {
-            iterator = g_slist_delete_link(blacklist, iterator);
-            continue;
-        } else {
-            iterator = g_slist_next(iterator);
-        }
-    }
-
-    return TRUE;
-}
-
-void loadKickstartModule(struct loaderData_s * loaderData,
-                         int argc, char **argv) {
-    gchar *opts = NULL;
-    gchar *module = NULL;
-    gchar **args = NULL, **remaining = NULL;
-    gboolean rc;
-    GOptionContext *optCon = g_option_context_new(NULL);
-    GError *optErr = NULL;
-    GOptionEntry ksDeviceOptions[] = {
-        { "opts", 0, 0, G_OPTION_ARG_STRING, &opts, NULL, NULL },
-        { G_OPTION_REMAINING, 0, 0, G_OPTION_ARG_STRING_ARRAY, &remaining,
-          NULL, NULL },
-        { NULL },
-    };
-
-    g_option_context_set_help_enabled(optCon, FALSE);
-    g_option_context_add_main_entries(optCon, ksDeviceOptions, NULL);
-
-    if (!g_option_context_parse(optCon, &argc, &argv, &optErr)) {
-        startNewt();
-        newtWinMessage(_("Kickstart Error"), _("OK"),
-                       _("Bad argument to device kickstart method "
-                         "command: %s"), optErr->message);
-        g_error_free(optErr);
-        g_option_context_free(optCon);
-        return;
-    }
-
-    g_option_context_free(optCon);
-
-    if ((remaining != NULL) && (g_strv_length(remaining) == 1)) {
-        module = remaining[0];
-    }
-
-    if (!module) {
-        startNewt();
-        newtWinMessage(_("Kickstart Error"), _("OK"),
-                       _("A module name must be specified for "
-                         "the kickstart device command."));
-        return;
-    }
-
-    if (opts) {
-        args = g_strsplit(opts, " ", 0);
-    }
-
-    rc = mlLoadModule(module, args);
-    g_strfreev(args);
-    return;
-}
-
-inline gint gcmp(gconstpointer a, gconstpointer b, gpointer userptr)
-{
-    return g_strcmp0(a, b);
-}
-
-int processModuleLines(GTree *data, int (*f)(gchar**, GTree*)){
-    char *line = NULL;
-    size_t linesize = 0;
-    gchar** lineparts = NULL;
-    int count = 0;
-
-    FILE *file = fopen("/proc/modules", "r");
-    if (file == NULL)
-        return -1;
-
-    while (1) {
-        if (getline(&line, &linesize, file) < 0)
-            break;
-
-        if (*line == NULL)
-            break;
-
-        lineparts = g_strsplit_set(line, " ", 4);
-
-        free(line);
-        line = NULL;
-
-        int ret = f(lineparts, data);
-        g_strfreev(lineparts);
-
-        if (ret < 0)
-            break;
-        count+=ret;
-    }
-
-    fclose(file);
-    return count;
-}
-
-inline int cb_savestate(gchar** parts, GTree *data)
-{
-    logMessage(DEBUGLVL, "Saving module %s", parts[0]);
-    g_tree_insert(data, g_strdup(parts[0]), (gchar*)1);
-    return 1;
-}
-
-GTree* mlSaveModuleState()
-{
-    GTree *state = NULL;
-
-    state = g_tree_new_full(gcmp, NULL, g_free, NULL);
-    if(!state)
-        return NULL;
-
-    processModuleLines(state, cb_savestate);
-
-    return state;
-}
-
-inline int cb_restorestate(gchar** parts, GTree *data)
-{
-    pid_t pid;
-    int status;
-
-    /* this module has to stay loaded */
-    if (g_tree_lookup(data, parts[0])){
-        return 0;
-    }
-
-    /* this module is still required */
-    if (parts[2][0] != '0') {
-        return 0;
-    }
-
-    /* rmmod parts[0] */
-    pid = fork();
-    if (pid == 0) {
-        execl("/sbin/rmmod", "-f", parts[0], NULL);
-        _exit(1);
-    }
-    else if (pid < 0) {
-        logMessage(ERROR, "Module %s removal FAILED", parts[0]);
-        return 0;
-    }
-
-    waitpid(pid, &status, 0);
-    if (WEXITSTATUS(status)) {
-        logMessage(DEBUGLVL, "Module %s was NOT removed", parts[0]);
-        return 0;
-    }
-    else{
-        logMessage(DEBUGLVL, "Module %s was removed", parts[0]);
-        return 1;
-    }
-    
-    return 0;
-}
-
-void mlRestoreModuleState(GTree *state)
-{
-    if(!state)
-        return;
-
-    logMessage(INFO, "Restoring module state...");
-
-    /* repeat until we can't remove anything else */
-    while (processModuleLines(state, cb_restorestate) > 0)
-        /* noop */;
-}
-
-void mlFreeModuleState(GTree *state)
-{
-    if(!state)
-        return;
-
-    g_tree_destroy(state);
-}
diff --git a/loader/modules.h b/loader/modules.h
deleted file mode 100644
index 605d01e..0000000
--- a/loader/modules.h
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * modules.h
- *
- * Copyright (C) 2007, 2009  Red Hat, Inc.  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 as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * 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, see <http://www.gnu.org/licenses/>.
- *
- * Author(s): David Cantrell <dcantrell@xxxxxxxxxx>
- */
-
-#ifndef H_MODULES
-#define H_MODULES
-
-#include <glib.h>
-#include "loader.h"
-#include "moduleinfo.h"
-
-#define MODULES_CONF "/etc/modprobe.d/anaconda.conf"
-
-typedef struct _module_t {
-    gchar *name;
-    GSList *options;
-} module_t;
-
-gboolean mlInitModuleConfig(void);
-gboolean mlLoadModule(const gchar *, gchar **);
-gboolean mlLoadModuleSet(const gchar *);
-gboolean mlAddBlacklist(gchar *);
-gboolean mlRemoveBlacklist(gchar *);
-void loadKickstartModule(struct loaderData_s *, int, char **);
-
-GTree* mlSaveModuleState();
-void mlRestoreModuleState(GTree *state);
-void mlFreeModuleState(GTree *state);
-
-#endif
diff --git a/loader/net.c b/loader/net.c
deleted file mode 100644
index 0a3afa1..0000000
--- a/loader/net.c
+++ /dev/null
@@ -1,2122 +0,0 @@
-/*
- * net.c
- *
- * Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005  Red Hat, Inc.
- *               2006, 2007, 2008, 2009
- *
- * 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; either version 2 of the License, or
- * (at your option) any later version.
- *
- * 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, see <http://www.gnu.org/licenses/>.
- *
- * Author(s): David Cantrell <dcantrell@xxxxxxxxxx>
- */
-
-#include <netdb.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <sys/ioctl.h>
-#include <sys/socket.h>
-#include <sys/utsname.h>
-#include <arpa/inet.h>
-#include <errno.h>
-#include <resolv.h>
-#include <net/if.h>
-#include <newt.h>
-#include <stdlib.h>
-#include <string.h>
-#include <strings.h>
-#include <unistd.h>
-
-#include <glib.h>
-#include <NetworkManager.h>
-#include <nm-client.h>
-
-#include "../isys/isys.h"
-#include "../isys/ethtool.h"
-#include "../isys/iface.h"
-#include "../isys/log.h"
-
-#include "lang.h"
-#include "loader.h"
-#include "loadermisc.h"
-#include "method.h"
-#include "net.h"
-#include "windows.h"
-#include "ibft.h"
-
-/* boot flags */
-extern uint64_t flags;
-
-/**
- * Callback function for the CIDR entry boxes on the manual TCP/IP
- * configuration window.
- *
- * @param co The entry field that triggered the callback.
- * @param dptr Pointer to intfconfig_s data structure for this field.
- * @see intfconfig_s
- */
-static void cidrCallback(newtComponent co, void * dptr) {
-    struct intfconfig_s * data = dptr;
-    int cidr, upper = 0;
-    struct in_addr addr;
-
-    if (co == data->cidr4Entry) {
-        if (data->cidr4 == NULL && data->ipv4 == NULL)
-            return;
-
-        if (inet_pton(AF_INET, data->cidr4, &addr) >= 1)
-            return;
-
-        errno = 0;
-        cidr = strtol(data->cidr4, NULL, 10);
-        if ((errno == ERANGE && (cidr == LONG_MIN || cidr == LONG_MAX)) ||
-            (errno != 0 && cidr == 0)) {
-            logMessage(ERROR, "%s: %d: %m", __func__, __LINE__);
-            abort();
-        }
-
-        if (strcmp(data->ipv4, ""))
-            upper = 32;
-#ifdef ENABLE_IPV6
-    } else if (co == data->cidr6Entry) {
-        if (data->cidr6 == NULL && data->ipv6 == NULL)
-            return;
-
-        errno = 0;
-        cidr = strtol(data->cidr6, NULL, 10);
-        if ((errno == ERANGE && (cidr == LONG_MIN || cidr == LONG_MAX)) ||
-            (errno != 0 && cidr == 0)) {
-            logMessage(ERROR, "%s: %d: %m", __func__, __LINE__);
-            abort();
-        }
-
-        if (strcmp(data->ipv6, ""))
-            upper = 128;
-#endif
-    }
-
-    if (upper != 0) {
-        if (cidr < 1 || cidr > upper) {
-            newtWinMessage(_("Invalid Prefix"), _("Retry"),
-                           _("Prefix must be between 1 and 32 "
-                             "for IPv4 networks or between 1 and 128 "
-                             "for IPv6 networks"));
-        }
-    }
-}
-
-static void ipCallback(newtComponent co, void * dptr) {
-    int i;
-    char *buf, *octet;
-    struct intfconfig_s * data = dptr;
-
-    if (co == data->ipv4Entry) {
-        /* do we need to guess a netmask for the user? */
-        if (data->cidr4 == NULL && data->ipv4 != NULL) {
-            buf = strdup(data->ipv4);
-            octet = strtok(buf, ".");
-            errno = 0;
-            i = strtol(octet, NULL, 10);
-
-            if ((errno == ERANGE && (i == LONG_MIN || i == LONG_MAX)) ||
-                (errno != 0 && i == 0)) {
-                logMessage(ERROR, "%s: %d: %m", __func__, __LINE__);
-                abort();
-            }
-
-            free(buf);
-            free(octet);
-
-            if (i >= 0 && i <= 127)
-                newtEntrySet(data->cidr4Entry, "8", 1);
-            else if (i >= 128 && i <= 191)
-                newtEntrySet(data->cidr4Entry, "16", 1);
-            else if (i >= 192 && i <= 222)
-                newtEntrySet(data->cidr4Entry, "24", 1);
-        }
-
-        return;
-#ifdef ENABLE_IPV6
-    } else if (co == data->ipv6Entry) {
-        /* users must provide a mask, we can't guess for ipv6 */
-        return;
-#endif
-    }
-}
-
-static void setMethodSensitivity(void *dptr, int radio_button_count) {
-    int i = 0;
-
-    for (i = 0; i < radio_button_count; i++) {
-        newtCheckboxSetFlags(*((newtComponent *) dptr), NEWT_FLAG_DISABLED,
-                             NEWT_FLAGS_TOGGLE);
-        dptr += sizeof (newtComponent);
-    }
-
-    return;
-}
-
-static void v4MethodCallback(newtComponent co, void *dptr) {
-    setMethodSensitivity(dptr, 2);
-    return;
-}
-
-#ifdef ENABLE_IPV6
-static void v6MethodCallback(newtComponent co, void *dptr) {
-    setMethodSensitivity(dptr, 3);
-    return;
-}
-#endif
-
-static void parseEthtoolSettings(struct loaderData_s * loaderData) {
-    char * option, * buf;
-    ethtool_duplex duplex = ETHTOOL_DUPLEX_UNSPEC;
-    ethtool_speed speed = ETHTOOL_SPEED_UNSPEC;
-    
-    buf = strdup(loaderData->ethtool);
-    option = strtok(buf, " ");
-    while (option) {
-        if (option[strlen(option) - 1] == '\"')
-            option[strlen(option) - 1] = '\0';
-        if (option[0] == '\"')
-            option++;
-        if (!strncmp(option, "duplex", 6)) {
-            if (!strncmp(option + 7, "full", 4)) 
-                duplex = ETHTOOL_DUPLEX_FULL;
-            else if (!strncmp(option + 7, "half", 4))
-                duplex = ETHTOOL_DUPLEX_HALF;
-            else
-                logMessage(WARNING, "Unknown duplex setting: %s", option + 7);
-            option = strtok(NULL, " ");
-        } else if (!strncmp("speed", option, 5)) {
-            if (!strncmp(option + 6, "1000", 4))
-                speed = ETHTOOL_SPEED_1000;
-            else if (!strncmp(option + 6, "100", 3))
-                speed = ETHTOOL_SPEED_100;
-            else if (!strncmp(option + 6, "10", 2))
-                speed = ETHTOOL_SPEED_10;
-            else
-                logMessage(WARNING, "Unknown speed setting: %s", option + 6);
-            option = strtok(NULL, " ");
-        } else {
-            logMessage(WARNING, "Unknown ethtool setting: %s", option);
-        }
-        option = strtok(NULL, " ");
-    }
-    setEthtoolSettings(loaderData->netDev, speed, duplex);
-    free(buf);
-}
-
-/* given loader data from kickstart, populate network configuration struct */
-void setupIfaceStruct(iface_t * iface, struct loaderData_s * loaderData) {
-    struct in_addr addr;
-    struct in6_addr addr6;
-    char * c;
-
-    memset(&addr, 0, sizeof(addr));
-    memset(&addr6, 0, sizeof(addr6));
-
-    if (loaderData->ethtool) {
-        parseEthtoolSettings(loaderData);
-    }
-
-    if (loaderData->netCls_set) {
-        iface->vendorclass = loaderData->netCls;
-    } else {
-        iface->vendorclass = NULL;
-    }
-
-    if (loaderData->ipinfo_set && loaderData->ipv4 != NULL) {
-	/* this is iBFT configured device */
-	if (!strncmp(loaderData->ipv4, "ibft", 4)) {
-	    char *devmacaddr = iface_mac2str(loaderData->netDev);
-	    iface->ipv4method = IPV4_IBFT_METHOD;
-	    iface->isiBFT = 1;
-
-	    /* Problems with getting the info from iBFT or iBFT uses dhcp*/
-	    if(!devmacaddr || !ibft_present()){
-		iface->ipv4method = IPV4_DHCP_METHOD;
-		logMessage(INFO, "iBFT is not present");
-	    }
-
-	    /* MAC address doesn't match */
-	    else if(strcasecmp(ibft_iface_mac(), devmacaddr)){
-		iface->ipv4method = IPV4_DHCP_METHOD;
-		logMessage(INFO, "iBFT doesn't know what NIC to use - falling back to DHCP");
-	    }
-	    else if(ibft_iface_dhcp()){
-		iface->ipv4method = IPV4_IBFT_DHCP_METHOD;
-		logMessage(INFO, "iBFT is configured to use DHCP");
-	    }
-	    if(devmacaddr) free(devmacaddr);
-	}
-        /* this is how we specify dhcp */
-        else if (!strncmp(loaderData->ipv4, "dhcp", 4)) {
-            iface->dhcptimeout = loaderData->dhcpTimeout;
-            iface->ipv4method = IPV4_DHCP_METHOD;
-        } else if (inet_pton(AF_INET, loaderData->ipv4, &addr) >= 1) {
-            iface->ipaddr.s_addr = addr.s_addr;
-            iface->ipv4method = IPV4_MANUAL_METHOD;
-        } else { /* invalid ip information, disable the setting of ip info */
-            loaderData->ipinfo_set = 0;
-            iface->ipv4method = 0;
-            loaderData->ipv4 = NULL;
-        }
-     }
-
-    if (loaderData->netmask != NULL) {
-        if (inet_pton(AF_INET, loaderData->netmask, &iface->netmask) <= 0) {
-            logMessage(ERROR, "%s (%d): %s", __func__, __LINE__,
-                       strerror(errno));
-        }
-    }
-
-    if (loaderData->gateway != NULL) {
-        if (inet_pton(AF_INET, loaderData->gateway, &iface->gateway) <= 0) {
-            logMessage(ERROR, "%s (%d): %s", __func__, __LINE__,
-                       strerror(errno));
-        }
-    }
-
-#ifdef ENABLE_IPV6
-    if (loaderData->ipv6info_set && loaderData->ipv6 != NULL) {
-        if (!strncmp(loaderData->ipv6, "dhcp", 4)) {
-            iface->ipv6method = IPV6_DHCP_METHOD;
-        } else if (!strncmp(loaderData->ipv6, "auto", 4)) {
-            iface->ipv6method = IPV6_AUTO_METHOD;
-        } else if (inet_pton(AF_INET6, loaderData->ipv6, &addr6) >= 1) {
-            memcpy(&iface->ip6addr, &addr6, sizeof(struct in6_addr));
-            iface->ipv6method = IPV6_MANUAL_METHOD;
-        } else {
-            iface->ipv6method = 0;
-            loaderData->ipv6info_set = 0;
-            loaderData->ipv6 = NULL;
-        }
-    }
-
-    if (loaderData->gateway6 != NULL) {
-        if (inet_pton(AF_INET6, loaderData->gateway6, &iface->gateway6) <= 0) {
-            logMessage(ERROR, "%s (%d): %s", __func__, __LINE__,
-                       strerror(errno));
-        }
-    }
-#endif
-
-    /* iBFT configured DNS */
-    if(iface->ipv4method == IPV4_IBFT_METHOD){
-	if(iface->numdns<MAXNS){
-	    if(ibft_iface_dns1() && inet_pton(AF_INET, ibft_iface_dns1(), &addr)>=1){
-		iface->dns[iface->numdns] = strdup(ibft_iface_dns1());
-		iface->numdns++;
-		logMessage(INFO, "adding iBFT dns server %s", ibft_iface_dns1());
-	    }
-	}
-	if(iface->numdns<MAXNS){
-	    if(ibft_iface_dns2() && inet_pton(AF_INET, ibft_iface_dns2(), &addr)>=1){
-		iface->dns[iface->numdns] = strdup(ibft_iface_dns2());
-		iface->numdns++;
-		logMessage(INFO, "adding iBFT dns server %s", ibft_iface_dns2());
-	    }
-	}
-    }
-
-    if (loaderData->dns) {
-        char * buf;
-        char ret[INET6_ADDRSTRLEN+1];
-        buf = strdup(loaderData->dns);
-
-        /* Scan the dns parameter for multiple comma-separated IP addresses */
-        c = strtok(buf, ",");
-        while ((iface->numdns < MAXNS) && (c != NULL)) {
-            if (inet_pton(AF_INET, c, &addr) >= 1) {
-                iface->dns[iface->numdns] = strdup(c);
-                iface->numdns++;
-
-                if (inet_ntop(AF_INET, &addr, ret, INET_ADDRSTRLEN) == NULL) {
-                    logMessage(ERROR, "%s (%d): %s", __func__, __LINE__, strerror(errno));
-                } else {
-                    logMessage(DEBUGLVL, "adding dns4 %s", ret);
-                    c = strtok(NULL, ",");
-                }
-            } else if (inet_pton(AF_INET6, c, &addr6) >= 1) {
-                iface->dns[iface->numdns] = strdup(c);
-                iface->numdns++;
-
-                if (inet_ntop(AF_INET6, &addr6, ret, INET6_ADDRSTRLEN) == NULL) {
-                    logMessage(ERROR, "%s (%d): %s", __func__, __LINE__, strerror(errno));
-                } else {
-                    logMessage(DEBUGLVL, "adding dns6 %s", ret);
-                    c = strtok(NULL, ",");
-                }
-            }
-        }
-
-
-
-        logMessage(INFO, "dnsservers is %s", loaderData->dns);
-    }
-
-    if (loaderData->hostname) {
-        logMessage(INFO, "setting specified hostname of %s",
-                   loaderData->hostname);
-        iface->hostname = strdup(loaderData->hostname);
-    }
-
-    if (loaderData->mtu) {
-        iface->mtu = loaderData->mtu;
-    }
-
-    if (loaderData->peerid) {
-        iface->peerid = strdup(loaderData->peerid);
-    }
-
-    if (loaderData->subchannels) {
-        iface->subchannels = strdup(loaderData->subchannels);
-    }
-
-    if (loaderData->ctcprot) {
-        iface->ctcprot = strdup(loaderData->ctcprot);
-    }
-
-    if (loaderData->portname) {
-        iface->portname = strdup(loaderData->portname);
-    }
-
-    if (loaderData->nettype) {
-        iface->nettype = strdup(loaderData->nettype);
-    }
-
-    if (loaderData->ethtool) {
-        parseEthtoolSettings(loaderData);
-    }
-
-    if (loaderData->layer2) {
-        iface->layer2 = strdup(loaderData->layer2);
-    }
-
-    if (loaderData->portno) {
-        iface->portno = strdup(loaderData->portno);
-    }
-
-    if (loaderData->noDns) {
-        iface->flags |= IFACE_FLAGS_NO_WRITE_RESOLV_CONF;
-    }
-
-    iface->dhcptimeout = loaderData->dhcpTimeout;
-
-    return;
-}
-
-int readNetConfig(char * device, iface_t * iface,
-                  char * dhcpclass, int methodNum) {
-    int err;
-    int ret;
-    int i = 0;
-    struct netconfopts opts;
-    struct in_addr addr;
-    struct intfconfig_s ipcomps;
-
-    /* ipcomps contains the user interface components */
-    ipcomps.ipv4 = NULL;
-    ipcomps.cidr4 = NULL;
-    ipcomps.gw = NULL;
-#ifdef ENABLE_IPV6
-    ipcomps.ipv6 = NULL;
-    ipcomps.cidr6 = NULL;
-    ipcomps.gw6 = NULL;
-#endif
-    ipcomps.ns = NULL;
-
-    /* init opts */
-    opts.ipv4Choice = 0;
-#ifdef ENABLE_IPV6
-    opts.ipv6Choice = 0;
-#endif
-
-    /* JKFIXME: we really need a way to override this and be able to change
-     * our network config */
-    if (!FL_ASKNETWORK(flags) &&
-        ((iface->ipv4method > IPV4_UNUSED_METHOD) ||
-         (iface->ipv6method > IPV4_UNUSED_METHOD))) {
-        logMessage(INFO, "doing kickstart... setting it up");
-
-        err = writeEnabledNetInfo(iface);
-        if (err) {
-            logMessage(ERROR, "failed to write %s data for %s (%d)",
-                       SYSCONFIG_PATH, iface->device, err);
-            return LOADER_BACK;
-        }
-
-        i = get_connection(iface);
-        newtPopWindow();
-
-        if (i > 0) {
-            if (FL_CMDLINE(flags)) {
-                fprintf(stderr, _("There was an error configuring your network "
-                                  "interface."));
-                fprintf(stderr, _("\nThis cannot be corrected in cmdline mode.\n"
-                                  "Halting.\n"));
-                exit(1);
-            }
-
-            newtWinMessage(_("Network Error"), _("Retry"),
-                           _("There was an error configuring your network "
-                             "interface."));
-            return LOADER_BACK;
-        }
-
-        return LOADER_NOOP;
-    }
-
-    /* dhcp/manual network configuration loop */
-    i = 1;
-    while (i == 1) {
-        ret = configureTCPIP(device, iface, &opts, methodNum);
-
-        if (ret == LOADER_NOOP) {
-            /* dhcp selected, proceed */
-            i = 0;
-        } else if (ret == LOADER_OK) {
-            /* do manual configuration */
-            ret = manualNetConfig(device, iface, &ipcomps, &opts);
-
-            if (ret == LOADER_BACK) {
-                continue;
-            } else if (ret == LOADER_OK) {
-                i = 0;
-            }
-        } else if (ret == LOADER_BACK) {
-            return LOADER_BACK;
-        }
-    }
-
-    /* calculate any missing IPv4 pieces */
-    if (opts.ipv4Choice == '*') {
-        memset(&addr, 0, sizeof(addr));
-        addr.s_addr = (iface->ipaddr.s_addr) & (iface->netmask.s_addr);
-
-        if (iface->broadcast.s_addr == 0) {
-            iface->broadcast.s_addr = addr.s_addr | ~(iface->netmask.s_addr);
-        }
-    }
-
-    /* bring up the interface */
-    err = writeEnabledNetInfo(iface);
-    if (err) {
-        logMessage(ERROR, "failed to write %s data for %s (%d)",
-                   SYSCONFIG_PATH, iface->device, err);
-        iface->ipv4method = IPV4_UNUSED_METHOD;
-        iface->ipv6method = IPV6_UNUSED_METHOD;
-        return LOADER_BACK;
-    }
-
-    i = get_connection(iface);
-    newtPopWindow();
-
-    if (i > 0) {
-        newtWinMessage(_("Network Error"), _("Retry"),
-                       _("There was an error configuring your network "
-                         "interface."));
-        iface->ipv4method = IPV4_UNUSED_METHOD;
-        iface->ipv6method = IPV6_UNUSED_METHOD;
-        return LOADER_ERROR;
-    }
-
-    return LOADER_OK;
-}
-
-int configureTCPIP(char * device, iface_t * iface,
-                   struct netconfopts * opts, int methodNum) {
-    int i = 0, z = 0, skipForm = 0, ret;
-    newtComponent f, okay, back, answer;
-    newtComponent ipv4Checkbox, v4Method[2];
-#ifdef ENABLE_IPV6
-    newtComponent ipv6Checkbox, v6Method[3];
-#endif
-    newtGrid grid, checkgrid, buttons;
-
-    /* UI WINDOW 1: ask for ipv4 choice, ipv6 choice, and conf methods */
-
-    /* IPv4 checkbox */
-    if (!opts->ipv4Choice) {
-        if (FL_NOIPV4(flags) && !FL_IP_PARAM(flags))
-            opts->ipv4Choice = ' ';
-        else
-            opts->ipv4Choice = '*';
-    }
-
-    ipv4Checkbox = newtCheckbox(-1, -1, _("Enable IPv4 support"),
-                                opts->ipv4Choice, NULL, &(opts->ipv4Choice));
-    v4Method[0] = newtRadiobutton(-1, -1, DHCP_METHOD_STR, 1, NULL);
-    v4Method[1] = newtRadiobutton(-1, -1, MANUAL_METHOD_STR, 0, v4Method[0]);
-
-#ifdef ENABLE_IPV6
-    /* IPv6 checkbox */
-    if (!opts->ipv6Choice) {
-        if (FL_NOIPV6(flags) && !FL_IPV6_PARAM(flags))
-            opts->ipv6Choice = ' ';
-        else
-            opts->ipv6Choice = '*';
-    }
-
-    ipv6Checkbox = newtCheckbox(-1, -1, _("Enable IPv6 support"),
-                                opts->ipv6Choice, NULL, &(opts->ipv6Choice));
-    v6Method[0] = newtRadiobutton(-1, -1, AUTO_METHOD_STR, 1, NULL);
-    v6Method[1] = newtRadiobutton(-1, -1, DHCPV6_METHOD_STR, 0, v6Method[0]);
-    v6Method[2] = newtRadiobutton(-1, -1, MANUAL_METHOD_STR, 0, v6Method[1]);
-#endif
-
-    /* button bar at the bottom of the window */
-    buttons = newtButtonBar(_("OK"), &okay, _("Back"), &back, NULL);
-
-    /* checkgrid contains the toggle options for net configuration */
-#ifdef ENABLE_IPV6
-    checkgrid = newtCreateGrid(1, 8);
-#else
-    checkgrid = newtCreateGrid(1, 3);
-#endif
-
-    newtGridSetField(checkgrid, 0, 0, NEWT_GRID_COMPONENT, ipv4Checkbox,
-                     0, 0, 0, 0, NEWT_ANCHOR_LEFT, 0);
-    for (i = 1; i < 3; i++)
-        newtGridSetField(checkgrid, 0, i, NEWT_GRID_COMPONENT, v4Method[i-1],
-                         7, 0, 0, 0, NEWT_ANCHOR_LEFT, 0);
-
-#ifdef ENABLE_IPV6
-    newtGridSetField(checkgrid, 0, 4, NEWT_GRID_COMPONENT, ipv6Checkbox,
-                     0, 1, 0, 0, NEWT_ANCHOR_LEFT, 0);
-    for (i = 5; i < 8; i++)
-        newtGridSetField(checkgrid, 0, i, NEWT_GRID_COMPONENT, v6Method[i-5],
-                         7, 0, 0, 0, NEWT_ANCHOR_LEFT, 0);
-#endif
-
-    /* main window layout */
-    grid = newtCreateGrid(1, 2);
-    newtGridSetField(grid, 0, 0, NEWT_GRID_SUBGRID, checkgrid,
-                     0, 0, 0, 1, 0, 0);
-    newtGridSetField(grid, 0, 1, NEWT_GRID_SUBGRID, buttons,
-                     0, 0, 0, 0, 0, NEWT_GRID_FLAG_GROWX);
-
-    f = newtForm(NULL, NULL, 0);
-    newtGridAddComponentsToForm(grid, f, 1);
-    newtGridWrappedWindow(grid, _("Configure TCP/IP"));
-    newtGridFree(grid, 1);
-
-    /* callbacks */
-    newtComponentAddCallback(ipv4Checkbox, v4MethodCallback, &v4Method);
-#ifdef ENABLE_IPV6
-    newtComponentAddCallback(ipv6Checkbox, v6MethodCallback, &v6Method);
-#endif
-
-    /* match radio button sensitivity to initial checkbox choices */
-    if (opts->ipv4Choice == ' ')
-        setMethodSensitivity(&v4Method, 2);
-
-#ifdef ENABLE_IPV6
-    if (opts->ipv6Choice == ' ')
-        setMethodSensitivity(&v6Method, 3);
-#endif
-
-#ifdef ENABLE_IPV6
-    /* If the user provided any of the following boot paramters, skip
-     * prompting for network configuration information:
-     *     ip=<val> ipv6=<val>
-     *     noipv4 noipv6
-     *     ip=<val> noipv6
-     *     ipv6=<val> noipv4
-     */
-    if ((FL_IP_PARAM(flags) && FL_IPV6_PARAM(flags)) ||
-        (FL_IP_PARAM(flags) && FL_NOIPV6(flags)) ||
-        (FL_IPV6_PARAM(flags) && FL_NOIPV4(flags)) ||
-        (FL_NOIPV4(flags) && FL_NOIPV6(flags))) {
-        skipForm = 1;
-        newtPopWindow();
-    }
-#else
-    if (FL_IP_PARAM(flags) || FL_NOIPV4(flags)) {
-        skipForm = 1;
-        newtPopWindow();
-    }
-#endif
-
-    /* run the form */
-    do {
-        if (!skipForm) {
-            answer = newtRunForm(f);
-
-            if (answer == back) {
-                newtFormDestroy(f);
-                newtPopWindow();
-                return LOADER_BACK;
-            }
-
-            /* need at least one stack */
-#ifdef ENABLE_IPV6
-            if (opts->ipv4Choice == ' ' && opts->ipv6Choice == ' ') {
-#else
-            if (opts->ipv4Choice == ' ') {
-#endif
-                newtWinMessage(_("Missing Protocol"), _("Retry"),
-                               _("You must select at least one protocol (IPv4 "
-                                 "or IPv6)."));
-                continue;
-            }
-
-            /* NFS only works over IPv4 */
-            if (opts->ipv4Choice == ' ' && methodNum == METHOD_NFS) {
-                newtWinMessage(_("IPv4 Needed for NFS"), _("Retry"),
-                           _("NFS installation method requires IPv4 support."));
-                continue;
-            }
-        }
-
-        /* what TCP/IP stacks do we use? what conf methods? */
-        if (opts->ipv4Choice == '*') {
-            flags &= ~LOADER_FLAGS_NOIPV4;
-            for (z = IPV4_FIRST_METHOD; z <= IPV4_LAST_METHOD; z++)
-                if (newtRadioGetCurrent(v4Method[0]) == v4Method[z-1])
-                    iface->ipv4method = z;
-        } else {
-            flags |= LOADER_FLAGS_NOIPV4;
-        }
-
-#ifdef ENABLE_IPV6
-        if (opts->ipv6Choice == '*') {
-            flags &= ~LOADER_FLAGS_NOIPV6;
-            for (z = IPV6_FIRST_METHOD; z <= IPV6_LAST_METHOD; z++)
-                if (newtRadioGetCurrent(v6Method[0]) == v6Method[z-1])
-                    iface->ipv6method = z;
-        } else {
-            flags |= LOADER_FLAGS_NOIPV6;
-        }
-#endif
-
-        /* do interface configuration (call DHCP here, or return for manual) */
-#ifdef ENABLE_IPV6
-        if ((!FL_NOIPV4(flags) && iface->ipv4method == IPV4_DHCP_METHOD) ||
-            (!FL_NOIPV6(flags) && (iface->ipv6method == IPV6_AUTO_METHOD ||
-                                   iface->ipv6method == IPV6_DHCP_METHOD))) {
-#else
-        if (!FL_NOIPV4(flags) && iface->ipv4method == IPV4_DHCP_METHOD) {
-#endif
-            /* DHCP selected, exit the loop */
-            ret = LOADER_NOOP;
-            i = 1;
-#ifdef ENABLE_IPV6
-        } else if ((!FL_NOIPV4(flags) && iface->ipv4method == IPV4_MANUAL_METHOD) ||
-                   (!FL_NOIPV6(flags) && iface->ipv6method == IPV6_MANUAL_METHOD)) {
-#else
-        } else if (!FL_NOIPV4(flags) && iface->ipv4method == IPV4_MANUAL_METHOD) {
-#endif
-
-            /* manual IP configuration selected */
-            ret = LOADER_OK;
-            i = 1;
-        }
-    } while (i != 1);
-
-    newtFormDestroy(f);
-    newtPopWindow();
-    return ret;
-}
-
-int manualNetConfig(char * device, iface_t * iface,
-                    struct intfconfig_s * ipcomps, struct netconfopts * opts) {
-    int i, rows, pos, cidr, have[2], stack[2];
-    char *buf = NULL;
-    char ret[48];
-    struct in_addr addr;
-#ifdef ENABLE_IPV6
-    struct in6_addr addr6;
-    int prefix;
-#endif
-    struct in_addr *tmpaddr = NULL;
-    newtComponent f, okay, back, answer;
-    newtGrid egrid = NULL;
-    newtGrid qgrid = NULL;
-#ifdef ENABLE_IPV6
-    newtGrid rgrid = NULL;
-#endif
-    newtGrid buttons, grid;
-    newtComponent text = NULL;
-
-    memset(ret, '\0', INET6_ADDRSTRLEN+1);
-
-    /* so we don't perform this test over and over */
-    stack[IPV4] = opts->ipv4Choice == '*' &&
-                  iface->ipv4method == IPV4_MANUAL_METHOD;
-#ifdef ENABLE_IPV6
-    stack[IPV6] = opts->ipv6Choice == '*' &&
-                  iface->ipv6method == IPV6_MANUAL_METHOD;
-#endif
-
-    /* UI WINDOW 2 (optional): manual IP config for non-DHCP installs */
-    rows = 2;
-    for (i = 0; i < 2; i++) {
-        if (stack[i]) {
-            rows++;
-        }
-    }
-    egrid = newtCreateGrid(4, rows);
-
-    pos = 0;
-
-    /* IPv4 entry items */
-    if (stack[IPV4]) {
-        newtGridSetField(egrid, 0, pos, NEWT_GRID_COMPONENT,
-                         newtLabel(-1, -1, _("IPv4 address:")),
-                         0, 0, 0, 0, NEWT_ANCHOR_LEFT, 0);
-
-        ipcomps->ipv4Entry = newtEntry(-1, -1, NULL, 16, &ipcomps->ipv4, 0);
-        ipcomps->cidr4Entry = newtEntry(-1, -1, NULL, 16, &ipcomps->cidr4, 0);
-
-        /* use a nested grid for ipv4 addr & netmask */
-        qgrid = newtCreateGrid(3, 1);
-
-        newtGridSetField(qgrid, 0, 0, NEWT_GRID_COMPONENT,
-                         ipcomps->ipv4Entry, 1, 0, 0, 0, NEWT_ANCHOR_LEFT, 0);
-        newtGridSetField(qgrid, 1, 0, NEWT_GRID_COMPONENT,
-                         newtLabel(-1, -1, _("/")),
-                         1, 0, 0, 0, NEWT_ANCHOR_LEFT, 0);
-        newtGridSetField(qgrid, 2, 0, NEWT_GRID_COMPONENT,
-                         ipcomps->cidr4Entry, 1, 0, 0, 0, NEWT_ANCHOR_LEFT, 0);
-
-        newtGridSetField(egrid, 1, pos, NEWT_GRID_SUBGRID, qgrid,
-                         0, 0, 0, 0, NEWT_ANCHOR_LEFT, 0);
-
-        newtComponentAddCallback(ipcomps->ipv4Entry, ipCallback, ipcomps);
-        newtComponentAddCallback(ipcomps->cidr4Entry, cidrCallback, ipcomps);
-
-        /* populate fields if we have data already */
-        if (iface_have_in_addr(&iface->ipaddr)) {
-            if (inet_ntop(AF_INET, &iface->ipaddr, ret,
-                          INET_ADDRSTRLEN) == NULL) {
-                logMessage(ERROR, "%s (%d): %s", __func__, __LINE__,
-                           strerror(errno));
-            }
-        } else if (iface_have_in_addr(&iface->ipaddr)) {
-            if (inet_ntop(AF_INET, &iface->ipaddr, ret,
-                          INET_ADDRSTRLEN) == NULL) {
-                logMessage(ERROR, "%s (%d): %s", __func__, __LINE__,
-                           strerror(errno));
-            }
-        }
-
-        if (*ret) {
-            newtEntrySet(ipcomps->ipv4Entry, ret, 1);
-        }
-
-        if (iface_have_in_addr(&iface->netmask)) {
-            if (inet_ntop(AF_INET, &iface->netmask, ret,
-                          INET_ADDRSTRLEN) == NULL) {
-                logMessage(ERROR, "%s (%d): %s", __func__, __LINE__,
-                           strerror(errno));
-            }
-        } else if (iface_have_in_addr(&iface->netmask)) {
-            if (inet_ntop(AF_INET, &iface->netmask, ret,
-                          INET_ADDRSTRLEN) == NULL) {
-                logMessage(ERROR, "%s (%d): %s", __func__, __LINE__,
-                           strerror(errno));
-            }
-        }
-
-        if (*ret) {
-            newtEntrySet(ipcomps->cidr4Entry, ret, 1);
-        }
-
-        pos++;
-    }
-
-#ifdef ENABLE_IPV6
-    /* IPv6 entry items */
-    if (stack[IPV6]) {
-        newtGridSetField(egrid, 0, pos, NEWT_GRID_COMPONENT,
-                         newtLabel(-1, -1, _("IPv6 address:")),
-                         0, 0, 0, 0, NEWT_ANCHOR_LEFT, 0);
-
-        ipcomps->ipv6Entry = newtEntry(-1, -1, NULL, 41, &ipcomps->ipv6, 0);
-        ipcomps->cidr6Entry = newtEntry(-1, -1, NULL, 4, &ipcomps->cidr6, 0);
-
-        /* use a nested grid for ipv6 addr & netmask */
-        rgrid = newtCreateGrid(3, 1);
-
-        newtGridSetField(rgrid, 0, 0, NEWT_GRID_COMPONENT,
-                         ipcomps->ipv6Entry, 1, 0, 0, 0, NEWT_ANCHOR_LEFT, 0);
-        newtGridSetField(rgrid, 1, 0, NEWT_GRID_COMPONENT,
-                         newtLabel(-1, -1, _("/")),
-                         1, 0, 0, 0, NEWT_ANCHOR_LEFT, 0);
-        newtGridSetField(rgrid, 2, 0, NEWT_GRID_COMPONENT,
-                         ipcomps->cidr6Entry, 1, 0, 0, 0, NEWT_ANCHOR_LEFT, 0);
-
-        newtGridSetField(egrid, 1, pos, NEWT_GRID_SUBGRID, rgrid,
-                         0, 0, 0, 0, NEWT_ANCHOR_LEFT, 0);
-
-        newtComponentAddCallback(ipcomps->ipv6Entry, ipCallback, ipcomps);
-        newtComponentAddCallback(ipcomps->cidr6Entry, cidrCallback, ipcomps);
-
-        /* populate fields if we have data already */
-        if (iface_have_in6_addr(&iface->ip6addr)) {
-            if (inet_ntop(AF_INET6, &iface->ip6addr, ret,
-                          INET6_ADDRSTRLEN) == NULL) {
-                logMessage(ERROR, "%s (%d): %s", __func__, __LINE__,
-                           strerror(errno));
-            }
-        } else if (iface_have_in6_addr(&iface->ip6addr)) {
-            if (inet_ntop(AF_INET6, &iface->ip6addr, ret,
-                          INET6_ADDRSTRLEN) == NULL) {
-                logMessage(ERROR, "%s (%d): %s", __func__, __LINE__,
-                           strerror(errno));
-            }
-        }
-
-        if (*ret) {
-            newtEntrySet(ipcomps->ipv6Entry, ret, 1);
-        }
-
-        if (iface->ip6prefix) {
-            if (asprintf(&buf, "%d", iface->ip6prefix) == -1) {
-                buf = NULL;
-            }
-        } else if (iface->ip6prefix) {
-            if (asprintf(&buf, "%d", iface->ip6prefix) == -1) {
-                buf = NULL;
-            }
-        }
-
-        if (buf != NULL) {
-            newtEntrySet(ipcomps->cidr6Entry, buf, 1);
-            free(buf);
-        }
-
-        pos++;
-    }
-#endif
-
-    /* common entry items */
-    ipcomps->gwEntry = newtEntry(-1, -1, NULL, 41, &ipcomps->gw, 0);
-    ipcomps->nsEntry = newtEntry(-1, -1, NULL, 41, &ipcomps->ns, 0);
-
-    newtGridSetField(egrid, 0, pos, NEWT_GRID_COMPONENT,
-                     newtLabel(-1, -1, _("Gateway:")),
-                     0, 0, 0, 0, NEWT_ANCHOR_LEFT, 0);
-    newtGridSetField(egrid, 1, pos, NEWT_GRID_COMPONENT,
-                     ipcomps->gwEntry, 1, 0, 0, 0, NEWT_ANCHOR_LEFT, 0);
-
-    pos++;
-
-    newtGridSetField(egrid, 0, pos, NEWT_GRID_COMPONENT,
-                     newtLabel(-1, -1, _("Name Server:")),
-                     0, 0, 0, 0, NEWT_ANCHOR_LEFT, 0);
-    newtGridSetField(egrid, 1, pos, NEWT_GRID_COMPONENT,
-                     ipcomps->nsEntry, 1, 0, 0, 0, NEWT_ANCHOR_LEFT, 0);
-
-    if (iface_have_in_addr(&iface->gateway)) {
-        if (inet_ntop(AF_INET, &iface->gateway, ret,
-                      INET_ADDRSTRLEN) == NULL) {
-            logMessage(ERROR, "%s (%d): %s", __func__, __LINE__,
-                       strerror(errno));
-        } else {
-            newtEntrySet(ipcomps->gwEntry, ret, 1);
-        }
-    } else if (iface_have_in6_addr(&iface->gateway6)) {
-        if (inet_ntop(AF_INET6, &iface->gateway6, ret,
-                      INET6_ADDRSTRLEN) == NULL) {
-            logMessage(ERROR, "%s (%d): %s", __func__, __LINE__,
-                       strerror(errno));
-        } else {
-            newtEntrySet(ipcomps->gwEntry, ret, 1);
-        }
-    }
-
-    if (iface->numdns) {
-        newtEntrySet(ipcomps->nsEntry, iface->dns[0], 1);
-    } else if (iface->numdns) {
-        newtEntrySet(ipcomps->nsEntry, iface->dns[0], 1);
-    }
-
-    newtComponentAddCallback(ipcomps->gwEntry, ipCallback, ipcomps);
-    newtComponentAddCallback(ipcomps->nsEntry, ipCallback, ipcomps);
-
-    /* button bar at the bottom of the window */
-    buttons = newtButtonBar(_("OK"), &okay, _("Back"), &back, NULL);
-
-    /* main window layout */
-    grid = newtCreateGrid(1, 3);
-
-    checked_asprintf(&buf,
-                     _("Enter the IPv4 and/or the IPv6 address and prefix "
-                       "(address / prefix).  For IPv4, the dotted-quad "
-                       "netmask or the CIDR-style prefix are acceptable. "
-                       "The gateway and name server fields must be valid IPv4 "
-                       "or IPv6 addresses."));
-
-    text = newtTextboxReflowed(-1, -1, buf, 52, 0, 10, 0);
-
-    newtGridSetField(grid, 0, 0, NEWT_GRID_COMPONENT, text,
-                     0, 0, 0, 1, NEWT_ANCHOR_LEFT, 0);
-    newtGridSetField(grid, 0, 1, NEWT_GRID_SUBGRID, egrid,
-                     0, 0, 0, 1, NEWT_ANCHOR_LEFT, 0);
-    newtGridSetField(grid, 0, 2, NEWT_GRID_SUBGRID, buttons,
-                     0, 0, 0, 0, 0, NEWT_GRID_FLAG_GROWX);
-
-    f = newtForm(NULL, NULL, 0);
-    newtGridAddComponentsToForm(grid, f, 1);
-    newtGridWrappedWindow(grid, _("Manual TCP/IP Configuration"));
-    newtGridFree(grid, 1);
-
-    have[IPV4] = 0;
-    have[IPV6] = 0;
-
-    for (i = IPV4; i <= IPV6; i++) {
-        if (!stack[i]) {
-            have[i] = 2;
-        }
-    }
-
-    /* run the form */
-    while ((have[IPV4] != 2) || (have[IPV6] != 2)) {
-        answer = newtRunForm(f);
-
-        /* collect IPv4 data */
-        if (stack[IPV4]) {
-            if (ipcomps->ipv4) {
-                if (inet_pton(AF_INET, ipcomps->ipv4, &iface->ipaddr) <= 0) {
-                    logMessage(ERROR, "%s (%d): %s", __func__, __LINE__,
-                               strerror(errno));
-                } else {
-                    have[IPV4]++;
-                }
-            }
-
-            if (ipcomps->cidr4) {
-                if (inet_pton(AF_INET, ipcomps->cidr4, &iface->netmask) >= 1) {
-                    have[IPV4]++;
-                } else {
-                    errno = 0;
-                    cidr = strtol(ipcomps->cidr4, NULL, 10);
-
-                    if ((errno == ERANGE && (cidr == LONG_MIN ||
-                                             cidr == LONG_MAX)) ||
-                        (errno != 0 && cidr == 0)) {
-                        logMessage(ERROR, "%s: %d: %m", __func__, __LINE__);
-                        abort();
-                    }
-
-                    if (cidr >= 1 && cidr <= 32) {
-                        tmpaddr = iface_prefix2netmask(cidr);
-                        if (tmpaddr != NULL) {
-                            memcpy(&iface->netmask, tmpaddr,
-                                   sizeof(struct in_addr));
-                            have[IPV4]++;
-                        } else {
-                            iface->netmask.s_addr = 0;
-                        }
-                    }
-                }
-            }
-        }
-
-#ifdef ENABLE_IPV6
-        /* collect IPv6 data */
-        if (stack[IPV6]) {
-            if (ipcomps->ipv6) {
-                if (inet_pton(AF_INET6, ipcomps->ipv6, &iface->ip6addr) <= 0) {
-                    logMessage(ERROR, "%s (%d): %s", __func__, __LINE__,
-                               strerror(errno));
-                } else {
-                    have[IPV6]++;
-                }
-            }
-
-            if (ipcomps->cidr6) {
-                errno = 0;
-                prefix = strtol(ipcomps->cidr6, NULL, 10);
-
-                if ((errno == ERANGE && (prefix == LONG_MIN ||
-                                         prefix == LONG_MAX)) ||
-                    (errno != 0 && prefix == 0)) {
-                    logMessage(ERROR, "%s: %d: %m", __func__, __LINE__);
-                    abort();
-                }
-
-                if (prefix > 0 || prefix <= 128) {
-                    iface->ip6prefix = prefix;
-                    have[IPV6]++;
-                }
-            }
-        }
-#endif
-
-        /* collect common network settings */
-        if (ipcomps->gw) {
-            if (inet_pton(AF_INET, ipcomps->gw, &iface->gateway) <= 0) {
-               memset(&iface->gateway, 0, sizeof(iface->gateway));
-
-               if (inet_pton(AF_INET6, ipcomps->gw, &iface->gateway6) <= 0) {
-                   logMessage(ERROR, "%s (%d): %s", __func__, __LINE__,
-                              strerror(errno));
-                   memset(&iface->gateway6, 0, sizeof(iface->gateway6));
-               }
-            }
-        }
-
-        /* gather nameservers */
-        if (ipcomps->ns) {
-#ifdef ENABLE_IPV6
-            if ((inet_pton(AF_INET, ipcomps->ns, &addr) >= 1) ||
-                (inet_pton(AF_INET6, ipcomps->ns, &addr6) >= 1)) {
-#else
-            if (inet_pton(AF_INET, ipcomps->ns, &addr) >= 1) {
-#endif
-                iface->dns[0] = strdup(ipcomps->ns);
-                if (iface->numdns < 1)
-                    iface->numdns = 1;
-            }
-        }
-
-        /* user selected back, but we've saved what they entered already */
-        if (answer == back) {
-            newtFormDestroy(f);
-            newtPopWindow();
-            free(buf);
-            return LOADER_BACK;
-        }
-
-        /* we might be done now */
-        if (stack[IPV4] && have[IPV4] != 2) {
-            have[IPV4] = 0;
-            newtWinMessage(_("Missing Information"), _("Retry"),
-                           _("You must enter both a valid IPv4 address and a "
-                             "network mask or CIDR prefix."));
-        }
-
-#ifdef ENABLE_IPV6
-        if (stack[IPV6] && have[IPV6] != 2) {
-            have[IPV6] = 0;
-            newtWinMessage(_("Missing Information"), _("Retry"),
-                           _("You must enter both a valid IPv6 address and a "
-                             "CIDR prefix."));
-        }
-#endif
-
-        strcpy(iface->device, device);
-    }
-
-    free(buf);
-    newtFormDestroy(f);
-    newtPopWindow();
-
-    return LOADER_OK;
-}
-
-/*
- * By default, we disable all network interfaces and then only
- * bring up the ones the user wants.
- */
-int writeDisabledNetInfo(void) {
-    int i = 0;
-    char *ofile = NULL;
-    char *nfile = NULL;
-    FILE *fp = NULL;
-    struct device **devs = NULL;
-
-    devs = getDevices(DEVICE_NETWORK);
-
-    if (devs == NULL) {
-        return 1;
-    }
-
-    for (i = 0; devs[i]; i++) {
-        /* remove dhclient-DEVICE.conf if we have it */
-        if (asprintf(&ofile, "/etc/dhcp/dhclient-%s.conf", devs[i]->device) == -1) {
-            return 5;
-        }
-
-        if (!access(ofile, R_OK|W_OK)) {
-            if (unlink(ofile)) {
-                logMessage(ERROR, "error removing %s", ofile);
-            }
-        }
-
-        if (ofile) {
-            free(ofile);
-            ofile = NULL;
-        }
-
-        /* write disabled ifcfg-DEVICE file */
-        
-        checked_asprintf(&ofile, "%s/.ifcfg-%s",
-                         NETWORK_SCRIPTS_PATH,
-                         devs[i]->device);
-        checked_asprintf(&nfile, "%s/ifcfg-%s",
-                         NETWORK_SCRIPTS_PATH,
-                         devs[i]->device);
-
-        if ((fp = fopen(ofile, "w")) == NULL) {
-            free(ofile);
-            return 2;
-        }
-
-        fprintf(fp, "DEVICE=%s\n", devs[i]->device);
-        fprintf(fp, "HWADDR=%s\n", iface_mac2str(devs[i]->device));
-        fprintf(fp, "ONBOOT=no\n");
-        fprintf(fp, "NM_CONTROLLED=no\n");
-
-        if (fclose(fp) == EOF) {
-            return 3;
-        }
-
-        if (rename(ofile, nfile) == -1) {
-            free(ofile);
-            free(nfile);
-            return 4;
-        }
-
-        if (ofile) {
-            free(ofile);
-            ofile = NULL;
-        }
-
-        if (nfile) {
-            free(nfile);
-            nfile = NULL;
-        }
-    }
-
-    return 0;
-}
-
-/*
- * Write out network interface control files:
- *     /etc/sysconfig/network-scripts/ifcfg-DEVICE
- *     /etc/sysconfig/network
- */
-int writeEnabledNetInfo(iface_t *iface) {
-    int i = 0, osa_layer2 = 0, osa_portno = 0;
-    mode_t mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH;
-    FILE *fp = NULL;
-    char buf[INET6_ADDRSTRLEN+1];
-    char *ofile = NULL;
-    char *nfile = NULL;
-    struct utsname kv;
-
-    memset(&buf, '\0', sizeof(buf));
-
-    if ((mkdir(NETWORK_SCRIPTS_PATH, mode) == -1) && (errno != EEXIST)) {
-        return 16;
-    }
-
-    /* write vendor class */
-    if (iface->vendorclass == NULL) {
-        if (uname(&kv) == -1) {
-            iface->vendorclass = "anaconda";
-        } else {
-            if (asprintf(&iface->vendorclass, "anaconda-%s %s %s",
-                         kv.sysname, kv.release, kv.machine) == -1 ) {
-                return 20;
-            }
-        }
-    }
-
-    if (asprintf(&ofile, "/etc/dhcp/dhclient-%s.conf", iface->device) == -1) {
-        return 17;
-    }
-
-    if ((fp = fopen(ofile, "w")) == NULL) {
-        free(ofile);
-        return 18;
-    }
-
-    fprintf(fp, "send vendor-class-identifier \"%s\";\n",
-            iface->vendorclass);
-
-    if (fclose(fp) == EOF) {
-        free(ofile);
-        return 19;
-    }
-
-    if (ofile) {
-        free(ofile);
-        ofile = NULL;
-    }
-
-    /* write out new ifcfg-DEVICE file */
-    if (asprintf(&ofile, "%s/.ifcfg-%s",
-                 NETWORK_SCRIPTS_PATH, iface->device) == -1) {
-        return 1;
-    }
-
-    if (asprintf(&nfile, "%s/ifcfg-%s",
-                 NETWORK_SCRIPTS_PATH, iface->device) == -1) {
-        return 13;
-    }
-
-    if ((fp = fopen(ofile, "w")) == NULL) {
-        free(ofile);
-        return 2;
-    }
-
-    fprintf(fp, "DEVICE=%s\n", iface->device);
-    fprintf(fp, "HWADDR=%s\n", iface_mac2str(iface->device));
-    fprintf(fp, "ONBOOT=yes\n");
-
-    if (!FL_NOIPV4(flags)) {
-        if (iface->ipv4method == IPV4_IBFT_METHOD) {
-	    /* When initrd and NM support iBFT, we should just write
-	     * BOOTPROTO=ibft and let NM deal with it. Until than,
-	     * just use static and do it ourselves. */
-            fprintf(fp, "BOOTPROTO=static\n");
-	    if(ibft_iface_ip()) fprintf(fp, "IPADDR=%s\n", ibft_iface_ip());
-	    if(ibft_iface_mask()) fprintf(fp, "NETMASK=%s\n", ibft_iface_mask());
-	    if(ibft_iface_gw()) fprintf(fp, "GATEWAY=%s\n", ibft_iface_gw());
-        } else if (iface->ipv4method == IPV4_IBFT_DHCP_METHOD) {
-            fprintf(fp, "BOOTPROTO=dhcp\n");
-        } else if (iface->ipv4method == IPV4_DHCP_METHOD) {
-            fprintf(fp, "BOOTPROTO=dhcp\n");
-        } else if (iface->ipv4method == IPV4_MANUAL_METHOD) {
-            fprintf(fp, "BOOTPROTO=static\n");
-
-            if (iface_have_in_addr(&iface->ipaddr)) {
-                if (inet_ntop(AF_INET, &iface->ipaddr, buf,
-                              INET_ADDRSTRLEN) == NULL) {
-                    free(ofile);
-                    fclose(fp);
-                    return 3;
-                }
-
-                fprintf(fp, "IPADDR=%s\n", buf);
-            }
-
-            if (iface_have_in_addr(&iface->netmask)) {
-                if (inet_ntop(AF_INET, &iface->netmask, buf,
-                              INET_ADDRSTRLEN) == NULL) {
-                    free(ofile);
-                    fclose(fp);
-                    return 4;
-                }
-
-                fprintf(fp, "NETMASK=%s\n", buf);
-            }
-
-            if (iface_have_in_addr(&iface->broadcast)) {
-                if (inet_ntop(AF_INET, &iface->broadcast, buf,
-                              INET_ADDRSTRLEN) == NULL) {
-                    free(ofile);
-                    fclose(fp);
-                    return 5;
-                }
-
-                fprintf(fp, "BROADCAST=%s\n", buf);
-            }
-
-            if (iface_have_in_addr(&iface->gateway)) {
-                if (inet_ntop(AF_INET, &iface->gateway, buf,
-                              INET_ADDRSTRLEN) == NULL) {
-                    free(ofile);
-                    fclose(fp);
-                    return 6;
-                }
-
-                fprintf(fp, "GATEWAY=%s\n", buf);
-            }
-        }
-    }
-
-#ifdef ENABLE_IPV6
-    if (!FL_NOIPV6(flags)) {
-        if (iface->ipv6method == IPV6_AUTO_METHOD ||
-            iface->ipv6method == IPV6_DHCP_METHOD ||
-            iface->ipv6method == IPV6_MANUAL_METHOD) {
-            fprintf(fp, "IPV6INIT=yes\n");
-
-            if (iface->ipv6method == IPV6_AUTO_METHOD) {
-                fprintf(fp, "IPV6_AUTOCONF=yes\n");
-            } else if (iface->ipv6method == IPV6_DHCP_METHOD) {
-                fprintf(fp, "DHCPV6C=yes\n");
-            } else if (iface->ipv6method == IPV6_MANUAL_METHOD) {
-                if (iface_have_in6_addr(&iface->ip6addr)) {
-                    if (inet_ntop(AF_INET6, &iface->ip6addr, buf,
-                                  INET6_ADDRSTRLEN) == NULL) {
-                        free(ofile);
-                        fclose(fp);
-                        return 7;
-                    }
-
-                    if (iface->ip6prefix) {
-                        fprintf(fp, "IPV6ADDR=%s/%d\n", buf, iface->ip6prefix);
-                    } else {
-                        fprintf(fp, "IPV6ADDR=%s\n", buf);
-                    }
-                }
-            }
-
-            if (iface_have_in6_addr(&iface->gateway6)) {
-                if (inet_ntop(AF_INET6, &iface->gateway6, buf,
-                              INET6_ADDRSTRLEN) == NULL) {
-                    free(ofile);
-                    fclose(fp);
-                    return 8;
-                }
-
-                fprintf(fp, "IPV6_DEFAULTGW=%s\n", buf);
-            }
-        }
-    }
-#endif
-
-    if (iface->numdns > 0) {
-        for (i = 0; i < iface->numdns; i++) {
-            fprintf(fp, "DNS%d=%s\n", i+1, iface->dns[i]);
-        }
-    }
-
-    if (iface->hostname) {
-        fprintf(fp, "HOSTNAME=%s\n", iface->hostname);
-    }
-
-    if (iface->domain) {
-        fprintf(fp, "DOMAIN=%s\n", iface->domain);
-    }
-
-    if (iface->mtu) {
-        fprintf(fp, "MTU=%d\n", iface->mtu);
-    }
-
-    if (iface->peerid) {
-        fprintf(fp, "PEERID=%s\n", iface->peerid);
-    }
-
-    if (iface->subchannels) {
-        fprintf(fp, "SUBCHANNELS=%s\n", iface->subchannels);
-    }
-
-    if (iface->portname) {
-        fprintf(fp, "PORTNAME=%s\n", iface->portname);
-    }
-
-    if (iface->nettype) {
-        fprintf(fp, "NETTYPE=%s\n", iface->nettype);
-    }
-
-    if (iface->ctcprot) {
-        fprintf(fp, "CTCPROT=%s\n", iface->ctcprot);
-    }
-
-    if (iface->layer2 && !strcmp(iface->layer2, "1")) {
-        osa_layer2 = 1;
-    }
-
-    if (iface->portno && !strcmp(iface->portno, "1")) {
-        osa_portno = 1;
-    }
-
-    if (osa_layer2 || osa_portno) {
-        fprintf(fp, "OPTIONS=\"");
-
-        if (osa_layer2) {
-            fprintf(fp, "layer2=1");
-        }
-
-        if (osa_layer2 && osa_portno) {
-            fprintf(fp, " ");
-        }
-
-        if (osa_portno) {
-            fprintf(fp, "portno=1");
-        }
-
-        fprintf(fp, "\"\n");
-    }
-
-    if (iface->macaddr) {
-        fprintf(fp, "MACADDR=%s\n", iface->macaddr);
-    }
-
-    if (fclose(fp) == EOF) {
-        free(ofile);
-        free(nfile);
-        return 8;
-    }
-
-    if (rename(ofile, nfile) == -1) {
-        free(ofile);
-        free(nfile);
-        return 14;
-    }
-
-    if (ofile) {
-        free(ofile);
-    }
-
-    if (nfile) {
-        free(nfile);
-    }
-
-    /* Global settings */
-    if ((fp = fopen(SYSCONFIG_PATH"/.network", "w")) == NULL) {
-        return 9;
-    }
-
-    if (!FL_NOIPV4(flags)) {
-        fprintf(fp, "NETWORKING=yes\n");
-    }
-
-#ifdef ENABLE_IPV6
-    if (!FL_NOIPV6(flags)) {
-        fprintf(fp, "NETWORKING_IPV6=yes\n");
-    }
-#endif
-
-    if (iface->hostname != NULL) {
-        fprintf(fp, "HOSTNAME=%s\n", iface->hostname);
-    }
-
-    if (iface_have_in_addr(&iface->gateway)) {
-        if (inet_ntop(AF_INET, &iface->gateway, buf,
-                      INET_ADDRSTRLEN) == NULL) {
-            fclose(fp);
-            return 10;
-        }
-
-        fprintf(fp, "GATEWAY=%s\n", buf);
-    }
-
-#ifdef ENABLE_IPV6
-    if (iface_have_in6_addr(&iface->gateway6)) {
-        if (inet_ntop(AF_INET6, &iface->gateway6, buf,
-                      INET6_ADDRSTRLEN) == NULL) {
-            fclose(fp);
-            return 11;
-        }
-
-        fprintf(fp, "IPV6_DEFAULTGW=%s\n", buf);
-    }
-#endif
-
-    if (fclose(fp) == EOF) {
-        return 12;
-    }
-
-    if (rename(SYSCONFIG_PATH"/.network",
-               SYSCONFIG_PATH"/network") == -1) {
-        return 15;
-    }
-
-    return 0;
-}
-
-void setKickstartNetwork(struct loaderData_s * loaderData, int argc, 
-                         char ** argv) {
-    iface_t iface;
-    gchar *bootProto = NULL, *device = NULL, *class = NULL, *ethtool = NULL;
-    gchar *essid = NULL, *wepkey = NULL, *onboot = NULL;
-    gint mtu = 1500, dhcpTimeout = -1;
-    gboolean noipv4 = FALSE, noipv6 = FALSE, noDns = FALSE, noksdev = FALSE;
-    GOptionContext *optCon = g_option_context_new(NULL);
-    GError *optErr = NULL;
-    GOptionEntry ksOptions[] = {
-        { "bootproto", 0, 0, G_OPTION_ARG_STRING, &bootProto, NULL, NULL },
-        { "device", 0, 0, G_OPTION_ARG_STRING, &device, NULL, NULL },
-        { "dhcpclass", 0, 0, G_OPTION_ARG_STRING, &class, NULL, NULL },
-        { "gateway", 'g', 0, G_OPTION_ARG_STRING, &loaderData->gateway,
-          NULL, NULL },
-        { "ip", 'i', 0, G_OPTION_ARG_STRING, &loaderData->ipv4, NULL, NULL },
-        { "mtu", 0, 0, G_OPTION_ARG_INT, &mtu, NULL, NULL },
-        { "nameserver", 'n', 0, G_OPTION_ARG_STRING, &loaderData->dns,
-          NULL, NULL },
-        { "netmask", 'm', 0, G_OPTION_ARG_STRING, &loaderData->netmask,
-          NULL, NULL },
-        { "noipv4", 0, 0, G_OPTION_ARG_NONE, &noipv4, NULL, NULL },
-        { "noipv6", 0, 0, G_OPTION_ARG_NONE, &noipv6, NULL, NULL },
-        { "nodns", 0, 0, G_OPTION_ARG_NONE, &noDns, NULL, NULL },
-        { "hostname", 'h', 0, G_OPTION_ARG_STRING, &loaderData->hostname,
-          NULL, NULL },
-        { "ethtool", 0, 0, G_OPTION_ARG_STRING, &ethtool, NULL, NULL },
-        { "essid", 0, 0, G_OPTION_ARG_STRING, &essid, NULL, NULL },
-        { "wepkey", 0, 0, G_OPTION_ARG_STRING, &wepkey, NULL, NULL },
-        { "onboot", 0, 0, G_OPTION_ARG_STRING, &onboot, NULL, NULL },
-        { "notksdevice", 0, 0, G_OPTION_ARG_NONE, &noksdev, NULL, NULL },
-        { "dhcptimeout", 0, 0, G_OPTION_ARG_INT, &dhcpTimeout, NULL, NULL },
-        { NULL },
-    };
-
-    iface_init_iface_t(&iface);
-
-    g_option_context_set_help_enabled(optCon, FALSE);
-    g_option_context_add_main_entries(optCon, ksOptions, NULL);
-
-    if (!g_option_context_parse(optCon, &argc, &argv, &optErr)) {
-        newtWinMessage(_("Kickstart Error"), _("OK"),
-                       _("Bad argument to kickstart network command: %s"),
-                       optErr->message);
-        g_error_free(optErr);
-    }
-
-    g_option_context_free(optCon);
-
-    /* if they've specified dhcp/bootp use dhcp for the interface */
-    if (bootProto && (!strncmp(bootProto, "dhcp", 4) || 
-                       !strncmp(bootProto, "bootp", 4))) {
-        loaderData->ipv4 = strdup("dhcp");
-        loaderData->ipinfo_set = 1;
-    } else if (loaderData->ipv4) {
-        /* JKFIXME: this assumes a bit... */
-        loaderData->ipinfo_set = 1;
-    }
-
-    /* now make sure the specified bootproto is valid */
-    if (bootProto && strcmp(bootProto, "dhcp") && strcmp(bootProto, "bootp") &&
-        strcmp(bootProto, "static") && strcmp(bootProto, "query")) {
-        newtWinMessage(_("Kickstart Error"), _("OK"),
-                       _("Bad bootproto %s specified in network command"),
-                       bootProto);
-    }
-
-    if (!noksdev) {
-        if (device) {
-            /* If --device=MAC was given, translate into a device name now. */
-            if (index(device, ':') != NULL)
-                loaderData->netDev = iface_mac2device(device);
-            else
-                loaderData->netDev = strdup(device);
-
-            loaderData->netDev_set = 1;
-        }
-
-        if (class) {
-            loaderData->netCls = strdup(class);
-            loaderData->netCls_set = 1;
-        }
-
-        if (ethtool) {
-            if (loaderData->ethtool)
-                free(loaderData->ethtool);
-            loaderData->ethtool = strdup(ethtool);
-            free(ethtool);
-        }
-
-        if (essid) {
-            if (loaderData->essid)
-                free(loaderData->essid);
-            loaderData->essid = strdup(essid);
-            free(essid);
-        }
-
-        if (wepkey) {
-            if (loaderData->wepkey)
-                free(loaderData->wepkey);
-            loaderData->wepkey = strdup(wepkey);
-            free(wepkey);
-        }
-
-        if (mtu) {
-           loaderData->mtu = mtu;
-        }
-
-        if (noipv4)
-            flags |= LOADER_FLAGS_NOIPV4;
-
-#ifdef ENABLE_IPV6
-        if (noipv6)
-            flags |= LOADER_FLAGS_NOIPV6;
-#endif
-    }
-
-    if (noDns) {
-        loaderData->noDns = 1;
-    }
-
-    /* Make sure the network is always up if there's a network line in the
-     * kickstart file, as %post/%pre scripts might require that.
-     */
-    if (loaderData->method != METHOD_NFS && loaderData->method != METHOD_URL) {
-        if (kickstartNetworkUp(loaderData, &iface))
-            logMessage(ERROR, "unable to bring up network");
-    }
-}
-
-/* if multiple interfaces get one to use from user.   */
-/* NOTE - uses kickstart data available in loaderData */
-int chooseNetworkInterface(struct loaderData_s * loaderData) {
-    int i, rc, ask, idrc, secs, deviceNums = 0, deviceNum, foundDev = 0;
-    unsigned int max = 40;
-    char **devices;
-    char **deviceNames;
-    char *ksMacAddr = NULL, *seconds = strdup("10"), *idstr = NULL;
-    struct device **devs;
-    int lookForLink = 0;
-    struct newtWinEntry entry[] = {{N_("Seconds:"), (char **) &seconds, 0},
-                                   {NULL, NULL, 0 }};
-
-    devs = getDevices(DEVICE_NETWORK);
-    if (!devs) {
-        logMessage(ERROR, "no network devices in choose network device!");
-        return LOADER_ERROR;
-    }
-
-    for (i = 0; devs[i]; i++);
-
-    devices = alloca((i + 1) * sizeof(*devices));
-    deviceNames = alloca((i + 1) * sizeof(*devices));
-    if (loaderData->netDev && (loaderData->netDev_set) == 1) {
-        if ((loaderData->bootIf && (loaderData->bootIf_set) == 1) &&
-            !strcasecmp(loaderData->netDev, "bootif")) {
-            ksMacAddr = g_ascii_strup(loaderData->bootIf, -1);
-        } else {
-            ksMacAddr = g_ascii_strup(loaderData->netDev, -1);
-        }
-    }
-
-    for (i = 0; devs[i]; i++) {
-        if (!devs[i]->device)
-            continue;
-
-        if (devs[i]->description) {
-            deviceNames[deviceNums] = alloca(strlen(devs[i]->device) +
-                                      strlen(devs[i]->description) + 4);
-            sprintf(deviceNames[deviceNums],"%s - %.50s",
-                    devs[i]->device, devs[i]->description);
-
-            if (strlen(deviceNames[deviceNums]) > max)
-                max = strlen(deviceNames[deviceNums]);
-
-            devices[deviceNums] = devs[i]->device;
-        } else {
-            devices[deviceNums] = devs[i]->device;
-            deviceNames[deviceNums] = devs[i]->device;
-        }
-
-        deviceNums++;
-
-        /* this device has been set and we don't really need to ask 
-         * about it again... */
-        if (loaderData->netDev && (loaderData->netDev_set == 1)) {
-            if (!strcmp(loaderData->netDev, devs[i]->device)) {
-                foundDev = 1;
-            } else if (ksMacAddr != NULL) {
-                /* maybe it's a mac address */
-                char *devmacaddr = iface_mac2str(devs[i]->device);
-
-                if ((devmacaddr != NULL) && !strcmp(ksMacAddr, devmacaddr)) {
-                    foundDev = 1;
-                    free(loaderData->netDev);
-                    loaderData->netDev = devs[i]->device;
-                    if (devmacaddr != NULL)
-                        free(devmacaddr);
-                    break;
-                }
-
-                if (devmacaddr != NULL)
-                    free(devmacaddr);
-            }
-        }
-    }
-
-    if (ksMacAddr)
-        free(ksMacAddr);
-    if (foundDev == 1)
-        return LOADER_NOOP;
-
-    devices[deviceNums] = NULL;
-    deviceNames[deviceNums] = NULL;
-    qsort(devices, deviceNums, sizeof(*devices), simpleStringCmp);
-    qsort(deviceNames, deviceNums, sizeof(*devices), simpleStringCmp);
-
-    /* ASSERT: we should *ALWAYS* have a network device when we get here */
-    if (!deviceNums) {
-        logMessage(CRITICAL, "no network device in chooseNetworkInterface");
-        return LOADER_ERROR;
-    }
-
-    /* If there is iBFT table and ksdevice doesn't say otherwise, use it */
-    while (!loaderData->netDev_set || !strcmp(loaderData->netDev, "ibft")) {
-        char *devmacaddr = NULL;
-        char *ibftmacaddr = "";
-
-        /* get MAC from the iBFT table */
-        if (!(ibftmacaddr = ibft_iface_mac())) { /* iBFT not present or error */
-            logMessage(ERROR, "iBFT doesn't couldn't provide valid NIC MAC address");
-            break;
-        }
-
-        logMessage(INFO, "looking for iBFT configured device %s with link",
-                   ibftmacaddr);
-
-        for (i = 0; devs[i]; i++) {
-            if (!devs[i]->device)
-                continue;
-
-            devmacaddr = iface_mac2str(devs[i]->device);
-
-            if(!strcasecmp(devmacaddr, ibftmacaddr)){
-                logMessage(INFO,
-                           "%s has the right MAC (%s), checking for link",
-                           devs[i]->device, devmacaddr);
-                free(devmacaddr);
-
-                /* wait for the link (max 5s) */
-                for (rc = 0; rc < 5; rc++) {
-                    if (get_link_status(devs[i]->device) == 0) {
-                        logMessage(INFO, "%s still has no link, waiting", devs[i]->device);
-                        sleep(1);                 
-                    } else {
-                        lookForLink = 0;
-                        loaderData->netDev = devs[i]->device;
-                        loaderData->netDev_set = 1;
-                        logMessage(INFO, "%s has link, using it", devs[i]->device);
-
-                        /* set the IP method to ibft if not requested differently */
-                        if (loaderData->ipv4 == NULL) {
-                            loaderData->ipv4 = strdup("ibft");
-                            loaderData->ipinfo_set = 1;
-                            logMessage(INFO,
-                                       "%s will be configured using iBFT values",
-                                       devices[i]);
-                        }
-
-                        return LOADER_NOOP;
-                    }
-                }
-
-                logMessage(INFO, "%s has no link, skipping it", devices[i]);
-
-                break;
-            } else {
-                free(devmacaddr);
-            }
-        }
-
-        break;
-    }
-
-    if ((loaderData->netDev && (loaderData->netDev_set == 1)) &&
-        !strcmp(loaderData->netDev, "link")) {
-        lookForLink = 1;
-    }
-
-    if (lookForLink) {
-        logMessage(INFO, "looking for first netDev with link");
-
-        for (rc = 0; rc < 5; rc++) {
-            for (i = 0; i < deviceNums; i++) {
-                if (get_link_status(devices[i]) == 1) {
-                    loaderData->netDev = devices[i];
-                    logMessage(INFO, "%s has link, using it", devices[i]);
-                    return LOADER_NOOP;
-                }
-            }
-
-            sleep(1);
-        }
-
-        logMessage(WARNING,
-                   "wanted netdev with link, but none present.  prompting");
-    }
-
-    /* JKFIXME: if we only have one interface and it doesn't have link,
-     * do we go ahead? */
-    if (deviceNums == 1) {
-        logMessage(INFO, "only have one network device: %s", devices[0]);
-        loaderData->netDev = devices[0];
-        loaderData->netDev_set = 1;
-        return LOADER_NOOP;
-    }
-
-    if (FL_CMDLINE(flags)) {
-        fprintf(stderr, "No way to determine which NIC to use, and cannot "
-                        "prompt in cmdline\nmode.  Halting.\n");
-        fprintf(stderr, "Please use the ksdevice= parameter to specify the "
-                        "device name (e.g., eth0)\n or the MAC address of "
-                        "the NIC to use for installation.\n");
-        exit(1);
-    }
-
-    startNewt();
-
-    if (max > 70)
-        max = 70;
-
-    /* JKFIXME: should display link status */
-    deviceNum = 0;
-    ask = 1;
-    while (ask) {
-        rc = newtWinMenu(_("Networking Device"),
-                         _("You have multiple network devices on this system. "
-                           "Which would you like to install through?"),
-                         max, 10, 10,
-                         deviceNums < 6 ? deviceNums : 6, deviceNames,
-                         &deviceNum, _("OK"), _("Identify"), _("Back"), NULL);
-
-        if (rc == 2) {
-            if (!devices[deviceNum]) {
-                logMessage(ERROR, "NIC %d contains no device name", deviceNum);
-                continue;
-            }
-
-            checked_asprintf(&idstr, "%s %s %s",
-                             _("You can identify the physical port for"),
-                             devices[deviceNum],
-                             _("by flashing the LED lights for a number of "
-                               "seconds.  Enter a number between 1 and 30 to "
-                               "set the duration to flash the LED port "
-                               "lights."));
-
-            i = 1;
-            while (i) {
-                idrc = newtWinEntries(_("Identify NIC"), idstr, 50, 5, 15, 24,
-                                      entry, _("OK"), _("Back"), NULL);
-
-                if (idrc == 0 || idrc == 1) {
-                    errno = 0;
-                    secs = strtol((const char *) seconds, NULL, 10);
-                    if (errno == EINVAL || errno == ERANGE) {
-                        logMessage(ERROR, "strtol() failure in %s: %m",
-                                   __func__);
-                        continue;
-                    }
-
-                    if (secs <=0 || secs > 300) {
-                        newtWinMessage(_("Invalid Duration"), _("OK"),
-                                       _("You must enter the number of "
-                                         "seconds as an integer between 1 "
-                                         "and 30."));
-                        continue;
-                    }
-
-                    idrc = 41 + strlen(devices[deviceNum]);
-                    if (secs > 9) {
-                        idrc += 1;
-                    }
-
-                    winStatus(idrc, 3, NULL,
-                              _("Flashing %s port lights for %d seconds."),
-                              devices[deviceNum], secs);
-
-                    if (identifyNIC(devices[deviceNum], secs)) {
-                        logMessage(ERROR,
-                                   "error during physical NIC identification");
-                    }
-
-                    newtPopWindow();
-                    i = 0;
-                } else if (idrc == 2) {
-                    i = 0;
-                }
-            }
-        } else if (rc == 3) {
-            ask = 0;
-            return LOADER_BACK;
-        } else {
-            ask = 0;
-        }
-    }
-
-    loaderData->netDev = devices[deviceNum];
-    return LOADER_OK;
-}
-
-/* JKFIXME: bad name.  this function brings up networking early on a 
- * kickstart install so that we can do things like grab the ks.cfg from
- * the network */
-int kickstartNetworkUp(struct loaderData_s * loaderData, iface_t * iface) {
-    int rc, err;
-
-    if ((is_nm_connected() == TRUE) &&
-        (loaderData->netDev != NULL) && (loaderData->netDev_set == 1))
-        return 0;
-
-    memset(iface, 0, sizeof(*iface));
-
-    do {
-        do {
-            /* this is smart and does the right thing based on whether or not
-             * we have ksdevice= specified */
-            rc = chooseNetworkInterface(loaderData);
-
-            if (rc == LOADER_ERROR) {
-                /* JKFIXME: ask for a driver disk? */
-                logMessage(ERROR, "no network drivers for doing kickstart");
-                return -1;
-            } else if (rc == LOADER_BACK) {
-                return -1;
-            }
-
-            /* insert device into iface structure */
-            strcpy(iface->device, loaderData->netDev);
-
-            break;
-        } while (1);
-
-        /* we don't want to end up asking about interface more than once
-         * if we're in a kickstart-ish case (#100724) */
-        loaderData->netDev_set = 1;
-
-        /* default to DHCP for IPv4 if nothing is provided */
-        if (loaderData->ipv4 == NULL) {
-            loaderData->ipv4 = strdup("dhcp");
-            loaderData->ipinfo_set = 1;
-        }
-
-        setupIfaceStruct(iface, loaderData);
-        rc = readNetConfig(loaderData->netDev, iface, loaderData->netCls,
-                           loaderData->method);
-
-        if (rc == LOADER_ERROR) {
-            logMessage(ERROR, "unable to setup networking");
-            return -1;
-        } else if (rc == LOADER_BACK) {
-            /* Going back to the interface selection screen, so unset anything
-             * we set before attempting to bring the incorrect interface up.
-             */
-            if ((rc = writeDisabledNetInfo()) != 0) {
-                logMessage(ERROR, "writeDisabledNetInfo failure (%s): %d",
-                           __func__, rc);
-            }
-
-            loaderData->netDev_set = 0;
-            loaderData->ipinfo_set = 0;
-            free(loaderData->ipv4);
-            loaderData->ipv4 = NULL;
-            break;
-        } else {
-            break;
-        }
-
-        err = writeEnabledNetInfo(iface);
-        if (err) {
-            logMessage(ERROR,
-                       "failed to write %s data for %s (%d)",
-                       SYSCONFIG_PATH, iface->device, err);
-            return -1;
-        }
-
-        err = get_connection(iface);
-        newtPopWindow();
-
-        if (err) {
-            logMessage(ERROR, "failed to start NetworkManager (%d)", err);
-            return -1;
-        }
-    } while (1);
-
-    return 0;
-}
-
-void splitHostname (char *str, char **host, char **port)
-{
-    char *rightbrack = strchr(str, ']');
-    char *firstcolon = strchr(str, ':');
-    char *secondcolon = strrchr(str, ':');
-
-    *host = NULL;
-    *port = NULL;
-
-    if (*str == '[' && rightbrack) {
-        /* An IPv6 address surrounded by brackets, optionally with a colon and
-         * port number.
-         */
-        char *colon = strrchr(rightbrack, ':');
-
-        if (colon) {
-            *host = strndup(str+1, rightbrack-1-str);
-            *port = strdup(colon+1);
-        }
-        else
-            *host = strndup(str+1, rightbrack-1-str);
-    } else if (firstcolon && secondcolon && firstcolon != secondcolon) {
-        /* An IPv6 address without brackets.  Don't make the user surround the
-         * address with brackets if there's no port number.
-         */
-        *host = strdup(str);
-    } else {
-        /* An IPv4 address, optionally with a colon and port number. */
-        char *colon = strrchr(str, ':');
-
-        if (colon) {
-            *host = strndup(str, colon-str);
-            *port = strdup(colon+1);
-        }
-        else
-            *host = strdup(str);
-    }
-}
-
-/*
- * Start NetworkManager and wait for a valid link, return non-zero on error.
- */
-int get_connection(iface_t *iface) {
-    int count = 0;
-    NMClient *client = NULL;
-    NMState state;
-    GMainLoop *loop;
-    GMainContext *ctx;
-
-    if (iface == NULL) {
-        return 1;
-    }
-
-    logMessage(DEBUGLVL, "configuring device %s", iface->device);
-
-    /* display status */
-    if (FL_CMDLINE(flags)) {
-        printf(_("Waiting for NetworkManager to configure %s.\n"),
-               iface->device);
-    } else {
-        winStatus(55, 3, NULL,
-                  _("Waiting for NetworkManager to configure %s.\n"),
-                  iface->device, 0);
-    }
-
-    g_type_init();
-
-    client = nm_client_new();
-    if (!client) {
-        logMessage(ERROR, "%s (%d): could not connect to system bus",
-                   __func__, __LINE__);
-        return 2;
-    }
-
-    /* Create a loop for processing dbus signals */
-    loop = g_main_loop_new(NULL, FALSE);
-    ctx = g_main_loop_get_context(loop);
-
-    /* pump the loop until all the messages are clear */
-    while (g_main_context_pending (ctx)) {
-        g_main_context_iteration (ctx, FALSE);
-    }
-
-    /* send message and block until a reply or error comes back */
-    while (count < 45) {
-        /* pump the loop again to clear the messages */
-        while (g_main_context_pending (ctx)) {
-            g_main_context_iteration (ctx, FALSE);
-        }
-        state = nm_client_get_state(client);
-
-        if (state == NM_STATE_CONNECTED) {
-            logMessage(INFO, "%s (%d): NetworkManager connected",
-                       __func__, __LINE__);
-            res_init();
-            g_object_unref(client);
-            return 0;
-        }
-
-        sleep(1);
-        count++;
-    }
-
-    g_main_loop_unref(loop);
-    g_object_unref(client);
-    return 3;
-}
-
-/* vim:set shiftwidth=4 softtabstop=4: */
diff --git a/loader/net.h b/loader/net.h
deleted file mode 100644
index 8245084..0000000
--- a/loader/net.h
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- * net.h
- *
- * Copyright (C) 2007  Red Hat, Inc.  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 as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * 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, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef H_LOADER_NET
-#define H_LOADER_NET
-
-#include <newt.h>
-#include "../isys/iface.h"
-#include "loader.h"
-
-#define DHCP_METHOD_STR   _("Dynamic IP configuration (DHCP)")
-#define MANUAL_METHOD_STR _("Manual configuration")
-#ifdef ENABLE_IPV6
-#define DHCPV6_METHOD_STR _("Dynamic IP configuration (DHCPv6)")
-#define AUTO_METHOD_STR   _("Automatic neighbor discovery")
-#endif
-
-#define SYSCONFIG_PATH       "/etc/sysconfig"
-#define NETWORK_SCRIPTS_PATH "/etc/sysconfig/network-scripts"
-
-struct intfconfig_s {
-    newtComponent ipv4Entry, cidr4Entry;
-    newtComponent gwEntry, nsEntry;
-    const char *ipv4, *cidr4;
-#ifdef ENABLE_IPV6
-    newtComponent ipv6Entry, cidr6Entry;
-    const char *ipv6, *cidr6;
-    const char *gw6;
-#endif
-    const char *gw, *ns;
-};
-
-struct netconfopts {
-    char ipv4Choice;
-#ifdef ENABLE_IPV6
-    char ipv6Choice;
-#endif
-};
-
-typedef int int32;
-
-int readNetConfig(char * device, iface_t * iface,
-                  char * dhcpclass, int methodNum);
-int configureTCPIP(char * device, iface_t * iface, struct netconfopts * opts,
-                   int methodNum);
-int manualNetConfig(char * device, iface_t * iface,
-                    struct intfconfig_s * ipcomps, struct netconfopts * opts);
-void debugNetworkInfo(iface_t * iface);
-int writeDisabledNetInfo(void);
-int writeEnabledNetInfo(iface_t * iface);
-int chooseNetworkInterface(struct loaderData_s * loaderData);
-void setupIfaceStruct(iface_t * iface, struct loaderData_s * loaderData);
-int setupWireless(iface_t * iface);
-void setKickstartNetwork(struct loaderData_s * loaderData, int argc, 
-                         char ** argv);
-int kickstartNetworkUp(struct loaderData_s * loaderData,
-                       iface_t * iface);
-void splitHostname (char *str, char **host, char **port);
-int get_connection(iface_t * iface);
-
-#endif
diff --git a/loader/nfsinstall.c b/loader/nfsinstall.c
deleted file mode 100644
index b6c3c82..0000000
--- a/loader/nfsinstall.c
+++ /dev/null
@@ -1,586 +0,0 @@
-/*
- * nfsinstall.c - code to set up nfs installs
- *
- * Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
- * 2006, 2007  Red Hat, Inc.  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 as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * 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, see <http://www.gnu.org/licenses/>.
- *
- * Author(s): Erik Troan <ewt@xxxxxxxxxx>
- *            Matt Wilson <msw@xxxxxxxxxx>
- *            Michael Fulbright <msf@xxxxxxxxxx>
- *            Jeremy Katz <katzj@xxxxxxxxxx>
- */
-
-#include <fcntl.h>
-#include <newt.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-#include <errno.h>
-#include <string.h>
-#include <sys/stat.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <arpa/inet.h>
-#include <netdb.h>
-#include <glib.h>
-#include <nm-client.h>
-#include <nm-device.h>
-#include <nm-dhcp4-config.h>
-
-#include "copy.h"
-#include "loader.h"
-#include "lang.h"
-#include "loadermisc.h"
-#include "kickstart.h"
-#include "method.h"
-#include "nfsinstall.h"
-#include "net.h"
-#include "cdinstall.h"
-#include "windows.h"
-
-#include "../isys/imount.h"
-#include "../isys/iface.h"
-#include "../isys/log.h"
-
-/* boot flags */
-extern uint64_t flags;
-
-/**
- * Test whether the mounted stage2 path is an uncompreseed image, not a squashfs.
- * 
- * Asusme path is readable.
- */
-static int isNfsMountDirect(const char * path) {
-    struct stat stat_info;
-    if (stat(path, &stat_info))
-        return 0;
-
-    if (!S_ISDIR(stat_info.st_mode))
-        /* if it's not a directory, then it's not an uncompressed image */
-        return 0;
-
-    char * buildstamp;
-    checked_asprintf(&buildstamp, "%s/%s", path, ".buildstamp");
-    if (access(buildstamp, F_OK))
-        /* if it doesn't contain buildstamp, then it's not an uncompressed image */
-        return 0;
-    free(buildstamp);
-
-    return 1;
-}
-
-static int nfsGetSetup(char ** hostptr, char ** dirptr, char ** optsptr) {
-    struct newtWinEntry entries[4];
-    char * buf;
-    char * newServer = *hostptr ? strdup(*hostptr) : NULL;
-    char * newDir = *dirptr ? strdup(*dirptr) : NULL;
-    char * newMountOpts = *optsptr ? strdup(*optsptr) : NULL;
-    int rc;
-
-    entries[0].text = _("NFS server name:");
-    entries[0].value = &newServer;
-    entries[0].flags = NEWT_FLAG_SCROLL;
-    
-    checked_asprintf(&entries[1].text, _("%s directory:"), getProductName());
-
-    entries[1].value = &newDir;
-    entries[1].flags = NEWT_FLAG_SCROLL;
-    entries[2].text = _("NFS mount options (optional):");
-    entries[2].value = &newMountOpts;
-    entries[2].flags = NEWT_FLAG_SCROLL;
-    entries[3].text = NULL; 
-    entries[3].value = NULL;
-
-    if (asprintf(&buf, _("Please enter the server and path to your %s "
-                         "installation image and optionally additional "
-                         "NFS mount options."), getProductName()) == -1) {
-        logMessage(CRITICAL, "%s: %d: %m", __func__, __LINE__);
-        abort();
-    }
-
-    do {
-        rc = newtWinEntries(_("NFS Setup"), buf, 60, 5, 15,
-                            24, entries, _("OK"), _("Back"), NULL);
-    } while ((!strcmp(newServer, "") || !strcmp(newDir, "")) && rc != 2);
-
-    free(buf);
-    free(entries[1].text);
-
-    if (rc == 2) {
-        if (newServer) free(newServer);
-        if (newDir) free(newDir);
-        if (newMountOpts) free(newMountOpts);
-        return LOADER_BACK;
-    }
-
-    if (*hostptr) free(*hostptr);
-    if (*dirptr) free(*dirptr);
-    if (*optsptr) free(*optsptr);
-    *hostptr = newServer;
-    *dirptr = newDir;
-    *optsptr = newMountOpts;
-
-    return 0;
-}
-
-void parseNfsHostPathOpts(char *url, char **host, char **path, char **opts) {
-    char *tmp;
-    char *hostsrc;
-
-    logMessage(DEBUGLVL, "parseNfsHostPathOpts url: |%s|", url);
-
-    hostsrc = strdup(url);
-    *host = hostsrc;
-    tmp = strchr(*host, ':');
-
-    if (tmp) {
-       *path = strdup(tmp + 1);
-       *tmp = '\0';
-    }
-    else {
-        *path = malloc(sizeof(char *));
-        **path = '\0';
-    }
-
-    tmp = strchr(*path, ':');
-    if (tmp && (strlen(tmp) > 1)) {
-	char * c = tmp;
-        *opts = *host;
-        *host = *path;
-	*path = strdup(c + 1);
-	*c = '\0';
-    } else {
-	*opts = NULL;
-    }
-
-    logMessage(DEBUGLVL, "parseNfsHostPathOpts host: |%s|", *host);
-    logMessage(DEBUGLVL, "parseNfsHostPathOpts path: |%s|", *path);
-    logMessage(DEBUGLVL, "parseNfsHostPathOpts opts: |%s|", *opts);
-}
-
-static void addDefaultKickstartFile(char **file, char *ip) {
-    /* if the filename ends with / or is null, use default kickstart
-     * name of IP_ADDRESS-kickstart appended to *file
-     */
-    if ((*file) && (((*file)[strlen(*file) - 1] == '/') ||
-                    ((*file)[strlen(*file) - 1] == '\0'))) {
-        checked_asprintf(file, "%s%s-kickstart", *file, ip);
-        logMessage(DEBUGLVL, "addDefaultKickstartFile file: |%s|", *file);
-    }
-}
-
-char * mountNfsImage(struct installMethod * method,
-                     char * location, struct loaderData_s * loaderData) {
-    char * host = NULL;
-    char * directory = NULL;
-    char * mountOpts = NULL;
-    char * fullPath = NULL;
-    char * url = NULL;
-
-    enum { NFS_STAGE_NFS, NFS_STAGE_MOUNT, NFS_STAGE_DONE,
-           NFS_STAGE_UPDATES } stage = NFS_STAGE_NFS;
-
-    int rc;
-
-    /* JKFIXME: ASSERT -- we have a network device setup when we get here */
-    while (stage != NFS_STAGE_DONE) {
-        switch (stage) {
-        case NFS_STAGE_NFS:
-            if (loaderData->method == METHOD_NFS && loaderData->stage2Data) {
-                host = ((struct nfsInstallData *)loaderData->stage2Data)->host;
-                directory = ((struct nfsInstallData *)loaderData->stage2Data)->directory;
-
-                if (((struct nfsInstallData *)
-                    loaderData->stage2Data)->mountOpts == NULL) {
-                    mountOpts = strdup("ro");
-                } else {
-                    checked_asprintf(&mountOpts, "ro,%s",
-                                     ((struct nfsInstallData *)
-                                      loaderData->stage2Data)->mountOpts);
-                }
-
-                logMessage(INFO, "host is %s, dir is %s, opts are '%s'", host, directory, mountOpts);
-
-                if (!host || !directory) {
-                    logMessage(ERROR, "missing host or directory specification");
-
-                    if (loaderData->inferredStage2)
-                        loaderData->invalidRepoParam = 1;
-
-                    loaderData->method = -1;
-                    break;
-                } else {
-                    host = strdup(host);
-                    directory = strdup(directory);
-                }
-            } else {
-                char *colonopts, *substr, *tmp;
-
-                logMessage(INFO, "going to do nfsGetSetup");
-                if (nfsGetSetup(&host, &directory, &mountOpts) == LOADER_BACK) {
-                    loaderData->stage2Data = NULL;
-                    return NULL;
-                }
-
-                /* If the user-provided URL points at a repo instead of a
-                 * stage2 image, fix that up now.
-                 */
-                substr = strstr(directory, ".img");
-                if (!substr || (substr && *(substr+4) != '\0')) {
-                    if (mountOpts && strlen(mountOpts)) {
-                        checked_asprintf(&colonopts, ":%s", mountOpts);
-                    } else {
-                        colonopts = strdup("");
-                    }
-
-                    checked_asprintf(&(loaderData->instRepo), "nfs%s:%s:%s",
-                                     colonopts, host, directory);
-                    checked_asprintf(&tmp, "nfs%s:%s:%s/images/install.img",
-                                     colonopts, host, directory);
-
-                    setStage2LocFromCmdline(tmp, loaderData);
-                    free(host);
-                    free(directory);
-                    free(mountOpts);
-                    free(colonopts);
-                    free(tmp);
-                    continue;
-                }
-
-                loaderData->invalidRepoParam = 1;
-            }
-
-            stage = NFS_STAGE_MOUNT;
-            break;
-
-        case NFS_STAGE_MOUNT: {
-            char *buf;
-
-            checked_asprintf(&fullPath, "%s:%.*s", host,
-                             (int) (strrchr(directory, '/')-directory),
-                             directory);
-            logMessage(INFO, "mounting nfs path %s", fullPath);
-
-            stage = NFS_STAGE_NFS;
-
-            if (!doPwMount(fullPath, "/mnt/stage2", "nfs", mountOpts, NULL)) {
-                checked_asprintf(&buf, "/mnt/stage2/%s",
-                                 strrchr(directory, '/') + 1);
-
-                if (!access(buf, R_OK)) {
-                    logMessage(INFO, "can access %s", buf);
-                    if (isNfsMountDirect(buf)) {
-                        logMessage(INFO, "using uncompressed stage2 image");
-                        rc = mountStage2Direct(buf);
-                    } else {
-                        rc = mountStage2(buf);
-                    }
-
-                    if (rc == 0) {
-                        stage = NFS_STAGE_UPDATES;
-                        checked_asprintf(&url, "nfs:%s:%s", host,
-                                         directory);
-                        free(buf);
-                        break;
-                    } else {
-                        logMessage(WARNING, "unable to mount %s", buf);
-                        free(buf);
-                        break;
-                    }
-                } else {
-                    logMessage(WARNING, "unable to access %s", buf);
-                    free(buf);
-                    umount("/mnt/stage2");
-                }
-            } else {
-                newtWinMessage(_("Error"), _("OK"),
-                               _("That directory could not be mounted from "
-                                 "the server."));
-                if (loaderData->method >= 0)
-                    loaderData->method = -1;
-
-                if (loaderData->inferredStage2)
-                    loaderData->invalidRepoParam = 1;
-
-                break;
-            }
-
-            checked_asprintf(&buf,
-                             _("That directory does not seem to "
-                               "contain a %s installation image."),
-                             getProductName());
-
-            newtWinMessage(_("Error"), _("OK"), buf);
-            free(buf);
-
-            if (loaderData->method >= 0)
-                loaderData->method = -1;
-
-            if (loaderData->inferredStage2)
-                loaderData->invalidRepoParam = 1;
-
-            break;
-        }
-
-        case NFS_STAGE_UPDATES: {
-            char *buf;
-
-            checked_asprintf(&buf, "%.*s/RHupdates",
-                             (int) (strrchr(fullPath, '/')-fullPath),
-                             fullPath);
-
-            logMessage(INFO, "mounting nfs path %s for updates", buf);
-
-            if (!doPwMount(buf, "/tmp/update-disk", "nfs", mountOpts, NULL)) {
-                logMessage(INFO, "Using RHupdates/ for NFS install");
-                copyDirectory("/tmp/update-disk", "/tmp/updates", NULL, NULL);
-                umount("/tmp/update-disk");
-                unlink("/tmp/update-disk");
-            } else {
-                logMessage(INFO, "No RHupdates/ directory found, skipping");
-            }
-
-            stage = NFS_STAGE_DONE;
-            break;
-        }
-
-        case NFS_STAGE_DONE:
-            break;
-        }
-    }
-
-    free(host);
-    free(directory);
-    if (mountOpts)
-        free(mountOpts);
-    if (fullPath)
-        free(fullPath);
-
-    return url;
-}
-
-
-void setKickstartNfs(struct loaderData_s * loaderData, int argc,
-                     char ** argv) {
-    char *substr = NULL;
-    gchar *host = NULL, *dir = NULL, *mountOpts = NULL;
-    GOptionContext *optCon = g_option_context_new(NULL);
-    GError *optErr = NULL;
-    GOptionEntry ksNfsOptions[] = {
-        { "server", 0, 0, G_OPTION_ARG_STRING, &host, NULL, NULL },
-        { "dir", 0, 0, G_OPTION_ARG_STRING, &dir, NULL, NULL },
-        { "opts", 0, 0, G_OPTION_ARG_STRING, &mountOpts, NULL, NULL },
-        { NULL },
-    };
-
-    logMessage(INFO, "kickstartFromNfs");
-
-    g_option_context_set_help_enabled(optCon, FALSE);
-    g_option_context_add_main_entries(optCon, ksNfsOptions, NULL);
-
-    if (!g_option_context_parse(optCon, &argc, &argv, &optErr)) {
-        startNewt();
-        newtWinMessage(_("Kickstart Error"), _("OK"),
-                       _("Bad argument to NFS kickstart method "
-                         "command: %s"), optErr->message);
-        g_error_free(optErr);
-        g_option_context_free(optCon);
-        return;
-    }
-
-    g_option_context_free(optCon);
-
-    if (!host || !dir) {
-        logMessage(ERROR, "host and directory for nfs kickstart not specified");
-        return;
-    }
-
-    loaderData->method = METHOD_NFS;
-    loaderData->stage2Data = NULL;
-
-    substr = strstr(dir, ".img");
-    if (!substr || (substr && *(substr+4) != '\0')) {
-        checked_asprintf(&(loaderData->instRepo), "nfs:%s:%s", host, dir);
-
-        logMessage(INFO, "results of nfs, host is %s, dir is %s, opts are '%s'",
-                   host, dir, mountOpts);
-    } else {
-        loaderData->stage2Data = calloc(sizeof(struct nfsInstallData *), 1);
-        ((struct nfsInstallData *)loaderData->stage2Data)->host = host;
-        ((struct nfsInstallData *)loaderData->stage2Data)->directory = dir;
-        ((struct nfsInstallData *)loaderData->stage2Data)->mountOpts = mountOpts;
-
-        logMessage(INFO, "results of nfs, host is %s, dir is %s, opts are '%s'",
-                   ((struct nfsInstallData *) loaderData->stage2Data)->host,
-                   ((struct nfsInstallData *) loaderData->stage2Data)->directory,
-                   ((struct nfsInstallData *) loaderData->stage2Data)->mountOpts);
-    }
-}
-
-
-int getFileFromNfs(char * url, char * dest, struct loaderData_s * loaderData) {
-    char * host = NULL, *path = NULL, * file = NULL, * opts = NULL;
-    char * chk = NULL, *ip = NULL;
-    int failed = 0, i = 0;
-    iface_t iface;
-    NMClient *client = NULL;
-    NMState state;
-    const GPtrArray *devices;
-
-    if (kickstartNetworkUp(loaderData, &iface)) {
-        logMessage(ERROR, "unable to bring up network");
-        return 1;
-    }
-
-    /* if they just did 'linux ks', they want us to figure it out from
-     * the dhcp/bootp information
-     */
-    if (!url) {
-        g_type_init();
-
-        client = nm_client_new();
-        if (!client) {
-            logMessage(CRITICAL, "%s (%d): failure creating NM proxy",
-                       __func__, __LINE__);
-            return 1;
-        }
-
-        state = nm_client_get_state(client);
-        if (state != NM_STATE_CONNECTED) {
-            logMessage(ERROR, "%s (%d): no active network devices",
-                       __func__, __LINE__);
-            g_object_unref(client);
-            return 1;
-        }
-
-        devices = nm_client_get_devices(client);
-        for (i = 0; i < devices->len; i++) {
-            NMDevice *candidate = g_ptr_array_index(devices, i);
-            const char *devname = nm_device_get_iface(candidate);
-            NMDHCP4Config *dhcp = NULL;
-            const char *server_name = NULL;
-            const char *filename = NULL;
-            struct in_addr addr;
-            char nextserver[INET_ADDRSTRLEN+1];
-
-            if (nm_device_get_state(candidate) != NM_DEVICE_STATE_ACTIVATED)
-                continue;
-
-            if (strcmp(iface.device, devname))
-                continue;
-
-            dhcp = nm_device_get_dhcp4_config(candidate);
-            if (!dhcp) {
-                logMessage(ERROR, "no boot options received by DHCP");
-                continue;
-            }
-
-            server_name = nm_dhcp4_config_get_one_option(dhcp, "server_name");
-            if (!server_name) {
-                logMessage(ERROR, "no bootserver was found");
-                g_object_unref(client);
-                return 1;
-            }
-
-            /* 'server_name' may be a hostname or an IPv4 address */
-            memset(&nextserver, '\0', sizeof(nextserver));
-            if (inet_pton(AF_INET, server_name, &addr) >= 1) {
-                strcpy(nextserver, server_name);
-            } else {
-                struct hostent *he = gethostbyname(server_name);
-                if (he != NULL) {
-                    if (inet_ntop(AF_INET, he->h_addr_list[0],
-                                  nextserver, INET_ADDRSTRLEN) == NULL) {
-                        memset(&nextserver, '\0', sizeof(nextserver));
-                    }
-                }
-            }
-
-            filename = nm_dhcp4_config_get_one_option(dhcp, "filename");
-            if (filename == NULL) {
-                checked_asprintf(&url, "%s:/kickstart/", nextserver);
-                logMessage(ERROR, "bootp: no bootfile received");
-            } else {
-                checked_asprintf(&url, "%s:%s", nextserver, filename);
-                logMessage(INFO, "bootp: bootfile is %s", filename);
-            }
-
-            break;
-        }
-
-        g_object_unref(client);
-    }
-
-    /* get the IP of the target system */
-    if ((ip = iface_ip2str(loaderData->netDev, AF_INET)) == NULL) {
-        logMessage(ERROR, "iface_ip2str returned NULL");
-        return 1;
-    }
-
-    logMessage(INFO, "url is %s", url);
-
-    parseNfsHostPathOpts(url, &host, &path, &opts);
-    addDefaultKickstartFile(&path, ip);
-
-    /* nfs has to be a little bit different... split off the last part as
-     * the file and then concatenate host + dir path */
-    file = strrchr(path, '/');
-    if (!file) {
-        file = path;
-    } else {
-        *file++ ='\0';
-        chk = host + strlen(host)-1;
-
-        if (*chk == '/' || *path == '/') {
-            checked_asprintf(&host, "%s:%s", host, path);
-        } else {
-            checked_asprintf(&host, "%s:/%s", host, path);
-        }
-    }
-
-    logMessage(INFO, "file location: nfs:%s/%s", host, file);
-
-    if (!doPwMount(host, "/tmp/mnt", "nfs", opts, NULL)) {
-        char * buf;
-
-        checked_asprintf(&buf, "/tmp/mnt/%s", file);
-
-        if (copyFile(buf, dest)) {
-            logMessage(ERROR, "failed to copy file to %s", dest);
-            failed = 1;
-        }
-
-        free(buf);
-    } else {
-        logMessage(ERROR, "failed to mount nfs source");
-        failed = 1;
-    }
-
-    free(host);
-    free(path);
-    if (ip) free(ip);
-
-    umount("/tmp/mnt");
-    unlink("/tmp/mnt");
-
-    return failed;
-}
-
-int kickstartFromNfs(char * url, struct loaderData_s * loaderData) {
-    return getFileFromNfs(url, "/tmp/ks.cfg", loaderData);
-}
-
-/* vim:set shiftwidth=4 softtabstop=4: */
diff --git a/loader/nfsinstall.h b/loader/nfsinstall.h
deleted file mode 100644
index 99a8b06..0000000
--- a/loader/nfsinstall.h
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * nfsinstall.h
- *
- * Copyright (C) 2007  Red Hat, Inc.  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 as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * 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, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef NFSINSTALL_H
-#define NFSINSTALL_H
-
-#include "method.h"
-
-struct nfsInstallData {
-    char * host;
-    char * directory;
-    char * mountOpts;
-};
-
-
-void setKickstartNfs(struct loaderData_s * loaderData, int argc,
-                     char ** argv);
-int kickstartFromNfs(char * url, struct loaderData_s * loaderData);
-char * mountNfsImage(struct installMethod * method,
-                     char * location, struct loaderData_s * loaderData);
-int getFileFromNfs(char * url, char * dest, struct loaderData_s * loaderData);
-void parseNfsHostPathOpts(char * url, char ** host, char ** path, char ** opts);
-
-#endif
diff --git a/loader/rpmextract.c b/loader/rpmextract.c
deleted file mode 100644
index d1549b8..0000000
--- a/loader/rpmextract.c
+++ /dev/null
@@ -1,325 +0,0 @@
-/* unpack the payload of RPM package to the current directory
- * 
- * File name: rpmextract.c
- * Date:      2009/12/18
- * Author:    Martin Sivak <msivak at redhat dot com>
- * 
- * Copyright (C) 2009 Red Hat, Inc. 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 as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- * 
- * 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, see <http://www.gnu.org/licenses/>.
- *
- * */
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-
-#include <rpm/rpmlib.h>		/* rpmReadPackageFile .. */
-#include <rpm/rpmtag.h>
-#include <rpm/rpmio.h>
-#include <rpm/rpmpgp.h>
-
-#include <rpm/rpmts.h>
-
-#include <stdio.h>
-#include <archive.h>
-#include <archive_entry.h>
-
-#include "loader.h"
-#include "rpmextract.h"
-
-#include "../isys/log.h"
-
-/*
- * internal structure to pass to libarchive callbacks
- */
-
-struct cpio_mydata {
-    FD_t gzdi;
-    char *buffer;
-};
-
-/*
- * libarchive callbacks
- */
-
-ssize_t rpm_myread(struct archive *a, void *client_data, const void **buff)
-{
-    struct cpio_mydata *mydata = client_data;
-    *buff = mydata->buffer;
-    return Fread(mydata->buffer, BUFFERSIZE, 1, mydata->gzdi);
-}
-
-int rpm_myclose(struct archive *a, void *client_data)
-{
-    struct cpio_mydata *mydata = client_data;
-    if (mydata->gzdi > 0)
-        Fclose(mydata->gzdi);
-    return ARCHIVE_OK;
-}
-
-/* read data from RPM header */
-
-const char * headerGetString(Header h, rpmTag tag)
-{
-    const char *res = NULL;
-    struct rpmtd_s td;
-
-    if (headerGet(h, tag, &td, HEADERGET_MINMEM)) {
-        if (rpmtdCount(&td) == 1) {
-            res = rpmtdGetString(&td);
-        }
-        rpmtdFreeData(&td);
-    }
-    return res;
-}
-
-/*
- * explode source RPM into the current directory
- * use filters to skip packages and files we do not need
- */
-int explodeRPM(const char *source,
-        filterfunc filter,
-        dependencyfunc provides,
-        dependencyfunc deps,
-        void* userptr)
-{
-    char buffer[BUFFERSIZE+1]; /* make space for trailing \0 */
-    FD_t fdi;
-    Header h;
-    char * rpmio_flags = NULL;
-    rpmRC rc;
-    FD_t gzdi;
-    struct archive *cpio;
-    struct archive_entry *cpio_entry;
-    struct cpio_mydata cpio_mydata;
-
-    rpmts ts;
-    rpmVSFlags vsflags;
-    const char *compr;
-
-    if (strcmp(source, "-") == 0)
-        fdi = fdDup(STDIN_FILENO);
-    else
-        fdi = Fopen(source, "r.ufdio");
-
-    if (Ferror(fdi)) {
-        const char *srcname = (strcmp(source, "-") == 0) ? "<stdin>" : source;
-        logMessage(ERROR, "%s: %s\n", srcname, Fstrerror(fdi));
-        return EXIT_FAILURE;
-    }
-    rpmReadConfigFiles(NULL, NULL);
-
-    /* Initialize RPM transaction */
-    ts = rpmtsCreate();
-    vsflags = 0;
-
-    /* Do not check digests, signatures or headers */
-    vsflags |= _RPMVSF_NODIGESTS;
-    vsflags |= _RPMVSF_NOSIGNATURES;
-    vsflags |= RPMVSF_NOHDRCHK;
-    (void) rpmtsSetVSFlags(ts, vsflags);
-
-    rc = rpmReadPackageFile(ts, fdi, "rpm2dir", &h);
-
-    ts = rpmtsFree(ts);
-
-    switch (rc) {
-        case RPMRC_OK:
-        case RPMRC_NOKEY:
-        case RPMRC_NOTTRUSTED:
-            break;
-        case RPMRC_NOTFOUND:
-            logMessage(ERROR, "%s is not an RPM package", source);
-            return EXIT_FAILURE;
-            break;
-        case RPMRC_FAIL:
-        default:
-            logMessage(ERROR, "error reading header from %s package\n", source);
-            return EXIT_FAILURE;
-            break;
-    }
-
-    /* Retrieve all dependencies and run them through deps function */
-    while (deps) {
-        struct rpmtd_s td;
-        const char *depname;
-
-        if (!headerGet(h, RPMTAG_REQUIRENAME, &td, HEADERGET_MINMEM))
-            break;
-
-        /* iterator */
-        while ((depname = rpmtdNextString(&td))) {
-            if (deps(depname, userptr)) {
-                Fclose(fdi);
-                return EXIT_BADDEPS;
-            }
-        }
-        rpmtdFreeData(&td);
-        break;
-    }
-
-    /* Retrieve all provides and run them through provides function */
-    while (provides) {
-        struct rpmtd_s td;
-        const char *depname;
-        int found = 0;
-
-        if (!headerGet(h, RPMTAG_PROVIDES, &td, HEADERGET_MINMEM))
-            break;
-
-        /* iterator */
-        while ((depname = rpmtdNextString(&td))) {
-            if (!provides(depname, userptr)) {
-                found++;
-            }
-        }
-        rpmtdFreeData(&td);
-        if (found<=0)
-            return EXIT_BADDEPS;
-        break;
-    }
-
-    /* Retrieve type of payload compression. */
-    compr = headerGetString(h, RPMTAG_PAYLOADCOMPRESSOR);
-    if (compr && strcmp(compr, "gzip")) {
-        checked_asprintf(&rpmio_flags, "r.%sdio", compr);
-    }
-    else {
-        checked_asprintf(&rpmio_flags, "r.gzdio");
-    }
-
-    /* Open uncompressed cpio stream */
-    gzdi = Fdopen(fdi, rpmio_flags);
-    free(rpmio_flags);
-
-    if (gzdi == NULL) {
-        logMessage(ERROR, "cannot re-open payload: %s\n", Fstrerror(gzdi));
-        return EXIT_FAILURE;
-    }
-
-    /* initialize cpio decompressor */
-    cpio = archive_read_new();
-    if (cpio==NULL) {
-        Fclose(gzdi);
-        return -1;
-    }
-
-    cpio_mydata.gzdi = gzdi;
-    cpio_mydata.buffer = buffer;
-    archive_read_support_compression_all(cpio);
-    archive_read_support_format_all(cpio);
-    rc = archive_read_open(cpio, &cpio_mydata, NULL, rpm_myread, rpm_myclose);
-
-    /* check the status of archive_open */
-    if (rc != ARCHIVE_OK){
-        Fclose(gzdi);
-        return -1;
-    }
-
-    /* read all files in cpio archive */
-    while ((rc = archive_read_next_header(cpio, &cpio_entry)) == ARCHIVE_OK){
-        const struct stat *fstat;
-        int64_t fsize;
-        const char* filename;
-        int needskip = 1; /* do we need to read the data to get to the next header? */
-        int offset = 0;
-        int towrite = 0;
-
-        filename = archive_entry_pathname(cpio_entry);
-        fstat = archive_entry_stat(cpio_entry);
-        fsize = archive_entry_size(cpio_entry);
-
-        /* Strip leading slashes */
-        while (filename[offset] == '/')
-            offset+=1;
-
-        /* Strip leading ./ */
-        while (filename[offset] == '.' && filename[offset+1] == '/')
-            offset+=2;
-
-        /* Other file type - we do not care except special cases */
-        if (!S_ISREG(fstat->st_mode))
-            towrite = 1;
-        else
-            towrite = 2;
-
-        if (filter && filter(filename+offset, fstat, userptr)) {
-            /* filter this file */
-            towrite = 0;
-        }
-
-        /* Create directories */
-        char* dirname = strdup(filename+offset);
-
-        /* If the dup fails, let's hope the dirs already exist */
-        if (dirname){
-            char* dirptr = dirname;
-            while (dirptr && *dirptr) {
-                dirptr = strchr(dirptr, '/');
-                if (dirptr) {
-                    *dirptr = 0;
-                    mkdir(dirname, 0700);
-                    *dirptr = '/';
-                    dirptr++;
-                }
-            }
-            free(dirname);
-        }
-
-        /* Regular file */
-        if (towrite>=2) {
-            FILE *fdout = fopen(filename+offset, "w");
-
-            if (fdout==NULL){
-                rc = 33;
-                break;
-            }
-            
-            rc = archive_read_data_into_fd(cpio, fileno(fdout));
-            if (rc!=ARCHIVE_OK) {
-                /* XXX We didn't get the file.. well.. */
-                needskip = 0;
-            } else {
-                needskip = 0;
-                fclose(fdout);
-            }
-        }
-
-        /* symlink, we assume that the path contained in symlink
-         * is shorter than BUFFERSIZE */
-        while (towrite && S_ISLNK(fstat->st_mode)) {
-            char symlinkbuffer[BUFFERSIZE-1];
-
-            needskip = 0;
-            if ((rc = archive_read_data(cpio, symlinkbuffer, fsize))!=ARCHIVE_OK) {
-                /* XXX We didn't get the file.. well.. */
-                break;
-            }
-
-            if (symlink(buffer, filename+offset)) {
-                logMessage(ERROR, "Failed to create symlink %s -> %s", filename+offset, buffer);
-            }
-
-            break;
-        }
-
-        if(needskip)
-            archive_read_data_skip(cpio);
-    }
-
-    archive_read_finish(cpio);
-
-    return rc != ARCHIVE_OK;
-}
diff --git a/loader/rpmextract.h b/loader/rpmextract.h
deleted file mode 100644
index 53a90cf..0000000
--- a/loader/rpmextract.h
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
-   File name: rpmextract.h
-   Date:      2009/09/16
-   Author:    msivak
-
-   Copyright (C) 2009 Red Hat, 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; either version 2 of the
-   License, or (at your option) any later version.
-
-   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, see <http://www.gnu.org/licenses/>.
-*/
-
-
-#ifndef __RPMEXTRACT_H__
-#define __RPMEXTRACT_H__
-
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <unistd.h>
-
-#define EXIT_BADDEPS 4
-#define BUFFERSIZE 1024
-
-/* both filter functions return 0 - match, 1 - match not found */
-typedef int (*filterfunc)(const char* name, const struct stat *fstat, void *userptr);
-typedef int (*dependencyfunc)(const char* depends, void *userptr);
-
-int explodeRPM(const char* file,
-               filterfunc filter,
-               dependencyfunc provides,
-               dependencyfunc deps,
-               void* userptr);
-
-#endif
-
-/* end of rpmextract.h */
diff --git a/loader/selinux.c b/loader/selinux.c
deleted file mode 100644
index 66bfe4d..0000000
--- a/loader/selinux.c
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * selinux.c - Various SELinux related functionality needed for the loader.
- * Portions extracted from libselinux which was released as public domain
- * software by the NSA.
- *
- * Copyright (C) 2004  Red Hat, Inc.  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 as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * 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, see <http://www.gnu.org/licenses/>.
- *
- * Author(s): Jeremy Katz <katzj@xxxxxxxxxx>
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <errno.h>
-#include <sys/types.h>
-#include <sys/wait.h>
-#include <string.h>
-
-#include "loader.h"
-#include "loadermisc.h"
-#include "../isys/log.h"
-
-int loadpolicy() {
-    int pid, status;
-
-    logMessage(INFO, "Loading SELinux policy");
-
-    if (!(pid = fork())) {
-        setenv("LD_LIBRARY_PATH", LIBPATH, 1);
-        execl("/sbin/load_policy",
-              "/sbin/load_policy", "-q", NULL);
-        logMessage(ERROR, "exec of load_policy failed: %m");
-        exit(1);
-    }
-
-    waitpid(pid, &status, 0);
-    if (WIFEXITED(status) && (WEXITSTATUS(status) != 0))
-        return 1;
-
-    return 0;
-}
-
diff --git a/loader/selinux.h b/loader/selinux.h
deleted file mode 100644
index 5877ddd..0000000
--- a/loader/selinux.h
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * selinux.h
- *
- * Copyright (C) 2007  Red Hat, Inc.  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 as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * 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, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef SELINUX_H
-#define SELINUX_H
-
-int loadpolicy();
-
-#define ANACONDA_CONTEXT "system_u:system_r:anaconda_t:s0"
-
-#endif
diff --git a/loader/shutdown.c b/loader/shutdown.c
deleted file mode 100644
index 3b481f2..0000000
--- a/loader/shutdown.c
+++ /dev/null
@@ -1,153 +0,0 @@
-/*
- * shutdown.c
- *
- * Shutdown a running system.  If built with -DAS_SHUTDOWN=1, then
- * it builds a standalone shutdown binary.
- *
- * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003  Red Hat, Inc.
- * 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 as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * 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, see <http://www.gnu.org/licenses/>.
- */
-
-#include <fcntl.h>
-#include <signal.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/reboot.h>
-#include <sys/types.h>
-#include <unistd.h>
-
-#include "init.h"
-
-void disableSwap(void);
-void unmountFilesystems(void);
-
-static void performTerminations(void) {
-	sync();
-	printf("sending termination signals...");
-	kill(-1, 15);
-	sleep(2);
-	printf("done\n");
-
-	printf("sending kill signals...");
-	kill(-1, 9);
-	sleep(2);
-	printf("done\n");
-}
-
-static void performUnmounts(void) {
-	int ignore;
-
-	printf("disabling swap...\n");
-	disableSwap();
-
-	printf("unmounting filesystems...\n"); 
-	unmountFilesystems();
-
-	printf("waiting for mdraid sets to become clean...\n"); 
-	ignore = system("/sbin/mdadm --wait-clean --scan");
-}
-
-static void performReboot(reboot_action rebootAction) {
-    switch (rebootAction) {
-    case POWEROFF:
-        printf("powering off system\n");
-        sleep(2);
-        reboot(RB_POWER_OFF);
-        break;
-    case REBOOT:
-        printf("rebooting system\n");
-        sleep(2);
-#if USE_MINILIBC
-        reboot(0xfee1dead, 672274793, 0x1234567);
-#else
-        reboot(RB_AUTOBOOT);
-#endif
-        break;
-    case HALT:
-        printf("halting system\n");
-        reboot(RB_HALT_SYSTEM);
-        break;
-    default:
-        break;
-    }
-}
-
-static void performDelayedReboot()
-{
-    printf("The system will be rebooted when you press Ctrl-C or Ctrl-Alt-Delete.\n");
-    while (1) {
-        sleep(1);
-    }
-}
-
-void shutDown(int doKill, reboot_action rebootAction)
-{
-    static int reentered = 0;
-    
-    if (reentered) {
-        performUnmounts();
-        performTerminations();
-        performReboot(rebootAction);
-    }
-    reentered = 1;
-    if (rebootAction != DELAYED_REBOOT && doKill) {
-        performUnmounts();
-        performTerminations();
-        performReboot(rebootAction);
-    } else {
-        performDelayedReboot();
-    }
-    exit(0);
-}
-
-#ifdef AS_SHUTDOWN
-int main(int argc, char ** argv) {
-    int fd;
-    reboot_action rebootAction = HALT;
-    int doKill = 1;
-    int i = 1;
-
-    while (i < argc) {
-      if (!strncmp("-r", argv[i], 2))
-        rebootAction = REBOOT;
-      else if (!strncmp("--nokill", argv[i], 8))
-        doKill = 0;
-      else if (!strncmp("-P", argv[i], 2))
-        rebootAction = POWEROFF;
-      i++;
-    }
-
-    /* ignore some signals so we don't kill ourself */
-    signal(SIGINT, SIG_IGN);
-    signal(SIGTSTP, SIG_IGN);
-
-    /* now change to / */
-    i = chdir("/");
-
-    /* redirect output to the real console */
-    fd = open("/dev/console", O_RDWR);
-    dup2(fd, 0);
-    dup2(fd, 1);
-    dup2(fd, 2);
-    close(fd);
-
-    shutDown(doKill, rebootAction);
-    return 0;
-}
-#endif
-
-/* vim:set shiftwidth=4 softtabstop=4 ts=4: */
diff --git a/loader/simplemot b/loader/simplemot
deleted file mode 100755
index bebc1cf..0000000
--- a/loader/simplemot
+++ /dev/null
@@ -1,81 +0,0 @@
-#!/usr/bin/perl
-#
-# simplemot
-#
-# Copyright (C) 2007  Red Hat, Inc.  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 as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# 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, see <http://www.gnu.org/licenses/>.
-#
-
-$inone = 0;
-$intran = 0;
-$total = 0;
-
-binmode(STDIN, ":raw");
-binmode(STDOUT, ":raw");
-
-while (<>) {
-    if (!$inone && /^msgid/) {
-	chop;
-	$str = substr($_, 7, length($_) - 8);
-	$inone = 1;
-    } elsif ($inone && /^"/) {
-	chop;
-	$str .= substr($_, 1, length($_) - 2);
-    } elsif ($inone) {
-	$inone = 0;
-
-	$str =~ s/\\n/\n/g;
-	$str =~ s/\\t/\t/g;
-	$str =~ s/\\"/"/g;
-
-	# the string is complete -- calculate a hash
-	$sum = 0;
-	$xor = 0;
-	for ($i = 0; $i < length($str); $i++) {
-	    $char = ord(substr($str, $i, 1));
-	    $sum += $char;
-	    $xor ^= $char;
-	}
-
-	$total = ($sum << 16) | (($xor & 0xFF) << 8) | (length($str) & 0xFF);
-    }
-
-    if (!$intran && /^msgstr/) {
-	chop;
-	$tran = substr($_, 8, length($_) - 9);
-	$intran = 1;
-    } elsif ($intran && /^"/) {
-	chop;
-	$tran .= substr($_, 1, length($_) - 2);
-    } elsif ($intran) {
-	$intran = 0;
-
-	$tran =~ s/\\n/\n/g;
-	$tran =~ s/\\t/\t/g;
-	$tran =~ s/\\"/"/g;
-
-	if (!$total && $str) {
-	    print STDERR "Missing string for $tran";
-	    exit 1
-	} elsif ($str && $tran) {
-	    print pack("Nn", $total, length($tran));
-	    print $tran;
-
-	    #if ($tran < 60) {
-		#printf STDERR ("0x%x %s\n", $total, $tran);
-	    #}
-	}
-    }
-}
diff --git a/loader/telnet.c b/loader/telnet.c
deleted file mode 100644
index 3c123ae..0000000
--- a/loader/telnet.c
+++ /dev/null
@@ -1,273 +0,0 @@
-/*
- * telnet.c -- basic telnet protocol handling for ttywatch
- *
- * Copyright (C) 2001  Red Hat, Inc.  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 as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * 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, see <http://www.gnu.org/licenses/>.
- *
- * Author(s): Michael K. Johnson <johnsonm@xxxxxxxxxx>
- */
-
-/* Shamelessly stolen from ttywatch -- oot */
-
-#include <ctype.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-
-#include "telnet.h"
-#include "../isys/log.h"
-
-#define IAC "\xff"
-#define DONT "\xfe"
-#define WONT "\xfc"
-#define WILL "\xfb"
-#define DO "\xfd"
-#define SB "\xfa"
-#define SE "\xf0"
-#define ECHO "\x01"
-#define SUPPRESS_GO_AHEAD "\x03"
-#define TERMINAL_TYPE "\x18"
-#define NAWS "\x1f"
-#define LINEMODE "\x22"
-#define NEWENVIRON "\x27"
-#define MODE "\x01"
-
-/* Make a request.  Not intended to be RFC-compatible, just enough
- * to convince telnet clients to do what we want...  To do this
- * right, we would have to honestly negotiate, not speak blind.
- *
- * For now, assume all responses will be favorable and stripped
- * out in telnet_process_input()...  Sending it all in a single
- * write makes it more efficient because it will all go out in a
- * single packet, and the responses are more likely to all come
- * back in a single packet (and thus, practically, a single read)
- * too.
- */
-void
-telnet_negotiate(int socket, char ** term_type_ptr, int * heightPtr,
-		 int * widthPtr) {
-    char ch;
-    int done = 0;
-    char * termType = NULL;
-    int termLength = 0, termAlloced = 0;
-    enum { ST_NONE, ST_TERMTYPE, ST_WINDOWSIZE } state;
-    char sizeBuf[4];
-    int height = -1, width = -1;
-    char * sizePtr = sizeBuf;
-    char request[]=
-      IAC DONT ECHO
-      IAC WILL ECHO
-      IAC WILL NAWS
-      IAC WILL SUPPRESS_GO_AHEAD
-      IAC DO SUPPRESS_GO_AHEAD
-      IAC DONT NEWENVIRON
-      IAC WONT NEWENVIRON
-      IAC WONT LINEMODE
-      IAC DO NAWS
-      IAC SB TERMINAL_TYPE "\x01" IAC SE
-      ;
-    int ret;
-
-    ret = write(socket, request, sizeof(request)-1);
-
-    /* Read from the terminal until we get the terminal type. This will
-       do bad things if the client doesn't send the terminal type, but
-       those clients have existed for aeons (right?) */
-
-    do {
-	ret = read(socket, &ch, 1);
-	if (ch != '\xff') {
-	    abort();
-	}
-
-	ret = read(socket, &ch, 1);	    /* command */
-
-	if (ch != '\xfa') {
-	    ret = read(socket, &ch, 1);   /* verb */
-	    continue;
-	}
-
-	ret = read(socket, &ch, 1);   /* suboption */
-	if (ch == '\x18') {
-	    state = ST_TERMTYPE;
-	    ret = read(socket, &ch, 1);	    /* should be 0x0! */
-	    done = 1;
-	} else if (ch == '\x1f') {
-	    state = ST_WINDOWSIZE;
-	} else {
-	    state = ST_NONE;;
-	}
-
-	ret = read(socket, &ch, 1);   /* data */
-	while (ch != '\xff') {
-	    if (state == ST_TERMTYPE) {
-		if (termAlloced == termLength) {
-		    termAlloced += 10;
-		    termType = realloc(termType, termAlloced + 1);
-		}
-
-		termType[termLength++] = tolower(ch);
-	    } else if (state == ST_WINDOWSIZE) {
-		if ((sizePtr - sizeBuf) < (int)sizeof(sizeBuf))
-		    *sizePtr++ = ch;
-	    }
-
-	    ret = read(socket, &ch, 1);   /* data */
-	}
-
-	ret = read(socket, &ch, 1);   /* should be a SE */
-
-    } while (!done);
-
-    termType[termLength] = '\0';
-
-    if (sizePtr - sizeBuf == sizeof(sizeBuf)) {
-	width = (sizeBuf[0] << 8) + sizeBuf[1];
-	height = (sizeBuf[2] << 8) + sizeBuf[3];
-    }
-
-    if (heightPtr) *heightPtr = height;
-    if (widthPtr) *widthPtr = width;
-
-    if (term_type_ptr) *term_type_ptr = termType;
-}
-
-int
-telnet_process_input(telnet_state * ts, char *data, int len) {
-    char *s, *d; /* source, destination */
-
-#   if DEBUG_TELNET
-    printf("\nprinting packet:");
-    for (s=data; s<data+len; s++) {
-	if (!((s-data)%10))
-	    printf("\n %03d: ", s-data);
-	printf("%02x ", *s & 0x000000FF);
-    }
-    printf("\n");
-#   endif /* DEBUG_TELNET */
-
-    for (s=data, d=data; s<data+len; s++) {
-	switch (*ts) {
-	case TS_DATA:
-	    if (*s == '\xff') { /* IAC */
-		*ts = TS_IAC;
-		continue;
-	    }
-#if	    DEBUG_TELNET
-	    printf("copying data element '%c'\n", *s);
-#endif	    /* DEBUG_TELNET */
-	    if (s>d) {
-		*(d++) = *s;
-	    } else {
-		d++;
-	    }
-	    break;
-
-	case TS_IAC:
-	    if (*s == '\xfa') { /* SB */
-		*ts = TS_SB;
-		continue;
-	    }
-	    /* if not SB, skip IAC verb object */
-#	    if DEBUG_TELNET
-	    printf("skipping verb/object (offset %d)...\n", s-data-1);
-#	    endif /* DEBUG_TELNET */
-	    s += 1;
-	    *ts = TS_DATA;
-	    break;
-
-	case TS_SB:
-#	    if DEBUG_TELNET
-	    printf("skipping SB (offset %d)...\n", s-data-1);
-#	    endif /* DEBUG_TELNET */
-	    while (s < (data+(len-1))) {
-		if (*s == '\xff') {
-		    break; /* fall through to TS_SB_IAC setting below */
-		} else {
-		    s++;
-		}
-	    }
-	    if (*s == '\xff') {
-		*ts = TS_SB_IAC;
-	    }
-	    break;
-
-	case TS_SB_IAC:
-	    if (*s == '\xf0') { /* SE */
-#		if DEBUG_TELNET
-		printf("SE ends SB (offset %d)...\n", s-data-1);
-#		endif /* DEBUG_TELNET */
-		*ts = TS_DATA;
-	    } else {
-#		if DEBUG_TELNET
-		printf("IAC without SE in SB (offset %d)\n", s-data-1);
-#		endif /* DEBUG_TELNET */
-		*ts = TS_SB;
-	    }
-	    break;
-
-	default:
-	    logMessage(WARNING, "unknown telnet state %d for data element %c",
-                       *ts, *s);
-	    *ts = TS_DATA;
-	    break;
-	}
-    }
-
-    /* calculate new length after copying data around */
-    len = d - data;
-#if DEBUG_TELNET
-    printf("returning len: %d of packet:", len);
-    for (s=data; s<data+len; s++) {
-	if (!((s-data)%10))
-	    printf("\n %03d: ", s-data);
-	printf("%02x ", *s & 0x000000FF);
-    }
-    printf("\n");
-#endif /* DEBUG_TELNET */
-
-    return len;
-}
-
-/* The telnet protocol requires CR/NL instead of just NL
- * We normally deal with Unix, which just uses NL, so we need to translate.
- *
- * It would be easy to go through line-by-line and write each line, but
- * that would create more packet overhead by sending out one packet
- * per line, and over things like slow PPP connections, that is painful.
- * Therefore, instead, we create a modified copy of the data and write
- * the whole modified copy at once.
- */
-void
-telnet_send_output(int sock, char *data, int len) {
-    char *s, *d; /* source, destination */
-    char *buf;
-    int ret;
-
-    buf = alloca((len*2)+1);  /* max necessary size */
-
-    /* just may need to add CR before NL (but do not double existing CRs) */
-    for (s=data, d=buf; d-buf<len; s++, d++) {
-	if ((*s == '\n') && (s == data || (*(s-1) != '\r'))) {
-	    /* NL without preceding CR */
-	    *(d++) = '\r';
-	    len++;
-	}
-	*d = *s;
-    }
-
-    /* now send it... */
-    ret = write(sock, buf, len);
-}
diff --git a/loader/telnet.h b/loader/telnet.h
deleted file mode 100644
index 5c34154..0000000
--- a/loader/telnet.h
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * telnet.h -- basic telnet protocol handling for ttywatch
- *
- * Copyright (C) 2001  Red Hat, Inc.  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 as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * 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, see <http://www.gnu.org/licenses/>.
- *
- * Author(s): Michael K. Johnson <johnsonm@xxxxxxxxxx>
- */
-
-#ifndef __TELNET_H__
-#define __TELNET_H__
-
-typedef enum {
-	TS_DATA = 0,
-	TS_IAC,
-	TS_SB,
-	TS_SB_IAC,
-} telnet_state;
-
-void
-telnet_negotiate(int socket, char ** term_type_ptr, int * heightPtr,
-		 int * widthPtr);
-int
-telnet_process_input(telnet_state * ts, char *data, int len);
-void
-telnet_send_output(int sock, char *data, int len);
-
-#endif /* __TELNET_H__ */
diff --git a/loader/telnetd.c b/loader/telnetd.c
deleted file mode 100644
index 219df78..0000000
--- a/loader/telnetd.c
+++ /dev/null
@@ -1,256 +0,0 @@
-/*
- * telnetd.c - glue to tie telnet.c from ttywatch to the loader
- *
- * Copyright (C) 2002  Red Hat, Inc.  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 as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * 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, see <http://www.gnu.org/licenses/>.
- *
- * Author(s): Erik Troan <ewt@xxxxxxxxxx>
- *            Jeremy Katz <katzj@xxxxxxxxxx>
- */
-
-#include <arpa/inet.h>
-#include <ctype.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <netinet/in.h>
-#include <newt.h>
-#include <pty.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/ioctl.h>
-#include <sys/poll.h>
-#include <sys/signal.h>
-#include <sys/socket.h>
-#include <sys/types.h>
-#include <unistd.h>
-
-#include "../isys/log.h"
-
-#include "lang.h"
-#include "loader.h"
-#include "modules.h"
-#include "net.h"
-#include "telnet.h"
-#include "windows.h"
-
-#ifndef IPPORT_TELNET
-#define IPPORT_TELNET 23
-#endif
-
-/* boot flags */
-extern uint64_t flags;
-
-/* Forks, keeping the loader as our child (so we know when it dies). */
-int beTelnet(void) {
-    int sock;
-    int conn;
-    socklen_t addrLength;
-    pid_t child;
-    int i;
-    int masterFd, ttyFd;
-    struct sockaddr_in address;
-    char buf[4096];
-    struct pollfd fds[3];
-    telnet_state ts = TS_DATA;
-    char * termType;
-    int height, width;
-    struct winsize ws;
-
-    if ((sock = socket(PF_INET, SOCK_STREAM, 0)) < 0) {
-        logMessage(ERROR, "socket: %s", strerror(errno));
-        return -1;
-    }
-
-    address.sin_family = AF_INET;
-    address.sin_port = htons(IPPORT_TELNET);
-    memset(&address.sin_addr, 0, sizeof(address.sin_addr));
-    addrLength = sizeof(address);
-
-    /* Let the kernel reuse the socket address. This lets us run
-       twice in a row, without waiting for the (ip, port) tuple
-       to time out. Makes testing much easier*/
-    conn = 1;
-    setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &conn, sizeof(conn));
-
-    bind(sock, (struct sockaddr *) &address, sizeof(address));
-    listen(sock, 5);
-
-    winStatus(45, 3, _("Telnet"), _("Waiting for telnet connection."));
-
-    if ((conn = accept(sock, (struct sockaddr *) &address, &addrLength)) < 0) {
-        newtWinMessage(_("Error"), _("OK"), "accept failed: %s",
-                       strerror(errno));
-        close(sock);
-        return -1;
-    }
-
-    stopNewt();
-    close(sock);
-    telnet_negotiate(conn, &termType, &height, &width);
-
-#ifdef DEBUG_TELNET
-    printf("got term type %s\n", termType);
-#endif
-
-    masterFd = open("/dev/ptmx", O_RDWR);
-    if (masterFd < 0) {
-        logMessage(CRITICAL, "cannot open /dev/ptmx");
-        close(conn);
-        return -1;
-    }
-
-    if (height != -1 && width != -1) {
-#ifdef DEBUG_TELNET
-        printf("setting window size to %d x %d\n", width, height);
-#endif
-        ws.ws_row = height;
-        ws.ws_col = width;
-        ioctl(masterFd, TIOCSWINSZ, &ws);
-    }
-
-
-    child = fork();
-
-    if (child) {
-#ifndef DEBUG_TELNET
-        startNewt();
-        winStatus(45, 3, _("Telnet"), _("Running anaconda via telnet."));
-#endif
-
-        fds[0].events = POLLIN;
-        fds[0].fd = masterFd;
-
-        fds[1].events = POLLIN;
-        fds[1].fd = conn;
-
-        while ((i = poll(fds, 2, -1)) > 0) {
-            if (fds[0].revents) {
-                i = read(masterFd, buf, sizeof(buf));
-#ifdef DEBUG_TELNET
-                {
-                    int j;
-                    int row;
-
-                    for (row = 0; row < (i / 12) + 1; row++) {
-                        printf("wrote:");
-
-                        for (j = (row * 12); j < i && j < ((row + 1) * 12); j++)
-                            printf(" 0x%2x", (unsigned char) buf[j]);
-
-                        printf("\nwrote:");
-
-                        for (j = (row*12); j < i && j < ((row+1)*12); j++) {
-                            if (isprint(buf[j]))
-                                printf("   %c ", buf[j]);
-                            else
-                                printf("     ");
-                        }
-
-                        printf("\n");
-                    }
-                }
-#endif
-                /* child died */
-                if (i < 0)
-                    break;
-
-                telnet_send_output(conn, buf, i);
-            }
-
-            if (fds[1].revents) {
-                int ret;
-                i = read(conn, buf, sizeof(buf));
-
-                /* connection went away */
-                if (!i)
-                    break;
-
-                i = telnet_process_input(&ts, buf, i);
-                ret = write(masterFd, buf, i);
-#ifdef DEBUG_TELNET
-                {
-                    int j;
-
-                    printf("got:");
-                    for (j = 0; j < i; j++)
-                        printf(" 0x%x", (unsigned char) buf[j]);
-                    printf("\n");
-                }
-#endif
-            }
-        }
-
-        if (i < 0) {
-            logMessage(ERROR, "poll: %s", strerror(errno));
-        }
-
-#ifndef DEBUG_TELNET
-        stopNewt();
-#endif
-
-        kill(child, SIGTERM);
-        close(conn);
-        doExit(0);
-    }
-
-    unlockpt(masterFd);
-    grantpt(masterFd);
-    ttyFd = open(ptsname(masterFd), O_RDWR);
-    close(masterFd);
-    setsid();
-    close(0);
-    close(1);
-    close(2);
-
-    if (ttyFd != 0) {
-        dup2(ttyFd, 0);
-        close(ttyFd);
-    }
-
-    dup2(0, 1);
-    dup2(0, 2);
-
-    /* brand new tty! */
-    setenv("TERM", termType, 1);
-
-    startNewt();
-
-    return 0;
-}
-
-void startTelnetd(struct loaderData_s * loaderData) {
-    char *ipaddr = NULL;
-    iface_t iface;
-
-    iface_init_iface_t(&iface);
-
-    if (kickstartNetworkUp(loaderData, &iface)) {
-        logMessage(ERROR, "unable to bring up network");
-        return;
-    }
-
-    ipaddr = iface_ip2str(iface.device, AF_INET);
-    if (ipaddr == NULL) {
-        logMessage(ERROR, "%s (%d): no IP address found for %s",
-                   __func__, __LINE__, iface.device);
-        return;
-    }
-
-    logMessage(INFO, "going to beTelnet for %s", ipaddr);
-    if (!beTelnet())
-        flags |= LOADER_FLAGS_TEXT | LOADER_FLAGS_NOSHELL;
-
-    return;
-}
diff --git a/loader/telnetd.h b/loader/telnetd.h
deleted file mode 100644
index fedb0fa..0000000
--- a/loader/telnetd.h
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * telnetd.h
- *
- * Copyright (C) 2007  Red Hat, Inc.  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 as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * 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, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef TELNETD_H
-#define TELNETD_H
-
-void startTelnetd(struct loaderData_s * loaderData);
-
-#endif
diff --git a/loader/udelay.h b/loader/udelay.h
deleted file mode 100644
index 5315074..0000000
--- a/loader/udelay.h
+++ /dev/null
@@ -1,199 +0,0 @@
-/*
- * udelay.h -- udelay and other time related functions.
- *
- * Copyright (C) 2006, 2007  Red Hat, Inc.  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 as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * 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, see <http://www.gnu.org/licenses/>.
- *
- * Author(s): Peter Jones <pjones@xxxxxxxxxx>
- */
-
-#ifndef UDELAY_H
-#define UDELAY_H 1
-
-#include <sys/types.h>
-#include <sys/param.h>
-#include <sys/time.h>
-#include <time.h>
-
-#define USECS_PER_SEC 1000000LL
-#define NSECS_PER_USEC 1000LL
-#define NSECS_PER_SEC (NSECS_PER_USEC * USECS_PER_SEC)
-
-static inline void
-nsectospec(long long nsecs, struct timespec *ts)
-{
-    if (nsecs < 0) {
-        ts->tv_sec = -1;
-        ts->tv_nsec = -1;
-        return;
-    }
-    ts->tv_sec = nsecs / NSECS_PER_SEC;
-    ts->tv_nsec = (nsecs % NSECS_PER_SEC);
-}
-
-static inline void
-usectospec(long long usecs, struct timespec *ts)
-{
-    if (usecs > 0 && LLONG_MAX / NSECS_PER_USEC > usecs)
-        usecs *= NSECS_PER_USEC;
-    
-    nsectospec(usecs, ts);
-}
-
-static inline int
-speczero(struct timespec *ts)
-{
-    return (ts->tv_sec == 0 && ts->tv_nsec == 0);
-}
-
-static inline int
-specinf(struct timespec *ts)
-{
-    return (ts->tv_sec < 0 || ts->tv_nsec < 0);
-}
-
-static inline long long
-spectonsec(struct timespec *ts)
-{
-    long long nsecs = 0;
-    if (specinf(ts))
-        return -1;
-    
-    nsecs = ts->tv_sec * NSECS_PER_SEC;
-    nsecs += ts->tv_nsec;
-    return nsecs;
-}
-
-static inline long long
-spectousec(struct timespec *ts)
-{
-    long long usecs = spectonsec(ts);
-
-    return usecs < 0 ? usecs : usecs / NSECS_PER_USEC;
-}
-
-static inline int
-gettimespecofday(struct timespec *ts)
-{
-    struct timeval tv = {0, 0};
-    int rc;
-
-    rc = gettimeofday(&tv, NULL);
-    if (rc >= 0) {
-        ts->tv_sec = tv.tv_sec;
-        ts->tv_nsec = tv.tv_usec * NSECS_PER_USEC;
-    }
-    return rc;
-}
-
-/* minuend minus subtrahend equals difference */
-static inline void
-tssub(struct timespec *minuend, struct timespec *subtrahend,
-      struct timespec *difference)
-{
-    long long m, s, d;
-
-    m = spectonsec(minuend);
-    s = spectonsec(subtrahend);
-
-    if (s < 0) {
-        d = 0;
-    } else if (m < 0) {
-        d = -1;
-    } else {
-        m -= s;
-        d = m < 0 ? 0 : m;
-    }
-
-    nsectospec(d, difference);
-    return;
-}
-
-static inline void
-tsadd(struct timespec *augend, struct timespec *addend, struct timespec *sum)
-{
-    long long aug, add;
-
-    aug = spectonsec(augend);
-    add = spectonsec(addend);
-
-//    printf("aug: %Ld add: %Ld\n", aug, add);
-
-    if (aug < 0 || add < 0)
-        nsectospec(-1, sum);
-    else if (LLONG_MAX - MAX(add,aug) < MAX(add,aug))
-        nsectospec(LLONG_MAX, sum);
-    else
-        nsectospec(aug+add, sum);
-    return;
-}
-
-#define tsGT(x,y) (tscmp((x), (y)) < 0)
-#define tsGE(x,y) (tscmp((x), (y)) <= 0)
-#define tsET(x,y) (tscmp((x), (y)) == 0)
-#define tsNE(x,y) (tscmp((x), (y)) != 0)
-#define tsLE(x,y) (tscmp((x), (y)) >= 0)
-#define tsLT(x,y) (tscmp((x), (y)) > 0)
-
-static inline int
-tscmp(struct timespec *a, struct timespec *b)
-{
-    long long m, s;
-    long long rc;
-
-    m = spectonsec(a);
-    s = spectonsec(b);
-
-    if (s < 0) {
-        rc = 1;
-        if (m < 0)
-            rc = 0;
-    } else if (m < 0) {
-        rc = -1;
-    } else {
-        rc = MIN(MAX(s-m, -1), 1);
-    }
-
-    return rc;
-}
-
-static inline void
-udelayspec(struct timespec total)
-{
-    struct timespec rem;
-    if (specinf(&total)) {
-        do {
-            usectospec(LLONG_MAX, &rem);
-        } while (nanosleep(&rem, &rem) == -1 && errno == EINTR);
-    } else {
-        rem = total;
-        while (nanosleep(&rem, &rem) == -1 && errno == EINTR)
-            ;
-    }
-}
-
-static inline void
-udelay(long long usecs)
-{
-    struct timespec rem = {0,0};
-
-    usectospec(usecs, &rem);
-    udelayspec(rem);
-}
-
-#endif /* UDELAY_H */
-/*
- * vim:ts=8:sw=4:sts=4:et
- */
diff --git a/loader/undomounts.c b/loader/undomounts.c
deleted file mode 100644
index af5caaa..0000000
--- a/loader/undomounts.c
+++ /dev/null
@@ -1,239 +0,0 @@
-/*
- * undomounts.c: Handles some basic unmounting stuff for init
- * Broken out so that it can be used on s390 in a shutdown binary
- *
- * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003  Red Hat, Inc.
- * 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 as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * 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, see <http://www.gnu.org/licenses/>.
- *
- * Author(s): Erik Troan <ewt@xxxxxxxxxx>
- *            Jeremy Katz <katzj@xxxxxxxxxx>
- */
-
-#include <errno.h>
-#include <fcntl.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/ioctl.h>
-#include <sys/mount.h>
-#include <sys/stat.h>
-#include <sys/swap.h>
-#include <unistd.h>
-
-#include "devt.h"
-
-/* Defined in linux/fs.h, but inside __KERNEL__. */
-#ifdef MNT_DETACH
-#undef MNT_DETACH
-#endif
-
-#define MNT_DETACH 0x00000002
-
-struct unmountInfo {
-    char * name;
-    int mounted;
-    int loopDevice;
-    enum { FS, LOOP } what;
-} ;
-
-void undoLoop(struct unmountInfo * fs, int numFs, int this);
-
-static void printstr(char * string) {
-    int ret;
-    
-    ret = write(1, string, strlen(string));
-}
-
-void undoMount(struct unmountInfo * fs, int numFs, int this) {
-    size_t len = strlen(fs[this].name);
-    int i;
-
-    if (!fs[this].mounted) return;
-    fs[this].mounted = 0;
-
-    /* unmount everything underneath this */
-    for (i = 0; i < numFs; i++) {
-	if (fs[i].name && (strlen(fs[i].name) >= len) &&
-	    (fs[i].name[len] == '/') && 
-	    !strncmp(fs[this].name, fs[i].name, len)) {
-	    if (fs[i].what == LOOP)
-		undoLoop(fs, numFs, i);
-	    else
-		undoMount(fs, numFs, i);
-	} 
-    }
-
-    printf("\t%s", fs[this].name);
-    /* don't need to unmount /tmp.  it is busy anyway. */
-    if (umount2(fs[this].name, MNT_DETACH) < 0) {
-        printf(" umount failed (%d)", errno);
-    } else {
-        printf(" done");
-    }
-    printf("\n");
-}
-
-void undoLoop(struct unmountInfo * fs, int numFs, int this) {
-    int i;
-    int fd;
-
-    if (!fs[this].mounted) return;
-    fs[this].mounted = 0;
-
-    /* find the device mount */
-    for (i = 0; i < numFs; i++) {
-	if (fs[i].what == FS && (fs[i].loopDevice == fs[this].loopDevice))
-	    break;
-    }
-
-    if (i < numFs) {
-	/* the device is mounted, unmount it (and recursively, anything
-	 * underneath) */
-	undoMount(fs, numFs, i);
-    }
-
-    unlink("/tmp/loop");
-    mknod("/tmp/loop", 0600 | S_IFBLK, (7 << 8) | fs[this].loopDevice);
-    printf("\tdisabling /dev/loop%d", fs[this].loopDevice);
-    if ((fd = open("/tmp/loop", O_RDONLY, 0)) < 0) {
-	printf(" failed to open device: %d", errno);
-    } else {
-	if (ioctl(fd, LOOP_CLR_FD, 0))
-	    printf(" LOOP_CLR_FD failed: %d", errno);
-	close(fd);
-    }
-
-    printf("\n");
-}
-
-void unmountFilesystems(void) {
-    int fd, size;
-    char buf[65535];			/* this should be big enough */
-    char * chptr, * start;
-    struct unmountInfo filesystems[500];
-    int numFilesystems = 0;
-    int i;
-    struct loop_info li;
-    char * device;
-    struct stat sb;
-
-    fd = open("/proc/mounts", O_RDONLY, 0);
-    if (fd < 1) {
-	/* FIXME: was perror */
-	printstr("failed to open /proc/mounts");
-	sleep(2);
-	return;
-    }
-
-    size = read(fd, buf, sizeof(buf) - 1);
-    buf[size] = '\0';
-
-    close(fd);
-
-    chptr = buf;
-    while (*chptr) {
-	device = chptr;
-	while (*chptr != ' ') chptr++;
-	*chptr++ = '\0';
-	start = chptr;
-	while (*chptr != ' ') chptr++;
-	*chptr++ = '\0';
-
-	if (strcmp(start, "/") && strcmp(start, "/tmp") &&
-            strcmp(start, "/dev")) {
-	    filesystems[numFilesystems].name = strdup(start);
-	    filesystems[numFilesystems].what = FS;
-	    filesystems[numFilesystems].mounted = 1;
-
-	    stat(start, &sb);
-	    if ((sb.st_dev >> 8) == 7) {
-		filesystems[numFilesystems].loopDevice = sb.st_dev & 0xf;
-	    } else {
-		filesystems[numFilesystems].loopDevice = -1;
-	    }
-
-	    numFilesystems++;
-	}
-
-	while (*chptr != '\n') chptr++;
-	chptr++;
-    }
-
-    for (i = 0; i < 7; i++) {
-	unlink("/tmp/loop");
-	mknod("/tmp/loop", 0600 | S_IFBLK, (7 << 8) | i);
-	if ((fd = open("/tmp/loop", O_RDONLY, 0)) >= 0) {
-	    if (!ioctl(fd, LOOP_GET_STATUS, &li) && li.lo_name[0]) {
-		filesystems[numFilesystems].name = strdup(li.lo_name);
-		filesystems[numFilesystems].what = LOOP;
-		filesystems[numFilesystems].mounted = 1;
-		filesystems[numFilesystems].loopDevice = i;
-		numFilesystems++;
-	    }
-
-	    close(fd);
-	}
-    }
-
-    for (i = 0; i < numFilesystems; i++) {
-	if (filesystems[i].what == LOOP) {
-	    undoLoop(filesystems, numFilesystems, i);
-	}
-    }
-
-    for (i = 0; i < numFilesystems; i++) {
-	if ((filesystems[i].mounted) && (filesystems[i].name)) {
-	    undoMount(filesystems, numFilesystems, i);
-	}
-    }
-
-    for (i = 0; i < numFilesystems; i++) 
-        free(filesystems[i].name);
-}
-
-void disableSwap(void) {
-    int fd;
-    char buf[4096];
-    int i;
-    char * start;
-    char * chptr;
-
-    if ((fd = open("/proc/swaps", O_RDONLY, 0)) < 0) return;
-
-    i = read(fd, buf, sizeof(buf) - 1);
-    close(fd);
-    if (i < 0) return;
-    buf[i] = '\0';
-
-    start = buf;
-    while (*start) {
-	while (*start != '\n' && *start) start++;
-	if (!*start) return;
-
-	start++;
-	if (*start != '/') return;
-	chptr = start;
-	while (*chptr && *chptr != ' ') chptr++;
-	if (!(*chptr)) return;
-	*chptr = '\0';
-	printf("\t%s", start);
-	if (swapoff(start)) 
-	    printf(" failed (%d)", errno);
-	printf("\n");
-
-	start = chptr + 1;
-    }
-}
diff --git a/loader/unicode-linedraw-chars.txt b/loader/unicode-linedraw-chars.txt
deleted file mode 100644
index c1a4814..0000000
--- a/loader/unicode-linedraw-chars.txt
+++ /dev/null
@@ -1,22 +0,0 @@
-â??
-â??
-â??
-â??
-â??
-â??
-â?¤
-â??
-â?´
-â?¬
-â?¼
-â??
-â??
-°
-±
-·
-â??
-â??
-â??
-â??
-â??
-â?®
diff --git a/loader/urlinstall.c b/loader/urlinstall.c
deleted file mode 100644
index 54d1398..0000000
--- a/loader/urlinstall.c
+++ /dev/null
@@ -1,414 +0,0 @@
-/*
- * urlinstall.c - code to set up url (ftp/http) installs
- *
- * Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003  Red Hat, Inc.
- * 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 as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * 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, see <http://www.gnu.org/licenses/>.
- *
- * Author(s): Erik Troan <ewt@xxxxxxxxxx>
- *            Matt Wilson <msw@xxxxxxxxxx>
- *            Michael Fulbright <msf@xxxxxxxxxx>
- *            Jeremy Katz <katzj@xxxxxxxxxx>
- */
-
-#include <newt.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/mount.h>
-#include <unistd.h>
-#include <errno.h>
-#include <glib.h>
-
-#include "../isys/iface.h"
-#include "../isys/log.h"
-
-#include "copy.h"
-#include "kickstart.h"
-#include "loader.h"
-#include "loadermisc.h"
-#include "lang.h"
-#include "method.h"
-#include "net.h"
-#include "method.h"
-#include "urlinstall.h"
-#include "cdinstall.h"
-#include "urls.h"
-#include "windows.h"
-
-/* boot flags */
-extern uint64_t flags;
-
-char **extraHeaders = NULL;
-
-static char **headers() {
-    int len = 2;
-
-    /* The list of HTTP headers is unlikely to change, unless a new ethernet
-     * device suddenly shows up since last time we downloaded a file.  So,
-     * cache the result here to save some time.
-     */
-    if (extraHeaders != NULL)
-        return extraHeaders;
-
-    if ((extraHeaders = realloc(extraHeaders, 2*sizeof(char *))) == NULL) {
-        logMessage(CRITICAL, "%s: %d: %m", __func__, __LINE__);
-        abort();
-    }
-    
-    checked_asprintf(&extraHeaders[0], "X-Anaconda-Architecture: %s", getProductArch());
-    checked_asprintf(&extraHeaders[1], "X-Anaconda-System-Release: %s", getProductName());
-
-    if (FL_KICKSTART_SEND_MAC(flags)) {
-        /* find all ethernet devices and make a header entry for each one */
-        int i;
-        char *dev, *mac;
-        struct device **devices;
-
-        devices = getDevices(DEVICE_NETWORK);
-        for (i = 0; devices && devices[i]; i++) {
-            dev = devices[i]->device;
-            mac = iface_mac2str(dev);
-
-            if (mac) {
-                extraHeaders = realloc(extraHeaders, (len+1)*sizeof(char *));
-                checked_asprintf(&extraHeaders[len], "X-RHN-Provisioning-MAC-%d: %s %s",
-                                 i, dev, mac);
-
-                len++;
-                free(mac);
-            }
-        }
-    }
-
-    if (FL_KICKSTART_SEND_SERIAL(flags) && !access("/sbin/dmidecode", X_OK)) {
-        FILE *f;
-        char sn[1024];
-        size_t sn_len;
-
-        if ((f = popen("/sbin/dmidecode -s system-serial-number", "r")) == NULL) {
-            logMessage(CRITICAL, "%s: %d: %m", __func__, __LINE__);
-            abort();
-        }
-
-        sn_len = fread(sn, sizeof(char), 1023, f);
-        if (ferror(f)) {
-            logMessage(CRITICAL, "%s: %d: %m", __func__, __LINE__);
-            abort();
-        }
-
-        sn[sn_len] = '\0';
-        pclose(f);
-
-        extraHeaders = realloc(extraHeaders, (len+1)*sizeof(char *));
-
-        checked_asprintf(&extraHeaders[len], "X-System-Serial-Number: %s", sn);
-
-        len++;
-    }
-
-    extraHeaders = realloc(extraHeaders, (len+1)*sizeof(char *));
-    extraHeaders[len] = NULL;
-    return extraHeaders;
-}
-
-static int loadSingleUrlImage(struct loaderData_s *loaderData, struct iurlinfo *ui,
-                              char *dest, char *mntpoint, char *device, int silentErrors) {
-    char **ehdrs = NULL;
-    int status;
-
-    if (!strncmp(ui->url, "http", 4))
-        ehdrs = headers();
-
-    status = urlinstTransfer(loaderData, ui, ehdrs, dest);
-    if (status) {
-        if (!silentErrors) {
-            newtWinMessage(_("Error"), _("OK"),
-                           _("Unable to retrieve %s."), ui->url);
-        }
-
-        return 2;
-    }
-
-    if (dest != NULL) {
-        if (mountLoopback(dest, mntpoint, device)) {
-            logMessage(ERROR, "Error mounting %s on %s: %m", device, mntpoint);
-            return 1;
-        }
-    }
-
-    return 0;
-}
-
-static void copyWarnFn (char *msg) {
-   logMessage(WARNING, msg);
-}
-
-static void copyErrorFn (char *msg) {
-   newtWinMessage(_("Error"), _("OK"), _(msg));
-}
-
-static int loadUrlImages(struct loaderData_s *loaderData, struct iurlinfo *ui) {
-    char *oldUrl, *path, *dest, *slash;
-    int rc;
-
-    oldUrl = strdup(ui->url);
-    free(ui->url);
-
-    /* Figure out the path where updates.img and product.img files are
-     * kept.  Since ui->url points to a stage2 image file, we just need
-     * to trim off the file name and look in the same directory.
-     */
-    if ((slash = strrchr(oldUrl, '/')) == NULL)
-        return 0;
-
-    if ((path = strndup(oldUrl, slash-oldUrl)) == NULL)
-        path = oldUrl;
-
-    /* grab the updates.img before install.img so that we minimize our
-     * ramdisk usage */
-    checked_asprintf(&ui->url, "%s/%s", path, "updates.img");
-
-    if (!loadSingleUrlImage(loaderData, ui, "/tmp/updates-disk.img", "/tmp/update-disk",
-                            "/dev/loop7", 1)) {
-        copyDirectory("/tmp/update-disk", "/tmp/updates", copyWarnFn,
-                      copyErrorFn);
-        umountLoopback("/tmp/update-disk", "/dev/loop7");
-        unlink("/tmp/updates-disk.img");
-        unlink("/tmp/update-disk");
-    } else if (!access("/tmp/updates-disk.img", R_OK)) {
-        unpackCpioBall("/tmp/updates-disk.img", "/tmp/updates");
-        unlink("/tmp/updates-disk.img");
-    }
-
-    free(ui->url);
-
-    /* grab the product.img before install.img so that we minimize our
-     * ramdisk usage */
-    checked_asprintf(&ui->url, "%s/%s", path, "product.img");
-
-    if (!loadSingleUrlImage(loaderData, ui, "/tmp/product-disk.img", "/tmp/product-disk",
-                            "/dev/loop7", 1)) {
-        copyDirectory("/tmp/product-disk", "/tmp/product", copyWarnFn,
-                      copyErrorFn);
-        umountLoopback("/tmp/product-disk", "/dev/loop7");
-        unlink("/tmp/product-disk.img");
-        unlink("/tmp/product-disk");
-    }
-
-    free(ui->url);
-    ui->url = strdup(oldUrl);
-
-    checked_asprintf(&dest, "/tmp/install.img");
-
-    rc = loadSingleUrlImage(loaderData, ui, dest, "/mnt/runtime", "/dev/loop0", 0);
-    free(dest);
-    free(oldUrl);
-
-    if (rc) {
-        if (rc != 2) 
-            newtWinMessage(_("Error"), _("OK"),
-                           _("Unable to retrieve the install image."));
-        return 1;
-    }
-
-    return 0;
-}
-
-char *mountUrlImage(struct installMethod *method, char *location,
-                    struct loaderData_s *loaderData) {
-    urlInstallData *stage2Data = (urlInstallData *) loaderData->stage2Data;
-    struct iurlinfo ui;
-
-    enum { URL_STAGE_MAIN, URL_STAGE_FETCH,
-           URL_STAGE_DONE } stage = URL_STAGE_MAIN;
-
-    memset(&ui, 0, sizeof(ui));
-
-    while (stage != URL_STAGE_DONE) {
-        switch(stage) {
-            case URL_STAGE_MAIN: {
-                /* If the stage2= parameter was given (or inferred from repo=)
-                 * then use that configuration info to fetch the image.  This
-                 * could also have come from kickstart.  Else, we need to show
-                 * the UI.
-                 */
-                if (loaderData->method == METHOD_URL && stage2Data) {
-                    ui.url = strdup(stage2Data->url);
-                    logMessage(INFO, "URL_STAGE_MAIN: url is %s", ui.url);
-
-                    if (!ui.url) {
-                        logMessage(ERROR, "missing URL specification");
-                        loaderData->method = -1;
-                        free(loaderData->stage2Data);
-                        loaderData->stage2Data = NULL;
-
-                        if (loaderData->inferredStage2)
-                            loaderData->invalidRepoParam = 1;
-
-                        break;
-                    }
-
-                    /* ks info was adequate, lets skip to fetching image */
-                    stage = URL_STAGE_FETCH;
-                    break;
-                } else {
-                    char *substr;
-
-                    if (urlMainSetupPanel(loaderData, &ui)) {
-                        loaderData->stage2Data = NULL;
-                        return NULL;
-                    }
-
-                    /* If the user-provided URL points at a repo instead of
-                     * a stage2 image, fix it up now.
-                     */
-                    substr = strstr(ui.url, ".img");
-                    if (!substr || (substr && *(substr+4) != '\0')) {
-                        loaderData->instRepo = strdup(ui.url);
-
-                        checked_asprintf(&ui.url, "%s/images/install.img",
-                                         ui.url);
-                    }
-
-                    loaderData->invalidRepoParam = 1;
-                }
-
-                stage = URL_STAGE_FETCH;
-                break;
-            }
-
-            case URL_STAGE_FETCH: {
-                if (loadUrlImages(loaderData, &ui)) {
-                    stage = URL_STAGE_MAIN;
-
-                    if (loaderData->method >= 0)
-                        loaderData->method = -1;
-
-                    if (loaderData->inferredStage2)
-                        loaderData->invalidRepoParam = 1;
-                } else {
-                    stage = URL_STAGE_DONE;
-                }
-
-                break;
-            }
-
-            case URL_STAGE_DONE:
-                break;
-        }
-    }
-
-    return ui.url;
-}
-
-int getFileFromUrl(char * url, char * dest, 
-                   struct loaderData_s * loaderData) {
-    struct iurlinfo ui;
-    char **ehdrs = NULL;
-    int rc;
-    iface_t iface;
-
-    iface_init_iface_t(&iface);
-
-    if (kickstartNetworkUp(loaderData, &iface)) {
-        logMessage(ERROR, "unable to bring up network");
-        return 1;
-    }
-
-    memset(&ui, 0, sizeof(ui));
-    ui.url = url;
-
-    logMessage(INFO, "file location: %s", url);
-
-    if (!strncmp(url, "http", 4)) {
-        ehdrs = headers();
-    }
-
-    rc = urlinstTransfer(loaderData, &ui, ehdrs, dest);
-    if (rc) {
-        logMessage(ERROR, "failed to retrieve %s", ui.url);
-        return 1;
-    }
-
-    return 0;
-}
-
-/* pull kickstart configuration file via http */
-int kickstartFromUrl(char * url, struct loaderData_s * loaderData) {
-    return getFileFromUrl(url, "/tmp/ks.cfg", loaderData);
-}
-
-void setKickstartUrl(struct loaderData_s * loaderData, int argc,
-		    char ** argv) {
-    char *substr = NULL;
-    gchar *url = NULL, *proxy = NULL;
-    GOptionContext *optCon = g_option_context_new(NULL);
-    GError *optErr = NULL;
-    GOptionEntry ksUrlOptions[] = {
-        { "url", 0, 0, G_OPTION_ARG_STRING, &url, NULL, NULL },
-        { "proxy", 0, 0, G_OPTION_ARG_STRING, &proxy, NULL, NULL },
-        { NULL },
-    };
-
-    logMessage(INFO, "kickstartFromUrl");
-
-    g_option_context_set_help_enabled(optCon, FALSE);
-    g_option_context_add_main_entries(optCon, ksUrlOptions, NULL);
-
-    if (!g_option_context_parse(optCon, &argc, &argv, &optErr)) {
-        startNewt();
-        newtWinMessage(_("Kickstart Error"), _("OK"),
-                       _("Bad argument to URL kickstart method "
-                         "command: %s"), optErr->message);
-        g_error_free(optErr);
-        g_option_context_free(optCon);
-        return;
-    }
-
-    g_option_context_free(optCon);
-
-    if (!url) {
-        newtWinMessage(_("Kickstart Error"), _("OK"),
-                       _("Must supply a --url argument to Url kickstart method."));
-        return;
-    }
-
-    /* determine install type */
-    if (strncmp(url, "http", 4) && strncmp(url, "ftp://";, 6)) {
-        newtWinMessage(_("Kickstart Error"), _("OK"),
-                       _("Unknown Url method %s"), url);
-        return;
-    }
-
-    substr = strstr(url, ".img");
-    if (!substr || (substr && *(substr+4) != '\0')) {
-        loaderData->instRepo = strdup(url);
-    } else {
-        if ((loaderData->stage2Data = calloc(sizeof(urlInstallData *), 1)) == NULL)
-            return;
-
-        ((urlInstallData *)loaderData->stage2Data)->url = url;
-        loaderData->method = METHOD_URL;
-    }
-
-    if (proxy) {
-        splitProxyParam(proxy, &loaderData->proxyUser,
-			       &loaderData->proxyPassword,
-			       &loaderData->proxy);
-    }
-    logMessage(INFO, "results of url ks, url %s", url);
-}
-
-/* vim:set shiftwidth=4 softtabstop=4: */
diff --git a/loader/urlinstall.h b/loader/urlinstall.h
deleted file mode 100644
index 710b0ae..0000000
--- a/loader/urlinstall.h
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * urlinstall.h
- *
- * Copyright (C) 2007  Red Hat, Inc.  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 as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * 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, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef URLINSTALL_H
-#define URLINSTALL_H
-
-#include "method.h"
-#include "urls.h"
-
-typedef struct iurlinfo urlInstallData;
-
-void setKickstartUrl(struct loaderData_s * loaderData, int argc,
-		     char ** argv);
-int kickstartFromUrl(char * url, struct loaderData_s * loaderData);
-char * mountUrlImage(struct installMethod * method,
-                     char * location, struct loaderData_s * loaderData);
-int getFileFromUrl(char * url, char * dest, struct loaderData_s * loaderData);
-
-
-#endif
diff --git a/loader/urls.c b/loader/urls.c
deleted file mode 100644
index c0a9f53..0000000
--- a/loader/urls.c
+++ /dev/null
@@ -1,371 +0,0 @@
-/*
- * urls.c - url handling code
- *
- * Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2009  Red Hat, Inc.
- * 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 as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * 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, see <http://www.gnu.org/licenses/>.
- *
- * Author(s): Erik Troan <ewt@xxxxxxxxxx>
- *            Matt Wilson <msw@xxxxxxxxxx>
- *            Michael Fulbright <msf@xxxxxxxxxx>
- *            Jeremy Katz <katzj@xxxxxxxxxx>
- *            Chris Lumens <clumens@xxxxxxxxxx>
- */
-
-#include <arpa/inet.h>
-#include <ctype.h>
-#include <fcntl.h>
-#include <netinet/in.h>
-#include <newt.h>
-#include <regex.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/types.h>
-#include <unistd.h>
-#include <netdb.h>
-#include <errno.h>
-#include <curl/curl.h>
-
-#include "../isys/log.h"
-
-#include "lang.h"
-#include "loader.h"
-#include "loadermisc.h"
-#include "urls.h"
-#include "windows.h"
-#include "net.h"
-
-#define NMATCH 10
-
-/* boot flags */
-extern uint64_t flags;
-
-/* This is just a wrapper around the windows.c progress callback that accepts
- * the arguments libcurl provides.
- */
-int progress_cb(void *data, double dltotal, double dlnow, double ultotal, double ulnow) {
-    struct progressCBdata *cb_data = (struct progressCBdata *) data;
-
-    progressCallback(cb_data, dlnow, dltotal);
-    return 0;
-}
-
-int splitProxyParam(char *param, char **user, char **password, char **proxy) {
-    /* proxy=[protocol://][username[:password]@]host[:port] */
-    char *pattern = "([[:alpha:]]+://)?(([[:alnum:]]+)(:[^:@]+)?@)?([^:]+)(:[[:digit:]]+)?(/.*)?";
-    regex_t re;
-    regmatch_t pmatch[NMATCH];
-
-    if (regcomp(&re, pattern, REG_EXTENDED)) {
-        return 0;
-    }
-
-    if (regexec(&re, param, NMATCH, pmatch, 0) == REG_NOMATCH) {
-        regfree(&re);
-        return 0;
-    }
-
-    /* Match 0 is always the whole string (assuming regexec matched anything)
-     * so skip it.  Then, these indices are just the number of the starting
-     * paren in pattern above.  Make sure to change these whenever changing
-     * the pattern.
-     */
-    if (pmatch[3].rm_so != -1)
-        *user = strndup(param+pmatch[3].rm_so, pmatch[3].rm_eo-pmatch[3].rm_so);
-
-    /* Skip the leading colon. */
-    if (pmatch[4].rm_so != -1)
-        *password = strndup(param+pmatch[4].rm_so+1, pmatch[4].rm_eo-pmatch[4].rm_so-1);
-
-    if (pmatch[5].rm_so != -1) {
-        char *portStr = "";
-
-        if (pmatch[6].rm_so != -1)
-            portStr = strndup(param+pmatch[6].rm_so, pmatch[6].rm_eo-pmatch[6].rm_so);
-
-        /* If no parameter was given, default to HTTP.  yum will want to know
-         * the protocol, and curl will just ignore it if given.
-         */
-        if (pmatch[1].rm_so != -1) {
-            checked_asprintf(proxy, "%.*s%.*s%s", pmatch[1].rm_eo-pmatch[1].rm_so,
-                                                  param+pmatch[1].rm_so,
-                                                  pmatch[5].rm_eo-pmatch[5].rm_so,
-                                                  param+pmatch[5].rm_so,
-                                                  portStr);
-        } else {
-            checked_asprintf(proxy, "http://%.*s%s";, pmatch[5].rm_eo-pmatch[5].rm_so,
-                                                     param+pmatch[5].rm_so,
-                                                     portStr);
-        }
-    }
-
-    regfree(&re);
-    return 1;
-}
-
-int urlinstTransfer(struct loaderData_s *loaderData, struct iurlinfo *ui,
-                    char **extraHeaders, char *dest) {
-    struct progressCBdata *cb_data;
-    CURL *curl = NULL;
-    CURLcode status;
-    struct curl_slist *headers = NULL;
-    char *version;
-    FILE *f = NULL;
-
-    logMessage(INFO, "transferring %s", ui->url);
-
-    f = fopen(dest, "w");
-
-    /* Initialize libcurl */
-    curl_global_init(CURL_GLOBAL_SSL);
-    curl = curl_easy_init();
-
-    checked_asprintf(&version, "anaconda/%s", VERSION);
-
-    curl_easy_setopt(curl, CURLOPT_USERAGENT, version);
-    curl_easy_setopt(curl, CURLOPT_URL, ui->url);
-    curl_easy_setopt(curl, CURLOPT_WRITEDATA, f);
-    curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1);
-    curl_easy_setopt(curl, CURLOPT_MAXREDIRS, 10);
-    curl_easy_setopt(curl, CURLOPT_FAILONERROR, 1);
-
-    /* If a proxy was provided, add the options for that now. */
-    if (loaderData->proxy && strcmp(loaderData->proxy, "")) {
-        curl_easy_setopt(curl, CURLOPT_PROXY, loaderData->proxy);
-
-        if (loaderData->proxyUser && strcmp(loaderData->proxyUser, ""))
-            curl_easy_setopt(curl, CURLOPT_PROXYUSERNAME,
-                             loaderData->proxyUser);
-
-        if (loaderData->proxyPassword && strcmp(loaderData->proxyPassword, ""))
-            curl_easy_setopt(curl, CURLOPT_PROXYPASSWORD,
-                             loaderData->proxyPassword);
-    }
-
-    if (extraHeaders) {
-        int i;
-        for (i = 0; extraHeaders[i] != NULL; i++) {
-            headers = curl_slist_append(headers, extraHeaders[i]);
-        }
-
-        curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
-    }
-
-    /* Only set up the progress bar if we've got a UI to display it. */
-    if (FL_CMDLINE(flags)) {
-        printf("%s %s...\n", _("Retrieving"), ui->url);
-    } else {
-        char *filename;
-
-        filename = strrchr(ui->url, '/');
-        if (!filename)
-           filename = ui->url;
-
-        cb_data = winProgressBar(70, 5, _("Retrieving"), "%s %s...", _("Retrieving"), filename);
-
-        curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 0);
-        curl_easy_setopt(curl, CURLOPT_PROGRESSFUNCTION, progress_cb);
-        curl_easy_setopt(curl, CURLOPT_PROGRESSDATA, cb_data);
-    }
-
-    /* Finally, do the transfer. */
-    status = curl_easy_perform(curl);
-    if (status)
-        logMessage(ERROR, "Error downloading %s: %s", ui->url, curl_easy_strerror(status));
-
-    if (!FL_CMDLINE(flags))
-       newtPopWindow();
-
-    if (headers)
-        curl_slist_free_all(headers);
-
-    fclose(f);
-    free(version);
-
-    curl_easy_cleanup(curl);
-    curl_global_cleanup();
-
-    return status;
-}
-
-char * addrToIp(char * hostname) {
-    struct in_addr ad;
-    struct in6_addr ad6;
-    char *ret;
-    struct hostent *host;
-
-    if ((ret = malloc(INET6_ADDRSTRLEN+1)) == NULL)
-        return hostname;
-
-    if (inet_ntop(AF_INET, &ad, ret, INET_ADDRSTRLEN) != NULL)
-        return ret;
-    else if (inet_ntop(AF_INET6, &ad6, ret, INET6_ADDRSTRLEN) != NULL)
-        return ret;
-    else if ((host = gethostbyname(hostname)) != NULL)
-        return host->h_name;
-    else
-        return NULL;
-}
-
-static void setProxySensitivity(newtComponent co, void *dptr) {
-    int i;
-
-    /* It's 3 because there are three entry boxes in the proxy grid.  Lame. */
-    for (i = 0; i < 3; i++) {
-        newtEntrySetFlags(*((newtComponent *) dptr), NEWT_FLAG_DISABLED,
-                          NEWT_FLAGS_TOGGLE);
-        dptr += sizeof(newtComponent);
-    }
-
-    return;
-}
-
-int urlMainSetupPanel(struct loaderData_s *loaderData, struct iurlinfo * ui) {
-    newtComponent form, okay, cancel, urlEntry, proxyCheckbox;
-    newtComponent proxyEntries[3];
-    newtComponent answer, text;
-    char enableProxy;
-    char *url = "", *proxy = "", *proxyUser = "", *proxyPassword = "";
-    char * reflowedText = NULL;
-    int width, height;
-    newtGrid buttons, grid, proxyGrid;
-    char * buf = NULL;
-
-    /* Populate the UI with whatever initial value we've got. */
-    if (ui && ui->url)
-        url = ui->url;
-
-    if (loaderData->proxy)
-        proxy = loaderData->proxy;
-
-    if (loaderData->proxyUser)
-        proxyUser = loaderData->proxyUser;
-
-    if (loaderData->proxyPassword)
-        proxyPassword = loaderData->proxyPassword;
-
-    buttons = newtButtonBar(_("OK"), &okay, _("Back"), &cancel, NULL);
-
-    checked_asprintf(&buf,
-                     _("Please enter the URL containing the %s installation image on your server."),
-                     getProductName());
-
-    reflowedText = newtReflowText(buf, 47, 5, 5, &width, &height);
-    free(buf);
-
-    text = newtTextbox(-1, -1, width, height, NEWT_TEXTBOX_WRAP);
-    newtTextboxSetText(text, reflowedText);
-    free(reflowedText);
-
-    urlEntry = newtEntry(22, 8, url, 60, (const char **) &url,
-                         NEWT_ENTRY_SCROLL);
-
-    /* If we've been provided with proxy settings already, enable the proxy
-     * grid.  This will make sure all the fields get filled in, too.
-     */
-    enableProxy = loaderData->proxy != NULL && strcmp("", loaderData->proxy) ? '*' : ' ';
-
-    proxyCheckbox = newtCheckbox(-1, -1, _("Enable HTTP proxy"), enableProxy,
-                                 NULL, &enableProxy);
-    newtComponentAddCallback(proxyCheckbox, setProxySensitivity, &proxyEntries);
-
-    proxyEntries[0] = newtEntry(-1, -1, proxy, 35, (const char **) &proxy, NEWT_FLAG_SCROLL);
-    proxyEntries[1] = newtEntry(-1, -1, proxyUser, 15, (const char **) &proxyUser, NEWT_FLAG_SCROLL);
-    proxyEntries[2] = newtEntry(-1, -1, proxyPassword, 15, (const char **) &proxyPassword, NEWT_FLAG_SCROLL|NEWT_FLAG_PASSWORD);
-
-    /* Set the initial proxy grid sensitivity to match. */
-    if (enableProxy == ' ')
-        setProxySensitivity(proxyCheckbox, proxyEntries);
-
-    proxyGrid = newtCreateGrid(2, 3);
-    newtGridSetField(proxyGrid, 0, 0, NEWT_GRID_COMPONENT,
-                     newtLabel(-1, -1, _("Proxy URL")),
-                     0, 0, 0, 0, 0, NEWT_ANCHOR_LEFT);
-    newtGridSetField(proxyGrid, 1, 0, NEWT_GRID_COMPONENT, proxyEntries[0],
-                     0, 0, 0, 0, 0, NEWT_ANCHOR_LEFT);
-    newtGridSetField(proxyGrid, 0, 1, NEWT_GRID_COMPONENT,
-                     newtLabel(-1, -1, _("Username")),
-                     0, 0, 0, 1, 0, NEWT_ANCHOR_LEFT);
-    newtGridSetField(proxyGrid, 1, 1, NEWT_GRID_COMPONENT, proxyEntries[1],
-                     0, 0, 0, 1, 0, NEWT_ANCHOR_LEFT);
-    newtGridSetField(proxyGrid, 0, 2, NEWT_GRID_COMPONENT,
-                     newtLabel(-1, -1, _("Password")),
-                     0, 0, 0, 1, 0, NEWT_ANCHOR_LEFT);
-    newtGridSetField(proxyGrid, 1, 2, NEWT_GRID_COMPONENT, proxyEntries[2],
-                     0, 0, 0, 1, 0, NEWT_ANCHOR_LEFT);
-
-    grid = newtCreateGrid(1, 5);
-    newtGridSetField(grid, 0, 0, NEWT_GRID_COMPONENT, text,
-                     0, 0, 0, 1, 0, 0);
-    newtGridSetField(grid, 0, 1, NEWT_GRID_COMPONENT, urlEntry,
-                     0, 0, 0, 1, 0, 0);
-    newtGridSetField(grid, 0, 2, NEWT_GRID_COMPONENT, proxyCheckbox,
-                     0, 0, 0, 1, 0, NEWT_ANCHOR_LEFT);
-    newtGridSetField(grid, 0, 3, NEWT_GRID_SUBGRID, proxyGrid,
-                     0, 0, 0, 0, 0, NEWT_GRID_FLAG_GROWX);
-    newtGridSetField(grid, 0, 4, NEWT_GRID_SUBGRID, buttons,
-                     0, 0, 0, 0, 0, NEWT_GRID_FLAG_GROWX);
-
-    form = newtForm(NULL, NULL, 0);
-    newtGridAddComponentsToForm(grid, form, 1); 
-    newtGridWrappedWindow(grid, _("URL Setup"));
-    newtGridFree(grid, 1);
-
-    do {
-        answer = newtRunForm(form);
-        if (answer != cancel) {
-            if (!strlen(url)) {
-                newtWinMessage(_("Error"), _("OK"),
-                               _("You must enter a URL."));
-                continue;
-            }
-
-            if (strncmp(url, "http", 4) && strncmp(url, "ftp://";, 6)) {
-                newtWinMessage(_("Error"), _("OK"),
-                               _("URL must be either an ftp or http URL"));
-                continue;
-            }
-
-            ui->url = strdup(url);
-
-            if (enableProxy == '*') {
-               loaderData->proxy = strdup(proxy);
-               loaderData->proxyUser = strdup(proxyUser);
-               loaderData->proxyPassword = strdup(proxyPassword);
-            } else {
-               loaderData->proxy = "";
-               loaderData->proxyUser = "";
-               loaderData->proxyPassword = "";
-            }
-
-            /* FIXME:  add back in hostname checking */
-        }
-
-        break;
-    } while (1);
-
-    if (answer == cancel) {
-        newtFormDestroy(form);
-        newtPopWindow();
-
-        return LOADER_BACK;
-    }
-
-    newtFormDestroy(form);
-    newtPopWindow();
-
-    return 0;
-}
diff --git a/loader/urls.h b/loader/urls.h
deleted file mode 100644
index 4ca538f..0000000
--- a/loader/urls.h
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * urls.h
- *
- * Copyright (C) 2007  Red Hat, Inc.  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 as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * 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, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef H_LOADER_URLS
-#define H_LOADER_URLS
-
-#include "loader.h"
-#include "windows.h"
-
-struct iurlinfo {
-    char * url;
-};
-
-int splitProxyParam(char *param, char **user, char **password, char **proxy);
-int urlMainSetupPanel(struct loaderData_s *loaderData, struct iurlinfo * ui);
-int urlinstTransfer(struct loaderData_s *loaderData, struct iurlinfo *ui,
-                    char **extraHeaders, char *dest);
-
-#endif
diff --git a/loader/windows.c b/loader/windows.c
deleted file mode 100644
index 51b00db..0000000
--- a/loader/windows.c
+++ /dev/null
@@ -1,121 +0,0 @@
-/*
- * windows.c - simple popup windows used by the loader
- *
- * Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002  Red Hat, Inc.
- * 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 as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * 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, see <http://www.gnu.org/licenses/>.
- *
- * Author(s): Erik Troan <ewt@xxxxxxxxxx>
- *            Matt Wilson <msw@xxxxxxxxxx>
- *            Michael Fulbright <msf@xxxxxxxxxx>
- *            Jeremy Katz <katzj@xxxxxxxxxx>
- */
-
-#include <errno.h>
-#include <newt.h>
-#include <stdlib.h>
-#include <string.h>
-#include <stdio.h>
-#include <stdarg.h>
-#include <math.h>
-
-#include "../isys/log.h"
-
-#include "windows.h"
-
-void winStatus(int width, int height, char * title, char * text, ...) {
-    newtComponent t, f;
-    char * buf = NULL;
-    va_list args;
-
-    va_start(args, text);
-
-    if (vasprintf(&buf, text, args) != -1) {
-        newtCenteredWindow(width, height, title);
-
-        t = newtTextbox(1, 1, width - 2, height - 2, NEWT_TEXTBOX_WRAP);
-        newtTextboxSetText(t, buf);
-        f = newtForm(NULL, NULL, 0);
-
-        free(buf);
-
-        newtFormAddComponent(f, t);
-
-        newtDrawForm(f);
-        newtRefresh();
-        newtFormDestroy(f);
-    }
-
-    va_end(args);
-}
-
-
-void scsiWindow(const char * driver) {
-    winStatus(40, 3, _("Loading SCSI driver"),
-        _("Loading %s driver"), driver);
-}
-
-int progressCallback(void *pbdata, long long pos, long long total) {
-    struct progressCBdata *data = pbdata;
-    char tickmark[2] = "-";
-    char *ticks = "-\\|/";
-    int x = ceil(pos * 100.0 / total);
-
-    newtScaleSet(data->scale, x);
-    *tickmark = ticks[x % 4];
-
-    newtLabelSetText(data->label, tickmark);
-    newtRefresh();
-    return 0;
-}
-
-struct progressCBdata *winProgressBar(int width, int height, char *title, char *text, ...) {
-    struct progressCBdata *data;
-    char *buf = NULL;
-    va_list args;
-    int llen;
-    newtComponent t, f, scale, label;
-
-    va_start(args, text);
-
-    if (vasprintf(&buf, text, args) != -1) {
-        va_end(args);
-        newtCenteredWindow(width, height, title);
-        t = newtTextbox(1, 1, width - 2, height - 2, NEWT_TEXTBOX_WRAP);
-        newtTextboxSetText(t, buf);
-        llen = strlen(buf);
-        free(buf);
-        label = newtLabel(llen + 1, 1, "-");
-        f = newtForm(NULL, NULL, 0);
-        newtFormAddComponent(f, t);
-        scale = newtScale(3, 3, width - 6, 100);
-        newtFormAddComponent(f, scale);
-        newtDrawForm(f);
-        newtRefresh();
-
-        if ((data = malloc(sizeof(struct progressCBdata))) == NULL) {
-            logMessage(ERROR, "%s: %d: %m", __func__, __LINE__);
-            abort();
-        }
-
-        data->scale = scale;
-        data->label = label;
-        return data;
-    }
-
-    return NULL;
-}
-
-/* vim:set shiftwidth=4 softtabstop=4: */
diff --git a/loader/windows.h b/loader/windows.h
deleted file mode 100644
index a1646d4..0000000
--- a/loader/windows.h
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * windows.h
- *
- * Copyright (C) 2007  Red Hat, Inc.  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 as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * 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, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef _WINDOWS_H_
-#define _WINDOWS_H_
-
-#include <newt.h>
-
-#include "lang.h"
-
-void winStatus(int width, int height, char * title, char * text, ...);
-void scsiWindow(const char * driver);
-
-#define errorWindow(String) \
-	newtWinMessage(_("Error"), _("OK"), String, strerror (errno));
-
-typedef void (*progressCB) (void *pbdata, long long offset, long long total);
-
-struct progressCBdata {
-    newtComponent scale;
-    newtComponent label;
-};
-
-int progressCallback(void *pbdata, long long pos, long long total);
-struct progressCBdata *winProgressBar(int width, int height, char *title, char *text, ...);
-
-#endif /* _WINDOWS_H_ */
diff --git a/network.py b/network.py
deleted file mode 100644
index 2c19349..0000000
--- a/network.py
+++ /dev/null
@@ -1,839 +0,0 @@
-#
-# network.py - network configuration install data
-#
-# Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007  Red Hat, Inc.
-#               2008, 2009
-#
-# 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; either version 2 of the License, or
-# (at your option) any later version.
-#
-# 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, see <http://www.gnu.org/licenses/>.
-#
-# Author(s): Matt Wilson <ewt@xxxxxxxxxx>
-#            Erik Troan <ewt@xxxxxxxxxx>
-#            Mike Fulbright <msf@xxxxxxxxxx>
-#            Brent Fox <bfox@xxxxxxxxxx>
-#            David Cantrell <dcantrell@xxxxxxxxxx>
-#
-
-import string
-import shutil
-import isys
-import iutil
-import socket
-import struct
-import os
-import time
-import dbus
-from flags import flags
-from simpleconfig import SimpleConfigFile
-
-import gettext
-_ = lambda x: gettext.ldgettext("anaconda", x)
-
-import logging
-log = logging.getLogger("anaconda")
-
-class IPError(Exception):
-    pass
-
-class IPMissing(Exception):
-    pass
-
-def sanityCheckHostname(hostname):
-    if len(hostname) < 1:
-        return None
-
-    if len(hostname) > 255:
-        return _("Hostname must be 255 or fewer characters in length.")
-
-    validStart = string.ascii_letters + string.digits
-    validAll = validStart + ".-"
-
-    if string.find(validStart, hostname[0]) == -1:
-        return _("Hostname must start with a valid character in the ranges "
-                 "'a-z', 'A-Z', or '0-9'")
-
-    for i in range(1, len(hostname)):
-        if string.find(validAll, hostname[i]) == -1:
-            return _("Hostnames can only contain the characters 'a-z', 'A-Z', '0-9', '-', or '.'")
-
-    return None
-
-# Try to determine what the hostname should be for this system
-def getDefaultHostname(anaconda):
-    isys.resetResolv()
-
-    hn = None
-    bus = dbus.SystemBus()
-    nm = bus.get_object(isys.NM_SERVICE, isys.NM_MANAGER_PATH)
-    nm_props_iface = dbus.Interface(nm, isys.DBUS_PROPS_IFACE)
-
-    active_connections = nm_props_iface.Get(isys.NM_MANAGER_IFACE, "ActiveConnections")
-
-    # XXX: account for Ip6Config objects when NetworkManager supports them
-    for connection in active_connections:
-        active_connection = bus.get_object(isys.NM_SERVICE, connection)
-        active_connection_props_iface = dbus.Interface(active_connection, isys.DBUS_PROPS_IFACE)
-        devices = active_connection_props_iface.Get(isys.NM_MANAGER_IFACE, 'Devices')
-
-        for device_path in devices:
-            device = bus.get_object(isys.NM_SERVICE, device_path)
-            device_props_iface = dbus.Interface(device, isys.DBUS_PROPS_IFACE)
-
-            ip4_config_path = device_props_iface.Get(isys.NM_MANAGER_IFACE, 'Ip4Config')
-            ip4_config_obj = bus.get_object(isys.NM_SERVICE, ip4_config_path)
-            ip4_config_props = dbus.Interface(ip4_config_obj, isys.DBUS_PROPS_IFACE)
-
-            # addresses (3-element list:  ipaddr, netmask, gateway)
-            addrs = ip4_config_props.Get(isys.NM_MANAGER_IFACE, "Addresses")[0]
-            try:
-                tmp = struct.pack('I', addrs[0])
-                ipaddr = socket.inet_ntop(socket.AF_INET, tmp)
-                hinfo = socket.gethostbyaddr(ipaddr)
-
-                if len(hinfo) == 3:
-                    hn = hinfo[0]
-                else:
-                    continue
-            except:
-                continue
-
-    if hn and hn != 'localhost' and hn != 'localhost.localdomain':
-        return hn
-
-    try:
-        hn = anaconda.network.hostname
-    except:
-        hn = None
-
-    if not hn or hn == '(none)' or hn == 'localhost' or hn == 'localhost.localdomain':
-        hn = socket.gethostname()
-
-    if not hn or hn == '(none)' or hn == 'localhost':
-        hn = 'localhost.localdomain'
-
-    return hn
-
-# return if the device is of a type that requires a ptpaddr to be specified
-def isPtpDev(devname):
-    if devname.startswith("ctc"):
-        return True
-    return False
-
-def _anyUsing(method):
-    # method names that NetworkManager might use
-    if method == 'auto':
-        methods = (method, 'dhcp')
-    else:
-        methods = (method)
-
-    try:
-        bus = dbus.SystemBus()
-        nm = bus.get_object(isys.NM_SERVICE, isys.NM_MANAGER_PATH)
-        nm_props_iface = dbus.Interface(nm, isys.DBUS_PROPS_IFACE)
-        active_connections = nm_props_iface.Get(isys.NM_MANAGER_IFACE, "ActiveConnections")
-
-        for path in active_connections:
-            active = bus.get_object(isys.NM_SERVICE, path)
-            active_props_iface = dbus.Interface(active, isys.DBUS_PROPS_IFACE)
-
-            active_service_name = active_props_iface.Get(isys.NM_ACTIVE_CONNECTION_IFACE, "ServiceName")
-            active_path = active_props_iface.Get(isys.NM_ACTIVE_CONNECTION_IFACE, "Connection")
-
-            connection = bus.get_object(active_service_name, active_path)
-            connection_iface = dbus.Interface(connection, isys.NM_CONNECTION_IFACE)
-            settings = connection_iface.GetSettings()
-
-            # XXX: add support for Ip6Config when it appears
-            ip4_setting = settings['ipv4']
-            if not ip4_setting or not ip4_setting['method'] or ip4_setting['method'] in methods:
-                return True
-
-            return False
-    except:
-        return False
-
-# determine whether any active at boot devices are using dhcp or dhcpv6
-def anyUsingDHCP():
-    return _anyUsing('auto')
-
-# determine whether any active at boot devices are using static IP config
-def anyUsingStatic():
-    return _anyUsing('manual')
-
-# sanity check an IP string.
-def sanityCheckIPString(ip_string):
-    if ip_string.strip() == "":
-        raise IPMissing, _("IP address is missing.")
-
-    if ip_string.find(':') == -1 and ip_string.find('.') > 0:
-        family = socket.AF_INET
-        errstr = _("IPv4 addresses must contain four numbers between 0 and 255, separated by periods.")
-    elif ip_string.find(':') > 0 and ip_string.find('.') == -1:
-        family = socket.AF_INET6
-        errstr = _("'%s' is not a valid IPv6 address.") % ip_string
-    else:
-        raise IPError, _("'%s' is an invalid IP address.") % ip_string
-
-    try:
-        socket.inet_pton(family, ip_string)
-    except socket.error:
-        raise IPError, errstr
-
-def hasActiveNetDev():
-    try:
-        bus = dbus.SystemBus()
-        nm = bus.get_object(isys.NM_SERVICE, isys.NM_MANAGER_PATH)
-        props = dbus.Interface(nm, isys.DBUS_PROPS_IFACE)
-        state = props.Get(isys.NM_SERVICE, "State")
-
-        if int(state) == isys.NM_STATE_CONNECTED:
-            return True
-        else:
-            return False
-    except:
-        return False
-
-# Return a list of device names (e.g., eth0) for all active devices.
-# Returning a list here even though we will almost always have one
-# device.  NM uses lists throughout its D-Bus communication, so trying
-# to follow suit here.  Also, if this uses a list now, we can think
-# about multihomed hosts during installation later.
-def getActiveNetDevs():
-    active_devs = set()
-
-    bus = dbus.SystemBus()
-    nm = bus.get_object(isys.NM_SERVICE, isys.NM_MANAGER_PATH)
-    nm_props_iface = dbus.Interface(nm, isys.DBUS_PROPS_IFACE)
-
-    active_connections = nm_props_iface.Get(isys.NM_MANAGER_IFACE, "ActiveConnections")
-
-    for connection in active_connections:
-        active_connection = bus.get_object(isys.NM_SERVICE, connection)
-        active_connection_props_iface = dbus.Interface(active_connection, isys.DBUS_PROPS_IFACE)
-        devices = active_connection_props_iface.Get(isys.NM_MANAGER_IFACE, 'Devices')
-
-        for device_path in devices:
-            device = bus.get_object(isys.NM_SERVICE, device_path)
-            device_props_iface = dbus.Interface(device, isys.DBUS_PROPS_IFACE)
-
-            interface_name = device_props_iface.Get(isys.NM_MANAGER_IFACE, 'Interface')
-            active_devs.add(interface_name)
-
-    ret = list(active_devs)
-    ret.sort()
-    return ret
-
-class NetworkDevice(SimpleConfigFile):
-    def __str__(self):
-        s = ""
-        s = s + "DEVICE=" + self.info["DEVICE"] + "\n"
-        keys = self.info.keys()
-        keys.sort()
-        keys.remove("DEVICE")
-        if "DESC" in keys:
-            keys.remove("DESC")
-        if "KEY" in keys:
-            keys.remove("KEY")
-        if iutil.isS390() and ("HWADDR" in keys):
-            keys.remove("HWADDR")
-
-        for key in keys:
-            if (key == 'NAME') or \
-               (key == 'NM_CONTROLLED' and not flags.livecdInstall):
-                continue
-            # make sure we include autoneg in the ethtool line
-            elif key == 'ETHTOOL_OPTS' and self.info[key].find("autoneg")== -1:
-                s = s + key + """="autoneg off %s"\n""" % (self.info[key])
-            elif self.info[key] is not None:
-                s = s + key + "=" + self.info[key] + "\n"
-
-        return s
-
-    def __init__(self, dev):
-        self.info = { "DEVICE" : dev }
-        if dev.startswith('ctc'):
-            self.info["TYPE"] = "CTC"
-
-class Network:
-    def __init__(self):
-        self.netdevices = {}
-        self.ksdevice = None
-        self.domains = []
-        self.hostname = socket.gethostname()
-        self.overrideDHCPhostname = False
-
-        # populate self.netdevices
-        devhash = isys.getDeviceProperties(dev=None)
-        for dev in devhash.keys():
-            self.netdevices[dev] = NetworkDevice(dev)
-            ifcfg_contents = self.readIfcfgContents(dev)
-
-            # if NM_CONTROLLED is set to yes, we read in settings from
-            # NetworkManager first, then fill in the gaps with the data
-            # from the ifcfg file
-            useNetworkManager = False
-            if ifcfg_contents.has_key('NM_CONTROLLED') and \
-               not ifcfg_contents['NM_CONTROLLED'].lower() == 'no':
-                useNetworkManager = True
-
-            # this interface is managed by NetworkManager, so read from
-            # NetworkManager first
-            if useNetworkManager:
-                props = devhash[dev]
-
-                if isys.isDeviceDHCP(dev):
-                    self.netdevices[dev].set(('BOOTPROTO', 'dhcp'))
-                else:
-                    self.netdevices[dev].unset('BOOTPROTO')
-                    bus = dbus.SystemBus()
-                    config_path = props.Get(isys.NM_MANAGER_IFACE, 'Ip4Config')
-                    config = bus.get_object(isys.NM_SERVICE, config_path)
-                    config_props = dbus.Interface(config, isys.DBUS_PROPS_IFACE)
-
-                    # addresses (3-element list:  ipaddr, netmask, gateway)
-                    addrs = config_props.Get(isys.NM_MANAGER_IFACE, 'Addresses')[0]
-                    try:
-                        tmp = struct.pack('I', addrs[0])
-                        ipaddr = socket.inet_ntop(socket.AF_INET, tmp)
-                        self.netdevices[dev].set(('IPADDR', ipaddr))
-                    except:
-                        pass
-
-                    try:
-                        tmp = struct.pack('I', addrs[1])
-                        netmask = socket.inet_ntop(socket.AF_INET, tmp)
-                        self.netdevices[dev].set(('NETMASK', netmask))
-                    except:
-                        pass
-
-                    try:
-                        tmp = struct.pack('I', addrs[2])
-                        gateway = socket.inet_ntop(socket.AF_INET, tmp)
-                        self.netdevices[dev].set(('GATEWAY', gateway))
-                    except:
-                        pass
-
-                self.hostname = socket.gethostname()
-
-            # read in remaining settings from ifcfg file
-            for key in ifcfg_contents.keys():
-                if key == 'GATEWAY':
-                    self.netdevices[dev].set((key, ifcfg_contents[key]))
-                elif key == 'DOMAIN':
-                    self.domains.append(ifcfg_contents[key])
-                elif key == 'HOSTNAME':
-                    self.hostname = ifcfg_contents[key]
-                elif self.netdevices[dev].get(key) == '':
-                    self.netdevices[dev].set((key, ifcfg_contents[key]))
-
-        # now initialize remaining devices
-        # XXX we just throw return away, the method initialize a
-        # object member so we dont need to
-        available_devices = self.available()
-
-        if len(available_devices) > 0:
-            # set first device to start up onboot
-            oneactive = 0
-            for dev in available_devices.keys():
-                try:
-                    if available_devices[dev].get("ONBOOT") == "yes":
-                        oneactive = 1
-                        break
-                except:
-                    continue
-
-    def readIfcfgContents(self, dev):
-        ifcfg = "/etc/sysconfig/network-scripts/ifcfg-%s" % (dev,)
-        contents = {}
-
-        try:
-            f = open(ifcfg, "r")
-            lines = f.readlines()
-            f.close()
-
-            for line in lines:
-                line = line.strip()
-                if line.startswith('#') or line == '':
-                    continue
-
-                var = string.splitfields(line, '=', 1)
-                if len(var) == 2:
-                    var[1] = var[1].replace('"', '')
-                    contents[var[0]] = string.strip(var[1])
-        except:
-            return {}
-
-        return contents
-
-    def getDevice(self, device):
-        return self.netdevices[device]
-
-    def available(self):
-        ksdevice = None
-        if flags.cmdline.has_key('ksdevice'):
-            ksdevice = flags.cmdline['ksdevice']
-
-        for dev in isys.getDeviceProperties().keys():
-            if not self.netdevices.has_key(dev):
-                self.netdevices[dev] = NetworkDevice(dev)
-
-            hwaddr = isys.getMacAddress(dev)
-
-            self.netdevices[dev].set(('HWADDR', hwaddr))
-            self.netdevices[dev].set(('DESC', isys.getNetDevDesc(dev)))
-
-            if not ksdevice:
-                continue
-
-            if ksdevice == 'link' and isys.getLinkStatus(dev):
-                self.ksdevice = dev
-            elif ksdevice == dev:
-                self.ksdevice = dev
-            elif ksdevice.find(':') != -1:
-                if ksdevice.upper() == hwaddr:
-                    self.ksdevice = dev
-
-        return self.netdevices
-
-    def getKSDevice(self):
-        if self.ksdevice is None:
-            return None
-
-        try:
-            return self.netdevices[self.ksdevice]
-        except:
-            return None
-
-    def setHostname(self, hn):
-        self.hostname = hn
-
-    def setDNS(self, ns, device):
-        dns = ns.split(',')
-        i = 1
-        for addr in dns:
-            addr = addr.strip()
-            dnslabel = "DNS%d" % (i,)
-            self.netdevices[device].set((dnslabel, addr))
-            i += 1
-
-    def setGateway(self, gw, device):
-        self.netdevices[device].set(('GATEWAY', gw))
-
-    def lookupHostname(self):
-        # can't look things up if they don't exist!
-        if not self.hostname or self.hostname == "localhost.localdomain":
-            return None
-
-        if not hasActiveNetDev():
-            log.warning("no network devices were available to look up host name")
-            return None
-
-        try:
-            (family, socktype, proto, canonname, sockaddr) = \
-                socket.getaddrinfo(self.hostname, None, socket.AF_INET)[0]
-            (ip, port) = sockaddr
-        except:
-            try:
-                (family, socktype, proto, canonname, sockaddr) = \
-                    socket.getaddrinfo(self.hostname, None, socket.AF_INET6)[0]
-                (ip, port, flowinfo, scopeid) = sockaddr
-            except:
-                return None
-
-        return ip
-
-    def writeKS(self, f):
-        devNames = self.netdevices.keys()
-        devNames.sort()
-
-        if len(devNames) == 0:
-            return
-
-        for devName in devNames:
-            dev = self.netdevices[devName]
-
-            if dev.get('bootproto').lower() == 'dhcp' or dev.get('ipaddr'):
-                f.write("network --device %s" % dev.get('device'))
-
-                if dev.get('MTU') and dev.get('MTU') != 0:
-                    f.write(" --mtu=%s" % dev.get('MTU'))
-
-                onboot = dev.get("onboot")
-                if onboot and onboot == "no":
-                    f.write(" --onboot no")
-                if dev.get('bootproto').lower() == 'dhcp':
-                    f.write(" --bootproto dhcp")
-                    if dev.get('dhcpclass'):
-                        f.write(" --dhcpclass %s" % dev.get('dhcpclass'))
-                    if self.overrideDHCPhostname:
-                        if (self.hostname and
-                            self.hostname != "localhost.localdomain"):
-                            f.write(" --hostname %s" % self.hostname)
-                else:
-                    f.write(" --bootproto static --ip %s" % dev.get('ipaddr'))
-
-                    if dev.get('netmask'):
-                        f.write(" --netmask %s" % dev.get('netmask'))
-
-                    if dev.get('GATEWAY'):
-                        f.write(" --gateway %s" % (dev.get('GATEWAY'),))
-
-                    dnsline = ''
-                    for key in dev.info.keys():
-                        if key.upper().startswith('DNS'):
-                            if dnsline == '':
-                                dnsline = dev.get(key)
-                            else:
-                                dnsline += "," + dev.get(key)
-
-                    if dnsline != '':
-                        f.write(" --nameserver %s" % (dnsline,))
-
-                    if (self.hostname and
-                        self.hostname != "localhost.localdomain"):
-                        f.write(" --hostname %s" % self.hostname)
-
-                f.write("\n")
-
-    def hasNameServers(self, hash):
-        if hash.keys() == []:
-            return False
-
-        for key in hash.keys():
-            if key.upper().startswith('DNS'):
-                return True
-
-        return False
-
-    def write(self, instPath='', anaconda=None, devices=None):
-
-        if devices is None:
-            devices = self.netdevices.values()
-
-        if len(devices) == 0:
-            return
-
-        sysconfig = "%s/etc/sysconfig" % (instPath,)
-        netscripts = "%s/network-scripts" % (sysconfig,)
-        destnetwork = "%s/network" % (sysconfig,)
-
-        if not os.path.isdir(netscripts):
-            iutil.mkdirChain(netscripts)
-
-        # /etc/sysconfig/network-scripts/ifcfg-*
-        for dev in devices:
-            device = dev.get('DEVICE')
-
-            cfgfile = "%s/ifcfg-%s" % (netscripts, device,)
-            if (instPath) and (os.path.isfile(cfgfile)):
-                continue
-
-            bootproto = dev.get('BOOTPROTO').lower()
-            ipv6addr = dev.get('IPV6ADDR').lower()
-            ipv6prefix = dev.get('IPV6PREFIX').lower()
-            ipv6autoconf = dev.get('IPV6_AUTOCONF').lower()
-            dhcpv6c = dev.get('DHCPV6C').lower()
-
-            newifcfg = "/tmp/ifcfg-%s.new" % (device,)
-            f = open(newifcfg, "w")
-            if len(dev.get("DESC")) > 0:
-                f.write("# %s\n" % (dev.get("DESC"),))
-
-            # if bootproto is dhcp, unset any static settings (#218489)
-            # *but* don't unset if either IPv4 or IPv6 is manual (#433290)
-            if bootproto == 'dhcp':
-                dev.unset('IPADDR')
-                dev.unset('NETMASK')
-                dev.unset('GATEWAY')
-
-            # handle IPv6 settings correctly for the ifcfg file
-            dev.unset('IPV6ADDR')
-            dev.unset('IPV6PREFIX')
-
-            if ipv6addr == 'dhcp':
-                dev.set(('IPV6INIT', 'yes'))
-                dev.set(('DHCPV6C', 'yes'))
-            elif ipv6addr != '' and ipv6addr is not None:
-                dev.set(('IPV6INIT', 'yes'))
-
-                if ipv6prefix != '' and ipv6prefix is not None:
-                    dev.set(('IPV6ADDR', ipv6addr + '/' + ipv6prefix))
-                else:
-                    dev.set(('IPV6ADDR', ipv6addr))
-
-            if dev.get('IPV6_AUTOCONF').lower() == 'yes':
-                dev.set(('IPV6INIT', 'yes'))
-
-            f.write(str(dev))
-
-            # write out the hostname as DHCP_HOSTNAME if given (#81613)
-            if (bootproto == 'dhcp' and self.hostname and
-                self.overrideDHCPhostname):
-                f.write("DHCP_HOSTNAME=%s\n" %(self.hostname,))
-
-            if dev.get('MTU') and dev.get('MTU') != 0:
-                f.write("MTU=%s\n" % dev.get('MTU'))
-
-            # tell NetworkManager not to touch any interfaces used during
-            # installation when / is on a network backed device.
-            if anaconda is not None:
-                import storage
-                rootdev = anaconda.storage.rootDevice
-                # FIXME: use d.host_address to only add "NM_CONTROLLED=no"
-                # for interfaces actually used enroute to the device
-                for d in anaconda.storage.devices:
-                    if isinstance(d, storage.devices.NetworkStorageDevice) and\
-                       (rootdev.dependsOn(d) or d.nic == device):
-                        f.write("NM_CONTROLLED=no\n")
-                        break
-
-            f.close()
-            os.chmod(newifcfg, 0644)
-
-            # move the new ifcfg in place
-            destcfg = "%s/ifcfg-%s" % (netscripts, device,)
-            try:
-                os.remove(destcfg)
-            except OSError as e:
-                if e.errno != 2:
-                    raise
-            shutil.move(newifcfg, destcfg)
-
-            # XXX: is this necessary with NetworkManager?
-            # handle the keys* files if we have those
-            if dev.get("KEY"):
-                cfgfile = "%s/keys-%s" % (netscripts, device,)
-                if not instPath == '' and os.path.isfile(cfgfile):
-                    continue
-
-                newkey = "%s/keys-%s.new" % (netscripts, device,)
-                f = open(newkey, "w")
-                f.write("KEY=%s\n" % (dev.get('KEY'),))
-                f.close()
-                os.chmod(newkey, 0600)
-
-                destkey = "%s/keys-%s" % (netscripts, device,)
-                shutil.move(newkey, destkey)
-
-            # /etc/dhclient-DEVICE.conf
-            dhclientconf = '/etc/dhclient-' + device + '.conf'
-            if os.path.isfile(dhclientconf):
-                destdhclientconf = '%s%s' % (instPath, dhclientconf,)
-                try:
-                    shutil.copy(dhclientconf, destdhclientconf)
-                except:
-                    log.warning("unable to copy %s to target system" % (dhclientconf,))
-
-        # /etc/sysconfig/network
-        if (not instPath) or (not os.path.isfile(destnetwork)) or flags.livecdInstall:
-            newnetwork = "%s.new" % (destnetwork,)
-
-            f = open(newnetwork, "w")
-            f.write("NETWORKING=yes\n")
-            f.write("HOSTNAME=")
-
-            # use instclass hostname if set(kickstart) to override
-            if self.hostname:
-                f.write(self.hostname + "\n")
-            else:
-                f.write("localhost.localdomain\n")
-
-            if dev.get('GATEWAY'):
-                f.write("GATEWAY=%s\n" % (dev.get('GATEWAY'),))
-
-            if dev.get('IPV6_DEFAULTGW'):
-                f.write("IPV6_DEFAULTGW=%s\n" % (dev.get('IPV6_DEFAULTGW'),))
-
-            f.close()
-            shutil.move(newnetwork, destnetwork)
-
-        # If the hostname was not looked up, but typed in by the user,
-        # domain might not be computed, so do it now.
-        domainname = None
-        if "." in self.hostname:
-            fqdn = self.hostname
-        else:
-            fqdn = socket.getfqdn(self.hostname)
-
-        if fqdn in [ "localhost.localdomain", "localhost",
-                     "localhost6.localdomain6", "localhost6",
-                     self.hostname ] or "." not in fqdn:
-            fqdn = None
-
-        if fqdn:
-            domainname = fqdn.split('.', 1)[1]
-            if domainname in [ "localdomain", "localdomain6" ]:
-                domainname = None
-        else:
-            domainname = None
-
-        if self.domains == ["localdomain"] or not self.domains:
-            if domainname:
-                self.domains = [domainname]
-
-        # /etc/resolv.conf
-        if (not instPath) or (not os.path.isfile(instPath + '/etc/resolv.conf')) or flags.livecdInstall:
-            if os.path.isfile('/etc/resolv.conf') and instPath != '':
-                destresolv = "%s/etc/resolv.conf" % (instPath,)
-                shutil.copy('/etc/resolv.conf', destresolv)
-            elif (self.domains != ['localdomain'] and self.domains) or \
-                self.hasNameServers(dev.info):
-                resolv = "%s/etc/resolv.conf" % (instPath,)
-
-                f = open(resolv, "w")
-
-                if self.domains != ['localdomain'] and self.domains:
-                    f.write("search %s\n" % (string.joinfields(self.domains, ' '),))
-
-                for key in dev.info.keys():
-                    if key.upper().startswith('DNS'):
-                        f.write("nameserver %s\n" % (dev.get(key),))
-
-                f.close()
-
-        # /etc/udev/rules.d/70-persistent-net.rules
-        rules = "/etc/udev/rules.d/70-persistent-net.rules"
-        destRules = instPath + rules
-        if (not instPath) or (not os.path.isfile(destRules)) or \
-           flags.livecdInstall:
-            if not os.path.isdir("%s/etc/udev/rules.d" %(instPath,)):
-                iutil.mkdirChain("%s/etc/udev/rules.d" %(instPath,))
-
-            if os.path.isfile(rules) and rules != destRules:
-                shutil.copy(rules, destRules)
-            else:
-                f = open(destRules, "w")
-                f.write("""
-# This file was automatically generated by the /lib/udev/write_net_rules
-# program run by the persistent-net-generator.rules rules file.
-#
-# You can modify it, as long as you keep each rule on a single line.
-
-""")
-                for dev in self.netdevices.values():
-                    addr = dev.get("HWADDR")
-                    if not addr:
-                        continue
-                    devname = dev.get("DEVICE")
-                    basename = devname
-                    while basename != "" and basename[-1] in string.digits:
-                        basename = basename[:-1]
-
-                    # rules are case senstive for address. Lame.
-                    addr = addr.lower()
-
-                    s = ""
-                    if len(dev.get("DESC")) > 0:
-                        s = "# %s (rule written by anaconda)\n" % (dev.get("DESC"),)
-                    else:
-                        s = "# %s (rule written by anaconda)\n" % (devname,)
-                        s = s + 'SUBSYSTEM==\"net\", ACTION==\"add\", DRIVERS=="?*", ATTR{address}=="%s", ATTR{type}=="1", KERNEL=="%s*", NAME="%s"\n' % (addr, basename, devname,)
-
-                    f.write(s)
-
-                f.close()
-
-    # write out current configuration state and wait for NetworkManager
-    # to bring the device up, watch NM state and return to the caller
-    # once we have a state
-    def bringUp(self, devices=None):
-        self.write(devices=devices)
-
-        bus = dbus.SystemBus()
-        nm = bus.get_object(isys.NM_SERVICE, isys.NM_MANAGER_PATH)
-        props = dbus.Interface(nm, isys.DBUS_PROPS_IFACE)
-
-        i = 0
-        while i < 45:
-            state = props.Get(isys.NM_SERVICE, "State")
-            if int(state) == isys.NM_STATE_CONNECTED:
-                isys.resetResolv()
-                return True
-            i += 1
-            time.sleep(1)
-
-        state = props.Get(isys.NM_SERVICE, "State")
-        if int(state) == isys.NM_STATE_CONNECTED:
-            isys.resetResolv()
-            return True
-
-        return False
-
-    # get a kernel cmdline string for dracut needed for access to host host
-    def dracutSetupString(self, networkStorageDevice):
-        netargs=""
-
-        if networkStorageDevice.nic:
-            # Storage bound to a specific nic (ie FCoE)
-            nic = networkStorageDevice.nic
-        else:
-            # Storage bound through ip, find out which interface leads to host
-            host = networkStorageDevice.host_address
-            route = iutil.execWithCapture("ip", [ "route", "get", "to", host ])
-            if not route:
-                log.error("Could net get interface for route to %s" % host)
-                return ""
-
-            routeInfo = route.split()
-            if routeInfo[0] != host or len(routeInfo) < 5 or \
-               "dev" not in routeInfo or routeInfo.index("dev") > 3:
-                log.error('Unexpected "ip route get to %s" reply: %s' %
-                          (host, routeInfo))
-                return ""
-
-            nic = routeInfo[routeInfo.index("dev") + 1]
-
-        if nic not in self.netdevices.keys():
-            log.error('Unknown network interface: %s' % nic)
-            return ""
-
-        dev = self.netdevices[nic]
-
-        if networkStorageDevice.host_address:
-            if dev.get('bootproto').lower() == 'dhcp':
-                netargs += "ip=%s:dhcp" % nic
-            else:
-                if dev.get('GATEWAY'):
-                    gateway = dev.get('GATEWAY')
-                else:
-                    gateway = ""
-
-                if self.hostname:
-                    hostname = self.hostname
-                else:
-                    hostname = ""
-
-                netargs += "ip=%s::%s:%s:%s:%s:none" % (dev.get('ipaddr'),
-                           gateway, dev.get('netmask'), hostname, nic)
-
-        hwaddr = dev.get("HWADDR")
-        if hwaddr:
-            if netargs != "":
-                netargs += " "
-
-            netargs += "ifname=%s:%s" % (nic, hwaddr.lower())
-
-        nettype = dev.get("NETTYPE")
-        subchannels = dev.get("SUBCHANNELS")
-        if iutil.isS390() and nettype and subchannels:
-            if netargs != "":
-                netargs += " "
-
-            netargs += "rd_CCW=%s,%s" % (nettype, subchannels)
-
-            options = dev.get("OPTIONS").strip("'\"")
-            if options:
-                options = filter(lambda x: x != '', options.split(' '))
-                netargs += ",%s" % (','.join(options))
-
-        return netargs
diff --git a/packages.py b/packages.py
deleted file mode 100644
index 6381c12..0000000
--- a/packages.py
+++ /dev/null
@@ -1,360 +0,0 @@
-#
-# packages.py: package management - mainly package installation
-#
-# Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006  Red Hat, Inc.
-# 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 as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# 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, see <http://www.gnu.org/licenses/>.
-#
-# Author(s): Erik Troan <ewt@xxxxxxxxxx>
-#            Matt Wilson <msw@xxxxxxxxxx>
-#            Michael Fulbright <msf@xxxxxxxxxx>
-#            Jeremy Katz <katzj@xxxxxxxxxx>
-#
-
-import glob
-import iutil
-import isys
-import os
-import time
-import sys
-import string
-import language
-import shutil
-import traceback
-from flags import flags
-from product import *
-from constants import *
-from upgrade import bindMountDevDirectory
-from storage.errors import *
-
-import logging
-log = logging.getLogger("anaconda")
-
-import gettext
-_ = lambda x: gettext.ldgettext("anaconda", x)
-
-def doPostAction(anaconda):
-    anaconda.instClass.postAction(anaconda)
-
-def firstbootConfiguration(anaconda):
-    if anaconda.firstboot == FIRSTBOOT_RECONFIG:
-        f = open(anaconda.rootPath + '/etc/reconfigSys', 'w+')
-        f.close()
-    elif anaconda.firstboot == FIRSTBOOT_SKIP:
-        f = open(anaconda.rootPath + '/etc/sysconfig/firstboot', 'w+')
-        f.write('RUN_FIRSTBOOT=NO')
-        f.close()
-
-    return
-
-def writeKSConfiguration(anaconda):
-    log.info("Writing autokickstart file")
-    fn = anaconda.rootPath + "/root/anaconda-ks.cfg"
-
-    anaconda.writeKS(fn)
-
-def copyAnacondaLogs(anaconda):
-    log.info("Copying anaconda logs")
-    for (fn, dest) in (("/tmp/anaconda.log", "anaconda.log"),
-                       ("/tmp/syslog", "anaconda.syslog"),
-                       ("/tmp/X.log", "anaconda.xlog"),
-                       ("/tmp/program.log", "anaconda.program.log"),
-                       ("/tmp/storage.log", "anaconda.storage.log"),
-                       ("/tmp/yum.log", "anaconda.yum.log")):
-        if os.access(fn, os.R_OK):
-            try:
-                shutil.copyfile(fn, "%s/var/log/%s" %(anaconda.rootPath, dest))
-                os.chmod("%s/var/log/%s" %(anaconda.rootPath, dest), 0600)
-            except:
-                pass
-
-def turnOnFilesystems(anaconda):
-    if anaconda.dir == DISPATCH_BACK:
-        if not anaconda.upgrade:
-            log.info("unmounting filesystems")
-            anaconda.storage.umountFilesystems()
-        return DISPATCH_NOOP
-
-    if not anaconda.upgrade:
-        if not anaconda.storage.fsset.active:
-            # turn off any swaps that we didn't turn on
-            # needed for live installs
-            iutil.execWithRedirect("swapoff", ["-a"],
-                                   stdout = "/dev/tty5", stderr="/dev/tty5")
-        anaconda.storage.devicetree.teardownAll()
-
-    upgrade_migrate = False
-    if anaconda.upgrade:
-        for d in anaconda.storage.migratableDevices:
-            if d.format.migrate:
-                upgrade_migrate = True
-
-    title = None
-    message = None
-    details = None
-
-    try:
-        anaconda.storage.doIt()
-    except FSResizeError as (msg, device):
-        title = _("Resizing Failed")
-        message = _("There was an error encountered while "
-                    "resizing the device %s.") % (device,)
-
-        if os.path.exists("/tmp/resize.out"):
-            details = open("/tmp/resize.out", "r").read()
-        else:
-            details = "%s" %(msg,)
-    except FSMigrateError as (msg, device):
-        title = _("Migration Failed")
-        message = _("An error was encountered while "
-                    "migrating filesystem on device %s.") % (device,)
-        details = msg
-    except Exception as e:
-        raise
-
-    if title:
-        rc = anaconda.intf.detailedMessageWindow(title, message, details,
-                        type = "custom",
-                        custom_buttons = [_("_File Bug"), _("_Exit installer")])
-
-        if rc == 0:
-            raise
-        elif rc == 1:
-            sys.exit(1)
-
-    if not anaconda.upgrade:
-        anaconda.storage.turnOnSwap()
-        anaconda.storage.mountFilesystems(raiseErrors=False,
-                                          readOnly=False,
-                                          skipRoot=anaconda.backend.skipFormatRoot)
-    else:
-        if upgrade_migrate:
-            # we should write out a new fstab with the migrated fstype
-            shutil.copyfile("%s/etc/fstab" % anaconda.rootPath,
-                            "%s/etc/fstab.anaconda" % anaconda.rootPath)
-            anaconda.storage.fsset.write(anaconda.rootPath)
-
-        # and make sure /dev is mounted so we can read the bootloader
-        bindMountDevDirectory(anaconda.rootPath)
-
-
-def setupTimezone(anaconda):
-    # we don't need this on an upgrade or going backwards
-    if anaconda.upgrade or anaconda.dir == DISPATCH_BACK:
-        return
-
-    os.environ["TZ"] = anaconda.timezone.tz
-    tzfile = "/usr/share/zoneinfo/" + anaconda.timezone.tz
-    tzlocalfile = "/etc/localtime"
-    if not os.access(tzfile, os.R_OK):
-        log.error("unable to set timezone")
-    else:
-        try:
-            os.remove(tzlocalfile)
-        except OSError:
-            pass
-        try:
-            shutil.copyfile(tzfile, tzlocalfile)
-        except OSError as e:
-            log.error("Error copying timezone (from %s): %s" %(tzfile, e.strerror))
-
-    if iutil.isS390():
-        return
-    args = [ "--hctosys" ]
-    if anaconda.timezone.utc:
-        args.append("-u")
-
-    try:
-        iutil.execWithRedirect("/usr/sbin/hwclock", args, stdin = None,
-                               stdout = "/dev/tty5", stderr = "/dev/tty5")
-    except RuntimeError:
-        log.error("Failed to set clock")
-
-
-# FIXME: this is a huge gross hack.  hard coded list of files
-# created by anaconda so that we can not be killed by selinux
-def setFileCons(anaconda):
-    if flags.selinux:
-        log.info("setting SELinux contexts for anaconda created files")
-
-        files = ["/etc/rpm/macros",
-                 "/etc/lilo.conf.anaconda", "/lib64", "/usr/lib64",
-                 "/etc/blkid.tab", "/etc/blkid.tab.old", 
-                 "/etc/mtab", "/etc/fstab", "/etc/resolv.conf",
-                 "/etc/modprobe.conf", "/etc/modprobe.conf~",
-                 "/var/log/wtmp", "/var/run/utmp", "/etc/crypttab",
-                 "/dev/log", "/var/lib/rpm", "/", "/etc/raidtab",
-                 "/etc/mdadm.conf", "/etc/sysconfig/network",
-                 "/etc/udev/rules.d/70-persistent-net.rules",
-                 "/root/install.log", "/root/install.log.syslog",
-                 "/etc/shadow", "/etc/shadow-", "/etc/gshadow"] + \
-                glob.glob('/etc/dhclient-*.conf')
-
-        vgs = ["/dev/%s" % vg.name for vg in anaconda.storage.vgs]
-
-        # ugh, this is ugly
-        for dir in ["/etc/sysconfig/network-scripts", "/var/lib/rpm", "/etc/lvm", "/dev/mapper", "/etc/iscsi", "/var/lib/iscsi", "/root", "/var/log", "/etc/modprobe.d", "/etc/sysconfig" ] + vgs:
-            def addpath(x): return dir + "/" + x
-
-            if not os.path.isdir(anaconda.rootPath + dir):
-                continue
-            dirfiles = os.listdir(anaconda.rootPath + dir)
-            files.extend(map(addpath, dirfiles))
-            files.append(dir)
-
-        for f in files:
-            if not os.access("%s/%s" %(anaconda.rootPath, f), os.R_OK):
-                log.warning("%s doesn't exist" %(f,))
-                continue
-            ret = isys.resetFileContext(os.path.normpath(f),
-                                        anaconda.rootPath)
-            log.info("set fc of %s to %s" %(f, ret))
-
-    return
-
-# FIXME: using rpm directly here is kind of lame, but in the yum backend
-# we don't want to use the metadata as the info we need would require
-# the filelists.  and since we only ever call this after an install is
-# done, we can be guaranteed this will work.  put here because it's also
-# used for livecd installs
-def rpmKernelVersionList(rootPath = "/"):
-    import rpm
-
-    def get_version(header):
-        for f in header['filenames']:
-            if f.startswith('/boot/vmlinuz-'):
-                return f[14:]
-            elif f.startswith('/boot/efi/EFI/redhat/vmlinuz-'):
-                return f[29:]
-        return ""
-
-    def get_tag(header):
-        if header['name'] == "kernel":
-            return "base"
-        elif header['name'].startswith("kernel-"):
-            return header['name'][7:]
-        return ""
-
-    versions = []
-
-    iutil.resetRpmDb(rootPath)
-    ts = rpm.TransactionSet(rootPath)
-
-    mi = ts.dbMatch('provides', 'kernel')
-    for h in mi:
-        v = get_version(h)
-        tag = get_tag(h)
-        if v == "" or tag == "":
-            log.warning("Unable to determine kernel type/version for %s-%s-%s.%s" %(h['name'], h['version'], h['release'], h['arch'])) 
-            continue
-        # rpm really shouldn't return the same kernel more than once... but
-        # sometimes it does (#467822)
-        if (v, h['arch'], tag) in versions:
-            continue
-        versions.append( (v, h['arch'], tag) )
-
-    return versions
-
-def rpmSetupGraphicalSystem(anaconda):
-    import rpm
-
-    iutil.resetRpmDb(anaconda.rootPath)
-    ts = rpm.TransactionSet(anaconda.rootPath)
-
-    # Only add "rhgb quiet" on non-s390, non-serial installs
-    if iutil.isConsoleOnVirtualTerminal() and \
-       (ts.dbMatch('provides', 'rhgb').count() or \
-        ts.dbMatch('provides', 'plymouth').count()):
-        anaconda.bootloader.args.append("rhgb quiet")
-
-    if ts.dbMatch('provides', 'service(graphical-login)').count() and \
-       anaconda.displayMode == 'g' and not flags.usevnc:
-        anaconda.desktop.setDefaultRunLevel(5)
-
-#Recreate initrd for use when driver disks add modules
-def recreateInitrd (kernelTag, instRoot):
-    log.info("recreating initrd for %s" % (kernelTag,))
-    iutil.execWithRedirect("/sbin/new-kernel-pkg",
-                           [ "--mkinitrd", "--dracut", "--depmod", "--install", kernelTag ],
-                           stdout = "/dev/null", stderr = "/dev/null",
-                           root = instRoot)
-
-def betaNagScreen(anaconda):
-    publicBetas = { "Red Hat Linux": "Red Hat Linux Public Beta",
-                    "Red Hat Enterprise Linux": "Red Hat Enterprise Linux Public Beta",
-                    "Fedora Core": "Fedora Core",
-                    "Fedora": "Fedora" }
-
-    
-    if anaconda.dir == DISPATCH_BACK:
-	return DISPATCH_NOOP
-
-    fileagainst = None
-    for (key, val) in publicBetas.items():
-        if productName.startswith(key):
-            fileagainst = val
-    if fileagainst is None:
-        fileagainst = "%s Beta" %(productName,)
-    
-    while 1:
-	rc = anaconda.intf.messageWindow(_("Warning"),
-				 _("Warning!  This is pre-release software!\n\n"
-                                   "Thank you for downloading this "
-				   "pre-release of %(productName)s.\n\n"
-				   "This is not a final "
-				   "release and is not intended for use "
-				   "on production systems.  The purpose of "
-				   "this release is to collect feedback "
-				   "from testers, and it is not suitable "
-				   "for day to day usage.\n\n"
-				   "To report feedback, please visit:\n\n"
-				   "   %(bugzillaUrl)s\n\n"
-				   "and file a report against '%(fileagainst)s'.\n")
-				 % {'productName': productName,
-				    'bugzillaUrl': bugzillaUrl,
-				    'fileagainst': fileagainst},
-				   type="custom", custom_icon="warning",
-				   custom_buttons=[_("_Exit"), _("_Install Anyway")])
-
-	if not rc:
-            msg =  _("Your system will now be rebooted...")
-            buttons = [_("_Back"), _("_Reboot")]
-	    rc = anaconda.intf.messageWindow( _("Warning! This is pre-release software!"),
-                                     msg,
-                                     type="custom", custom_icon="warning",
-                                     custom_buttons=buttons)
-	    if rc:
-		sys.exit(0)
-	else:
-	    break
-
-def doReIPL(anaconda):
-#   # This is here as an example to fix the screen during the TUI debugging path
-#   anaconda.intf.screen.suspend ()
-#   import pdb
-#   pdb.set_trace ()
-
-    if not iutil.isS390() or anaconda.dir == DISPATCH_BACK:
-        return DISPATCH_NOOP
-
-    messageInfo = iutil.reIPL(anaconda, os.getppid())
-
-    if messageInfo:
-        (errorMessage, rebootInstr) = messageInfo
-
-        # errorMessage intentionally not shown in UI
-        anaconda.reIPLMessage = rebootInstr
-
-    return DISPATCH_FORWARD
diff --git a/partIntfHelpers.py b/partIntfHelpers.py
deleted file mode 100644
index 3aaba71..0000000
--- a/partIntfHelpers.py
+++ /dev/null
@@ -1,354 +0,0 @@
-#
-# partIntfHelpers.py: partitioning interface helper functions
-#
-# Copyright (C) 2002  Red Hat, Inc.  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 as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# 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, see <http://www.gnu.org/licenses/>.
-#
-# Author(s): Matt Wilson <msw@xxxxxxxxxx>
-#            Jeremy Katz <katzj@xxxxxxxxxx>
-#            Mike Fulbright <msf@xxxxxxxxxx>
-#            Harald Hoyer <harald@xxxxxxxxx>
-#
-
-"""Helper functions shared between partitioning interfaces."""
-
-import string
-from constants import *
-import parted
-import iutil
-from storage.formats import getFormat
-
-import gettext
-_ = lambda x: gettext.ldgettext("anaconda", x)
-
-def sanityCheckVolumeGroupName(volname):
-    """Make sure that the volume group name doesn't contain invalid chars."""
-    badNames = ['lvm', 'root', '.', '..' ]
-
-    if not volname:
-	return _("Please enter a volume group name.")
-
-    # ripped the value for this out of linux/include/lvm.h
-    if len(volname) > 128:
-        return _("Volume Group Names must be less than 128 characters")
-
-    if volname in badNames:
-	return _("Error - the volume group name %s is not valid." % (volname,))
-
-    for i in range(0, len(volname)):
-	rc = string.find(string.letters + string.digits + '.' + '_' + '-', volname[i])
-	if rc == -1:
-	    return _("Error - the volume group name contains illegal "
-		     "characters or spaces.  Acceptable characters "
-		     "are letters, digits, '.' or '_'.")
-    return None
-
-def sanityCheckLogicalVolumeName(logvolname):
-    """Make sure that the logical volume name doesn't contain invalid chars."""
-    badNames = ['group', '.', '..' ]
-    
-    if not logvolname:
-	return _("Please enter a logical volume name.")
-
-    # ripped the value for this out of linux/include/lvm.h
-    if len(logvolname) > 128:
-        return _("Logical Volume Names must be less than 128 characters")
-    
-
-    if logvolname in badNames:
-	return _("Error - the logical volume name %s is not "
-                 "valid." % (logvolname,))
-
-    for i in range(0, len(logvolname)):
-	rc = string.find(string.letters + string.digits + '.' + '_', logvolname[i])
-	if rc == -1:
-	    return _("Error - the logical volume name contains illegal "
-		     "characters or spaces.  Acceptable characters "
-		     "are letters, digits, '.' or '_'.")
-    return None
-
-def sanityCheckMountPoint(mntpt, fstype, preexisting, format):
-    """Sanity check that the mountpoint is valid.
-
-    mntpt is the mountpoint being used.
-    fstype is the file system being used on the request.
-    preexisting is whether the request was preexisting (request.preexist)
-    format is whether the request is being formatted or not
-    """
-    if mntpt:
-        passed = 1
-        if not mntpt:
-            passed = 0
-        else:
-            if mntpt[0] != '/' or (len(mntpt) > 1 and mntpt[-1:] == '/'):
-                passed = 0
-	    elif mntpt.find(' ') > -1:
-		passed = 0
-                
-        if not passed:
-            return _("The mount point %s is invalid.  Mount points must start "
-                     "with '/' and cannot end with '/', and must contain "
-                     "printable characters and no spaces." % mntpt)
-        else:
-            return None
-    else:
-        if (fstype and fstype.mountable and (not preexisting or format)):
-            return _("Please specify a mount point for this partition.")
-        else:
-            # its an existing partition so don't force a mount point
-            return None
-
-def doDeleteDevice(intf, storage, device, confirm=1, quiet=0):
-    """Delete a partition from the request list.
-
-    intf is the interface
-    storage is the storage instance
-    device is the device to delete
-    """
-    if not device:
-        intf.messageWindow(_("Unable To Delete"),
-                           _("You must first select a partition to delete."),
-			   custom_icon="error")
-        return False
-
-    reason = storage.deviceImmutable(device)
-    if reason:
-        intf.messageWindow(_("Unable To Delete"),
-                           reason,
-                           custom_icon="error")
-        return False
-
-    if confirm and not confirmDelete(intf, device):
-        return False
-
-    deps = storage.deviceDeps(device)
-    while deps:
-        leaves = [d for d in deps if d.isleaf]
-        for leaf in leaves:
-            storage.destroyDevice(leaf)
-            deps.remove(leaf)
-
-    storage.destroyDevice(device)
-    return True
-
-def doClearPartitionedDevice(intf, storage, device, confirm=1, quiet=0):
-    """ Remove all devices/partitions currently on device.
-
-            device -- a partitioned device such as a disk
-
-     """
-    if confirm:
-	rc = intf.messageWindow(_("Confirm Delete"),
-				_("You are about to delete all partitions on "
-				  "the device '%s'.") % (device.path,),
-				type="custom", custom_icon="warning",
-				custom_buttons=[_("Cancel"), _("_Delete")])
-
-	if not rc:
-	    return False
-
-    immutable = []
-    partitions = [p for p in storage.partitions if p.disk == device]
-    if not partitions:
-        return False
-
-    partitions.sort(key=lambda p: p.partedPartition.number, reverse=True)
-    for p in partitions:
-        deps = storage.deviceDeps(p)
-        clean = True    # true if part and its deps were removed
-        while deps:
-            leaves = [d for d in deps if d.isleaf]
-            for leaf in leaves:
-                if leaf in immutable:
-                    # this device was removed from deps at the same time it
-                    # was added to immutable, so it won't appear in leaves
-                    # in the next iteration
-                    continue
-
-                if storage.deviceImmutable(leaf):
-                    immutable.append(leaf)
-                    for dep in [d for d in deps if d != leaf]:
-                        # mark devices this device depends on as immutable
-                        # to prevent getting stuck with non-leaf deps
-                        # protected by immutable leaf devices
-                        if leaf.dependsOn(dep):
-                            deps.remove(dep)
-                            if dep not in immutable:
-                                immutable.append(dep)
-                    clean = False
-                else:
-                    storage.destroyDevice(leaf)
-                deps.remove(leaf)
-
-        if storage.deviceImmutable(p):
-            immutable.append(p)
-            clean = False
-
-        if clean:
-            storage.destroyDevice(p)
-
-    if immutable and not quiet:
-        remaining = "\t" + "\n\t".join(p.path for p in immutable) + "\n"
-        intf.messageWindow(_("Notice"),
-                           _("The following partitions were not deleted "
-                             "because they are in use:\n\n%s") % remaining,
-			   custom_icon="warning")
-
-    return True
-
-def checkForSwapNoMatch(anaconda):
-    """Check for any partitions of type 0x82 which don't have a swap fs."""
-    for device in anaconda.storage.partitions:
-        if not device.exists:
-            # this is only for existing partitions
-            continue
-
-        if device.getFlag(parted.PARTITION_SWAP) and \
-           not device.format.type == "swap":
-            rc = anaconda.intf.messageWindow(_("Format as Swap?"),
-                                    _("%s has a partition type of 0x82 "
-                                      "(Linux swap) but does not appear to "
-                                      "be formatted as a Linux swap "
-                                      "partition.\n\n"
-                                      "Would you like to format this "
-                                      "partition as a swap partition?")
-                                    % device.path, type = "yesno",
-                                    custom_icon="question")
-            if rc == 1:
-                format = getFormat("swap", device=device.path)
-                anaconda.storage.formatDevice(device, format)
-
-    return
-
-def mustHaveSelectedDrive(intf):
-    txt =_("You need to select at least one hard drive to install %s.") % (productName,)
-    intf.messageWindow(_("Error"), txt, custom_icon="error")
-     
-def queryNoFormatPreExisting(intf):
-    """Ensure the user wants to use a partition without formatting."""
-    txt = _("You have chosen to use a pre-existing "
-            "partition for this installation without formatting it. "
-            "We recommend that you format this partition "
-            "to make sure files from a previous operating system installation "
-            "do not cause problems with this installation of Linux. "
-            "However, if this partition contains files that you need "
-            "to keep, such as home directories, then "
-            "continue without formatting this partition.")
-    rc = intf.messageWindow(_("Format?"), txt, type = "custom", custom_buttons=[_("_Modify Partition"), _("Do _Not Format")], custom_icon="warning")
-    return rc
-
-def partitionSanityErrors(intf, errors):
-    """Errors were found sanity checking.  Tell the user they must fix."""
-    rc = 1
-    if errors:
-        errorstr = string.join(errors, "\n\n")
-        rc = intf.messageWindow(_("Error with Partitioning"),
-                                _("The following critical errors exist "
-                                  "with your requested partitioning "
-                                  "scheme. "
-                                  "These errors must be corrected prior "
-                                  "to continuing with your install of "
-                                  "%(productName)s.\n\n%(errorstr)s") \
-                                % {'productName': productName,
-                                   'errorstr': errorstr},
-                                custom_icon="error")
-    return rc
-
-def partitionSanityWarnings(intf, warnings):
-    """Sanity check found warnings.  Make sure the user wants to continue."""
-    rc = 1
-    if warnings:
-        warningstr = string.join(warnings, "\n\n")
-        rc = intf.messageWindow(_("Partitioning Warning"),
-                                     _("The following warnings exist with "
-                                       "your requested partition scheme.\n\n%s"
-                                       "\n\nWould you like to continue with "
-                                       "your requested partitioning "
-                                       "scheme?") % (warningstr),
-                                     type="yesno", custom_icon="warning")
-    return rc
-
-
-def partitionPreExistFormatWarnings(intf, warnings):
-    """Double check that preexistings being formatted are fine."""
-    rc = 1
-    if warnings:
-
-        labelstr1 = _("The following pre-existing partitions have been "
-                      "selected to be formatted, destroying all data.")
-
-        labelstr2 = _("Select 'Yes' to continue and format these "
-                      "partitions, or 'No' to go back and change these "
-                      "settings.")
-        commentstr = ""
-        for (dev, type, mntpt) in warnings:
-            commentstr = commentstr + "/dev/%s %s %s\n" % (dev,type,mntpt)
-        rc = intf.messageWindow(_("Format Warning"), "%s\n\n%s\n\n%s" %
-                                (labelstr1, labelstr2, commentstr),
-                                type="yesno", custom_icon="warning")
-    return rc
-
-def getPreExistFormatWarnings(storage):
-    """Return a list of preexisting devices being formatted."""
-    devices = []
-    for device in storage.devicetree.devices:
-        if device.exists and not device.format.exists and \
-           not device.format.hidden:
-            devices.append(device)
-
-    devices.sort(key=lambda d: d.name)
-    rc = []
-    for device in devices:
-        rc.append((device.path,
-                   device.format.name,
-                   getattr(device.format, "mountpoint", "")))
-    return rc
-            
-def confirmDelete(intf, device):
-    """Confirm the deletion of a device."""
-    if not device:
-	return
-    
-    if device.type == "lvmvg":
-	errmsg = (_("You are about to delete the volume group \"%s\"."
-                    "\n\nALL logical volumes in this volume group "
-                    "will be lost!") % device.name)
-    elif device.type == "lvmlv":
-	errmsg = (_("You are about to delete the logical volume \"%s\".")
-                  % device.name)
-    elif device.type == "mdarray":
-	errmsg = _("You are about to delete a RAID device.")
-    elif device.type == "partition":
-	errmsg = (_("You are about to delete the %s partition.")
-                  % device.path)
-    else:
-        # we may want something a little bit prettier than device.type
-        errmsg = (_("You are about to delete the %(type)s %(name)s") \
-                  % {'type': device.type, 'name': device.name})
-
-    rc = intf.messageWindow(_("Confirm Delete"), errmsg, type="custom",
-				custom_buttons=[_("Cancel"), _("_Delete")],
-			    custom_icon="question")
-
-    return rc
-
-def confirmResetPartitionState(intf):
-    """Confirm reset of partitioning to that present on the system."""
-    rc = intf.messageWindow(_("Confirm Reset"),
-                            _("Are you sure you want to reset the "
-                              "partition table to its original state?"),
-                            type="yesno", custom_icon="question")
-    return rc
-
diff --git a/pixmaps/Makefile.am b/pixmaps/Makefile.am
deleted file mode 100644
index 00320b0..0000000
--- a/pixmaps/Makefile.am
+++ /dev/null
@@ -1,23 +0,0 @@
-# pixmaps/Makefile.am for anaconda
-#
-# Copyright (C) 2009  Red Hat, Inc.
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU Lesser General Public License as published
-# by the Free Software Foundation; either version 2.1 of the License, or
-# (at your option) any later version.
-#
-# 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 Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public License
-# along with this program.  If not, see <http://www.gnu.org/licenses/>.
-#
-# Author: David Cantrell <dcantrell@xxxxxxxxxx>
-
-pixmapsdir        = $(datadir)/$(PACKAGE_NAME)/pixmaps
-dist_pixmaps_DATA = *.png
-
-MAINTAINERCLEANFILES = Makefile.in
diff --git a/pixmaps/about-to-install.png b/pixmaps/about-to-install.png
deleted file mode 100644
index 8343e3d188309ff4dd01f1869f8fb7b76aae83be..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001

literal 10818
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

diff --git a/pixmaps/checkMark.png b/pixmaps/checkMark.png
deleted file mode 100644
index 838f93700bad874ab55a880ae1c2cf4e563cd54d..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001

literal 347
zcmeAS@N?(olHy`uVBq!ia0vp^LLkh+1|-AI^@Rf|#^NA%Cx&(BWL^R}Y)RhkE)4%c
zaKYZ?lYt_f1s;*b3=G`DAk4@xYmNj^kiEpy*OmPyhbTXb$%AXP%Yj0-JzX3_EKZ-D
zVk^YxDByPg5tFb-i}LI#(md`DIAj`?3s|aIoD_vmd8l9JTX0IQaY<<I%0ur|O0InV
z{;F1%=TEe0uzb|>-pt!;GjID9?v;`1oWNPY_D$%p(bbf+x%(rZvp@a2MlFT4r(xld
z0xzc8rYlAp&)tuIyyVQ2b<BQkJtCWal$mcnC!N6lrD5ff3ED@P+!suc*md85_W;A9
z*R4&A*Q(6cCC#6jBy%<EUklUDBL-`kvZnsp={D!(E)B<(Lc9!}iTra+`T}P!GV{=`
mzkHo7_sS}L!xR4h7PDtdx_3-p(9i?)CWEJ|pUXO@geCwVwS-^*

diff --git a/pixmaps/config-language.png b/pixmaps/config-language.png
deleted file mode 100644
index 3fa4f1a9b269383ca7ac92be583dc79e37081cce..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001

literal 3079
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
VD`w?)wd()?002ovPDHLkV1g{>&;tMf

diff --git a/pixmaps/done.png b/pixmaps/done.png
deleted file mode 100644
index f5dc63496ce988951f8e24849a9a3eb6f70c35bc..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001

literal 25801
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

diff --git a/pixmaps/filter-menu.png b/pixmaps/filter-menu.png
deleted file mode 100644
index 037519f9dcd2e216430a8a6a64974cfef9f68aa0..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001

literal 456
zcmV;(0XP1MP)<h;3K|Lk000e1NJLTq000;O000;W1^@s6;CDUv00004b3#c}2nYxW
zd<bNS00009a7bBm000fw000fw0YWI7cmMzZ8FWQhbW?9;ba!ELWdL_~cP?peYja~^
zaAhuUa%Y?FJQ@H10YynfK~zYI?NmKW!%!4G_tD`MD!4hj8GKMkLWyMTl7hdY{s9-q
z(3Fgw-Q4^G?!_?>2^~bFV}F8zgBc9hsUb~YqK$1)@W6$0&%M0!xbK6Q8M}no>FWD1
zXqAQWczjsQN2Aee6TQ*^z{`@vag4!WkQW@sDQ=`{(^O2fBkCFkx`qJ&ShV|CwEJs%
z6)$7|X8-_?^LfsX-|w}06<-50uS5_8yoBd@Je*8<IGM8NdAVNf(eRb^{{B1oH~13T
zYnrC1ws}(>0I2+3hhg|eL@fY_qDU5NuIr`%kY!n}3n4&6DF86@hwu9bwFcWp<1<i7
zb?WjT87QSXQp#t`vd#g(w(S!s<x{WMJ1zG%9+7F9XF`ZOBD!Jb3nIEolH_)41^{5&
ywh7>YnJ;Iv*|oN*{5fqJN~xo|`tQ9(-^C~Aq4s7|cda@A0000<MNUMnLSTZTzQq;*

diff --git a/pixmaps/gnome-lock.png b/pixmaps/gnome-lock.png
deleted file mode 100644
index 7c2c69158b31e9c1b245ad4a6d26a6e2e42b9d93..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001

literal 810
zcmV+_1J(SAP)<h;3K|Lk000e1NJLTq000&M000&U1^@s6#I$TX00004b3#c}2nYxW
zd<bNS00009a7bBm000fw000fw0YWI7cmMzZ8FWQhbW?9;ba!ELWdL_~cP?peYja~^
zaAhuUa%Y?FJQ@H10;fqtK~y-6wUxVX6G0Hhzd8HtIF5<)5>dK{mWql7QW1I*0S!V(
z5fLq5h)jVfurPikiV`6Kp+ibThlmnH0}V7(`~f%;j>$uI67QWI-|kTO?(EpknF2;S
z-D+p&H#^_Hh?(&}%zu(2l}eoR2ZB#nsS7o$*5B;Y{rWy>+867n`ZyMgfA0uj=C&`h
zkeXduUNpA0@+_s~R+G}={MIjCT3$3V3#r*o3~H4kkxrbAMj~Ht&)f+EfMwO7l(J_5
zFc?G{bX^C5@N(saC><W2kKd2~@RXvjCzQE5bv?|?*v$Rpwe=4|2+`L(CKT!wlb0rY
z$H&jm^p$Jj)z!Bd0GB<%)uZaf(9kdpQ(%2#ty~u7^js{y(L5%Zd3y2Vr;YbFZ`_KE
z43D6CRGnz$XssQ7pFaoyN-3BXGeC;IwT^js@6l&N7!j#tJ;q;;@dOhQ06?)qw~ffQ
z_D+l^_*hUEva)wTr*W>vsqC{UANgJff&n*3N*RQPQZkh|F*&n>=JO#tpDIe0GqJmK
z@9IuFYdV`Onx@Ij%)%)1?%sCW{%y6wcAgIoOI)*RyuV-KbT(OZc<ziX%Zdhr0qhlb
zpcDgO?CkyqH`VFvdG`-SS(G6Rfr01{EX#_vN#O)2rP={aASX|w&0vtbkR8F!VmK%5
zWDo#u)I!Wq>;Yz0?u@-aZrlD7p>gaxf)&@{%$^|o(r9XvH(1$FR;mlgt)qUE5qV3Y
zlp}>Y24Y(h2h=E}(Wj(r2NO~FdHR{CR4U<t{y{sSseDIky8_1#Zom!GfTsBb5rvsq
z_=#u`Ks1-j&9A(9^+4D4W10Wv>Eik+MJ~5F58yNrl?Xr&fIa}B(a}-g*x1;quA~l@
o&*u*cg@OcN0w}k=Apgq#04yvgeQPwSNB{r;07*qoM6N<$f^>yyOaK4?

diff --git a/pixmaps/gnome-mouse.png b/pixmaps/gnome-mouse.png
deleted file mode 100644
index 0d90a36e826265342e13c9fa81ce6d0561539072..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001

literal 2744
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

diff --git a/pixmaps/install.png b/pixmaps/install.png
deleted file mode 100644
index 24612cc208d7bf42df506453cca79d17afbfa13e..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001

literal 4180
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

diff --git a/pixmaps/network.png b/pixmaps/network.png
deleted file mode 100644
index 8808d0eab2ad59fc5df04661862e67251cd0ccbc..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001

literal 2458
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
Y11C>u;LlnJv;Y7A07*qoM6N<$f_k=DIsgCw

diff --git a/pixmaps/partscheme-all.png b/pixmaps/partscheme-all.png
deleted file mode 100644
index 9c7398a66e7adc375bdb5105a8436dfdd2b32fb7..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001

literal 1594
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

diff --git a/pixmaps/partscheme-custom.png b/pixmaps/partscheme-custom.png
deleted file mode 100644
index ac4501fd84c963bed888e38d50e7f27dff7d92b2..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001

literal 805
zcmV+=1KRwFP)<h;3K|Lk000e1NJLTq001BW000*V1^@s6Y6VT<00004b3#c}2nYxW
zd<bNS00009a7bBm000fw000fw0YWI7cmMzZ8FWQhbW?9;ba!ELWdL_~cP?peYja~^
zaAhuUa%Y?FJQ@H10-{MoK~zYIy_UUe8!;HhAAKDJ4q_aaWC`&Q@L;g#e#C2_B^~ky
zv>x(TgqBQ&QVgC-CU<Gc9z1k#9ZzYyWXYPzkYEz7375%;oYcYS(B0{r8dJX@?s(DZ
z`Mr-`$tE8^eJBt@zA?sLK0G`SEFgpsN-5QgqUbHBlzv$$uDsfMv4v9U$&5>BX#KDG
zNkVHN_!H1yzkhBALD1ox^ViRwKF9w4``JsGBMuJUq1W$ib15ZTU0nqLEH5uFL_7>b
ztgWp<O3CR$6dhr<XfA-Ir6qWtHx~$>^#kAcvAesATCIjcp#T5~f&kra7pJGEGpsbR
zU?v9$AsCOx*xcMi7={=O1~@xAL#b3kv)RPP#s&zP?IcfifDi&g2q>lTJ0S$ERtr+f
zSgca1!1sNuudib?8bNCftu>TV@q0Q<$_ZdZ?O_9Gt>Jkd7-QJk*@5r-xWB*0#l;1L
z5D5T#xIi)hlu|IpG5~1^&-1Xiw}*1MjNx#IqoX58DPw@NxKavH6hSFvJjent#^T`u
zu>tD!I?ClTE-x?9>2wf9QEv4{m=J;}in0zEYdGhz@H7ZYDXy=taeRD?+uPfCzOgwi
zZVQ{farS^Mp67-EV2q(yEJ8{N&+`&Z_gK}rJ>U}0bEDB{pjxd$DTQ{sJ+*3gBzi!{
z4&=FDgHTFwetr%i1V*C~IOhp~JaN~N<o15pXWrg-7s%b+9s2z~06+*4S8fX%L9;EC
zQtK2rw!rT4^d;nip>%SQ8gX0H7EG^c=4AlVVJ5qt2F8S`Ebp7VNc2ED45j_FyWHgM
zo6hykqX1^ka5$Vg`F{i#La3{&D|&eN8MYHia92KA*(9I$qm#|w+}wb3uDMd`>yMM(
jn??O2Ho-a90KWePG6%Bq>?(fW00000NkvXXu0mjfz5rn0

diff --git a/pixmaps/partscheme-freespace.png b/pixmaps/partscheme-freespace.png
deleted file mode 100644
index 47726bdf8ac2a329166a4f3de8830c83a45781a3..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001

literal 1724
zcmV;t21EIYP)<h;3K|Lk000e1NJLTq001BW001cn1^@s6RCOyn00004b3#c}2nYxW
zd<bNS00009a7bBm000fw000fw0YWI7cmMzZ8FWQhbW?9;ba!ELWdL_~cP?peYja~^
zaAhuUa%Y?FJQ@H1202MYK~z|UwU=FN99I>`fA?cH>-Fy1YdeV*Du471RlHEbN1;M(
z1r%&5fm*4^DM<9eK?tO%5)T!TpAaO_Ahklx6ED;SVp=2NP!*>QiPFRlQjy9Fk?Ptm
zNl3!l>yKUU*UY^<cxN-SJG*w>_DCboUY~o;|D5wb_uLWITB2lTX6E}+%9F;J-bjT#
zh?H{081s|S(b3=fYa$B3%*@P>9LITnXn260-X4SyAKJOKmerM2mKNWqTCM(gbaeCu
z0Nn!VGlN6-kW6)wUA=?nc^?{pQi^n{i@~9LcyD3(8Q=u~*#hlgcP7JTe&Zu?4&Zqn
zoB0j8Ga0P4gZ_GC2CTJct#Lg!(wOVIEG@o|wT8i=L1HlnfNHhM!n=!Tr5L(*5Us=J
zUC%{pO|a~d0NRN)mZ?9yN-C8?X~mVd<{5kHNt9N+G5dFlTSXFy4h|gLPr56;qrJ!y
zw3C}R|4X5;#mF}w<?AC~1z>4u8Gur;L{D!IUwQPAT{+(qfZ|q>&dvlvZg)l^k)Tv8
z0r1cxUncv%75@10pD35h9}j@O{k^Q^*2r(>DV55stgO<zfBUG=j^^7>Jcc!v8`p2{
z%H9X&KzF8_`wxGb-@h~kz<u|9lK%dK0Q_b8EQLaWcs$ObPaOJq004aU^Pl1H=kBK~
z)s0fBzW#$Bj^ny6`NAfa=o5BV0E7^@u8UT!TTv@b|A9kn6}LidmF!Hh{GSC%l~Uv$
z*L6cDYa|DR5X)=19I0eF6k$;En+23oR4WxKm2&-2O0vGb(WI}GB9%<Dmdhc8SZ<pE
zW6X2QOV^(t8Xlmp_dw(<Sa^2<DHV<r!&(ynFDVtv3=R&3^!-_|ymTF7%yV`9y-vei
zZj~cPj<CMI7Aip|)5GNC%XD>hHSLL-hFEL&^qe?x;+E%mHkVtmtE<`iW392LPMs?3
z*3PcFV0?W1R63n}Iv!8N{Iyst7Hc)8UANkC{P^*r|GQEtyX)&4e?EQs^iz$xElbcS
z$BrGlG(0@~z|o`QLhJ3}<9ROm{ANh6volp6Le^T&otx$L*Z=nKuCA_6O-xKQwUqe9
z$)9x#Azo5SeZzI#wl|Np)eQy)1{fbdN~u(&TyAbP0IfBhohdF}yvSc)J4;V*cZkT2
z;}~Pitmk>(6DNQ5^H+O&dcXDHmmZ|AZ-3h?SZjIZm1*MfeT<DAVQZ^EwOR@3NGVCB
z(p<SR$JMJ>85{dft(9%f24q*VT$#H}Hk&=GwbqY4@P#k(?6b$)IuA-;UmyGS?c?#s
zpP*RWz6bculgSkG^YctjPLj=LxqSI@q>YJ*pECQ#?ALUqQc(vFZlC4m@Uci``Hx?R
z+NxTuGB-C*B9UNZWQ0N?k1>{HGRfO-|C2Lk&QPgTNT;Jm^7{HZ{r&w^Diyt_SpcxH
zvB9NFZ_&|_;NgcK!dlBa@BE9YsVO!$^E>YMx&MIxH1_bVTerAy;Q}2U9b_`yOixd9
z`}Xa+z7QhxM9Gc-tTh;8@H`J=OcRL3#YN7aKaZ4>g@uLsso3aTO4$I!wgynU>|l(=
z8Ur<FLBqzFnvUVxwQB&ON#{EaW^Y#+P*UK76hdIJ2qB2YVj&~`yA6O-N;T;O0R=M<
z$pIli3V{#YnC;dQQWB5HLym<IA!mL@f`FpV{<axVLZBqbS`7piYXt^y9H%X*8XXy9
znjW7=wH?g>q!dUgP%?01v9ttmH=WIqMmZKjG<|95U|OZ9f$$AWkfw%I>pGKtas>hS
zWr%Vfbi4xxM6C>d8-Q2a;5beQKvW5W0NO>}l!3b?*v^8IzESFgR7#<gLQ2^dKvdMx
z65>FO*$7092LQr?@V4Kz)*%2v5RGYX<vgkrv>z$>ZAiTYp0V{a!OuW26O8~o&kH$j
zB&C!x&;<bizKB{Dd=d%-exm)T8$ked=Rv1IhpjrN2|x`2b+5s9?lRaXV(^>6k1VJY
z{M$-G9KcdL_iO*Pmf#mwFgnlkLhTnERKW;$x^sp&kiYm#T21n~xw*E6_A1(O9CPEw
z4f*1WzabcI7<klrII`{a=4e~3-??)Kt+mz0nBSdybN0JC-H1PG(OO&Jwf_S=4CA(1
Sqx(|;0000<MNUMnLSTaEojtbz

diff --git a/pixmaps/partscheme-replace.png b/pixmaps/partscheme-replace.png
deleted file mode 100644
index 6490d7279e899f4c529558bea1231abcc32b6c8d..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001

literal 1783
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
Z^8fxBcL8dXm`VTu002ovPDHLkV1i3^W#|9^

diff --git a/pixmaps/partscheme-shrink.png b/pixmaps/partscheme-shrink.png
deleted file mode 100644
index d86d40fa3a01bf957d632e7f7c7688227afc5925..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001

literal 1875
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
N002ovPDHLkV1hegbOZnZ

diff --git a/pixmaps/root-password.png b/pixmaps/root-password.png
deleted file mode 100644
index 0125821ec86d6501fe9f5fa7215b4f634797a20d..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001

literal 4316
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
KMNUMnLSTZRf=40%

diff --git a/pixmaps/upgrade.png b/pixmaps/upgrade.png
deleted file mode 100644
index f0fb9f2c3edf9338f2c2dc41ebe5faa3dd6b6b60..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001

literal 4632
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
O0000<MNUMnLSTY>sJ#aO

diff --git a/platform.py b/platform.py
deleted file mode 100644
index e3d4480..0000000
--- a/platform.py
+++ /dev/null
@@ -1,574 +0,0 @@
-#
-# platform.py:  Architecture-specific information
-#
-# Copyright (C) 2009
-# Red Hat, Inc.  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 as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# 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, see <http://www.gnu.org/licenses/>.
-#
-# Authors: Chris Lumens <clumens@xxxxxxxxxx>
-#
-
-import iutil
-import parted
-import storage
-from storage.errors import *
-from storage.formats import *
-from storage.partspec import *
-
-import gettext
-_ = lambda x: gettext.ldgettext("anaconda", x)
-N_ = lambda x: x
-
-class Platform(object):
-    """Platform
-
-       A class containing platform-specific information and methods for use
-       during installation.  The intent is to eventually encapsulate all the
-       architecture quirks in one place to avoid lots of platform checks
-       throughout anaconda."""
-    _bootFSTypes = ["ext3"]
-    _diskLabelType = "msdos"
-    _isEfi = iutil.isEfi()
-    _minimumSector = 0
-    _packages = []
-    _supportsMdRaidBoot = False
-    _minBootPartSize = 50
-    _maxBootPartSize = 0
-
-    def __init__(self, anaconda):
-        """Creates a new Platform object.  This is basically an abstract class.
-           You should instead use one of the platform-specific classes as
-           returned by getPlatform below.  Not all subclasses need to provide
-           all the methods in this class."""
-        self.anaconda = anaconda
-
-    def _mntDict(self):
-        """Return a dictionary mapping mount points to devices."""
-        ret = {}
-        for device in [d for d in self.anaconda.storage.devices if d.format.mountable]:
-            ret[device.format.mountpoint] = device
-
-        return ret
-
-    def bootDevice(self):
-        """Return the device where /boot is mounted."""
-        if self.__class__ is Platform:
-            raise NotImplementedError("bootDevice not implemented for this platform")
-
-        mntDict = self._mntDict()
-        return mntDict.get("/boot", mntDict.get("/"))
-
-    @property
-    def defaultBootFSType(self):
-        """Return the default filesystem type for the boot partition."""
-        return self._bootFSTypes[0]
-
-    @property
-    def bootFSTypes(self):
-        """Return a list of all valid filesystem types for the boot partition."""
-        return self._bootFSTypes
-
-    def bootloaderChoices(self, bl):
-        """Return the default list of places to install the bootloader.
-           This is returned as a dictionary of locations to (device, identifier)
-           tuples.  If there is no boot device, an empty dictionary is
-           returned."""
-        if self.__class__ is Platform:
-            raise NotImplementedError("bootloaderChoices not implemented for this platform")
-
-        bootDev = self.bootDevice()
-        ret = {}
-
-        if not bootDev:
-            return ret
-
-        if bootDev.type == "mdarray":
-            ret["boot"] = (bootDev.name, N_("RAID Device"))
-            ret["mbr"] = (bl.drivelist[0], N_("Master Boot Record (MBR)"))
-        else:
-            ret["boot"] = (bootDev.name, N_("First sector of boot partition"))
-            ret["mbr"] = (bl.drivelist[0], N_("Master Boot Record (MBR)"))
-
-        return ret
-
-    def checkBootRequest(self, req):
-        """Perform an architecture-specific check on the boot device.  Not all
-           platforms may need to do any checks.  Returns a list of errors if
-           there is a problem, or [] otherwise."""
-        errors = []
-
-        if not req:
-            return [_("You have not created a bootable partition.")]
-
-        # most arches can't have boot on RAID
-        if req.type == "mdarray":
-            if not self.supportsMdRaidBoot:
-                errors.append(_("Bootable partitions cannot be on a RAID device."))
-            elif req.type == "mdarray" and req.level != 1:
-                errors.append(_("Bootable partitions can only be on RAID1 devices."))
-            else:
-                for p in req.parents:
-                    if p.type != "partition":
-                        errors.append(_("Bootable RAID1 set members must be partitions."))
-                        break
-
-        # can't have bootable partition on LV
-        if req.type == "lvmlv":
-            errors.append(_("Bootable partitions cannot be on a logical volume."))
-
-        # Make sure /boot is on a supported FS type.  This prevents crazy
-        # things like boot on vfat.
-        if not req.format.bootable or \
-           (getattr(req.format, "mountpoint", None) == "/boot" and
-            req.format.type not in self.bootFSTypes):
-            errors.append(_("Bootable partitions cannot be on an %s filesystem.") % req.format.type)
-
-        if req.type == "luks/dm-crypt":
-            # Handle encrypted boot on a partition.
-            errors.append(_("Bootable partitions cannot be on an encrypted block device"))
-        else:
-            # Handle encrypted boot on more complicated devices.
-            for dev in filter(lambda d: d.type == "luks/dm-crypt", self.anaconda.storage.devices):
-                if req in self.anaconda.storage.deviceDeps(dev):
-                    errors.append(_("Bootable partitions cannot be on an encrypted block device"))
-
-        return errors
-
-    def diskLabelType(self, deviceType):
-        """Return the disk label type as a string."""
-        return self._diskLabelType
-
-    @property
-    def isEfi(self):
-        return self._isEfi
-
-    @property
-    def minimumSector(self, disk):
-        """Return the minimum starting sector for the provided disk."""
-        return self._minimumSector
-
-    @property
-    def packages (self):
-        return self._packages
-
-    def setDefaultPartitioning(self):
-        """Return the default platform-specific partitioning information."""
-        return [PartSpec(mountpoint="/boot", fstype=self.defaultBootFSType, size=500,
-                         weight=self.weight(mountpoint="/boot"))]
-
-    @property
-    def supportsMdRaidBoot(self):
-        """Does the platform support /boot on MD RAID?"""
-        return self._supportsMdRaidBoot
-
-    @property
-    def minBootPartSize(self):
-        return self._minBootPartSize
-
-    @property
-    def maxBootPartSize(self):
-        return self._maxBootPartSize
-
-    def validBootPartSize(self, size):
-        """ Is the given size (in MB) acceptable for a boot device? """
-        if not isinstance(size, int) and not isinstance(size, float):
-            return False
-
-        return ((not self.minBootPartSize or size >= self.minBootPartSize)
-                and
-                (not self.maxBootPartSize or size <= self.maxBootPartSize))
-
-    def weight(self, fstype=None, mountpoint=None):
-        """ Given an fstype (as a string) or a mountpoint, return an integer
-            for the base sorting weight.  This is used to modify the sort
-            algorithm for partition requests, mainly to make sure bootable
-            partitions and /boot are placed where they need to be."""
-        return 0
-
-class EFI(Platform):
-    _bootFSTypes = ["ext4", "ext3", "ext2"]
-    _diskLabelType = "gpt"
-    _minBootPartSize = 50
-    _maxBootPartSize = 256
-
-    def bootDevice(self):
-        mntDict = self._mntDict()
-        return mntDict.get("/boot/efi")
-
-    def bootloaderChoices(self, bl):
-        bootDev = self.bootDevice()
-        ret = {}
-
-        if not bootDev:
-            return ret
-
-        ret["boot"] = (bootDev.name, N_("EFI System Partition"))
-        return ret
-
-    def checkBootRequest(self, req):
-        """ Perform architecture-specific checks on the boot device.
-
-            Returns a list of error strings.
-
-            NOTE: X86 does not have a separate checkBootRequest method,
-                  so this one must work for x86 as well as EFI.
-        """
-        if not req:
-            return [_("You have not created a /boot/efi partition.")]
-
-        errors = Platform.checkBootRequest(self, req)
-
-        if req.format.mountpoint == "/boot/efi":
-            if req.format.type != "efi":
-                errors.append(_("/boot/efi is not EFI."))
-
-        # Don't try to check the disklabel on lv's etc, using lv for /boot
-        # is already checked in the generic Platform.checkBootRequest()
-        partitions = []
-        if req.type == "partition":
-            partitions = [ req ]
-        elif req.type == "mdarray":
-            partitions = filter(lambda d: d.type == "partition", req.parents)
-
-        # Check that we've got a correct disk label.
-        for p in partitions:        
-            partedDisk = p.disk.format.partedDisk
-            labelType = self.diskLabelType(partedDisk.device.type)
-            # Allow using gpt with x86, but not msdos with EFI
-            if partedDisk.type != labelType and partedDisk.type != "gpt":
-                errors.append(_("%s must have a %s disk label.")
-                              % (p.disk.name, labelType.upper()))
-
-        return errors
-
-    def setDefaultPartitioning(self):
-        ret = Platform.setDefaultPartitioning(self)
-
-        # Only add the EFI partition to the default set if there's not already
-        # one on the system.
-        if len(filter(lambda dev: dev.format.type == "efi" and self.validBootPartSize(dev.size),
-                      self.anaconda.storage.partitions)) == 0:
-            ret.append(PartSpec(mountpoint="/boot/efi", fstype="efi", size=20,
-                                maxSize=200, grow=True, weight=self.weight(fstype="efi")))
-
-        return ret
-
-    def weight(self, fstype=None, mountpoint=None):
-        if fstype and fstype == "efi" or mountpoint and mountpoint == "/boot/efi":
-            return 5000
-        elif mountpoint and mountpoint == "/boot":
-            return 2000
-        else:
-            return 0
-
-class Alpha(Platform):
-    _diskLabelType = "bsd"
-
-    def checkBootRequest(self, req):
-        errors = Platform.checkBootRequest(self, req)
-
-        if not req or req.type != "partition" or not req.disk:
-            return errors
-
-        disk = req.disk.format.partedDisk
-
-        # Check that we're a BSD disk label
-        if not disk.type == self._diskLabelType:
-            errors.append(_("%s must have a bsd disk label.") % req.disk.name)
-
-        # The first free space should start at the beginning of the drive and
-        # span for a megabyte or more.
-        free = disk.getFirstPartition()
-        while free:
-            if free.type & parted.PARTITION_FREESPACE:
-                break
-
-            free = free.nextPartition()
-
-        if not free or free.geoemtry.start != 1L or free.getSize(unit="MB") < 1:
-            errors.append(_("The disk %s requires at least 1MB of free space at the beginning.") % req.disk.name)
-
-        return errors
-
-class IA64(EFI):
-    _packages = ["elilo"]
-
-    def __init__(self, anaconda):
-        EFI.__init__(self, anaconda)
-
-class PPC(Platform):
-    _bootFSTypes = ["ext4", "ext3", "ext2"]
-    _packages = ["yaboot"]
-    _ppcMachine = iutil.getPPCMachine()
-    _supportsMdRaidBoot = True
-
-    @property
-    def ppcMachine(self):
-        return self._ppcMachine
-
-class IPSeriesPPC(PPC):
-    _minBootPartSize = 4
-    _maxBootPartSize = 10
-
-    def bootDevice(self):
-        bootDev = None
-
-        # We want the first PReP partition.
-        for device in self.anaconda.storage.partitions:
-            if device.format.type == "prepboot":
-                bootDev = device
-                break
-
-        return bootDev
-
-    def bootloaderChoices(self, bl):
-        ret = {}
-
-        bootDev = self.bootDevice()
-        if not bootDev:
-            return ret
-
-        if bootDev.type == "mdarray":
-            ret["boot"] = (bootDev.name, N_("RAID Device"))
-            ret["mbr"] = (bl.drivelist[0], N_("Master Boot Record (MBR)"))
-        else:
-            ret["boot"] = (bootDev.name, N_("PPC PReP Boot"))
-
-        return ret
-
-    def checkBootRequest(self, req):
-        errors = PPC.checkBootRequest(self, req)
-
-        bootPart = getattr(req, "partedPartition", None)
-        if not bootPart:
-            return errors
-
-        # All of the above just checks the PPC PReP boot partitions.  We still
-        # need to make sure that whatever /boot is on also meets these criteria.
-        if req == self.bootDevice():
-            # However, this check only applies to prepboot.
-            if bootPart.geometry.end * bootPart.geometry.device.sectorSize / (1024.0 * 1024) > 4096:
-                errors.append(_("The boot partition must be within the first 4MB of the disk."))
-
-            try:
-                req = self.anaconda.storage.mountpoints["/boot"]
-            except KeyError:
-                req = self.anaconda.storage.rootDevice
-
-            return errors + self.checkBootRequest(req)
-        else:
-            return errors
-
-    def setDefaultPartitioning(self):
-        ret = PPC.setDefaultPartitioning(self)
-        ret.append(PartSpec(fstype="PPC PReP Boot", size=4,
-                            weight=self.weight(fstype="prepboot")))
-        return ret
-
-    def weight(self, fstype=None, mountpoint=None):
-        if fstype and fstype == "prepboot":
-            return 5000
-        elif mountpoint and mountpoint == "/boot":
-            return 2000
-        else:
-            return 0
-
-class NewWorldPPC(PPC):
-    _diskLabelType = "mac"
-    _minBootPartSize = (800.00 / 1024.00)
-    _maxBootPartSize = 1
-
-    def bootDevice(self):
-        bootDev = None
-
-        for part in self.anaconda.storage.partitions:
-            if part.format.type == "appleboot" and self.validBootPartSize(part.size):
-                bootDev = part
-                # if we're only picking one, it might as well be the first
-                break
-
-        return bootDev
-
-    def bootloaderChoices(self, bl):
-        ret = {}
-
-        bootDev = self.bootDevice()
-        if not bootDev:
-            return ret
-
-        if bootDev.type == "mdarray":
-            ret["boot"] = (bootDev.name, N_("RAID Device"))
-            ret["mbr"] = (bl.drivelist[0], N_("Master Boot Record (MBR)"))
-        else:
-            ret["boot"] = (bootDev.name, N_("Apple Bootstrap"))
-            for (n, device) in enumerate(self.anaconda.storage.partitions):
-                if device.format.type == "appleboot" and device.path != bootDev.path:
-                    ret["boot%d" % n] = (device.path, N_("Apple Bootstrap"))
-
-        return ret
-
-    def checkBootRequest(self, req):
-        errors = PPC.checkBootRequest(self, req)
-
-        if not req or req.type != "partition" or not req.disk:
-            return errors
-
-        disk = req.disk.format.partedDisk
-
-        # Check that we're a Mac disk label
-        if not disk.type == self._diskLabelType:
-            errors.append(_("%s must have a mac disk label.") % req.disk.name)
-
-        # All of the above just checks the appleboot partitions.  We still
-        # need to make sure that whatever /boot is on also meets these criteria.
-        if req == self.bootDevice():
-            try:
-                req = self.anaconda.storage.mountpoints["/boot"]
-            except KeyError:
-                req = self.anaconda.storage.rootDevice
-
-            return errors + self.checkBootRequest(req)
-        else:
-            return errors
-
-    def setDefaultPartitioning(self):
-        ret = Platform.setDefaultPartitioning(self)
-        ret.append(PartSpec(fstype="Apple Bootstrap", size=1, maxSize=1,
-                            weight=self.weight(fstype="appleboot")))
-        return ret
-
-    def weight(self, fstype=None, mountpoint=None):
-        if fstype and fstype == "appleboot":
-            return 5000
-        elif mountpoint and mountpoint == "/boot":
-            return 2000
-        else:
-            return 0
-
-class PS3(PPC):
-    _diskLabelType = "msdos"
-
-    def __init__(self, anaconda):
-        PPC.__init__(self, anaconda)
-
-class S390(Platform):
-    _packages = ["s390utils"]
-
-    def __init__(self, anaconda):
-        Platform.__init__(self, anaconda)
-
-    def diskLabelType(self, deviceType):
-        """Return the disk label type as a string."""
-        if deviceType == parted.DEVICE_DASD:
-            return "dasd"
-        else:
-            return Platform.diskLabelType(self, deviceType)
-
-class Sparc(Platform):
-    _diskLabelType = "sun"
-    _packages = ["silo"]
-
-    @property
-    def minimumSector(self, disk):
-        (cylinders, heads, sectors) = disk.device.biosGeometry
-        start = long(sectors * heads)
-        start /= long(1024 / disk.device.sectorSize)
-        return start+1
-
-class X86(EFI):
-    _bootFSTypes = ["ext4", "ext3", "ext2"]
-    _packages = ["grub"]
-    _supportsMdRaidBoot = True
-
-    def __init__(self, anaconda):
-        EFI.__init__(self, anaconda)
-
-        if self.isEfi:
-            self._diskLabelType = "gpt"
-        else:
-            self._diskLabelType = "msdos"
-
-    def bootDevice(self):
-        if self.isEfi:
-            return EFI.bootDevice(self)
-        else:
-            return Platform.bootDevice(self)
-
-    def bootloaderChoices(self, bl):
-        if self.isEfi:
-            return EFI.bootloaderChoices(self, bl)
-
-        bootDev = self.bootDevice()
-        ret = {}
-
-        if not bootDev:
-            return {}
-
-        if bootDev.type == "mdarray":
-            ret["boot"] = (bootDev.name, N_("RAID Device"))
-            ret["mbr"] = (bl.drivelist[0], N_("Master Boot Record (MBR)"))
-        else:
-            ret["boot"] = (bootDev.name, N_("First sector of boot partition"))
-            ret["mbr"] = (bl.drivelist[0], N_("Master Boot Record (MBR)"))
-
-        return ret
-
-    @property
-    def maxBootPartSize(self):
-        if self.isEfi:
-            return EFI._maxBootPartSize
-        else:
-            return Platform._maxBootPartSize
-
-    @property
-    def minBootPartSize(self):
-        if self.isEfi:
-            return EFI._minBootPartSize
-        else:
-            return Platform._minBootPartSize
-
-    def setDefaultPartitioning(self):
-        if self.isEfi:
-            return EFI.setDefaultPartitioning(self)
-        else:
-            return Platform.setDefaultPartitioning(self)
-
-def getPlatform(anaconda):
-    """Check the architecture of the system and return an instance of a
-       Platform subclass to match.  If the architecture could not be determined,
-       raise an exception."""
-    if iutil.isAlpha():
-        return Alpha(anaconda)
-    elif iutil.isIA64():
-        return IA64(anaconda)
-    elif iutil.isPPC():
-        ppcMachine = iutil.getPPCMachine()
-
-        if (ppcMachine == "PMac" and iutil.getPPCMacGen() == "NewWorld"):
-            return NewWorldPPC(anaconda)
-        elif ppcMachine in ["iSeries", "pSeries"]:
-            return IPSeriesPPC(anaconda)
-        elif ppcMachine == "PS3":
-            return PS3(anaconda)
-        else:
-            raise SystemError, "Unsupported PPC machine type"
-    elif iutil.isS390():
-        return S390(anaconda)
-    elif iutil.isSparc():
-        return Sparc(anaconda)
-    elif iutil.isX86():
-        return X86(anaconda)
-    else:
-        raise SystemError, "Could not determine system architecture."
diff --git a/product.py b/product.py
deleted file mode 100644
index 68df00c..0000000
--- a/product.py
+++ /dev/null
@@ -1,63 +0,0 @@
-#
-# product.py: product identification string
-#
-# Copyright (C) 2003  Red Hat, Inc.  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 as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# 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, see <http://www.gnu.org/licenses/>.
-#
-
-import os
-
-if os.access("/tmp/product/.buildstamp", os.R_OK):
-    path = "/tmp/product/.buildstamp"
-elif os.access("/.buildstamp", os.R_OK):
-    path = "/.buildstamp"
-elif os.environ.has_key("PRODBUILDPATH") and \
-         os.access(os.environ["PRODBUILDPATH"], os.R_OK):
-    path = os.environ["PRODBUILDPATH"]
-else:
-    path = None
-
-productStamp = ""
-productName = "anaconda"
-productVersion = "bluesky"
-productPath = "Packages"
-productArch = None
-bugUrl = "your distribution provided bug reporting tool."
-
-if path is not None:
-    f = open(path, "r")
-    lines = f.readlines()
-    del f
-    if len(lines) >= 3:
-        productStamp = lines[0][:-1]
-        productArch = productStamp[productStamp.index(".")+1:]
-        productName = lines[1][:-1]
-        productVersion = lines[2][:-1]
-    if len(lines) >= 4:
-        bugUrl = lines[3][:-1]
-
-if os.environ.has_key("ANACONDA_PRODUCTNAME"):
-    productName = os.environ["ANACONDA_PRODUCTNAME"]
-if os.environ.has_key("ANACONDA_PRODUCTVERSION"):
-    productVersion = os.environ["ANACONDA_PRODUCTVERSION"]
-if os.environ.has_key("ANACONDA_PRODUCTPATH"):
-    productPath = os.environ["ANACONDA_PRODUCTPATH"]
-if os.environ.has_key("ANACONDA_PRODUCTARCH"):
-    productArch = os.environ["ANACONDA_PRODUCTARCH"]
-if os.environ.has_key("ANACONDA_BUGURL"):
-    bugUrl = os.environ["ANACONDA_BUGURL"]
-
-if productVersion == "development": # hack to transform for now
-    productVersion = "rawhide"
diff --git a/pyanaconda/Makefile.am b/pyanaconda/Makefile.am
new file mode 100644
index 0000000..f156057
--- /dev/null
+++ b/pyanaconda/Makefile.am
@@ -0,0 +1,34 @@
+# liveinst/Makefile.am for anaconda
+#
+# Copyright (C) 2009  Red Hat, Inc.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License as published
+# by the Free Software Foundation; either version 2.1 of the License, or
+# (at your option) any later version.
+#
+# 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 Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+#
+# Author: Martin Sivak <msivak@xxxxxxxxxx>
+
+SUBDIRS = installclasses iw iw textw storage 
+
+MAINTAINERCLEANFILES = Makefile.in
+
+# anaconda Python code
+pkgpyexecdir    = $(pyexecdir)/py$(PACKAGE_NAME)
+anacondadir     = $(pkgpyexecdir)
+anaconda_PYTHON = *.py
+pkgpyexec_LTLIBRARIES = xutils.la
+
+xutils_la_CFLAGS      = $(PYTHON_INCLUDES) $(GDK_CFLAGS) -fno-strict-aliasing
+xutils_la_LDFLAGS     = -module -avoid-version $(PYTHON_LDFLAGS) $(GDK_LDFLAGS)
+xutils_la_LIBADD      = $(PYTHON_LIBS) $(GDK_LIBS)
+xutils_la_SOURCES     = xutils.c
+
diff --git a/pyanaconda/__init__.py b/pyanaconda/__init__.py
new file mode 100644
index 0000000..b53877c
--- /dev/null
+++ b/pyanaconda/__init__.py
@@ -0,0 +1,395 @@
+#!/usr/bin/python
+#
+# anaconda: The Red Hat Linux Installation program
+#
+# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007
+# Red Hat, Inc.  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 as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# 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, see <http://www.gnu.org/licenses/>.
+#
+# Author(s): Brent Fox <bfox@xxxxxxxxxx>
+#            Mike Fulbright <msf@xxxxxxxxxx>
+#            Jakub Jelinek <jakub@xxxxxxxxxx>
+#            Jeremy Katz <katzj@xxxxxxxxxx>
+#            Chris Lumens <clumens@xxxxxxxxxx>
+#            Paul Nasrat <pnasrat@xxxxxxxxxx>
+#            Erik Troan <ewt@xxxxxxxxx>
+#            Matt Wilson <msw@xxxxxxxxx>
+#
+
+import os, time, string
+import iutil
+import isys
+from tempfile import mkstemp
+
+import logging
+log = logging.getLogger("anaconda")
+stdoutLog = logging.getLogger("anaconda.stdout")
+
+import gettext
+_ = lambda x: gettext.ldgettext("anaconda", x)
+
+class Anaconda(object):
+    def __init__(self):
+        import desktop, dispatch, firewall, security
+        import system_config_keyboard.keyboard as keyboard
+        from flags import flags
+
+        self._backend = None
+        self._bootloader = None
+        self.canReIPL = False
+        self.desktop = desktop.Desktop()
+        self.dir = None
+        self.dispatch = dispatch.Dispatcher(self)
+        self.displayMode = None
+        self.extraModules = []
+        self.firewall = firewall.Firewall()
+        self.id = None
+        self._instClass = None
+        self._instLanguage = None
+        self._intf = None
+        self.isHeadless = False
+        self.keyboard = keyboard.Keyboard()
+        self.ksdata = None
+        self.mediaDevice = None
+        self.methodstr = None
+        self._network = None
+        self._platform = None
+        self.proxy = None
+        self.proxyUsername = None
+        self.proxyPassword = None
+        self.reIPLMessage = None
+        self.rescue = False
+        self.rescue_mount = True
+        self.rootParts = None
+        self.rootPath = "/mnt/sysimage"
+        self.security = security.Security()
+        self.simpleFilter = not iutil.isS390()
+        self.stage2 = None
+        self._storage = None
+        self._timezone = None
+        self.updateSrc = None
+        self.upgrade = flags.cmdline.has_key("preupgrade")
+        self.upgradeRoot = None
+        self.upgradeSwapInfo = None
+        self._users = None
+        self.mehConfig = None
+
+        # *sigh* we still need to be able to write this out
+        self.xdriver = None
+
+    @property
+    def backend(self):
+        if not self._backend:
+            b = self.instClass.getBackend()
+            self._backend = apply(b, (self, ))
+
+        return self._backend
+
+    @property
+    def bootloader(self):
+        if not self._bootloader:
+            import booty
+            self._bootloader = booty.getBootloader(self)
+
+        return self._bootloader
+
+    @property
+    def firstboot(self):
+        from pykickstart.constants import FIRSTBOOT_SKIP, FIRSTBOOT_DEFAULT
+
+        if self.ksdata:
+            return self.ksdata.firstboot.firstboot
+        elif iutil.isS390():
+            return FIRSTBOOT_SKIP
+        else:
+            return FIRSTBOOT_DEFAULT
+
+    @property
+    def instClass(self):
+        if not self._instClass:
+            from installclass import DefaultInstall
+            self._instClass = DefaultInstall()
+
+        return self._instClass
+
+    @property
+    def instLanguage(self):
+        if not self._instLanguage:
+            import language
+            self._instLanguage = language.Language(self.displayMode)
+
+        return self._instLanguage
+
+    def _getInterface(self):
+        return self._intf
+
+    def _setInterface(self, v):
+        # "lambda cannot contain assignment"
+        self._intf = v
+
+    def _delInterface(self):
+        del self._intf
+
+    intf = property(_getInterface, _setInterface, _delInterface)
+
+    @property
+    def network(self):
+        if not self._network:
+            import network
+            self._network = network.Network()
+
+        return self._network
+
+    @property
+    def platform(self):
+        if not self._platform:
+            import platform
+            self._platform = platform.getPlatform(self)
+
+        return self._platform
+
+    @property
+    def protected(self):
+        import stat
+
+        if os.path.exists("/dev/live") and \
+           stat.S_ISBLK(os.stat("/dev/live")[stat.ST_MODE]):
+            return [os.readlink("/dev/live")]
+        elif self.methodstr and self.methodstr.startswith("hd:"):
+            method = self.methodstr[3:]
+            return [method.split(":", 3)[0]]
+        else:
+            return []
+
+    @property
+    def users(self):
+        if not self._users:
+            import users
+            self._users = users.Users(self)
+
+        return self._users
+
+    @property
+    def storage(self):
+        if not self._storage:
+            import storage
+            self._storage = storage.Storage(self)
+
+        return self._storage
+
+    @property
+    def timezone(self):
+        if not self._timezone:
+            import timezone
+            self._timezone = timezone.Timezone()
+            self._timezone.setTimezoneInfo(self.instLanguage.getDefaultTimeZone(self.rootPath))
+
+        return self._timezone
+
+    def dumpState(self):
+        from meh.dump import ReverseExceptionDump
+        from inspect import stack as _stack
+
+        # Skip the frames for dumpState and the signal handler.
+        stack = _stack()[2:]
+        stack.reverse()
+        exn = ReverseExceptionDump((None, None, stack), self.mehConfig)
+
+        (fd, filename) = mkstemp("", "anaconda-tb-", "/tmp")
+        fo = os.fdopen(fd, "w")
+
+        exn.write(self, fo)
+
+    def initInterface(self):
+        if self._intf:
+            raise RuntimeError, "Second attempt to initialize the InstallInterface"
+
+        # setup links required by graphical mode if installing and verify display mode
+        if self.displayMode == 'g':
+            stdoutLog.info (_("Starting graphical installation."))
+
+            try:
+                from gui import InstallInterface
+            except Exception, e:
+                from flags import flags
+                stdoutLog.error("Exception starting GUI installer: %s" %(e,))
+                # if we're not going to really go into GUI mode, we need to get
+                # back to vc1 where the text install is going to pop up.
+                if not flags.livecdInstall:
+                    isys.vtActivate (1)
+                stdoutLog.warning("GUI installer startup failed, falling back to text mode.")
+                self.displayMode = 't'
+                if 'DISPLAY' in os.environ.keys():
+                    del os.environ['DISPLAY']
+                time.sleep(2)
+
+        if self.displayMode == 't':
+            from text import InstallInterface
+            if not os.environ.has_key("LANG"):
+                os.environ["LANG"] = "en_US.UTF-8"
+
+        if self.displayMode == 'c':
+            from cmdline import InstallInterface
+
+        self._intf = InstallInterface()
+        return self._intf
+
+    def writeXdriver(self, root = None):
+        # this should go away at some point, but until it does, we
+        # need to keep it around.
+        if self.xdriver is None:
+            return
+        if root is None:
+            root = self.rootPath
+        if not os.path.isdir("%s/etc/X11" %(root,)):
+            os.makedirs("%s/etc/X11" %(root,), mode=0755)
+        f = open("%s/etc/X11/xorg.conf" %(root,), 'w')
+        f.write('Section "Device"\n\tIdentifier "Videocard0"\n\tDriver "%s"\nEndSection\n' % self.xdriver)
+        f.close()
+
+    def setMethodstr(self, methodstr):
+        if methodstr.startswith("cdrom://"):
+            (device, tree) = string.split(methodstr[8:], ":", 1)
+
+            if not tree.startswith("/"):
+                tree = "/%s" %(tree,)
+
+            if device.startswith("/dev/"):
+                device = device[5:]
+
+            self.mediaDevice = device
+            self.methodstr = "cdrom://%s" % tree
+        else:
+            self.methodstr = methodstr
+
+    def requiresNetworkInstall(self):
+        fail = False
+        numNetDevs = isys.getNetworkDeviceCount()
+
+        if self.methodstr is not None:
+            if (self.methodstr.startswith("http") or \
+                self.methodstr.startswith("ftp://";) or \
+                self.methodstr.startswith("nfs:")) and \
+               numNetDevs == 0:
+                fail = True
+        elif self.stage2 is not None:
+            if self.stage2.startswith("cdrom://") and \
+               not os.path.isdir("/mnt/stage2/Packages") and \
+               numNetDevs == 0:
+                fail = True
+
+        if fail:
+            log.error("network install required, but no network devices available")
+
+        return fail
+
+    def write(self):
+        self.writeXdriver()
+        self.instLanguage.write(self.rootPath)
+
+        self.timezone.write(self.rootPath)
+        self.network.write(instPath=self.rootPath, anaconda=self)
+        self.desktop.write(self.rootPath)
+        self.users.write(self.rootPath)
+        self.security.write(self.rootPath)
+        self.firewall.write(self.rootPath)
+
+        if self.ksdata:
+            for svc in self.ksdata.services.disabled:
+                iutil.execWithRedirect("/sbin/chkconfig",
+                                       [svc, "off"],
+                                       stdout="/dev/tty5", stderr="/dev/tty5",
+                                       root=self.rootPath)
+
+            for svc in self.ksdata.services.enabled:
+                iutil.execWithRedirect("/sbin/chkconfig",
+                                       [svc, "on"],
+                                       stdout="/dev/tty5", stderr="/dev/tty5",
+                                       root=self.rootPath)
+
+    def writeKS(self, filename):
+        import urllib
+        from pykickstart.version import versionToString, DEVEL
+
+        f = open(filename, "w")
+
+        f.write("# Kickstart file automatically generated by anaconda.\n\n")
+        f.write("#version=%s\n" % versionToString(DEVEL))
+
+        if self.upgrade:
+            f.write("upgrade\n")
+        else:
+            f.write("install\n")
+
+        m = None
+
+        if self.methodstr:
+            m = self.methodstr
+        elif self.stage2:
+            m = self.stage2
+
+        if m:
+            if m.startswith("cdrom:"):
+                f.write("cdrom\n")
+            elif m.startswith("hd:"):
+                if m.count(":") == 3:
+                    (part, fs, dir) = string.split(m[3:], ":")
+                else:
+                    (part, dir) = string.split(m[3:], ":")
+
+                f.write("harddrive --partition=%s --dir=%s\n" % (part, dir))
+            elif m.startswith("nfs:"):
+                if m.count(":") == 3:
+                    (server, opts, dir) = string.split(m[4:], ":")
+                    f.write("nfs --server=%s --opts=%s --dir=%s" % (server, opts, dir))
+                else:
+                    (server, dir) = string.split(m[4:], ":")
+                    f.write("nfs --server=%s --dir=%s\n" % (server, dir))
+            elif m.startswith("ftp://";) or m.startswith("http"):
+                f.write("url --url=%s\n" % urllib.unquote(m))
+
+        # Some kickstart commands do not correspond to any anaconda UI
+        # component.  If this is a kickstart install, we need to make sure
+        # the information from the input file ends up in the output file.
+        if self.ksdata:
+            f.write(self.ksdata.user.__str__())
+            f.write(self.ksdata.services.__str__())
+            f.write(self.ksdata.reboot.__str__())
+
+        self.instLanguage.writeKS(f)
+
+        if not self.isHeadless:
+            self.keyboard.writeKS(f)
+            self.network.writeKS(f)
+
+        self.timezone.writeKS(f)
+        self.users.writeKS(f)
+        self.security.writeKS(f)
+        self.firewall.writeKS(f)
+
+        self.storage.writeKS(f)
+        self.bootloader.writeKS(f)
+
+        if self.backend:
+            self.backend.writeKS(f)
+            self.backend.writePackagesKS(f, self)
+
+        # Also write out any scripts from the input ksfile.
+        if self.ksdata:
+            for s in self.ksdata.scripts:
+                f.write(s.__str__())
+
+        # make it so only root can read, could have password
+        os.chmod(filename, 0600)
diff --git a/pyanaconda/anaconda_log.py b/pyanaconda/anaconda_log.py
new file mode 100644
index 0000000..961cba1
--- /dev/null
+++ b/pyanaconda/anaconda_log.py
@@ -0,0 +1,170 @@
+#
+# anaconda_log.py: Support for logging to multiple destinations with log
+# levels.
+#
+# Copyright (C) 2000, 2001, 2002, 2005  Red Hat, Inc.  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 as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# 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, see <http://www.gnu.org/licenses/>.
+#
+# Author(s): Chris Lumens <clumens@xxxxxxxxxx>
+#            Matt Wilson <msw@xxxxxxxxxx>
+#            Michael Fulbright <msf@xxxxxxxxxx>
+#
+
+import os
+import signal
+import sys
+import logging
+from logging.handlers import SysLogHandler, SYSLOG_UDP_PORT
+import types
+
+import iutil
+
+DEFAULT_TTY_LEVEL = logging.INFO
+ENTRY_FORMAT = "%(asctime)s,%(msecs)03d %(levelname)s %(name)s: %(message)s"
+TTY_FORMAT = "%(levelname)s %(name)s: %(message)s"
+STDOUT_FORMAT = "%(asctime)s %(message)s"
+DATE_FORMAT = "%H:%M:%S"
+
+MAIN_LOG_FILE = "/tmp/anaconda.log"
+MAIN_LOG_TTY = "/dev/tty3"
+PROGRAM_LOG_FILE = "/tmp/program.log"
+ANACONDA_SYSLOG_FACILITY = SysLogHandler.LOG_LOCAL1
+
+logLevelMap = {"debug": logging.DEBUG, "info": logging.INFO,
+               "warning": logging.WARNING, "error": logging.ERROR,
+               "critical": logging.CRITICAL}
+
+# sets autoSetLevel for the given handler
+def autoSetLevel(handler, value):
+    handler.autoSetLevel = value
+
+# all handlers of given logger with autoSetLevel == True are set to level
+def setHandlersLevel(logger, level):
+    map(lambda hdlr: hdlr.setLevel(level),
+        filter (lambda hdlr: hasattr(hdlr, "autoSetLevel") and hdlr.autoSetLevel, logger.handlers))
+
+class AnacondaSyslogHandler(SysLogHandler):
+    def __init__(self, 
+                 address=('localhost', SYSLOG_UDP_PORT),
+                 facility=SysLogHandler.LOG_USER, 
+                 tag=''):
+        self.tag = tag
+        SysLogHandler.__init__(self, address, facility)
+
+    def emit(self, record):
+        original_msg = record.msg
+        record.msg = '%s: %s' %(self.tag, original_msg)
+        SysLogHandler.emit(self, record)
+        record.msg = original_msg
+
+class AnacondaLog:
+    def __init__ (self):
+        self.tty_loglevel = DEFAULT_TTY_LEVEL
+        self.remote_syslog = None
+        # Create the base of the logger hierarcy.
+        logger = logging.getLogger("anaconda")
+        logger.setLevel(logging.DEBUG)
+        self.addFileHandler(MAIN_LOG_FILE, logger,
+                            minLevel=logging.DEBUG)
+        self.forwardToSyslog(logger)
+        # Log to tty3.
+        if not iutil.isS390() and os.access(MAIN_LOG_TTY, os.W_OK):
+            self.addFileHandler(MAIN_LOG_TTY, logger,
+                                fmtStr=TTY_FORMAT,
+                                autoLevel=True)
+
+        # External program output log
+        program_logger = logging.getLogger("program")
+        program_logger.setLevel(logging.DEBUG)
+        self.addFileHandler(PROGRAM_LOG_FILE, program_logger,
+                            minLevel=logging.DEBUG)
+        self.forwardToSyslog(program_logger)
+
+        # Create a second logger for just the stuff we want to dup on
+        # stdout.  Anything written here will also get passed up to the
+        # parent loggers for processing and possibly be written to the
+        # log.
+        stdoutLogger = logging.getLogger("anaconda.stdout")
+        stdoutLogger.setLevel(logging.INFO)
+        # Add a handler for the duped stuff.  No fancy formatting, thanks.
+        self.addFileHandler(sys.stdout, stdoutLogger,
+                            fmtStr=STDOUT_FORMAT, minLevel=logging.INFO)
+
+        # Stderr logger
+        stderrLogger = logging.getLogger("anaconda.stderr")
+        stderrLogger.setLevel(logging.INFO)
+        self.addFileHandler(sys.stderr, stderrLogger,
+                            fmtStr=STDOUT_FORMAT, minLevel=logging.INFO)
+
+    # Add a simple handler - file or stream, depending on what we're given.
+    def addFileHandler (self, file, addToLogger, minLevel=DEFAULT_TTY_LEVEL,
+                        fmtStr=ENTRY_FORMAT,
+                        autoLevel=False):
+        if isinstance(file, types.StringTypes):
+            logfileHandler = logging.FileHandler(file)
+        else:
+            logfileHandler = logging.StreamHandler(file)
+
+        logfileHandler.setLevel(minLevel)
+        logfileHandler.setFormatter(logging.Formatter(fmtStr, DATE_FORMAT))
+        autoSetLevel(logfileHandler, autoLevel)
+        addToLogger.addHandler(logfileHandler)
+
+    # Add another logger to the hierarchy.  For best results, make sure
+    # name falls under anaconda in the tree.
+    def addLogger (self, name, minLevel=DEFAULT_TTY_LEVEL):
+        newLogger = logging.getLogger(name)
+        newLogger.setLevel(minLevel)
+
+    # Add a handler for remote syslogs.
+    def addSysLogHandler (self, logger, host, port=SYSLOG_UDP_PORT,
+                          minLevel=DEFAULT_TTY_LEVEL):
+        fmt = logging.Formatter("%(levelname)-8s %(message)s")
+        syslogHandler = SysLogHandler((host, port))
+        syslogHandler.setLevel(minLevel)
+        syslogHandler.setFormatter(fmt)
+        logger.addHandler(syslogHandler)
+
+    def forwardToSyslog(self, logger):
+        """Forward everything that goes in the logger to the syslog daemon.
+        """
+        syslogHandler = AnacondaSyslogHandler(
+            '/dev/log', 
+            ANACONDA_SYSLOG_FACILITY,
+            logger.name)
+        syslogHandler.setLevel(logging.DEBUG)
+        logger.addHandler(syslogHandler)
+
+    def updateRemote(self, remote_syslog):
+        """Updates the location of remote rsyslogd to forward to.
+
+        Requires updating rsyslogd config and sending SIGHUP to the daemon.
+        """
+        PIDFILE  = "/var/run/syslogd.pid"
+        CFGFILE  = "/etc/rsyslog.conf"
+        TEMPLATE = "*.* @@%s\n"
+
+        self.remote_syslog = remote_syslog
+        with open(CFGFILE, 'a') as cfgfile:
+            forward_line = TEMPLATE % remote_syslog
+            cfgfile.write(forward_line)
+        with open(PIDFILE, 'r') as pidfile:
+            pid = int(pidfile.read())
+            os.kill(pid, signal.SIGHUP)
+
+logger = None
+def init():
+    global logger
+    logger = AnacondaLog()
diff --git a/pyanaconda/backend.py b/pyanaconda/backend.py
new file mode 100644
index 0000000..217fa55
--- /dev/null
+++ b/pyanaconda/backend.py
@@ -0,0 +1,301 @@
+#
+# backend.py: Interface for installation backends
+#
+# Copyright (C) 2005, 2006, 2007  Red Hat, Inc.  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 as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# 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, see <http://www.gnu.org/licenses/>.
+#
+# Author(s): Paul Nasrat <pnasrat@xxxxxxxxxx>
+#            Jeremy Katz <katzj@xxxxxxxxxx>
+#
+
+import glob
+import shutil
+import iutil
+import os, sys
+import logging
+import backend_log
+from constants import *
+
+import isys
+import kickstart
+import packages
+import storage
+
+from flags import flags
+log = logging.getLogger("anaconda")
+
+import gettext
+_ = lambda x: gettext.ldgettext("anaconda", x)
+
+class AnacondaBackend:
+    def __init__(self, anaconda):
+        """Abstract backend class all backends should inherit from this
+           @param instPath: root path for the installation to occur"""
+        self.anaconda = anaconda
+        self.instPath = anaconda.rootPath
+        self.instLog = None
+        self.modeText = ""
+
+        # some backends may not support upgrading
+        self.supportsUpgrades = True
+        self.supportsPackageSelection = False
+
+        # some backends may have a special case for rootfs formatting
+        # FIXME: we should handle this a little more elegantly
+        self.skipFormatRoot = False
+        self.rootFsType = None
+
+        self._loopbackFile = None
+
+    def postAction(self, anaconda):
+        pass
+
+    def doPreSelection(self, intf, id, instPath):
+        pass
+
+    def doPostSelection(self, anaconda):
+        pass
+
+    def doPreInstall(self, anaconda):
+        self.initLog(anaconda.rootPath)
+
+    def copyFirmware(self, anaconda):
+        # Multiple driver disks may be loaded, so we need to glob for all
+        # the firmware files in the common DD firmware directory
+        for f in glob.glob(DD_EXTRACTED+"/lib/firmware/*"):
+            try:
+                shutil.copyfile(f, "%s/lib/firmware/" % anaconda.rootPath)
+            except IOError, e:
+                log.error("Could not copy firmware file %s: %s" % (f, e.strerror))
+
+    def doPostInstall(self, anaconda):
+        #always copy the firmware files from DD
+        self.copyFirmware(anaconda)
+
+        if anaconda.extraModules:
+            for (n, arch, tag) in self.kernelVersionList(anaconda.rootPath):
+                packages.recreateInitrd(n, anaconda.rootPath)
+
+        #copy RPMS
+        for d in glob.glob(DD_RPMS):
+            shutil.copytree(d, anaconda.rootPath + "/root/" + os.path.basename(d))
+
+        #copy modules and firmware
+        if os.path.exists(DD_EXTRACTED):
+            try:
+                shutil.copytree(DD_EXTRACTED, anaconda.rootPath + "/root/DD")
+            except IOError, e:
+                pass
+
+        storage.writeEscrowPackets(anaconda)
+        sys.stdout.flush()
+        backend_log.log.stop()
+
+    def doInstall(self, anaconda):
+        log.warning("doInstall not implemented for backend!")
+        raise NotImplementedError
+
+    def initLog(self, instPath):
+        if not os.path.isdir(instPath + "/root"):
+            iutil.mkdirChain(instPath + "/root")
+
+        if self.anaconda.upgrade:
+            logname = '/root/upgrade.log'
+        else:
+            logname = '/root/install.log'
+
+        instLogName = instPath + logname
+        try:
+            shutil.rmtree (instLogName)
+        except OSError:
+            pass
+
+        self.instLog = open(instLogName, "w+")
+
+        syslogname = "%s%s.syslog" % (instPath, logname)
+        try:
+            shutil.rmtree (syslogname)
+        except OSError:
+            pass
+        backend_log.log.start(instPath, syslogname)
+
+        if self.anaconda.upgrade:
+            self.modeText = _("Upgrading %s\n")
+        else:
+            self.modeText = _("Installing %s\n")
+
+    def mountInstallImage(self, anaconda, installimg):
+        if self._loopbackFile and os.path.exists(self._loopbackFile):
+            return
+
+        # Copy the install.img to the filesystem and switch loopback devices
+        # to there.  Otherwise we won't be able to unmount and swap media.
+        free = anaconda.storage.fsFreeSpace
+        self._loopbackFile = "%s%s/rhinstall-install.img" % (anaconda.rootPath,
+                                                             free[-1][0])
+        try:
+            log.info("transferring install image to install target")
+            win = anaconda.intf.waitWindow(_("Copying File"),
+                    _("Transferring install image to hard drive"))
+            shutil.copyfile(installimg, self._loopbackFile)
+            win.pop()
+        except Exception, e:
+            if win:
+                win.pop()
+
+            log.critical("error transferring install.img: %s" %(e,))
+
+            if isinstance(e, IOError) and e.errno == 5:
+                msg = _("An error occurred transferring the install image "
+                        "to your hard drive.  This is often cause by "
+                        "damaged or low quality media.")
+            else:
+                msg = _("An error occurred transferring the install image "
+                        "to your hard drive. You are probably out of disk "
+                        "space.")
+
+            anaconda.intf.messageWindow(_("Error"), msg)
+            try:
+                os.unlink(self._loopbackFile)
+            except:
+                pass
+
+            return 1
+
+        isys.lochangefd("/dev/loop0", self._loopbackFile)
+        if os.path.ismount("/mnt/stage2"):
+            isys.umount("/mnt/stage2")
+
+    def removeInstallImage(self):
+        if self._loopbackFile:
+            try:
+                os.unlink(self._loopbackFile)
+            except SystemError:
+                pass
+   
+    def freetmp(self, anaconda):
+    # installs that don't use /mnt/stage2 hold the install.img on
+    # a tmpfs, free this ram if things are tight.
+        stage2img = "/tmp/install.img"
+        if os.path.exists(stage2img):
+            # free up /tmp for more memory before yum is called,
+            if self.mountInstallImage(anaconda, stage2img):
+               	return DISPATCH_BACK
+            try:
+                os.unlink(stage2img)
+            except SystemError:
+                log.info("clearing /tmp failed")
+                return DISPATCH_BACK
+
+    def kernelVersionList(self, rootPath="/"):
+        return []
+
+    def getMinimumSizeMB(self, part):
+        """Return the minimal size for part in megabytes if we can."""
+        return 0
+
+    def doBackendSetup(self, anaconda):
+        log.warning("doBackendSetup not implemented for backend!")
+        raise NotImplementedError
+
+    def groupExists(self, group):
+        log.warning("groupExists not implemented for backend!")
+        raise NotImplementedError
+
+    def selectGroup(self, group, *args):
+        log.warning("selectGroup not implemented for backend!")
+        raise NotImplementedError
+
+    def deselectGroup(self, group, *args):
+        log.warning("deselectGroup not implemented for backend!")
+        raise NotImplementedError
+
+    def packageExists(self, pkg):
+        log.warning("packageExists not implemented for backend!")
+        raise NotImplementedError
+    
+    def selectPackage(self, pkg, *args):
+        log.warning("selectPackage not implemented for backend!")
+        raise NotImplementedError
+
+    def deselectPackage(self, pkg, *args):
+        log.warning("deselectPackage not implemented for backend!")
+        raise NotImplementedError
+
+    def getDefaultGroups(self, anaconda):
+        log.warning("getDefaultGroups not implemented for backend!")
+        raise NotImplementedError
+
+    def resetPackageSelections(self):
+        # we just leave this one unimplemented if it's not needed
+        pass
+
+    # write out the %packages section of anaconda-ks.cfg
+    def writePackagesKS(self, f, anaconda):
+        log.warning("writePackagesKS not implemented for backend!")
+        raise NotImplementedError
+
+    # write out any config files that live on the installed system
+    # (e.g., /etc/yum.repos.d/* files)
+    def writeConfiguration(self):
+        log.warning("writeConfig not implemented for backend!")
+        raise NotImplementedError
+
+    # write out any other kickstart bits the backend requires - no warning
+    # here because this may not be needed
+    def writeKS(self, f):
+        pass
+
+    def getRequiredMedia(self):
+        log.warning("getRequiredMedia not implmented for backend!")
+        raise NotImplementedError
+
+    def complete(self, anaconda):
+        pass
+
+def doBackendSetup(anaconda):
+    if anaconda.backend.doBackendSetup(anaconda) == DISPATCH_BACK:
+        return DISPATCH_BACK
+
+    if anaconda.upgrade:
+        anaconda.backend.checkSupportedUpgrade(anaconda)
+        iutil.writeRpmPlatform(anaconda.rootPath)
+
+def doPostSelection(anaconda):
+    return anaconda.backend.doPostSelection(anaconda)
+
+def doPreInstall(anaconda):
+    anaconda.backend.doPreInstall(anaconda)
+
+def doPostInstall(anaconda):
+    anaconda.backend.doPostInstall(anaconda)
+
+def doInstall(anaconda):
+    return anaconda.backend.doInstall(anaconda)
+
+# does this need to be per-backend?  we'll just leave here until it does :)
+def doBasePackageSelect(anaconda):
+    if anaconda.ksdata:
+        anaconda.backend.resetPackageSelections()
+        kickstart.selectPackages(anaconda)
+    elif anaconda.displayMode != 't':
+        anaconda.backend.resetPackageSelections()
+        anaconda.instClass.setPackageSelection(anaconda)
+        anaconda.instClass.setGroupSelection(anaconda)
+
+def writeConfiguration(anaconda):
+    log.info("Writing main configuration")
+    anaconda.write()
+    anaconda.backend.writeConfiguration()
diff --git a/pyanaconda/backend_log.py b/pyanaconda/backend_log.py
new file mode 100644
index 0000000..fd11692
--- /dev/null
+++ b/pyanaconda/backend_log.py
@@ -0,0 +1,88 @@
+# backend_log.py
+# Logging infrastructure for Anaconda's backend.
+#
+# Copyright (C) 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, or (at your option) any later version.
+# 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.
+#
+# Red Hat Author(s): Ales Kozumplik <akozumpl@xxxxxxxxxx>
+#
+
+import logging
+import os
+import signal
+
+import anaconda_log
+import iutil
+
+SYSLOG_PATH           = '/sbin/rsyslogd'
+SYSLOG_PIDFILE        = '/var/run/rsyslog_backend.pid'
+SYSLOG_CFGFILE        = '/etc/rsyslog_backend.conf'
+
+CFG_TEMPLATE = """
+$ModLoad imuxsock
+$InputUnixListenSocketHostName sysimage
+$AddUnixListenSocket %(socket)s
++sysimage
+*.* %(logfile)s;RSYSLOG_TraditionalFileFormat
+%(remote_syslog)s
+"""
+
+global_log = logging.getLogger("anaconda")
+class BackendSyslog:
+    def __init__(self):
+        pass
+    
+    def build_cfg(self, root, log):
+        socket = "%s/dev/log" % (root, )
+        remote_syslog = ''
+        if anaconda_log.logger.remote_syslog:
+            remote_syslog = "*.* @@%s" % (anaconda_log.logger.remote_syslog, )
+        
+        cfg = CFG_TEMPLATE % {
+            'socket' : socket,
+            'logfile' : log,
+            'remote_syslog' : remote_syslog
+            }
+        with open(SYSLOG_CFGFILE, 'w') as cfg_file:
+            cfg_file.write(cfg)
+
+    def start(self, root, log):
+        """ Start an rsyslogd instance dedicated for the sysimage.
+
+        Other possibility would be to change configuration and SIGHUP the
+        existing instance, but it could lose some of its internal queues and
+        give us problems with remote logging.
+        """
+        self.build_cfg(root, log)
+        args = ['-c', '4', 
+                '-f', SYSLOG_CFGFILE,
+                '-i', str(SYSLOG_PIDFILE)]
+        status = iutil.execWithRedirect(SYSLOG_PATH, args)
+        if status == 0:
+            global_log.info("Backend logger started.")
+        else:
+            global_log.error("Unable to start backend logger")
+    
+    def stop(self):
+        try:
+            with open(SYSLOG_PIDFILE, 'r') as pidfile:
+                pid = int(pidfile.read())
+            os.kill(pid, signal.SIGKILL)
+        except:
+            return
+        global_log.info("Backend logger stopped.")
+
+log = BackendSyslog()
diff --git a/pyanaconda/baseudev.py b/pyanaconda/baseudev.py
new file mode 100644
index 0000000..3d9ee45
--- /dev/null
+++ b/pyanaconda/baseudev.py
@@ -0,0 +1,92 @@
+# udev.py
+# Python module for querying the udev database for device information.
+#
+# Copyright (C) 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, or (at your option) any later version.
+# 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.
+#
+# Red Hat Author(s): Dave Lehman <dlehman@xxxxxxxxxx>
+#                    Chris Lumens <clumens@xxxxxxxxxx>
+#
+
+import iutil
+import os
+
+import pyudev
+global_udev = pyudev.Udev()
+
+import logging
+log = logging.getLogger("storage")
+
+def udev_enumerate_devices(deviceClass="block"):
+    devices = global_udev.enumerate_devices(subsystem=deviceClass)
+    return [path[4:] for path in devices]
+
+def udev_get_device(sysfs_path):
+    if not os.path.exists("/sys%s" % sysfs_path):
+        log.debug("%s does not exist" % sysfs_path)
+        return None
+
+    # XXX we remove the /sys part when enumerating devices,
+    # so we have to prepend it when creating the device
+    dev = global_udev.create_device("/sys" + sysfs_path)
+
+    if dev:
+        dev["name"] = dev.sysname
+        dev["sysfs_path"] = sysfs_path
+
+        # now add in the contents of the uevent file since they're handy
+        dev = udev_parse_uevent_file(dev)
+
+    return dev
+
+def udev_get_devices(deviceClass="block"):
+    udev_settle()
+    entries = []
+    for path in udev_enumerate_devices(deviceClass):
+        entry = udev_get_device(path)
+        if entry:
+            entries.append(entry)
+    return entries
+
+def udev_parse_uevent_file(dev):
+    path = os.path.normpath("/sys/%s/uevent" % dev['sysfs_path'])
+    if not os.access(path, os.R_OK):
+        return dev
+
+    with open(path) as f:
+        for line in f.readlines():
+            (key, equals, value) = line.strip().partition("=")
+            if not equals:
+                continue
+
+            dev[key] = value
+
+    return dev
+
+def udev_settle():
+    # wait maximal 300 seconds for udev to be done running blkid, lvm,
+    # mdadm etc. This large timeout is needed when running on machines with
+    # lots of disks, or with slow disks
+    argv = ["settle", "--timeout=300"]
+
+    iutil.execWithRedirect("udevadm", argv, stderr="/dev/null")
+
+def udev_trigger(subsystem=None, action="add"):
+    argv = ["trigger", "--action=%s" % action]
+    if subsystem:
+        argv.append("--subsystem-match=%s" % subsystem)
+
+    iutil.execWithRedirect("udevadm", argv, stderr="/dev/null")
diff --git a/pyanaconda/bootloader.py b/pyanaconda/bootloader.py
new file mode 100644
index 0000000..30912e7
--- /dev/null
+++ b/pyanaconda/bootloader.py
@@ -0,0 +1,244 @@
+#
+# bootloader.py: anaconda bootloader shims
+#
+# Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006  Red Hat, Inc.
+# 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 as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# 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, see <http://www.gnu.org/licenses/>.
+#
+# Author(s): Erik Troan <ewt@xxxxxxxxxx>
+#            Jeremy Katz <katzj@xxxxxxxxxx>
+#
+
+import isys
+import parted
+import os, sys
+import iutil
+import string
+from flags import flags
+from constants import *
+from storage.devices import devicePathToName
+from storage import getReleaseString
+from booty.util import getDiskPart
+
+import gettext
+_ = lambda x: gettext.ldgettext("anaconda", x)
+
+import logging
+log = logging.getLogger("anaconda")
+
+import booty
+from booty import bootloaderInfo, checkbootloader
+
+def isEfiSystemPartition(part):
+    if not part.active:
+        return False
+    return (part.disk.type == "gpt" and
+            part.name == "EFI System Partition" and
+            part.getFlag(parted.PARTITION_BOOT) and
+            part.fileSystem.type in ("fat16", "fat32") and
+            isys.readFSLabel(part.getDeviceNodeName()) != "ANACONDA")
+
+def bootloaderSetupChoices(anaconda):
+    if anaconda.dir == DISPATCH_BACK:
+        rc = anaconda.intf.messageWindow(_("Warning"),
+                _("Filesystems have already been activated.  You "
+                  "cannot go back past this point.\n\nWould you like to "
+                  "continue with the installation?"),
+                type="custom", custom_icon=["error","error"],
+                custom_buttons=[_("_Exit installer"), _("_Continue")])
+
+        if rc == 0:
+            sys.exit(0)
+        return DISPATCH_FORWARD
+
+    if anaconda.ksdata and anaconda.ksdata.bootloader.driveorder:
+        anaconda.bootloader.updateDriveList(anaconda.ksdata.bootloader.driveorder)
+    else:
+        #We want the selected bootloader drive to be preferred
+        pref = anaconda.bootloader.drivelist[:1]
+        anaconda.bootloader.updateDriveList(pref)
+
+    if iutil.isEfi() and not anaconda.bootloader.device:
+        bootPart = None
+        partitions = anaconda.storage.partitions
+        for part in partitions:
+            if part.partedPartition.active and isEfiSystemPartition(part.partedPartition):
+                bootPart = part.name
+                break
+        if bootPart:
+            anaconda.bootloader.setDevice(bootPart)
+
+# iSeries bootloader on upgrades
+    if iutil.getPPCMachine() == "iSeries" and not anaconda.bootloader.device:
+        bootPart = None
+        partitions = anaconda.storage.partitions
+        for part in partitions:
+            if part.partedPartition.active and \
+               part.partedPartition.getFlag(parted.PARTITION_PREP):
+                bootPart = part.name
+                break
+        if bootPart:
+            anaconda.bootloader.setDevice(bootPart)
+
+    choices = anaconda.platform.bootloaderChoices(anaconda.bootloader)
+    if not choices and iutil.getPPCMachine() != "iSeries":
+	anaconda.dispatch.skipStep("instbootloader")
+    else:
+	anaconda.dispatch.skipStep("instbootloader", skip = 0)
+
+    # FIXME: ...
+    anaconda.bootloader.images.setup(anaconda.storage)
+
+    if anaconda.bootloader.defaultDevice != None and choices:
+        keys = choices.keys()
+        # there are only two possible things that can be in the keys
+        # mbr and boot.  boot is ALWAYS present.  so if the dev isn't
+        # listed, it was mbr and we should nicely fall back to boot
+        if anaconda.bootloader.defaultDevice not in keys:
+            log.warning("MBR not suitable as boot device; installing to partition")
+            anaconda.bootloader.defaultDevice = "boot"
+        anaconda.bootloader.setDevice(choices[anaconda.bootloader.defaultDevice][0])
+    elif choices and iutil.isMactel() and choices.has_key("boot"): # haccckkkk
+        anaconda.bootloader.setDevice(choices["boot"][0])        
+    elif choices and choices.has_key("mbr"):
+        anaconda.bootloader.setDevice(choices["mbr"][0])
+    elif choices and choices.has_key("boot"):
+        anaconda.bootloader.setDevice(choices["boot"][0])
+
+def fixedMdraidGrubTarget(anaconda, grubTarget):
+    # handle change made in F12 - before F12 mdX used to mean installation
+    # into mbrs of mdX members' disks
+    fixedGrubTarget = grubTarget
+    (product, version) = getReleaseString(anaconda.rootPath)
+    try:
+        if float(version) < 12:
+            stage1Devs = anaconda.bootloader.getPhysicalDevices(grubTarget)
+            fixedGrubTarget = getDiskPart(stage1Devs[0], anaconda.storage)[0]
+            log.info("Mdraid grub upgrade: %s -> %s" % (grubTarget,
+                                                       fixedGrubTarget))
+    except ValueError:
+        log.warning("Can't decide mdraid grub upgrade fix, product: %s, version: %s" % (product, version))
+
+    return fixedGrubTarget
+
+def writeBootloader(anaconda):
+    def dosync():
+        isys.sync()
+        isys.sync()
+        isys.sync()
+
+    if anaconda.bootloader.defaultDevice == -1:
+        return
+
+    if anaconda.bootloader.doUpgradeOnly:
+        (bootType, theDev) = checkbootloader.getBootloaderTypeAndBoot(anaconda.rootPath, storage=anaconda.storage)
+        
+        anaconda.bootloader.doUpgradeonly = 1
+        if bootType == "GRUB":
+            if theDev.startswith('/dev/md'):
+                theDev = fixedMdraidGrubTarget(anaconda,
+                                               devicePathToName(theDev))
+            anaconda.bootloader.useGrubVal = 1
+            anaconda.bootloader.setDevice(devicePathToName(theDev))
+        else:
+            anaconda.bootloader.doUpgradeOnly = 0    
+
+    w = anaconda.intf.waitWindow(_("Bootloader"), _("Installing bootloader."))
+
+    kernelList = []
+    otherList = []
+    # getDefault needs to return a device, but that's too invasive for now.
+    rootDev = anaconda.storage.rootDevice
+
+    if not anaconda.bootloader.images.getDefault():
+        defaultDev = None
+    else:
+        defaultDev = anaconda.storage.devicetree.getDeviceByName(anaconda.bootloader.images.getDefault())
+
+    kernelLabel = None
+    kernelLongLabel = None
+
+    for (dev, (label, longlabel, type)) in anaconda.bootloader.images.getImages().items():
+        if (rootDev is None and kernelLabel is None) or (dev == rootDev.name):
+	    kernelLabel = label
+            kernelLongLabel = longlabel
+	elif (not defaultDev and not dev) or (defaultDev and dev == defaultDev.name):
+	    otherList = [(label, longlabel, dev)] + otherList
+	else:
+	    otherList.append((label, longlabel, dev))
+
+    if kernelLabel is None:
+        log.error("unable to find default image, bailing")
+        w.pop()
+        return
+
+    plainLabelUsed = 0
+    defkern = "kernel"
+    for (version, arch, nick) in \
+            anaconda.backend.kernelVersionList(anaconda.rootPath):
+	if plainLabelUsed:
+            kernelList.append(("%s-%s" %(kernelLabel, nick),
+                               "%s-%s" %(kernelLongLabel, nick),
+                               version))
+	else:
+	    kernelList.append((kernelLabel, kernelLongLabel, version))
+            if nick != "base":
+                defkern = "kernel-%s" %(nick,)
+	    plainLabelUsed = 1
+
+    f = open(anaconda.rootPath + "/etc/sysconfig/kernel", "w+")
+    f.write("# UPDATEDEFAULT specifies if new-kernel-pkg should make\n"
+            "# new kernels the default\n")
+    # only update the default if we're setting the default to linux (#156678)
+    if (not defaultDev and not rootDev) or (defaultDev and rootDev.name == defaultDev.name):
+        f.write("UPDATEDEFAULT=yes\n")
+    else:
+        f.write("UPDATEDEFAULT=no\n")        
+    f.write("\n")
+    f.write("# DEFAULTKERNEL specifies the default kernel package type\n")
+    f.write("DEFAULTKERNEL=%s\n" %(defkern,))
+    f.close()
+
+    dosync()
+    try:
+        rc = anaconda.bootloader.write(anaconda.rootPath, anaconda.bootloader,
+                                       kernelList, otherList, defaultDev)
+        w.pop()
+
+        if rc and anaconda.intf:
+            anaconda.intf.messageWindow(_("Warning"),
+                               _("There was an error installing the bootloader.  "
+                                 "The system may not be bootable."))
+    except booty.BootyNoKernelWarning:
+        w.pop()
+        if anaconda.intf:
+            anaconda.intf.messageWindow(_("Warning"),
+                               _("No kernel packages were installed on the "
+                                 "system.  Bootloader configuration "
+                                 "will not be changed."))
+
+    dosync()
+
+def hasWindows(bl):
+    if not booty.doesDualBoot():
+        return False
+
+    foundWindows = False
+    for (dev, type) in bl.images.availableBootDevices(bl.storage):
+        if type in booty.dosFilesystems:
+            foundWindows = True
+            break
+
+    return foundWindows
diff --git a/pyanaconda/cmdline.py b/pyanaconda/cmdline.py
new file mode 100644
index 0000000..a531940
--- /dev/null
+++ b/pyanaconda/cmdline.py
@@ -0,0 +1,221 @@
+#
+# cmdline.py - non-interactive, very very simple frontend to anaconda
+#
+# Copyright (C) 2003, 2004, 2005, 2006, 2007  Red Hat, Inc.
+# 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 as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# 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, see <http://www.gnu.org/licenses/>.
+#
+# Author(s): Jeremy Katz <katzj@xxxxxxxxxx
+#
+
+import time
+import signal
+import parted
+from constants import *
+from flags import flags
+from iutil import strip_markup
+from installinterfacebase import InstallInterfaceBase
+
+import gettext
+_ = lambda x: gettext.ldgettext("anaconda", x)
+
+import logging
+log = logging.getLogger("anaconda")
+
+stepToClasses = { "install" : "setupProgressDisplay" }
+
+class WaitWindow:
+    def pop(self):
+        pass
+    def refresh(self):
+        pass
+    def __init__(self, title, text):
+        print(text)
+
+class ProgressWindow:
+    def pop(self):
+        print("")
+
+    def pulse(self):
+        pass
+
+    def set(self, amount):
+        if amount == self.total:
+            print(_("Completed"))
+
+    def refresh(self):
+        pass
+
+    def __init__(self, title, text, total, updpct = 0.05, pulse = False):
+        self.total = total
+        print(text)
+        print(_("In progress"))
+
+class InstallInterface(InstallInterfaceBase):
+    def __init__(self):
+        InstallInterfaceBase.__init__(self)
+#        signal.signal(signal.SIGINT, signal.SIG_IGN)
+        signal.signal(signal.SIGTSTP, signal.SIG_DFL)
+        self.instProgress = None
+
+    def __del__(self):
+        pass
+
+    def shutdown(self):
+        pass
+
+    def suspend(self):
+        pass
+
+    def resume(self):
+        pass
+
+    def progressWindow(self, title, text, total, updpct = 0.05, pulse = False):
+        return ProgressWindow(title, text, total, updpct, pulse)
+
+    def kickstartErrorWindow(self, text):
+        s = _("The following error was found while parsing the "
+              "kickstart configuration file:\n\n%s") %(text,)
+        print(s)
+
+        while 1:
+            time.sleep(5)
+
+    def messageWindow(self, title, text, type="ok", default = None,
+                      custom_icon = None, custom_buttons = []):
+        if type == "ok":
+            print(text)
+        else:
+            print(_("Command line mode requires all choices to be specified in a kickstart configuration file."))
+            print(title)
+            print(text)
+            print(type, custom_buttons)
+
+            # don't exit
+            while 1:
+                time.sleep(5)
+
+    def detailedMessageWindow(self, title, text, longText=None, type="ok",
+                              default=None, custom_buttons=None,
+                              custom_icon=None, expanded=False):
+        if longText:
+            text += "\n\n%s" % longText
+
+        self.messageWindow(title, text, type=type, default=default,
+                           custom_buttons=custom_buttons, custom_icon=custom_icon)
+
+    def passphraseEntryWindow(self, device):
+        print(_("Can't have a question in command line mode!"))
+        print("(passphraseEntryWindow: '%s')" % device)
+        # don't exit
+        while 1:
+            time.sleep(5)
+
+    def getLUKSPassphrase(self, passphrase = "", isglobal = False):
+        print(_("Can't have a question in command line mode!"))
+        print("(getLUKSPassphrase)")
+        # don't exit
+        while 1:
+            time.sleep(5)
+
+    def enableNetwork(self):
+        print(_("Can't have a question in command line mode!"))
+        print("(enableNetwork)")
+        # don't exit
+        while 1:
+            time.sleep(5)
+
+    def resetInitializeDiskQuestion(self):
+        pass
+
+    def questionInitializeDisk(self, path, description, size, details=""):
+        print(_("Can't have a question in command line mode!"))
+        print("(questionInitializeDisk)")
+        # don't exit
+        while 1:
+            time.sleep(5)
+
+    def resetReinitInconsistentLVMQuestion(self):
+        pass
+
+    def questionReinitInconsistentLVM(self, pv_names=None, lv_name=None, vg_name=None):
+        print(_("Can't have a question in command line mode!"))
+        print("(questionReinitInconsistentLVM)")
+        # don't exit
+        while 1:
+            time.sleep(5)
+
+    def mainExceptionWindow(self, shortText, longTextFile):
+        print(shortText)
+
+    def waitWindow(self, title, text):
+        return WaitWindow(title, text)
+
+    def beep(self):
+        pass
+
+    def run(self, anaconda):
+        (step, instance) = anaconda.dispatch.currentStep()
+        while step:
+            if stepToClasses.has_key(step):
+                s = "nextWin = %s" %(stepToClasses[step],)
+                exec s
+                nextWin(instance)
+            else:
+                print("In interactive step %s, can't continue" %(step,))
+                while 1:
+                    time.sleep(1)
+
+            anaconda.dispatch.gotoNext()
+	    (step, instance) = anaconda.dispatch.currentStep()
+
+    def setInstallProgressClass(self, c):
+        self.instProgress = c
+
+    def setSteps(self, anaconda):
+        pass
+
+class progressDisplay:
+    def __init__(self):
+        self.pct = 0
+        self.display = ""
+
+    def __del__(self):
+        pass
+
+    def processEvents(self):
+        pass
+    def setShowPercentage(self, val):
+        pass
+    def get_fraction(self):
+        return self.pct
+    def set_fraction(self, pct):
+        self.pct = pct
+    def set_text(self, txt):
+        pass
+    def set_label(self, txt):
+        stripped = strip_markup(txt)
+        if stripped != self.display:
+            self.display = stripped
+            print(self.display)
+
+def setupProgressDisplay(anaconda):
+    if anaconda.dir == DISPATCH_BACK:
+        anaconda.intf.setInstallProgressClass(None)
+        return DISPATCH_BACK
+    else:
+        anaconda.intf.setInstallProgressClass(progressDisplay())
+        
+    return DISPATCH_FORWARD
diff --git a/pyanaconda/compssort.py b/pyanaconda/compssort.py
new file mode 100644
index 0000000..3ad9795
--- /dev/null
+++ b/pyanaconda/compssort.py
@@ -0,0 +1,69 @@
+#
+# compssort.py
+#
+# Copyright (C) 2005, 2006, 2007  Red Hat, Inc.  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 as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# 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, see <http://www.gnu.org/licenses/>.
+#
+
+import os
+
+import gettext
+_ = lambda x: gettext.ldgettext("anaconda", x)
+
+def _getDefaultLangs():
+    languages = []
+    for envar in ('LANGUAGE', 'LC_ALL', 'LC_MESSAGES', 'LANG'):
+        val = os.environ.get(envar)
+        if val:
+            languages = val.split(':')
+            break
+    if 'C' not in languages:
+        languages.append('C')
+
+    # now normalize and expand the languages
+    nelangs = []
+    for lang in languages:
+        for nelang in gettext._expand_lang(lang):
+            if nelang not in nelangs:
+                nelangs.append(nelang)
+    return nelangs
+
+# kind of lame caching of translations so we don't always have
+# to do all the looping
+strs = {}
+def xmltrans(base, thedict):
+    if strs.has_key(base):
+        return strs[base]
+
+    langs = _getDefaultLangs()
+    for l in langs:
+        if thedict.has_key(l):
+            strs[base] = thedict[l]
+            return strs[base]
+    strs[base] = base
+    return base
+
+def ui_comps_sort(one, two):
+    if one.display_order > two.display_order:
+        return 1
+    elif one.display_order < two.display_order:
+        return -1
+    elif xmltrans(one.name, one.translated_name) > \
+         xmltrans(two.name, two.translated_name):
+        return 1
+    elif xmltrans(one.name, one.translated_name) < \
+         xmltrans(two.name, two.translated_name):
+        return -1
+    return 0
diff --git a/pyanaconda/constants.py b/pyanaconda/constants.py
new file mode 100644
index 0000000..fb81c90
--- /dev/null
+++ b/pyanaconda/constants.py
@@ -0,0 +1,89 @@
+#
+# constants.py: anaconda constants
+#
+# Copyright (C) 2001  Red Hat, Inc.  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 as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# 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, see <http://www.gnu.org/licenses/>.
+#
+# Author(s): Erik Troan <ewt@xxxxxxxxxx>
+#
+
+import gettext
+_ = lambda x: gettext.ldgettext("anaconda", x)
+N_ = lambda x: x
+
+BETANAG = 1
+
+SELINUX_DEFAULT = 1
+
+DISPATCH_BACK = -1
+DISPATCH_FORWARD = 1
+DISPATCH_NOOP = None
+
+EXN_OK = 0
+EXN_DEBUG = 1
+EXN_SAVE = 2
+EXN_CANCEL = 3
+
+# different types of partition requests
+# REQUEST_PREEXIST is a placeholder for a pre-existing partition on the system
+# REQUEST_NEW is a request for a partition which will be automatically
+#              created based on various constraints on size, drive, etc
+# REQUEST_RAID is a request for a raid device
+# REQUEST_PROTECTED is a preexisting partition which can't change
+#              (harddrive install, harddrive with the isos on it)
+#
+REQUEST_PREEXIST = 1
+REQUEST_NEW = 2
+REQUEST_RAID = 4
+REQUEST_PROTECTED = 8
+REQUEST_VG = 16 # volume group
+REQUEST_LV = 32 # logical volume
+
+# XXX this is made up and used by the size spinner; should just be set with
+# a callback
+MAX_PART_SIZE = 1024*1024*1024
+
+# install key related constants
+SKIP_KEY = -50
+
+# pull in kickstart constants as well
+from pykickstart.constants import *
+
+# common string needs to be easy to change
+import product
+productName = product.productName
+productVersion = product.productVersion
+productArch = product.productArch
+productPath = product.productPath
+bugzillaUrl = product.bugUrl
+
+lvmErrorOutput = "/tmp/lvmout"
+
+exceptionText = _("An unhandled exception has occurred.  This "
+                  "is most likely a bug.  Please save a copy of "
+                  "the detailed exception and file a bug report")
+if not bugzillaUrl:
+    # this string will be combined with "An unhandled exception"...
+    # the leading space is not a typo.
+    exceptionText += _(" with the provider of this software.")
+else:
+    # this string will be combined with "An unhandled exception"...
+    # the leading space is not a typo.
+    exceptionText += _(" against anaconda at %s") %(bugzillaUrl,)
+
+# DriverDisc Paths
+DD_EXTRACTED = "/tmp/DD"
+DD_RPMS = "/tmp/DD-*"
+
diff --git a/pyanaconda/desktop.py b/pyanaconda/desktop.py
new file mode 100644
index 0000000..49b7bbe
--- /dev/null
+++ b/pyanaconda/desktop.py
@@ -0,0 +1,71 @@
+#
+# desktop.py - install data for default desktop and run level
+#
+# Copyright (C) 2001, 2002  Red Hat, Inc.  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 as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# 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, see <http://www.gnu.org/licenses/>.
+#
+# Author(s): Matt Wilson <msw@xxxxxxxxxx>
+#
+
+import string
+from simpleconfig import SimpleConfigFile
+
+import logging
+log = logging.getLogger("anaconda")
+
+class Desktop (SimpleConfigFile):
+#
+# This class represents the default desktop to run and the default runlevel
+# to start in
+#
+    def setDefaultRunLevel(self, runlevel):
+        if str(runlevel) != "3" and str(runlevel) != "5":
+            raise RuntimeError, "Desktop::setDefaultRunLevel() - Must specify runlevel as 3 or 5!"
+        self.runlevel = runlevel
+
+    def getDefaultRunLevel(self):
+        return self.runlevel
+
+    def setDefaultDesktop(self, desktop):
+        self.info["DESKTOP"] = desktop
+
+    def getDefaultDesktop(self):
+        return self.get("DESKTOP")
+
+    def __init__ (self):
+        SimpleConfigFile.__init__ (self)
+        self.runlevel = 3
+
+    def write (self, instPath):
+        try:
+            inittab = open (instPath + '/etc/inittab', 'r')
+        except IOError:
+            log.warning ("there is no inittab, bad things will happen!")
+            return
+        lines = inittab.readlines ()
+        inittab.close ()
+        inittab = open (instPath + '/etc/inittab', 'w')        
+        for line in lines:
+            if len (line) > 3 and line[:3] == "id:":
+                fields = string.split (line, ':')
+                fields[1] = str (self.runlevel)
+                line = string.join (fields, ':')
+            inittab.write (line)
+        inittab.close ()
+
+        if self.getDefaultDesktop():
+            f = open(instPath + "/etc/sysconfig/desktop", "w")
+            f.write(str (self))
+            f.close()
diff --git a/pyanaconda/dispatch.py b/pyanaconda/dispatch.py
new file mode 100644
index 0000000..2f3d787
--- /dev/null
+++ b/pyanaconda/dispatch.py
@@ -0,0 +1,254 @@
+#
+# dispatch.py: install/upgrade master flow control
+#
+# Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006  Red Hat, Inc.
+# 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 as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# 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, see <http://www.gnu.org/licenses/>.
+#
+# Author(s): Erik Troan <ewt@xxxxxxxxxx>
+#
+
+import string
+from types import *
+from constants import *
+from packages import writeKSConfiguration, turnOnFilesystems
+from packages import doPostAction
+from packages import copyAnacondaLogs
+from packages import firstbootConfiguration
+from packages import betaNagScreen
+from packages import setupTimezone
+from packages import setFileCons
+from storage import storageInitialize
+from storage import storageComplete
+from storage.partitioning import doAutoPartition
+from bootloader import writeBootloader, bootloaderSetupChoices
+from flags import flags
+from upgrade import upgradeMountFilesystems
+from upgrade import restoreTime
+from upgrade import upgradeSwapSuggestion, upgradeMigrateFind
+from upgrade import findRootParts, queryUpgradeContinue
+from installmethod import doMethodComplete
+from kickstart import runPostScripts
+
+from backend import doPostSelection, doBackendSetup, doBasePackageSelect
+from backend import doPreInstall, doPostInstall, doInstall
+from backend import writeConfiguration
+
+from packages import doReIPL
+
+import logging
+log = logging.getLogger("anaconda")
+
+# These are all of the install steps, in order. Note that upgrade and
+# install steps are the same thing! Upgrades skip install steps, while
+# installs skip upgrade steps.
+
+#
+# items are one of
+#
+#       ( name )
+#       ( name, Function )
+#
+# in the second case, the function is called directly from the dispatcher
+
+# All install steps take the anaconda object as their sole argument.  This
+# gets passed in when we call the function.
+installSteps = [
+    ("welcome", ),
+    ("language", ),
+    ("keyboard", ),
+    ("betanag", betaNagScreen, ),
+    ("filtertype", ),
+    ("filter", ),
+    ("storageinit", storageInitialize, ),
+    ("findrootparts", findRootParts, ),
+    ("findinstall", ),
+    ("network", ),
+    ("timezone", ),
+    ("accounts", ),
+    ("setuptime", setupTimezone, ),
+    ("parttype", ),
+    ("cleardiskssel", ),
+    ("autopartitionexecute", doAutoPartition, ),
+    ("partition", ),
+    ("upgrademount", upgradeMountFilesystems, ),
+    ("restoretime", restoreTime, ),
+    ("upgradecontinue", queryUpgradeContinue, ),
+    ("upgradeswapsuggestion", upgradeSwapSuggestion, ),
+    ("addswap", ),
+    ("upgrademigfind", upgradeMigrateFind, ),
+    ("upgrademigratefs", ),
+    ("storagedone", storageComplete, ),
+    ("enablefilesystems", turnOnFilesystems, ),
+    ("upgbootloader", ),
+    ("bootloadersetup", bootloaderSetupChoices, ),
+    ("bootloader", ),
+    ("reposetup", doBackendSetup, ),
+    ("tasksel", ),
+    ("basepkgsel", doBasePackageSelect, ),
+    ("group-selection", ),
+    ("postselection", doPostSelection, ),
+    ("reipl", doReIPL, ),
+    ("install", ),
+    ("preinstallconfig", doPreInstall, ),
+    ("installpackages", doInstall, ),
+    ("postinstallconfig", doPostInstall, ),
+    ("writeconfig", writeConfiguration, ),
+    ("firstboot", firstbootConfiguration, ),
+    ("instbootloader", writeBootloader, ),
+    ("writeksconfig", writeKSConfiguration, ),
+    ("setfilecon", setFileCons, ),
+    ("copylogs", copyAnacondaLogs, ),
+    ("methodcomplete", doMethodComplete, ),
+    ("postscripts", runPostScripts, ),
+    ("dopostaction", doPostAction, ),
+    ("complete", ),
+    ]
+
+class Dispatcher(object):
+
+    def gotoPrev(self):
+        self._setDir(DISPATCH_BACK)
+        self.moveStep()
+
+    def gotoNext(self):
+        self._setDir(DISPATCH_FORWARD)
+        self.moveStep()
+
+    def canGoBack(self):
+        # begin with the step before this one.  If all steps are skipped,
+        # we can not go backwards from this screen
+        i = self.step - 1
+        while i >= self.firstStep:
+            if not self.stepIsDirect(i) and not self.skipSteps.has_key(installSteps[i][0]):
+                return True
+            i = i - 1
+        return False
+
+    def setStepList(self, *steps):
+        # only remove non-permanently skipped steps from our skip list
+        for step, state in self.skipSteps.items():
+            if state == 1:
+                del self.skipSteps[step]
+
+        stepExists = {}
+        for step in installSteps:
+            name = step[0]
+            if not name in steps:
+                self.skipSteps[name] = 1
+
+            stepExists[name] = 1
+
+        for name in steps:
+            if not stepExists.has_key(name):
+                #XXX: hack for yum support
+                #raise KeyError, ("step %s does not exist" % name)
+                log.warning("step %s does not exist", name)
+
+    def stepInSkipList(self, step):
+        if type(step) == type(1):
+            step = installSteps[step][0]
+        return self.skipSteps.has_key(step)
+
+    def skipStep(self, stepToSkip, skip = 1, permanent = 0):
+        for step in installSteps:
+            name = step[0]
+            if name == stepToSkip:
+                if skip:
+                    if permanent:
+                        self.skipSteps[name] = 2
+                    elif not self.skipSteps.has_key(name):
+                        self.skipSteps[name] = 1
+                elif self.skipSteps.has_key(name):
+                    # if marked as permanent then dont change
+                    if self.skipSteps[name] != 2:
+                        del self.skipSteps[name]
+                return
+
+        #raise KeyError, ("unknown step %s" % stepToSkip)
+        log.warning("step %s does not exist", name)
+
+    def stepIsDirect(self, step):
+        """Takes a step number"""
+        if len(installSteps[step]) == 2:
+            return True
+        else:
+            return False
+
+    def moveStep(self):
+        if self.step == None:
+            self.step = self.firstStep
+        else:
+            log.info("leaving (%d) step %s" %(self._getDir(), installSteps[self.step][0]))
+            self.step = self.step + self._getDir()
+
+        if self.step >= len(installSteps):
+            return None
+
+        while self.step >= self.firstStep and self.step < len(installSteps) \
+            and (self.stepInSkipList(self.step) or self.stepIsDirect(self.step)):
+
+            if self.stepIsDirect(self.step) and not self.stepInSkipList(self.step):
+                (stepName, stepFunc) = installSteps[self.step]
+                log.info("moving (%d) to step %s" %(self._getDir(), stepName))
+                log.debug("%s is a direct step" %(stepName,))
+                rc = stepFunc(self.anaconda)
+                if rc in [DISPATCH_BACK, DISPATCH_FORWARD]:
+                    self._setDir(rc)
+                log.info("leaving (%d) step %s" %(self._getDir(), stepName))
+                # if anything else, leave self.dir alone
+
+            self.step = self.step + self._getDir()
+            if self.step == len(installSteps):
+                return None
+
+        if (self.step < 0):
+            # pick the first step not in the skip list
+            self.step = 0
+            while self.skipSteps.has_key(installSteps[self.step][0]):
+                self.step = self.step + 1
+        elif self.step >= len(installSteps):
+            self.step = len(installSteps) - 1
+            while self.skipSteps.has_key(installSteps[self.step][0]):
+                self.step = self.step - 1
+        log.info("moving (%d) to step %s" %(self._getDir(), installSteps[self.step][0]))
+
+    def currentStep(self):
+        if self.step == None:
+            self.gotoNext()
+        elif self.step >= len(installSteps):
+            return (None, None)
+
+        stepInfo = installSteps[self.step]
+        step = stepInfo[0]
+
+        return (step, self.anaconda)
+
+    def __init__(self, anaconda):
+        self.anaconda = anaconda
+        self.anaconda.dir = DISPATCH_FORWARD
+        self.step = None
+        self.skipSteps = {}
+
+        self.firstStep = 0
+
+    def _getDir(self):
+        return self.anaconda.dir
+
+    def _setDir(self, dir):
+        self.anaconda.dir = dir
+
+    dir = property(_getDir,_setDir)
+
diff --git a/pyanaconda/errors.py b/pyanaconda/errors.py
new file mode 100644
index 0000000..9733733
--- /dev/null
+++ b/pyanaconda/errors.py
@@ -0,0 +1,159 @@
+#
+# errors.py: exception classes used throughout anaconda
+#
+# Copyright (C) 2002, 2007, 2008  Red Hat, Inc.  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 as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# 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, see <http://www.gnu.org/licenses/>.
+#
+# Author(s): Peter Jones <pjones@xxxxxxxxxx>
+#            Chris Lumens <clumens@xxxxxxxxxx>
+#            Matt Wilson <msw@xxxxxxxxxx>
+#            Jeremy Katz <katzj@xxxxxxxxxx>
+#            Mike Fulbright <msf@xxxxxxxxxx>
+#
+
+import string
+import os
+from constants import lvmErrorOutput
+
+# Exceptions for use in lvm operations.
+
+class LvmError(Exception):
+    """An error occurred with lvm."""
+    def __init__(self, command, name=None):
+        self.command = command
+        self.name = name
+        self.log = self.getLvmOutput()
+
+    def getLvmOutput(self):
+        if not os.access(lvmErrorOutput, os.R_OK):
+            return ""
+        f = open(lvmErrorOutput, "r")
+        lines = reduce(lambda x,y: x + [string.strip(y),], f.readlines(), [])
+        lines = string.join(reduce(lambda x,y: x + ["   %s" % (y,)], \
+                                    lines, []), "\n")
+        return lines
+
+    def __str__(self):
+        s = ""
+        if not self.name is None:
+            s = " for device %s" % (self.name,)
+        return "%s failed%s\nLog:\n%s" % (self.command, s, self.log)
+
+class LVCreateError(LvmError):
+    def __init__(self, vgname, lvname, size):
+        self.vgname = vgname
+        self.lvname = lvname
+        self.size = size
+        self.log = self.getLvmOutput()
+
+    def __str__(self):
+        return "lvcreate of %d Megabyte lv \"%s\" on vg \"%s\" failed\n" \
+               "Log:\n%s" % ( \
+            self.size, self.lvname, self.vgname, self.log)
+
+class LVRemoveError(LvmError):
+    def __init__(self, vgname, lvname):
+        self.vgname = vgname
+        self.lvname = lvname
+        self.log = self.getLvmOutput()
+
+    def __str__(self):
+        return "lvremove of lv \"%s\" from vg \"%s\" failed\nLog:\n%s" % ( \
+            self.lvname, self.vgname, self.log)
+
+class LVResizeError(LvmError):
+    def __init__(self, vgname, lvname):
+        self.vgname = vgname
+        self.lvname = lvname
+        self.log = self.getLvmOutput()
+
+    def __str__(self):
+        return "lvresize of lv \"%s\" from vg \"%s\" failed\nLog:\n%s" % ( \
+            self.lvname, self.vgname, self.log)
+
+class VGCreateError(LvmError):
+    def __init__(self, vgname, PESize, nodes):
+        self.vgname = vgname
+        self.PESize = PESize
+        self.nodes = nodes
+        self.log = self.getLvmOutput()
+
+    def __str__(self):
+        nodes = string.join(self.nodes, ' ')
+        return "vgcreate failed creating vg \"%s\" (PESize=%dkB) on PVs: %s\n" \
+               "Log:\n%s" % ( \
+            self.vgname, self.PESize, nodes, self.log)
+
+class VGRemoveError(LvmError):
+    def __init__(self, vgname):
+        self.vgname = vgname
+        self.log = self.getLvmOutput()
+
+    def __str__(self):
+        return "vgremove of vg \"%s\" failed\nLog:\n%s" % ( \
+            self.vgname, self.log)
+
+class PVRemoveError(LvmError):
+    def __init__(self, pvname):
+        self.pvname = pvname
+        self.log = self.getLvmOutput()
+
+    def __str__(self):
+        return "pvremove of pv \"%s\" failed\nLog:\n%s" % ( \
+            self.pvname, self.log)
+
+class PVCreateError(LvmError):
+    def __init__(self, pvname):
+        self.pvname = pvname
+        self.log = self.getLvmOutput()
+
+    def __str__(self):
+        return "pvcreate of pv \"%s\" failed\nLog:\n%s" % ( \
+            self.pvname, self.log)
+
+# Exceptions for use in partitioning.
+
+class PartitioningError(Exception):
+    """A critical error which must be resolved to continue the installation."""
+    def __init__(self, message=""):
+        self.message = str(message)
+
+    def __str__ (self):
+        return self.message
+
+class PartitioningWarning(Exception):
+    """A warning which may be ignored and still complete the installation."""
+    def __init__(self, message=""):
+        self.message = str(message)
+
+    def __str__ (self):
+        return self.message
+
+class LabelError(Exception):
+    """The device could not be labeled."""
+    def __init__(self, message=""):
+        self.message = str(message)
+
+    def __str__(self):
+        return self.message
+
+# Exceptions for use in package selection.
+
+class NoSuchGroup(Exception):
+    def __init__ (self, value):
+        self.value = value
+
+    def __str__ (self):
+        return self.value
diff --git a/pyanaconda/exception.py b/pyanaconda/exception.py
new file mode 100644
index 0000000..1075717
--- /dev/null
+++ b/pyanaconda/exception.py
@@ -0,0 +1,132 @@
+#
+# exception.py - general exception formatting and saving
+#
+# Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007  Red Hat, Inc.
+# 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 as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# 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, see <http://www.gnu.org/licenses/>.
+#
+# Author(s): Matt Wilson <msw@xxxxxxxxxx>
+#            Erik Troan <ewt@xxxxxxxxxx>
+#            Chris Lumens <clumens@xxxxxxxxxx>
+#
+from meh.handler import *
+from meh.dump import *
+import isys
+import sys
+import os
+import shutil
+import signal
+from flags import flags
+import kickstart
+
+import logging
+log = logging.getLogger("anaconda")
+
+class AnacondaExceptionHandler(ExceptionHandler):
+    def postWriteHook(self, (ty, value, tb), anaconda):
+        # See if /mnt/sysimage is present and put exception there as well
+        if os.access("/mnt/sysimage/root", os.X_OK):
+            try:
+                dest = "/mnt/sysimage/root/%s" % os.path.basename(self.exnFile)
+                shutil.copyfile(self.exnFile, dest)
+            except:
+                log.error("Failed to copy %s to /mnt/sysimage/root" % self.exnFile)
+                pass
+
+        # run kickstart traceback scripts (if necessary)
+        try:
+            if anaconda.ksdata:
+                kickstart.runTracebackScripts(anaconda)
+        except:
+            pass
+
+    def runDebug(self, (ty, value, tb)):
+        # vtActivate does not work on certain ppc64 machines, so just skip
+        # that and continue with the rest of the debugger setup.
+        try:
+            isys.vtActivate(1)
+        except SystemError:
+            pass
+
+        self.intf.__del__ ()
+
+        pidfl = "/tmp/vncshell.pid"
+        if os.path.exists(pidfl) and os.path.isfile(pidfl):
+            pf = open(pidfl, "r")
+            for pid in pf.readlines():
+                if not int(pid) == os.getpid():
+                    os.kill(int(pid), signal.SIGKILL)
+            pf.close()
+
+        os.open("/dev/console", os.O_RDWR)   # reclaim stdin
+        os.dup2(0, 1)                        # reclaim stdout
+        os.dup2(0, 2)                        # reclaim stderr
+        #   ^
+        #   |
+        #   +------ dup2 is magic, I tells ya!
+
+        # bring back the echo
+        import termios
+        si = sys.stdin.fileno()
+        attr = termios.tcgetattr(si)
+        attr[3] = attr[3] & termios.ECHO
+        termios.tcsetattr(si, termios.TCSADRAIN, attr)
+
+        print("\nEntering debugger...")
+        import pdb
+        pdb.post_mortem (tb)
+        os.kill(os.getpid(), signal.SIGKILL)
+
+def initExceptionHandling(anaconda):
+    fileList = [ "/tmp/anaconda.log", "/tmp/lvmout", "/tmp/resize.out",
+                 "/tmp/program.log", "/tmp/storage.log", "/tmp/yum.log",
+                 anaconda.rootPath + "/root/install.log",
+                 anaconda.rootPath + "/root/upgrade.log", "/proc/cmdline" ]
+    if flags.livecdInstall:
+        fileList.extend(["/var/log/dmesg"])
+    else:
+        fileList.extend(["/tmp/syslog"])
+
+    conf = Config(programName="anaconda",
+                  programVersion=isys.getAnacondaVersion(),
+                  attrSkipList=[ "backend.ayum",
+                                 "backend.dlpkgs",
+                                 "accounts",
+                                 "bootloader.password",
+                                 "comps",
+                                 "dispatch",
+                                 "hdList",
+                                 "ksdata",
+                                 "instLanguage.font",
+                                 "instLanguage.kbd",
+                                 "instLanguage.info",
+                                 "instLanguage.localeInfo",
+                                 "instLanguage.nativeLangNames",
+                                 "instLanguage.tz",
+                                 "keyboard._mods._modelDict",
+                                 "keyboard.modelDict",
+                                 "storage.encryptionPassphrase",
+                                 "users.rootPassword",
+                                 "tmpData",
+                                 "intf.icw.buff",
+                                 "intf.icw.currentWindow.storage.encryptionPassphrase",
+                                 "intf.icw.stockButtons",
+                               ],
+                  localSkipList=[ "passphrase", "password" ],
+                  fileList=fileList)
+    handler = AnacondaExceptionHandler(conf, anaconda.intf, ReverseExceptionDump)
+    handler.install(anaconda)
+
+    return conf
diff --git a/pyanaconda/firewall.py b/pyanaconda/firewall.py
new file mode 100644
index 0000000..750d755
--- /dev/null
+++ b/pyanaconda/firewall.py
@@ -0,0 +1,93 @@
+#
+# firewall.py - firewall install data and installation
+#
+# Copyright (C) 2004  Red Hat, Inc.  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 as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# 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, see <http://www.gnu.org/licenses/>.
+#
+# Author(s): Bill Nottingham <notting@xxxxxxxxxx>
+#            Jeremy Katz <katzj@xxxxxxxxxx>
+#
+
+import iutil
+import os.path
+from flags import flags
+from constants import *
+
+import gettext
+_ = lambda x: gettext.ldgettext("anaconda", x)
+
+import logging
+log = logging.getLogger("anaconda")
+
+class Firewall:
+    def __init__ (self):
+	self.enabled = 1
+        self.trustdevs = []
+	self.portlist = []
+        self.servicelist = []
+
+    def writeKS(self, f):
+	f.write("firewall")
+
+        if self.enabled:
+	    for arg in self.getArgList():
+		f.write(" " + arg)
+	else:
+	    f.write(" --disabled")
+
+	f.write("\n")
+
+    def getArgList(self):
+	args = []
+
+        if not self.enabled:
+            args.append("--disabled")
+            return args
+
+        if not "ssh" in self.servicelist and not "22:tcp" in self.portlist:
+            args += ["--service=ssh"]
+
+        for dev in self.trustdevs:
+            args = args + [ "--trust=%s" %(dev,) ]
+
+	for port in self.portlist:
+	    args = args + [ "--port=%s" %(port,) ]
+
+        for service in self.servicelist:
+            args = args + [ "--service=%s" % (service,) ]
+
+	return args
+
+    def write (self, instPath):
+	args = [ "--quiet", "--nostart", "-f" ] + self.getArgList()
+
+        try:
+            if not os.path.exists("%s/etc/sysconfig/iptables" %(instPath,)):
+                iutil.execWithRedirect("/usr/sbin/lokkit", args,
+                                       root=instPath, stdout="/dev/null",
+                                       stderr="/dev/null")
+            else:
+                log.error("would have run %s", args)
+        except RuntimeError, msg:
+            log.error ("lokkit run failed: %s", msg)
+        except OSError as e:
+            log.error ("lokkit run failed: %s", e.strerror)
+        else:
+            f = open(instPath +
+                     '/etc/sysconfig/system-config-firewall', 'w')
+            f.write("# system-config-firewall config written out by anaconda\n\n")
+            for arg in args[3:]:
+                f.write("%s\n" %(arg,))
+            f.close()
diff --git a/pyanaconda/flags.py b/pyanaconda/flags.py
new file mode 100644
index 0000000..af6216c
--- /dev/null
+++ b/pyanaconda/flags.py
@@ -0,0 +1,122 @@
+#
+# flags.py: global anaconda flags
+#
+# Copyright (C) 2001  Red Hat, Inc.  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 as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# 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, see <http://www.gnu.org/licenses/>.
+#
+
+import os
+import shlex
+from constants import *
+
+# A lot of effort, but it only allows a limited set of flags to be referenced
+class Flags:
+
+    def __getattr__(self, attr):
+	if self.__dict__['flags'].has_key(attr):
+	    return self.__dict__['flags'][attr]
+
+	raise AttributeError, attr
+
+    def __setattr__(self, attr, val):
+	if self.__dict__['flags'].has_key(attr):
+	    self.__dict__['flags'][attr] = val
+	else:
+	    raise AttributeError, attr
+
+    def get(self, attr, val=None):
+        if self.__dict__['flags'].has_key(attr):
+            return self.__dict__['flags'][attr]
+        else:
+            return val
+
+    def createCmdlineDict(self):
+        cmdlineDict = {}
+        cmdline = open("/proc/cmdline", "r").read().strip()
+
+        # if the BOOT_IMAGE contains a space, pxelinux will strip one of the
+        # quotes leaving one at the end that shlex doesn't know what to do
+        # with
+        if cmdline.find("BOOT_IMAGE=") and cmdline.endswith('"'):
+            cmdline = cmdline.replace("BOOT_IMAGE=", "BOOT_IMAGE=\"")
+
+        lst = shlex.split(cmdline)
+
+        for i in lst:
+            try:
+                (key, val) = i.split("=", 1)
+            except:
+                key = i
+                val = None
+
+            cmdlineDict[key] = val
+
+        return cmdlineDict
+
+    def decideCmdlineFlag(self, flag):
+        if self.__dict__['flags']['cmdline'].has_key(flag) \
+                and not self.__dict__['flags']['cmdline'].has_key("no" + flag) \
+                and self.__dict__['flags']['cmdline'][flag] != "0":
+            self.__dict__['flags'][flag] = 1
+	
+    def __init__(self):
+	self.__dict__['flags'] = {}
+	self.__dict__['flags']['test'] = 0
+	self.__dict__['flags']['livecdInstall'] = 0
+        self.__dict__['flags']['dlabel'] = 0
+	self.__dict__['flags']['ibft'] = 1
+	self.__dict__['flags']['iscsi'] = 0
+	self.__dict__['flags']['serial'] = 0
+	self.__dict__['flags']['autostep'] = 0
+	self.__dict__['flags']['autoscreenshot'] = 0
+	self.__dict__['flags']['usevnc'] = 0
+	self.__dict__['flags']['vncquestion'] = True
+        self.__dict__['flags']['mpath'] = 1
+	self.__dict__['flags']['dmraid'] = 1
+	self.__dict__['flags']['selinux'] = SELINUX_DEFAULT
+        self.__dict__['flags']['debug'] = 0
+	self.__dict__['flags']['targetarch'] = None
+        self.__dict__['flags']['cmdline'] = self.createCmdlineDict()
+        self.__dict__['flags']['useIPv4'] = True
+        self.__dict__['flags']['useIPv6'] = True
+        self.__dict__['flags']['sshd'] = 0
+        self.__dict__['flags']['preexisting_x11'] = False
+        # for non-physical consoles like some ppc and sgi altix,
+        # we need to preserve the console device and not try to
+        # do things like bogl on them.  this preserves what that
+        # device is
+        self.__dict__['flags']['virtpconsole'] = None
+
+        for x in ['selinux']:
+            if self.__dict__['flags']['cmdline'].has_key(x):
+                if self.__dict__['flags']['cmdline'][x]:
+                    self.__dict__['flags'][x] = 1
+                else:
+                    self.__dict__['flags'][x] = 0
+
+        self.decideCmdlineFlag('sshd')
+
+        if self.__dict__['flags']['cmdline'].has_key("debug"):
+            self.__dict__['flags']['debug'] = self.__dict__['flags']['cmdline']['debug']
+
+        if self.__dict__['flags']['cmdline'].has_key("rpmarch"):
+            self.__dict__['flags']['targetarch'] = self.__dict__['flags']['cmdline']['rpmarch']             
+
+        if not os.path.exists("/selinux/load"):
+            self.__dict__['flags']['selinux'] = 0
+
+                
+global flags
+flags = Flags()
diff --git a/pyanaconda/gui.py b/pyanaconda/gui.py
new file mode 100755
index 0000000..a27a834
--- /dev/null
+++ b/pyanaconda/gui.py
@@ -0,0 +1,1530 @@
+#
+# gui.py - Graphical front end for anaconda
+#
+# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007
+# Red Hat, Inc.  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 as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# 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, see <http://www.gnu.org/licenses/>.
+#
+# Author(s): Matt Wilson <msw@xxxxxxxxxx>
+#            Michael Fulbright <msf@xxxxxxxxxx>
+#
+
+import os
+from flags import flags
+os.environ["GNOME_DISABLE_CRASH_DIALOG"] = "1"
+
+# we only want to enable the accessibility stuff if requested for now...
+if flags.cmdline.has_key("dogtail"):
+    os.environ["GTK_MODULES"] = "gail:atk-bridge"
+
+import string
+import time
+import isys
+import iutil
+import sys
+import shutil
+import gtk
+import gtk.glade
+import gobject
+from language import expandLangs
+from constants import *
+from product import *
+from network import hasActiveNetDev
+from installinterfacebase import InstallInterfaceBase
+import xutils
+import imputil
+
+import gettext
+_ = lambda x: gettext.ldgettext("anaconda", x)
+
+import logging
+log = logging.getLogger("anaconda")
+
+isys.bind_textdomain_codeset("redhat-dist", "UTF-8")
+
+class StayOnScreen(Exception):
+    pass
+
+mainWindow = None
+
+stepToClass = {
+    "language" : ("language_gui", "LanguageWindow"),
+    "keyboard" : ("kbd_gui", "KeyboardWindow"),
+    "welcome" : ("welcome_gui", "WelcomeWindow"),
+    "filtertype" : ("filter_type", "FilterTypeWindow"),
+    "filter" : ("filter_gui", "FilterWindow"), 
+    "zfcpconfig" : ("zfcp_gui", "ZFCPWindow"),
+    "partition" : ("partition_gui", "PartitionWindow"),
+    "parttype" : ("autopart_type", "PartitionTypeWindow"),
+    "cleardiskssel": ("cleardisks_gui", "ClearDisksWindow"),
+    "findinstall" : ("examine_gui", "UpgradeExamineWindow"),
+    "addswap" : ("upgrade_swap_gui", "UpgradeSwapWindow"),
+    "upgrademigratefs" : ("upgrade_migratefs_gui", "UpgradeMigrateFSWindow"),
+    "bootloader": ("bootloader_main_gui", "MainBootloaderWindow"),
+    "upgbootloader": ("upgrade_bootloader_gui", "UpgradeBootloaderWindow"),
+    "network" : ("network_gui", "NetworkWindow"),
+    "timezone" : ("timezone_gui", "TimezoneWindow"),
+    "accounts" : ("account_gui", "AccountWindow"),
+    "tasksel": ("task_gui", "TaskWindow"),    
+    "group-selection": ("package_gui", "GroupSelectionWindow"),
+    "install" : ("progress_gui", "InstallProgressWindow"),
+    "complete" : ("congrats_gui", "CongratulationWindow"),
+}
+
+if iutil.isS390():
+    stepToClass["bootloader"] = ("zipl_gui", "ZiplWindow")
+
+#
+# Stuff for screenshots
+#
+screenshotDir = None
+screenshotIndex = 0
+
+def copyScreenshots():
+    global screenshotIndex
+    global screenshotDir
+    
+    # see if any screenshots taken
+    if screenshotIndex == 0:
+        return
+
+    destDir = "/mnt/sysimage/root/anaconda-screenshots"
+    if not os.access(destDir, os.R_OK):
+        try:
+            os.mkdir(destDir, 0750)
+        except:
+            window = MessageWindow("Error Saving Screenshot", 
+                                   _("An error occurred saving screenshots "
+                                     "to disk."), type="warning")
+            return
+
+    # copy all png's over
+    for f in os.listdir(screenshotDir):
+        (path, fname) = os.path.split(f)
+        (b, ext) = os.path.splitext(f)
+        if ext == ".png":
+            shutil.copyfile(screenshotDir + '/' + f, destDir + '/' + fname)
+
+    window = MessageWindow(_("Screenshots Copied"), 
+                           _("The screenshots have been saved in the "
+                             "directory:\n\n"
+                             "\t/root/anaconda-screenshots/\n\n"
+                             "You can access these when you reboot and "
+                             "login as root."))
+
+def takeScreenShot():
+    global screenshotIndex
+    global screenshotDir
+
+    if screenshotDir is None:
+        screenshotDir = "/tmp/anaconda-screenshots"
+
+    if not os.access(screenshotDir, os.R_OK):
+        try:
+            os.mkdir(screenshotDir)
+        except:
+            screenshotDir = None
+            return
+
+    try:
+        screenshot = gtk.gdk.Pixbuf(gtk.gdk.COLORSPACE_RGB, False, 8,
+                     gtk.gdk.screen_width(), gtk.gdk.screen_height())
+        screenshot.get_from_drawable(gtk.gdk.get_default_root_window(),
+                                     gtk.gdk.colormap_get_system(),
+                                     0, 0, 0, 0,
+                                     gtk.gdk.screen_width(),
+                                     gtk.gdk.screen_height())
+
+        if screenshot:
+            while (1):
+                sname = "screenshot-%04d.png" % ( screenshotIndex,)
+                if not os.access(screenshotDir + '/' + sname, os.R_OK):
+                    break
+
+                screenshotIndex = screenshotIndex + 1
+                if screenshotIndex > 9999:
+                    log.error("Too many screenshots!")
+                    return
+
+            screenshot.save (screenshotDir + '/' + sname, "png")
+            screenshotIndex = screenshotIndex + 1
+
+            window = MessageWindow(_("Saving Screenshot"), 
+               _("A screenshot named '%s' has been saved.") % (sname,) ,
+               type="ok")
+    except:
+        window = MessageWindow(_("Error Saving Screenshot"), 
+                               _("An error occurred while saving "
+                                 "the screenshot.  If this occurred "
+                                 "during package installation, you may need "
+                                 "to try several times for it to succeed."),
+                               type="warning")
+
+def handleShiftPrintScrnRelease (window, event):
+    if (event.keyval == gtk.keysyms.Print and event.state & gtk.gdk.SHIFT_MASK):
+        takeScreenShot()
+        
+#
+# HACK to make treeview work
+# 
+ 
+def setupTreeViewFixupIdleHandler(view, store):
+    id = {}
+    id["id"] = gobject.idle_add(scrollToIdleHandler, (view, store, id))
+
+def scrollToIdleHandler((view, store, iddict)):
+    if not view or not store or not iddict:
+        return
+
+    try:
+        id = iddict["id"]
+    except:
+        return
+    
+    selection = view.get_selection()
+    if not selection:
+        return
+    
+    model, iter = selection.get_selected()
+    if not iter:
+        return
+
+    path = store.get_path(iter)
+    col = view.get_column(0)
+    view.scroll_to_cell(path, col, True, 0.5, 0.5)
+
+    if id:
+        gobject.source_remove(id)
+
+# setup globals
+def processEvents():
+    gtk.gdk.flush()
+    while gtk.events_pending():
+        gtk.main_iteration(False)
+
+def widgetExpander(widget, growTo=None):
+    widget.connect("size-allocate", growToParent, growTo)
+
+def growToParent(widget, rect, growTo=None):
+    if not widget.parent:
+        return
+    ignore = widget.__dict__.get("ignoreEvents")
+    if not ignore:
+        if growTo:
+            x, y, width, height = growTo.get_allocation()
+            widget.set_size_request(width, -1)
+        else:
+            widget.set_size_request(rect.width, -1)
+        widget.ignoreEvents = 1
+    else:
+        widget.ignoreEvents = 0
+
+_busyCursor = 0
+
+def setCursorToBusy(process=1):
+    root = gtk.gdk.get_default_root_window()
+    cursor = gtk.gdk.Cursor(gtk.gdk.WATCH)
+    root.set_cursor(cursor)
+    if process:
+        processEvents()
+
+def setCursorToNormal():
+    root = gtk.gdk.get_default_root_window()
+    cursor = gtk.gdk.Cursor(gtk.gdk.LEFT_PTR)
+    root.set_cursor(cursor)
+
+def rootPushBusyCursor(process=1):
+    global _busyCursor
+    _busyCursor += 1
+    if _busyCursor > 0:
+        setCursorToBusy(process)
+
+def rootPopBusyCursor():
+    global _busyCursor
+    _busyCursor -= 1
+    if _busyCursor <= 0:
+        setCursorToNormal()
+
+def getBusyCursorStatus():
+    global _busyCursor
+    
+    return _busyCursor
+
+class MnemonicLabel(gtk.Label):
+    def __init__(self, text="", alignment = None):
+        gtk.Label.__init__(self, "")
+        self.set_text_with_mnemonic(text)
+        if alignment is not None:
+            apply(self.set_alignment, alignment)
+
+class WrappingLabel(gtk.Label):
+    def __init__(self, label=""):
+        gtk.Label.__init__(self, label)
+        self.set_line_wrap(True)
+        self.ignoreEvents = 0
+        widgetExpander(self)
+
+def titleBarMousePressCB(widget, event, data):
+    if event.type & gtk.gdk.BUTTON_PRESS:
+        (x, y) = data["window"].get_position()
+        data["state"] = 1
+        data["button"] = event.button
+        data["deltax"] = event.x_root - x
+        data["deltay"] = event.y_root - y
+    
+def titleBarMouseReleaseCB(widget, event, data):
+    if data["state"] and event.button == data["button"]:
+        data["state"] = 0
+        data["button"] = 0
+        data["deltax"] = 0
+        data["deltay"] = 0
+
+def titleBarMotionEventCB(widget, event, data):
+    if data["state"]:
+        newx = event.x_root - data["deltax"]
+        newy = event.y_root - data["deltay"]
+        if newx < 0:
+            newx = 0
+        if newy < 0:
+            newy = 0
+        (w, h) = data["window"].get_size()
+        if (newx+w) > gtk.gdk.screen_width():
+            newx = gtk.gdk.screen_width() - w
+        if (newy+20) > (gtk.gdk.screen_height()):
+            newy = gtk.gdk.screen_height() - 20
+
+        data["window"].move(int(newx), int(newy))
+
+def addFrame(dialog, title=None):
+    # make screen shots work
+    dialog.connect ("key-release-event", handleShiftPrintScrnRelease)
+    if title:
+        dialog.set_title(title)
+
+def findGladeFile(file):
+    path = os.environ.get("GLADEPATH", "./:ui/:/tmp/updates/:/tmp/updates/ui/")
+    for dir in path.split(":"):
+        fn = dir + file
+        if os.access(fn, os.R_OK):
+            return fn
+    raise RuntimeError, "Unable to find glade file %s" % file
+
+def getGladeWidget(file, rootwidget, i18ndomain="anaconda"):
+    f = findGladeFile(file)
+    xml = gtk.glade.XML(f, root = rootwidget, domain = i18ndomain)
+    w = xml.get_widget(rootwidget)
+    if w is None:
+        raise RuntimeError, "Unable to find root widget %s in %s" %(rootwidget, file)
+
+    return (xml, w)
+
+def findPixmap(file):
+    path = os.environ.get("PIXMAPPATH", "./:pixmaps/:/tmp/updates/:/tmp/updates/pixmaps/")
+    for dir in path.split(":"):
+        fn = dir + file
+        if os.access(fn, os.R_OK):
+            return fn
+    return None
+
+def getPixbuf(file):
+    fn = findPixmap(file)
+    if not fn:
+        log.error("unable to load %s" %(file,))
+        return None
+
+    try:
+        pixbuf = gtk.gdk.pixbuf_new_from_file(fn)
+    except RuntimeError, msg:
+        log.error("unable to read %s: %s" %(file, msg))
+        pixbuf = None
+    
+    return pixbuf
+
+def readImageFromFile(file, width = None, height = None, dither = None,
+                      image = None):
+    pixbuf = getPixbuf(file)
+    if pixbuf is None:
+        log.warning("can't find pixmap %s" %(file,))
+        return None
+
+    if (width is not None and height is not None
+        and height != pixbuf.get_height()
+        and width != pixbuf.get_width()):
+        pixbuf = pixbuf.scale_simple(width, height,
+                                     gtk.gdk.INTERP_BILINEAR)
+
+    if image is None:
+        p = gtk.Image()
+    else:
+        p = image
+    if dither:
+        (pixmap, mask) = pixbuf.render_pixmap_and_mask()
+        pixmap.draw_pixbuf(gtk.gdk.GC(pixmap), pixbuf, 0, 0, 0, 0,
+                           pixbuf.get_width(), pixbuf.get_height(),
+                           gtk.gdk.RGB_DITHER_MAX, 0, 0)
+        p = gtk.Image()
+        p.set_from_pixmap(pixmap, mask)
+    else:
+        source = gtk.IconSource()
+        source.set_pixbuf(pixbuf)
+        source.set_size(gtk.ICON_SIZE_DIALOG)
+        source.set_size_wildcarded(False)
+        iconset = gtk.IconSet()
+        iconset.add_source(source)
+        p.set_from_icon_set(iconset, gtk.ICON_SIZE_DIALOG)
+
+    return p
+
+class WaitWindow:
+    def __init__(self, title, text, parent = None):
+        if flags.livecdInstall:
+            self.window = gtk.Window()
+            if parent:
+                self.window.set_transient_for(parent)
+        else:
+            self.window = gtk.Window()
+        self.window.set_modal(True)
+        self.window.set_type_hint (gtk.gdk.WINDOW_TYPE_HINT_DIALOG)
+        self.window.set_title(title)
+        self.window.set_position(gtk.WIN_POS_CENTER)
+        label = WrappingLabel(text)
+        box = gtk.Frame()
+        box.set_border_width(10)
+        box.add(label)
+        box.set_shadow_type(gtk.SHADOW_NONE)
+        self.window.add(box)
+        box.show_all()
+        addFrame(self.window)
+        # Displaying windows should not be done outside of the gtk
+        # mainloop. With metacity this bites us and we have to do
+        # window.show_now() AND refresh() to correctly display the window and
+        # its contents:
+        self.window.show_now()
+        rootPushBusyCursor()
+        self.refresh()
+
+    def refresh(self):
+        processEvents()
+            
+    def pop(self):
+        self.window.destroy()
+        rootPopBusyCursor()
+
+class ProgressWindow:
+    def __init__(self, title, text, total, updpct = 0.05, updsecs=10,
+                 parent = None, pulse = False):
+        if flags.livecdInstall:
+            self.window = gtk.Window()
+            if parent:
+                self.window.set_transient_for(parent)
+        else:
+            self.window = gtk.Window()
+
+        self.window.set_modal(True)
+        self.window.set_type_hint (gtk.gdk.WINDOW_TYPE_HINT_DIALOG)
+        self.window.set_title (title)
+        self.window.set_position (gtk.WIN_POS_CENTER)
+        self.lastUpdate = time.time()
+        self.updsecs = updsecs
+        box = gtk.VBox (False, 5)
+        box.set_border_width (10)
+
+        label = WrappingLabel (text)
+        label.set_alignment (0.0, 0.5)
+        box.pack_start (label, False)
+
+        self.total = total
+        self.updpct = updpct
+        self.progress = gtk.ProgressBar ()
+        box.pack_start (self.progress, True)
+        box.show_all()
+        self.window.add(box)
+        addFrame(self.window)
+        # see comment at WaitWindow.__init__():
+        self.window.show_now ()
+        rootPushBusyCursor()
+        self.refresh()
+
+    def refresh(self):
+        processEvents()
+
+    def pulse(self):
+        then = self.lastUpdate
+        now = time.time()
+        delta = now-then
+        if delta < 0.01:
+            return
+        self.progress.set_pulse_step(self.updpct)
+        self.lastUpdate = now
+        # if we've had a largish gap, some smoothing does actually help,
+        # but don't go crazy
+        if delta > 2:
+            delta=2
+        while delta > 0:
+            self.progress.pulse()
+            processEvents()
+            delta -= 0.05
+
+    def set (self, amount):
+        # only update widget if we've changed by 5% or our timeout has
+        # expired
+        curval = self.progress.get_fraction()
+        newval = float (amount) / self.total
+        then = self.lastUpdate
+        now = time.time()
+        if newval < 0.998:
+            if ((newval - curval) < self.updpct and (now-then) < self.updsecs):
+                return
+        self.lastUpdate = now
+        self.progress.set_fraction (newval)
+        processEvents ()
+
+    def pop(self):
+        self.window.destroy ()
+        rootPopBusyCursor()
+
+class InstallKeyWindow:
+    def __init__(self, anaconda, key):
+        (keyxml, self.win) = getGladeWidget("instkey.glade", "instkeyDialog")
+        if anaconda.instClass.instkeydesc is not None:
+            w = keyxml.get_widget("instkeyLabel")
+            w.set_text(_(anaconda.instClass.instkeydesc))
+
+        if not anaconda.instClass.allowinstkeyskip:
+            keyxml.get_widget("skipRadio").hide()
+
+        keyName = _(anaconda.instClass.instkeyname)
+        if anaconda.instClass.instkeyname is None:
+            keyName = _("Installation Key")
+
+        # set the install key name based on the installclass
+        for l in ("instkeyLabel", "keyEntryLabel", "skipLabel"):
+            w = keyxml.get_widget(l)
+            t = w.get_text()
+            w.set_text(t % {"instkey": keyName})
+
+        self.entry = keyxml.get_widget("keyEntry")
+        self.entry.set_text(key)
+        self.entry.set_sensitive(True)
+
+        self.keyradio = keyxml.get_widget("keyRadio")
+        self.skipradio = keyxml.get_widget("skipRadio")
+        self.rc = 0
+
+        if anaconda.instClass.skipkey:
+            self.skipradio.set_active(True)
+        else:
+            self.entry.grab_focus()
+
+        self.win.connect("key-release-event", self.keyRelease)
+        addFrame(self.win, title=keyName)        
+
+    def keyRelease(self, window, event):
+        # XXX hack: remove this, too, when the accelerators work again
+        if event.keyval == gtk.keysyms.F12:
+            window.response(1)
+
+    def run(self):
+        self.win.show()
+        self.rc = self.win.run()
+        return self.rc
+
+    def get_key(self):
+        if self.skipradio.get_active():
+            return SKIP_KEY
+        key = self.entry.get_text()
+        key.strip()
+        return key
+
+    def destroy(self):
+        self.win.destroy()
+
+class luksPassphraseWindow:
+    def __init__(self, passphrase=None, preexist = False, parent = None):
+        luksxml = gtk.glade.XML(findGladeFile("lukspassphrase.glade"),
+                                domain="anaconda",
+                                root="luksPassphraseDialog")
+        self.passphraseEntry = luksxml.get_widget("passphraseEntry")
+        self.passphraseEntry.set_visibility(False)
+        self.confirmEntry = luksxml.get_widget("confirmEntry")
+        self.confirmEntry.set_visibility(False)
+        self.win = luksxml.get_widget("luksPassphraseDialog")
+        self.okButton = luksxml.get_widget("okbutton1")
+        self.globalcheckbutton = luksxml.get_widget("globalcheckbutton")
+
+        self.isglobal = preexist
+        if not preexist:
+            self.globalcheckbutton.hide()
+        else:
+            self.globalcheckbutton.set_active(True)
+
+        self.minimumLength = 8  # arbitrary; should probably be much larger
+        if passphrase:
+            self.initialPassphrase = passphrase
+            self.passphraseEntry.set_text(passphrase)
+            self.confirmEntry.set_text(passphrase)
+        else:
+            self.initialPassphrase = ""
+
+        txt = _("Choose a passphrase for the encrypted devices. "
+                "You will be prompted for this passphrase during system "
+                "boot.")
+        luksxml.get_widget("mainLabel").set_text(txt)
+
+        if parent:
+            self.win.set_transient_for(parent)
+
+        addFrame(self.win)
+
+    def run(self):
+        self.win.show()
+        while True:
+            self.passphraseEntry.grab_focus()
+            self.rc = self.win.run()
+            if self.rc == gtk.RESPONSE_OK:
+                passphrase = self.passphraseEntry.get_text()
+                confirm = self.confirmEntry.get_text()
+                if passphrase != confirm:
+                    MessageWindow(_("Error with passphrase"),
+                                  _("The passphrases you entered were "
+                                    "different.  Please try again."),
+                                  type = "ok", custom_icon = "error")
+                    self.confirmEntry.set_text("")
+                    continue
+
+                if len(passphrase) < self.minimumLength:
+                    MessageWindow(_("Error with passphrase"),
+                                    _("The passphrase must be at least "
+                                      "eight characters long."),
+                                  type = "ok", custom_icon = "error")
+                    self.passphraseEntry.set_text("")
+                    self.confirmEntry.set_text("")
+                    continue
+
+                if self.isglobal:
+                    self.isglobal = self.globalcheckbutton.get_active()
+            else:
+                self.passphraseEntry.set_text(self.initialPassphrase)
+                self.confirmEntry.set_text(self.initialPassphrase)
+
+            return self.rc
+
+    def getPassphrase(self):
+        return self.passphraseEntry.get_text()
+
+    def getGlobal(self):
+        return self.isglobal
+
+    def getrc(self):
+        return self.rc
+
+    def destroy(self):
+        self.win.destroy()
+
+class PassphraseEntryWindow:
+    def __init__(self, device, parent = None):
+        def ok(*args):
+            self.win.response(gtk.RESPONSE_OK)
+        xml = gtk.glade.XML(findGladeFile("lukspassphrase.glade"),
+                            domain="anaconda",
+                            root="passphraseEntryDialog")
+        self.txt = _("Device %s is encrypted. In order to "
+                     "access the device's contents during "
+                     "installation you must enter the device's "
+                     "passphrase below.") % (device,)
+        self.win = xml.get_widget("passphraseEntryDialog")
+        self.passphraseLabel = xml.get_widget("passphraseLabel")
+        self.passphraseEntry = xml.get_widget("passphraseEntry2")
+        self.globalcheckbutton = xml.get_widget("globalcheckbutton")
+
+        if parent:
+            self.win.set_transient_for(parent)
+
+        self.passphraseEntry.connect('activate', ok)
+        addFrame(self.win)
+
+    def run(self):
+        self.win.show()
+        self.passphraseLabel.set_text(self.txt)
+        self.passphraseEntry.grab_focus()
+
+        busycursor = getBusyCursorStatus()
+        setCursorToNormal()
+
+        rc = self.win.run()
+        passphrase = None
+        isglobal = False
+        if rc == gtk.RESPONSE_OK:
+            passphrase = self.passphraseEntry.get_text()
+            isglobal = self.globalcheckbutton.get_active()
+
+        if busycursor:
+            setCursorToBusy()
+
+        self.rc = (passphrase, isglobal)
+        return self.rc
+
+    def getrc(self):
+        return self.rc
+
+    def destroy(self):
+        self.win.destroy()
+
+class MessageWindow:
+    def getrc (self):
+        return self.rc
+
+    def __init__ (self, title, text, type="ok", default=None, custom_buttons=None, custom_icon=None, run = True, parent = None, destroyAfterRun = True):
+        self.debugRid = None
+        self.title = title
+        if flags.autostep:
+            self.rc = 1
+            return
+        self.rc = None
+        self.framed = False
+        self.doCustom = False
+
+        style = 0
+        if type == 'ok':
+            buttons = gtk.BUTTONS_OK
+            style = gtk.MESSAGE_INFO
+        elif type == 'warning':
+            buttons = gtk.BUTTONS_OK
+            style = gtk.MESSAGE_WARNING
+        elif type == 'okcancel':
+            buttons = gtk.BUTTONS_OK_CANCEL
+            style = gtk.MESSAGE_WARNING
+        elif type == 'yesno':
+            buttons = gtk.BUTTONS_YES_NO
+            style = gtk.MESSAGE_QUESTION
+        elif type == 'custom':
+            self.doCustom = True
+            buttons = gtk.BUTTONS_NONE
+            style = gtk.MESSAGE_QUESTION
+
+        if custom_icon == "warning":
+            style = gtk.MESSAGE_WARNING
+        elif custom_icon == "question":
+            style = gtk.MESSAGE_QUESTION
+        elif custom_icon == "error":
+            style = gtk.MESSAGE_ERROR
+        elif custom_icon == "info":
+            style = gtk.MESSAGE_INFO
+
+        self.dialog = gtk.MessageDialog(mainWindow, 0, style, buttons, str(text))
+
+        if parent:
+            self.dialog.set_transient_for(parent)
+
+        if self.doCustom:
+            rid=0
+            for button in custom_buttons:
+                if button == _("Cancel"):
+                    tbutton = "gtk-cancel"
+                else:
+                    tbutton = button
+
+                widget = self.dialog.add_button(tbutton, rid)
+                rid = rid + 1
+
+            if default is not None:
+                defaultchoice = default
+            else:
+                defaultchoice = rid - 1
+            if flags.debug and not _("_Debug") in custom_buttons:
+                widget = self.dialog.add_button(_("_Debug"), rid)
+                self.debugRid = rid
+                rid += 1
+
+        else:
+            if default == "no":
+                defaultchoice = 0
+            elif default == "yes" or default == "ok":
+                defaultchoice = 1
+            else:
+                defaultchoice = 0
+
+        self.dialog.set_position (gtk.WIN_POS_CENTER)
+        self.dialog.set_default_response(defaultchoice)
+        if run:
+            self.run(destroyAfterRun)
+
+    def run(self, destroy = False):
+        if not self.framed:
+            addFrame(self.dialog, title=self.title)
+            self.framed = True
+        self.dialog.show_all ()
+
+        # XXX - Messy - turn off busy cursor if necessary
+        busycursor = getBusyCursorStatus()
+        setCursorToNormal()
+        self.rc = self.dialog.run()
+
+        if not self.doCustom:
+            if self.rc in [gtk.RESPONSE_OK, gtk.RESPONSE_YES]:
+                self.rc = 1
+            elif self.rc in [gtk.RESPONSE_CANCEL, gtk.RESPONSE_NO,
+                             gtk.RESPONSE_CLOSE, gtk.RESPONSE_DELETE_EVENT]:
+                self.rc = 0
+        else:
+            # generated by Esc key
+            if self.rc == gtk.RESPONSE_DELETE_EVENT:
+                self.rc = 0
+
+        if not self.debugRid is None and self.rc == self.debugRid:
+            self.debugClicked(self)
+            return self.run(destroy)
+
+        if destroy:
+            self.dialog.destroy()
+
+        # restore busy cursor
+        if busycursor:
+            setCursorToBusy()
+
+    def debugClicked (self, *args):
+        try:
+            # switch to VC1 so we can debug
+            isys.vtActivate (1)
+        except SystemError:
+            pass
+        import pdb
+        try:
+            pdb.set_trace()
+        except:
+            sys.exit(-1)
+        try:
+            # switch back
+            isys.vtActivate (6)
+        except SystemError:
+            pass
+
+class DetailedMessageWindow(MessageWindow):
+    def __init__(self, title, text, longText=None, type="ok", default=None, custom_buttons=None, custom_icon=None, run=True, parent=None, destroyAfterRun=True, expanded=False):
+        self.title = title
+
+        if flags.autostep:
+            self.rc = 1
+            return
+
+        self.debugRid = None
+        self.rc = None
+        self.framed = False
+        self.doCustom = False
+
+        if type == 'ok':
+            buttons = ["gtk-ok"]
+        elif type == 'warning':
+            buttons = ["gtk-ok"]
+        elif type == 'okcancel':
+            buttons = ["gtk-ok", "gtk-cancel"]
+        elif type == 'yesno':
+            buttons = ["gtk-yes", "gtk-no"]
+        elif type == 'custom':
+            self.doCustom = True
+            buttons = custom_buttons
+
+        xml = gtk.glade.XML(findGladeFile("detailed-dialog.glade"), domain="anaconda")
+        self.dialog = xml.get_widget("detailedDialog")
+        self.mainVBox = xml.get_widget("mainVBox")
+        self.hbox = xml.get_widget("hbox1")
+        self.info = xml.get_widget("info")
+        self.detailedExpander = xml.get_widget("detailedExpander")
+        self.detailedView = xml.get_widget("detailedView")
+
+        self.detailedExpander.set_expanded(expanded)
+
+        if parent:
+            self.dialog.set_transient_for(parent)
+
+        if custom_icon:
+            img = gtk.Image()
+            img.set_from_file(custom_icon)
+            self.hbox.pack_start(img)
+            self.hbox.reorder_child(img, 0)
+
+        rid = 0
+        for button in buttons:
+            self.dialog.add_button(button, rid)
+            rid += 1
+
+        if self.doCustom:
+            defaultchoice = rid-1
+            if flags.debug and not _("_Debug") in buttons:
+                self.dialog.add_button(_("_Debug"), rid)
+                self.debugRid = rid
+                rid += 1
+        else:
+            if default == "no":
+                defaultchoice = 0
+            elif default == "yes" or default == "ok":
+                defaultchoice = 1
+            else:
+                defaultchoice = 0
+
+        self.info.set_text(text)
+
+        if longText:
+            textbuf = gtk.TextBuffer()
+            iter = textbuf.get_start_iter()
+
+            for line in longText:
+                if __builtins__.get("type")(line) != unicode:
+                    try:
+                        line = unicode(line, encoding='utf-8')
+                    except UnicodeDecodeError, e:
+                        log.error("UnicodeDecodeException: line = %s" % (line,))
+                        log.error("UnicodeDecodeException: %s" % (str(e),))
+
+                textbuf.insert(iter, line)
+
+            self.detailedView.set_buffer(textbuf)
+        else:
+            self.mainVBox.remove(self.detailedExpander)
+
+        self.dialog.set_position (gtk.WIN_POS_CENTER)
+        self.dialog.set_default_response(defaultchoice)
+
+        if run:
+            self.run(destroyAfterRun)
+
+class EntryWindow(MessageWindow):
+    def __init__ (self, title, text, prompt, entrylength = None):
+        mainWindow = None
+        MessageWindow.__init__(self, title, text, type = "okcancel", custom_icon="question", run = False)
+        self.entry = gtk.Entry()
+        if entrylength:
+            self.entry.set_width_chars(entrylength)
+            self.entry.set_max_length(entrylength)
+
+        # eww, eww, eww... but if we pack in the vbox, it goes to the right
+        # place!
+        self.dialog.child.pack_start(self.entry)
+
+    def run(self):
+        MessageWindow.run(self)
+        if self.rc == 0:
+            return None
+        t = self.entry.get_text()
+        t.strip()
+        if len(t) == 0:
+            return None
+        return t
+
+    def destroy(self):
+        self.dialog.destroy()
+
+class InstallInterface(InstallInterfaceBase):
+    def __init__ (self):
+        InstallInterfaceBase.__init__(self)
+        self.icw = None
+        self.installProgress = None
+
+        # figure out if we want to run interface at 800x600 or 640x480
+        if gtk.gdk.screen_width() >= 800:
+            self.runres = "800x600"
+        else:
+            self.runres = "640x480"
+        root = gtk.gdk.get_default_root_window()
+        cursor = gtk.gdk.Cursor(gtk.gdk.LEFT_PTR)
+        root.set_cursor(cursor)
+        self._initLabelAnswers = {}
+        self._inconsistentLVMAnswers = {}
+
+    def __del__ (self):
+        pass
+
+    def shutdown (self):
+        pass
+
+    def suspend(self):
+        pass
+    
+    def resume(self):
+        pass
+
+    def enableNetwork(self):
+        if len(self.anaconda.network.netdevices) == 0:
+            return False
+        from netconfig_dialog import NetworkConfigurator
+        net = NetworkConfigurator(self.anaconda.network)
+        ret = net.run()
+        net.destroy()
+
+        return ret not in [gtk.RESPONSE_CANCEL, gtk.RESPONSE_DELETE_EVENT]
+
+    def setInstallProgressClass(self, c):
+        self.instProgress = c
+
+    def setPackageProgressWindow (self, ppw):
+        self.ppw = ppw
+
+    def waitWindow (self, title, text):
+        if self.icw:
+            return WaitWindow (title, text, self.icw.window)
+        else:
+            return WaitWindow (title, text)
+
+    def progressWindow (self, title, text, total, updpct = 0.05, pulse = False):
+        if self.icw:
+            return ProgressWindow (title, text, total, updpct,
+                                   parent = self.icw.window, pulse = pulse)
+        else:
+            return ProgressWindow (title, text, total, updpct, pulse = pulse)
+
+    def messageWindow(self, title, text, type="ok", default = None,
+             custom_buttons=None,  custom_icon=None):
+        if self.icw:
+            parent = self.icw.window
+        else:
+            parent = None
+
+        rc = MessageWindow (title, text, type, default,
+                custom_buttons, custom_icon, run=True, parent=parent).getrc()
+        return rc
+
+    def createRepoWindow(self):
+        from task_gui import RepoCreator
+        dialog = RepoCreator(self.anaconda)
+        dialog.createDialog()
+        dialog.run()
+
+    def editRepoWindow(self, repoObj):
+        from task_gui import RepoEditor
+        dialog = RepoEditor(self.anaconda, repoObj)
+        dialog.createDialog()
+        dialog.run()
+
+    def methodstrRepoWindow(self, methodstr):
+        from task_gui import RepoMethodstrEditor
+        dialog = RepoMethodstrEditor(self.anaconda, methodstr)
+        dialog.createDialog()
+        return dialog.run()
+
+    def entryWindow(self, title, text, type="ok", entrylength = None):
+        d = EntryWindow(title, text, type, entrylength)
+        rc = d.run()
+        d.destroy()
+        return rc
+
+    def detailedMessageWindow(self, title, text, longText=None, type="ok",
+                              default=None, custom_buttons=None,
+                              custom_icon=None, expanded=False):
+        if self.icw:
+            parent = self.icw.window
+        else:
+            parent = None
+
+        rc = DetailedMessageWindow (title, text, longText, type, default,
+                                    custom_buttons, custom_icon, run=True,
+                                    parent=parent, expanded=expanded).getrc()
+        return rc
+
+    def mainExceptionWindow(self, shortText, longTextFile):
+        from meh.ui.gui import MainExceptionWindow
+        log.critical(shortText)
+        win = MainExceptionWindow (shortText, longTextFile)
+        addFrame(win.dialog)
+        return win
+
+    def saveExceptionWindow(self, accountManager, signature):
+        from meh.ui.gui import SaveExceptionWindow
+        win = SaveExceptionWindow (accountManager, signature)
+        win.run()
+
+    def exitWindow(self, title, text):
+        if self.icw:
+            parent = self.icw.window
+        else:
+            parent = None
+
+        rc = MessageWindow (title, text, type="custom",
+                            custom_icon="info", parent=parent,
+                            custom_buttons=[_("_Exit installer")]).getrc()
+        return rc
+
+    def getLuksPassphrase(self, passphrase = "", preexist = False):
+        if self.icw:
+            parent = self.icw.window
+        else:
+            parent = None
+
+        d = luksPassphraseWindow(passphrase, parent = parent,
+                                 preexist = preexist)
+        rc = d.run()
+        passphrase = d.getPassphrase()
+        isglobal = d.getGlobal()
+        d.destroy()
+        return (passphrase, isglobal)
+
+    def passphraseEntryWindow(self, device):
+        if self.icw:
+            parent = self.icw.window
+        else:
+            parent = None
+
+        d = PassphraseEntryWindow(device, parent = parent)
+        rc = d.run()
+        d.destroy()
+        return rc
+
+    def resetInitializeDiskQuestion(self):
+        self._initLabelAnswers = {}
+
+    def questionInitializeDisk(self, path, description, size, details=""):
+
+        retVal = False # The less destructive default
+
+        if not path:
+            return retVal
+
+        # we are caching answers so that we don't
+        # ask in each storage.reset() again
+        if path in self._initLabelAnswers:
+            log.info("UI not asking about disk initialization, "
+                     "using cached answer: %s" % self._initLabelAnswers[path])
+            return self._initLabelAnswers[path]
+        elif "all" in self._initLabelAnswers:
+            log.info("UI not asking about disk initialization, "
+                     "using cached answer: %s" % self._initLabelAnswers["all"])
+            return self._initLabelAnswers["all"]
+
+        rc = self.messageWindow(_("Warning"),
+                _("Error processing drive:\n\n"
+                  "%(path)s\n%(size)-0.fMB\n%(description)s\n\n"
+                  "This device may need to be reinitialized.\n\n"
+                  "REINITIALIZING WILL CAUSE ALL DATA TO BE LOST!\n\n"
+                  "This action may also be applied to all other disks "
+                  "needing reinitialization.%(details)s")
+                % {'path': path, 'size': size,
+                   'description': description, 'details': details},
+                type="custom",
+                custom_buttons = [ _("_Ignore"),
+                                   _("Ignore _all"),
+                                   _("_Re-initialize"),
+                                   _("Re-ini_tialize all") ],
+                custom_icon="question")
+        if rc == 0:
+            retVal = False
+        elif rc == 1:
+            path = "all"
+            retVal = False
+        elif rc == 2:
+            retVal = True
+        elif rc == 3:
+            path = "all"
+            retVal = True
+
+        self._initLabelAnswers[path] = retVal
+        return retVal
+
+    def resetReinitInconsistentLVMQuestion(self):
+        self._inconsistentLVMAnswers = {}
+
+    def questionReinitInconsistentLVM(self, pv_names=None, lv_name=None, vg_name=None):
+
+        retVal = False # The less destructive default
+        allSet = frozenset(["all"])
+
+        if not pv_names or (lv_name is None and vg_name is None):
+            return retVal
+
+        # We are caching answers so that we don't ask for ignoring
+        # in each storage.reset() again (note that reinitialization is
+        # done right after confirmation in dialog, not as a planned
+        # action).
+        key = frozenset(pv_names)
+        if key in self._inconsistentLVMAnswers:
+            log.info("UI not asking about disk initialization, "
+                     "using cached answer: %s" % self._inconsistentLVMAnswers[key])
+            return self._inconsistentLVMAnswers[key]
+        elif allSet in self._inconsistentLVMAnswers:
+            log.info("UI not asking about disk initialization, "
+                     "using cached answer: %s" % self._inconsistentLVMAnswers[allSet])
+            return self._inconsistentLVMAnswers[allSet]
+
+        if vg_name is not None:
+            message = "Volume Group %s" % vg_name
+        elif lv_name is not None:
+            message = "Logical Volume %s" % lv_name
+
+        na = {'msg': message, 'pvs': ", ".join(pv_names)}
+        rc = self.messageWindow(_("Warning"),
+                  _("Error processing LVM.\n"
+                    "There is inconsistent LVM data on %(msg)s.  You can "
+                    "reinitialize all related PVs (%(pvs)s) which will erase "
+                    "the LVM metadata, or ignore which will preserve the "
+                    "contents.  This action may also be applied to all other "
+                    "PVs with inconsistent metadata.") % na,
+                type="custom",
+                custom_buttons = [ _("_Ignore"),
+                                   _("Ignore _all"),
+                                   _("_Re-initialize"),
+                                   _("Re-ini_tialize all") ],
+                custom_icon="question")
+        if rc == 0:
+            retVal = False
+        elif rc == 1:
+            key = allSet
+            retVal = False
+        elif rc == 2:
+            retVal = True
+        elif rc == 3:
+            key = allSet
+            retVal = True
+
+        self._inconsistentLVMAnswers[key] = retVal
+        return retVal
+
+    def beep(self):
+        gtk.gdk.beep()
+
+    def kickstartErrorWindow(self, text):
+        s = _("The following error was found while parsing the "
+              "kickstart configuration file:\n\n%s") %(text,)
+        return self.messageWindow(_("Error Parsing Kickstart Config"),
+                                  s,
+                                  type = "custom",
+                                  custom_buttons = [_("_Exit installer")],
+                                  custom_icon = "error")
+
+    def getBootdisk (self):
+        return None
+
+    def run(self, anaconda):
+        self.anaconda = anaconda
+
+        if anaconda.keyboard and not flags.livecdInstall:
+            anaconda.keyboard.activate()
+
+        self.icw = InstallControlWindow (self.anaconda)
+        self.icw.run (self.runres)
+
+    def setSteps(self, anaconda):
+        pass
+
+class InstallControlWindow:
+    def setLanguage (self):
+        if not self.__dict__.has_key('window'): return
+        self.reloadRcQueued = 1
+        self.setup_window(True)
+
+    def setLtR(self):
+        ltrrtl = gettext.dgettext("gtk20", "default:LTR")
+        if ltrrtl == "default:RTL":
+            gtk.widget_set_default_direction (gtk.TEXT_DIR_RTL)
+        elif ltrrtl == "default:LTR":
+            gtk.widget_set_default_direction (gtk.TEXT_DIR_LTR)
+        else:
+            log.error("someone didn't translate the ltr bits right: %s" %(ltrrtl,))
+            gtk.widget_set_default_direction (gtk.TEXT_DIR_LTR)            
+        
+    def prevClicked (self, *args):
+        try:
+            self.currentWindow.getPrev ()
+        except StayOnScreen:
+            return
+
+        self.anaconda.dispatch.gotoPrev()
+        self.setScreen ()
+
+    def nextClicked (self, *args):
+        try:
+            rc = self.currentWindow.getNext ()
+        except StayOnScreen:
+            return
+
+        self.anaconda.dispatch.gotoNext()
+        self.setScreen ()
+
+    def debugClicked (self, *args):
+        try:
+            # switch to VC1 so we can debug
+            isys.vtActivate (1)
+        except SystemError:
+            pass
+        import pdb
+        try:
+            pdb.set_trace()
+        except:
+            sys.exit(-1)
+        try:
+            # switch back
+            isys.vtActivate (6)
+        except SystemError:
+            pass
+
+    def handleRenderCallback(self):
+        self.currentWindow.renderCallback()
+        if flags.autostep:
+            if flags.autoscreenshot:
+                # let things settle down graphically
+                processEvents()
+                time.sleep(1)
+                takeScreenShot()
+            self.nextClicked()
+        else:
+            gobject.source_remove(self.handle)
+
+    def setScreen (self):
+        (step, anaconda) = self.anaconda.dispatch.currentStep()
+        if step is None:
+            gtk.main_quit()
+            return
+
+        if not stepToClass[step]:
+            if self.anaconda.dispatch.dir == DISPATCH_FORWARD:
+                return self.nextClicked()
+            else:
+                return self.prevClicked()
+
+        (file, className) = stepToClass[step]
+        newScreenClass = None
+
+        while True:
+            try:
+                found = imputil.imp.find_module(file)
+                loaded = imputil.imp.load_module(className, found[0], found[1],
+                                                 found[2])
+                newScreenClass = loaded.__dict__[className]
+                break
+            except ImportError, e:
+                print(e)
+                win = MessageWindow(_("Error!"),
+                                    _("An error occurred when attempting "
+                                      "to load an installer interface "
+                                      "component.\n\nclassName = %s")
+                                    % (className,),
+                                    type="custom", custom_icon="warning",
+                                    custom_buttons=[_("_Exit"),
+                                                    _("_Retry")])
+                if not win.getrc():
+                    msg =  _("The system will now reboot.")
+                    buttons = [_("_Reboot")]
+
+                    MessageWindow(_("Exiting"),
+                                  msg,
+                                  type="custom",
+                                  custom_icon="warning",
+                                  custom_buttons=buttons)
+                    sys.exit(0)
+
+        ics = InstallControlState (self)
+        ics.setPrevEnabled(self.anaconda.dispatch.canGoBack())
+        self.destroyCurrentWindow()
+        self.currentWindow = newScreenClass(ics)
+
+        new_screen = self.currentWindow.getScreen(anaconda)
+
+        # If the getScreen method returned None, that means the screen did not
+        # want to be displayed for some reason and we should skip to the next
+        # step.  However, we do not want to remove the current step from the
+        # list as later events may cause the screen to be displayed.
+        if not new_screen:
+            if self.anaconda.dispatch.dir == DISPATCH_FORWARD:
+                self.anaconda.dispatch.gotoNext()
+            else:
+                self.anaconda.dispatch.gotoPrev()
+
+            return self.setScreen()
+
+        self.update (ics)
+
+        self.installFrame.add(new_screen)
+        self.installFrame.show_all()
+
+        self.currentWindow.focus()
+
+        self.handle = gobject.idle_add(self.handleRenderCallback)
+
+        if self.reloadRcQueued:
+            self.window.reset_rc_styles()
+            self.reloadRcQueued = 0
+
+    def destroyCurrentWindow(self):
+        children = self.installFrame.get_children ()
+        if children:
+            child = children[0]
+            self.installFrame.remove (child)
+            child.destroy ()
+        self.currentWindow = None
+
+    def update (self, ics):
+        self.mainxml.get_widget("backButton").set_sensitive(ics.getPrevEnabled())
+        self.mainxml.get_widget("nextButton").set_sensitive(ics.getNextEnabled())
+
+        if ics.getGrabNext():
+            self.mainxml.get_widget("nextButton").grab_focus()
+
+        self.mainxml.get_widget("nextButton").set_flags(gtk.HAS_DEFAULT)
+
+    def __init__ (self, anaconda):
+        self.reloadRcQueued = 0
+        self.currentWindow = None
+        self.anaconda = anaconda
+        self.handle = None
+        self.window = None
+
+    def keyRelease (self, window, event):
+        if ((event.keyval == gtk.keysyms.KP_Delete
+             or event.keyval == gtk.keysyms.Delete)
+            and (event.state & (gtk.gdk.CONTROL_MASK | gtk.gdk.MOD1_MASK))):
+            self._doExit()
+        # XXX hack: remove me when the accelerators work again.
+        elif (event.keyval == gtk.keysyms.F12
+              and self.currentWindow.getICS().getNextEnabled()):
+            self.nextClicked()
+        elif (event.keyval == gtk.keysyms.Print
+              and event.state & gtk.gdk.SHIFT_MASK):
+            takeScreenShot()
+
+    def _doExit (self, *args):
+        gtk.main_quit()
+        os._exit(0)
+
+    def _doExitConfirm (self, win = None, *args):
+        # FIXME: translate the string
+        win = MessageWindow(_("Exit installer"),
+                            _("Are you sure you wish to exit the installer?"),
+                            type="custom", custom_icon="question",
+                            custom_buttons = [_("Cancel"), _("_Exit installer")],
+                            parent = win)
+        if win.getrc() == 0:
+            return True
+        self._doExit()
+
+    def createWidgets (self):
+        self.window.set_title(_("%s Installer") %(productName,))
+        
+        i = self.mainxml.get_widget("headerImage")        
+        p = readImageFromFile("anaconda_header.png",
+                              dither = False, image = i)
+        if p is None:
+            print(_("Unable to load title bar"))
+        if (gtk.gdk.screen_height() < 600) or \
+                (gtk.gdk.screen_height() <= 675 and flags.livecdInstall):
+            i.hide()
+            self.window.set_resizable(True)
+            self.window.set_size_request(-1, -1)
+            self.window.fullscreen()
+        else:
+            self.window.set_size_request(800, 600)
+            # if we're running in the live mode and the dpi is something weird,
+            # give ourselves as much space as we can.  this gets things to fit
+            # with a dpi of up to 147
+            if flags.livecdInstall:
+                i.hide()
+            elif flags.preexisting_x11:
+                # running on a pre-existing X, probably through X11 forwarding
+                pass 
+            else:
+                self.window.set_type_hint(gtk.gdk.WINDOW_TYPE_HINT_DESKTOP)
+
+        if flags.debug:
+            self.mainxml.get_widget("debugButton").show_now()
+        self.installFrame = self.mainxml.get_widget("installFrame")
+
+    def connectSignals(self):
+        sigs = { "on_nextButton_clicked": self.nextClicked,
+            "on_rebootButton_clicked": self._doExit,
+            "on_closeButton_clicked": self._doExit,                 
+            "on_backButton_clicked": self.prevClicked,
+            "on_debugButton_clicked": self.debugClicked,
+            "on_mainWindow_key_release_event": self.keyRelease,
+            "on_mainWindow_delete_event": self._doExitConfirm, }
+        self.mainxml.signal_autoconnect(sigs)
+
+    def loadGlade(self):
+        self.mainxml = gtk.glade.XML(findGladeFile("anaconda.glade"),
+                                     domain="anaconda")
+
+    def setup_theme(self):
+        settings = gtk.settings_get_default()
+        settings.set_long_property("gtk-button-images", 0, "gui.py:setup_theme")
+
+    def setup_window (self, window_reload):
+        self.setLtR()
+
+        if window_reload:
+            self.window.destroy()
+
+        self.loadGlade()
+        self.window = self.mainxml.get_widget("mainWindow")
+
+        self.createWidgets()
+        self.connectSignals()
+        self.setScreen()
+        self.window.show()
+        # calling present() will focus the window in the winodw manager so
+        # the mnemonics work without additional clicking
+        self.window.present()
+            
+    def busyCursorPush(self):
+        rootPushBusyCursor()
+        
+    def busyCursorPop(self):
+        rootPopBusyCursor()
+        
+    def run (self, runres):
+        self.setup_theme()
+        self.setup_window(False)
+        gtk.main()
+            
+class InstallControlState:
+    def __init__ (self, cw):
+        self.cw = cw
+        self.prevEnabled = True
+        self.nextEnabled = True
+        self.title = _("Install Window")
+        self.grabNext = True
+
+    def setTitle (self, title):
+        self.title = title
+        self.cw.update (self)
+        
+    def getTitle (self):
+        return self.title
+
+    def setPrevEnabled (self, value):
+        if value == self.prevEnabled: return
+        self.prevEnabled = value
+        self.cw.update (self)
+
+    def getPrevEnabled (self):
+        return self.prevEnabled
+    
+    def setNextEnabled (self, value):
+        if value == self.nextEnabled: return
+        self.nextEnabled = value
+        self.cw.update (self)
+
+    def getNextEnabled (self):
+        return self.nextEnabled
+
+    def setScreenPrev (self):
+        self.cw.prevClicked ()
+
+    def setScreenNext (self):
+        self.cw.nextClicked ()
+
+    def setGrabNext (self, value):
+        self.grabNext = value
+        self.cw.update (self)
+
+    def getGrabNext (self):
+        return self.grabNext
+
+    def getICW (self):
+        return self.cw
diff --git a/pyanaconda/image.py b/pyanaconda/image.py
new file mode 100644
index 0000000..60f03aa
--- /dev/null
+++ b/pyanaconda/image.py
@@ -0,0 +1,326 @@
+#
+# image.py: Support methods for CD/DVD and ISO image installations.
+#
+# Copyright (C) 2007  Red Hat, Inc.  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 as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# 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, see <http://www.gnu.org/licenses/>.
+#
+
+import isys, iutil
+import os, os.path, stat, string, sys
+from constants import *
+
+import gettext
+_ = lambda x: gettext.ldgettext("anaconda", x)
+
+import logging
+log = logging.getLogger("anaconda")
+
+_arch = iutil.getArch()
+
+def findIsoImages(path, messageWindow):
+    flush = os.stat(path)
+    files = os.listdir(path)
+    arch = _arch
+    discImages = {}
+
+    for file in files:
+        what = path + '/' + file
+        if not isys.isIsoImage(what):
+            continue
+
+        try:
+            isys.losetup("/dev/loop2", what, readOnly = 1)
+        except SystemError:
+            continue
+
+        try:
+            isys.mount("/dev/loop2", "/mnt/cdimage", fstype = "iso9660",
+                       readOnly = True)
+            for num in range(1, 10):
+                if os.access("/mnt/cdimage/.discinfo", os.R_OK):
+                    f = open("/mnt/cdimage/.discinfo")
+                    try:
+                        f.readline() # skip timestamp
+                        f.readline() # skip release description
+                        discArch = string.strip(f.readline()) # read architecture
+                        discNum = getDiscNums(f.readline().strip())
+                    except:
+                        discArch = None
+                        discNum = [ 0 ]
+
+                    f.close()
+
+                    if num not in discNum or discArch != arch:
+                        continue
+
+                    # if it's disc1, it needs to have images/install.img
+                    if (num == 1 and not
+                        os.access("/mnt/cdimage/images/install.img", os.R_OK)):
+                        log.warning("%s doesn't have a install.img, skipping" %(what,))
+                        continue
+                    # we only install binary packages, so let's look for a
+                    # product/ dir and hope that this avoids getting
+                    # discs from the src.rpm set
+                    if not os.path.isdir("/mnt/cdimage/%s" %(productPath,)):
+                        log.warning("%s doesn't have binary RPMS, skipping" %(what,))
+                        continue
+
+                    # warn user if images appears to be wrong size
+                    if os.stat(what)[stat.ST_SIZE] % 2048:
+                        rc = messageWindow(_("Warning"),
+                             _("The ISO image %s has a size which is not "
+                               "a multiple of 2048 bytes.  This may mean "
+                               "it was corrupted on transfer to this computer."
+                               "\n\n"
+                               "It is recommended that you exit and abort your "
+                               "installation, but you can choose to continue if "
+                               "you think this is in error.") % (file,),
+                               type="custom", custom_icon="warning",
+                               custom_buttons= [_("_Exit installer"),
+                                                _("_Continue")])
+                        if rc == 0:
+                            sys.exit(0)
+
+                    discImages[num] = file
+
+            isys.umount("/mnt/cdimage", removeDir=False)
+        except SystemError:
+            pass
+
+        isys.unlosetup("/dev/loop2")
+
+    return discImages
+
+def getDiscNums(line):
+    # get the disc numbers for this disc
+    nums = line.split(",")
+    if nums == ['ALL']: # Treat "ALL" DVD as disc 1
+        return [1]
+    discNums = []
+    for num in nums:
+        discNums.append(int(num))
+    return discNums
+
+def getMediaId(path):
+    if os.access("%s/.discinfo" % path, os.R_OK):
+        f = open("%s/.discinfo" % path)
+        newStamp = f.readline().strip()
+        f.close()
+
+        return newStamp
+    else:
+        return None
+
+# This mounts the directory containing the iso images, and places the
+# mount point in /mnt/isodir.
+def mountDirectory(methodstr, messageWindow):
+    if methodstr.startswith("hd:"):
+        method = methodstr[3:]
+        if method.count(":") == 1:
+            (device, path) = method.split(":")
+            fstype = "auto"
+        else:
+            (device, fstype, path) = method.split(":")
+
+        if not device.startswith("/dev/") and not device.startswith("UUID=") \
+           and not device.startswith("LABEL="):
+            device = "/dev/%s" % device
+    elif methodstr.startswith("nfsiso:"):
+        device = methodstr[7:]
+        fstype = "nfs"
+    else:
+        return
+
+    # No need to mount it again.
+    if os.path.ismount("/mnt/isodir"):
+        return
+
+    while True:
+        try:
+            isys.mount(device, "/mnt/isodir", fstype = fstype)
+            break
+        except SystemError, msg:
+            log.error("couldn't mount ISO source directory: %s" % msg)
+            ans = messageWindow(_("Couldn't Mount ISO Source"),
+                          _("An error occurred mounting the source "
+                            "device %s.  This may happen if your ISO "
+                            "images are located on an advanced storage "
+                            "device like LVM or RAID, or if there was a "
+                            "problem mounting a partition.  Click exit "
+                            "to abort the installation.")
+                          % (device,), type="custom", custom_icon="error",
+                          custom_buttons=[_("_Exit"), _("_Retry")])
+
+            if ans == 0:
+                sys.exit(0)
+            else:
+                continue
+
+def mountImage(isodir, tree, discnum, messageWindow, discImages={}):
+    if os.path.ismount(tree):
+        raise SystemError, "trying to mount already-mounted iso image!"
+
+    if discImages == {}:
+        discImages = findIsoImages(isodir, messageWindow)
+
+    while True:
+        try:
+            isoImage = "%s/%s" % (isodir, discImages[discnum])
+            isys.losetup("/dev/loop1", isoImage, readOnly = 1)
+            isys.mount("/dev/loop1", tree, fstype = 'iso9660', readOnly = True)
+            break
+        except:
+            ans = messageWindow(_("Missing ISO 9660 Image"),
+                                _("The installer has tried to mount "
+                                  "image #%s, but cannot find it on "
+                                  "the hard drive.\n\n"
+                                  "Please copy this image to the "
+                                  "drive and click Retry.  Click Exit "
+                                  "to abort the installation.")
+                                  % (discnum,), type="custom",
+                                  custom_icon="warning",
+                                  custom_buttons=[_("_Exit"), _("_Retry")])
+            if ans == 0:
+                sys.exit(0)
+            elif ans == 1:
+                discImages = findIsoImages(isodir, messageWindow)
+
+    return discImages
+
+# given groupset containing information about selected packages, use
+# the disc number info in the headers to come up with message describing
+# the required CDs
+#
+# dialog returns a value of 0 if user selected to abort install
+def presentRequiredMediaMessage(anaconda):
+    reqcds = anaconda.backend.getRequiredMedia()
+
+    # if only one CD required no need to pop up a message
+    if len(reqcds) < 2:
+        return
+
+    # check what discs our currently mounted one provides
+    if os.access("%s/.discinfo" % anaconda.backend.ayum.tree, os.R_OK):
+        discNums = []
+        try:
+            f = open("%s/.discinfo" % anaconda.backend.ayum.tree)
+            stamp = f.readline().strip()
+            descr = f.readline().strip()
+            arch = f.readline().strip()
+            discNums = getDiscNums(f.readline().strip())
+            f.close()
+        except Exception, e:
+            log.critical("Exception reading discinfo: %s" %(e,))
+
+        log.info("discNums is %s" %(discNums,))
+        haveall = 0
+        s = set(reqcds)
+        t = set(discNums)
+        if s.issubset(t):
+            haveall = 1
+
+        if haveall == 1:
+            return
+
+    reqcds.sort()
+    reqcds = map(lambda disc: "#%s" % disc, filter(lambda disc: disc != -99, reqcds))
+    reqcdstr = ", ".join(reqcds)
+
+    return anaconda.intf.messageWindow(_("Required Install Media"),
+               _("The software you have selected to install will require the "
+                 "following %(productName)s %(productVersion)s "
+                 "discs:\n\n%(reqcdstr)s\nPlease have these ready "
+                 "before proceeding with the installation.  If you need to "
+                 "abort the installation and exit please select "
+                 "\"Reboot\".") % {'productName': product.productName,
+                                   'productVersion': product.productVersion,
+                                   'reqcdstr': reqcdstr},
+                 type="custom", custom_icon="warning",
+                 custom_buttons=[_("_Reboot"), _("_Back"), _("_Continue")])
+
+# Find an attached CD/DVD drive with media in it that contains packages,
+# and return that device name.
+def scanForMedia(tree, storage):
+    for dev in storage.devicetree.devices:
+        if dev.type != "cdrom":
+            continue
+
+        storage.devicetree.updateDeviceFormat(dev)
+        try:
+            dev.format.mount(mountpoint=tree)
+        except:
+            continue
+
+        if not verifyMedia(tree, 1):
+            dev.format.unmount()
+            continue
+
+        return dev.name
+
+    return None
+
+def umountImage(tree, currentMedia):
+    if currentMedia is not None:
+        isys.umount(tree, removeDir=False)
+        isys.unlosetup("/dev/loop1")
+
+def unmountCD(dev, messageWindow):
+    if not dev:
+        return
+
+    while True:
+        try:
+            dev.format.unmount()
+            break
+        except Exception, e:
+            log.error("exception in _unmountCD: %s" %(e,))
+            messageWindow(_("Error"),
+                          _("An error occurred unmounting the disc.  "
+                            "Please make sure you're not accessing "
+                            "%s from the shell on tty2 "
+                            "and then click OK to retry.")
+                          % (dev.path,))
+
+def verifyMedia(tree, discnum, timestamp=None):
+    if os.access("%s/.discinfo" % tree, os.R_OK):
+        f = open("%s/.discinfo" % tree)
+
+        newStamp = f.readline().strip()
+
+        try:
+            descr = f.readline().strip()
+        except:
+            descr = None
+
+        try:
+            arch = f.readline().strip()
+        except:
+            arch = None
+
+        try:
+            discs = getDiscNums(f.readline().strip())
+        except:
+            discs = [ 0 ]
+
+        f.close()
+
+        if timestamp is not None:
+            if newStamp == timestamp and arch == _arch and discnum in discs:
+                return True
+        else:
+            if arch == _arch and discnum in discs:
+                return True
+
+    return False
diff --git a/pyanaconda/installclass.py b/pyanaconda/installclass.py
new file mode 100644
index 0000000..2e8fcf6
--- /dev/null
+++ b/pyanaconda/installclass.py
@@ -0,0 +1,336 @@
+#
+# installclass.py:  This is the prototypical class for workstation, server, and
+# kickstart installs.  The interface to BaseInstallClass is *public* --
+# ISVs/OEMs can customize the install by creating a new derived type of this
+# class.
+#
+# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007
+# Red Hat, Inc.  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 as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# 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, see <http://www.gnu.org/licenses/>.
+#
+
+from distutils.sysconfig import get_python_lib
+import os, sys, iutil
+import isys
+import string
+import language
+import imputil
+import types
+
+from constants import *
+from product import *
+from storage.partspec import *
+
+import gettext
+_ = lambda x: gettext.ldgettext("anaconda", x)
+
+import logging
+log = logging.getLogger("anaconda")
+
+from flags import flags
+
+class BaseInstallClass(object):
+    # default to not being hidden
+    hidden = 0
+    pixmap = None
+    showMinimal = 1
+    showLoginChoice = 0
+    _description = ""
+    _descriptionFields = ()
+    name = "base"
+    pkgstext = ""
+    # default to showing the upgrade option
+    showUpgrade = True
+    bootloaderTimeoutDefault = None
+    bootloaderExtraArgs = ""
+
+    # list of of (txt, grplist) tuples for task selection screen
+    tasks = []
+
+    # don't select this class by default
+    default = 0
+
+    # by default, place this under the "install" category; it gets it's
+    # own toplevel category otherwise
+    parentClass = ( _("Install on System"), "install.png" )
+
+    def _get_description(self):
+        return _(self._description) % self._descriptionFields
+    description = property(_get_description)
+
+    def postAction(self, anaconda):
+        anaconda.backend.postAction(anaconda)
+
+    def setSteps(self, anaconda):
+        dispatch = anaconda.dispatch
+	dispatch.setStepList(
+		 "language",
+		 "keyboard",
+		 "welcome",
+                 "filtertype",
+                 "filter",
+                 "storageinit",
+                 "findrootparts",
+		 "betanag",
+		 "installtype",
+                 "cleardiskssel",
+                 "parttype",
+                 "autopartitionexecute",
+                 "partition",
+		 "storagedone",
+		 "bootloadersetup",                 
+		 "bootloader",
+		 "network",
+		 "timezone",
+		 "accounts",
+                 "reposetup",
+                 "basepkgsel",
+		 "tasksel",                                  
+		 "postselection",
+		 "confirminstall",
+                 "reipl",
+		 "install",
+		 "enablefilesystems",
+                 "setuptime",
+                 "preinstallconfig",
+		 "installpackages",
+                 "postinstallconfig",
+		 "writeconfig",
+                 "firstboot",
+		 "instbootloader",
+                 "dopostaction",
+                 "postscripts",
+		 "writeksconfig",
+                 "methodcomplete",
+                 "copylogs",
+                 "setfilecon",
+		 "complete"
+		)
+
+	if not BETANAG:
+	    dispatch.skipStep("betanag", permanent=1)
+
+        if not iutil.isX86():
+            dispatch.skipStep("bootloader", permanent=1)
+
+        # allow backends to disable interactive package selection
+        if not anaconda.backend.supportsPackageSelection:
+            dispatch.skipStep("tasksel", skip = 1, permanent=1)
+            dispatch.skipStep("group-selection", skip = 1, permanent=1)
+
+        # allow install classes to turn off the upgrade 
+        if not self.showUpgrade or not anaconda.backend.supportsUpgrades:
+            dispatch.skipStep("findrootparts", skip = 1)
+
+        # 'noupgrade' can be used on the command line to force not looking
+        # for partitions to upgrade.  useful in some cases...
+        if flags.cmdline.has_key("noupgrade"):
+            dispatch.skipStep("findrootparts", skip = 1)
+
+        # upgrade will also always force looking for an upgrade. 
+        if flags.cmdline.has_key("upgrade"):
+            dispatch.skipStep("findrootparts", skip = 0)
+
+        # if there's only one install class, it doesn't make much sense
+        # to show it
+        if len(availableClasses()) < 2:
+            dispatch.skipStep("installtype", permanent=1)
+
+        # allow interface backends to skip certain steps.
+        anaconda.intf.setSteps(anaconda)
+
+    # modifies the uri from installmethod.getMethodUri() to take into
+    # account any installclass specific things including multiple base
+    # repositories.  takes a string or list of strings, returns a dict 
+    # with string keys and list values {%repo: %uri_list}
+    def getPackagePaths(self, uri):
+        if not type(uri) == types.ListType:
+            uri = [uri,]
+
+        return {'base': uri}
+
+    def setPackageSelection(self, anaconda):
+	pass
+
+    def setGroupSelection(self, anaconda):
+        grps = anaconda.backend.getDefaultGroups(anaconda)
+        map(lambda x: anaconda.backend.selectGroup(x), grps)
+
+    def getBackend(self):
+        # this should be overriden in distro install classes
+        from backend import AnacondaBackend
+        return AnacondaBackend
+
+    def setDefaultPartitioning(self, storage, platform):
+        autorequests = [PartSpec(mountpoint="/", fstype=storage.defaultFSType,
+                                 size=1024, maxSize=50*1024, grow=True,
+                                 asVol=True),
+                        PartSpec(mountpoint="/home", fstype=storage.defaultFSType,
+                                 size=100, grow=True, asVol=True, requiredSpace=50*1024)]
+
+        bootreq = platform.setDefaultPartitioning()
+        if bootreq:
+            autorequests.extend(bootreq)
+
+        (minswap, maxswap) = iutil.swapSuggestion()
+        autorequests.append(PartSpec(fstype="swap", size=minswap, maxSize=maxswap,
+                                     grow=True, asVol=True))
+
+        storage.autoPartitionRequests = autorequests
+
+    def configure(self, anaconda):
+        anaconda.bootloader.timeout = self.bootloaderTimeoutDefault
+        anaconda.bootloader.args.append(self.bootloaderExtraArgs)
+
+    def versionMatches(self, oldver):
+        pass
+
+    def productMatches(self, oldprod):
+        pass
+
+    def productUpgradable(self, oldprod, oldver):
+        return self.productMatches(oldprod) and self.versionMatches(oldver)
+
+    def __init__(self):
+	pass
+
+allClasses = []
+allClasses_hidden = []
+
+# returns ( className, classObject, classLogo ) tuples
+def availableClasses(showHidden=0):
+    global allClasses
+    global allClasses_hidden
+
+    def _ordering(first, second):
+        ((name1, obj, logo), priority1) = first
+        ((name2, obj, logo), priority2) = second
+
+        if priority1 < priority2:
+            return -1
+        elif priority1 > priority2:
+            return 1
+
+        if name1 < name2:
+            return -1
+        elif name1 > name2:
+            return 1
+
+        return 0
+
+    if not showHidden:
+        if allClasses: return allClasses
+    else:
+        if allClasses_hidden: return allClasses_hidden
+
+    path = []
+
+    for dir in ["installclasses",
+                "/tmp/updates/pyanaconda/installclasses",
+                "/tmp/product/pyanaconda/installclasses",
+                "%s/pyanaconda/installclasses" % get_python_lib(plat_specific=1) ]:
+        if os.access(dir, os.R_OK):
+            path.append(dir)
+
+    # append the location of installclasses to the python path so we
+    # can import them
+    sys.path = path + sys.path
+
+    files = []
+    for p in reversed(path):
+        files += os.listdir(p)
+
+    done = {}
+    list = []
+    for file in files:
+	if file[0] == '.': continue
+        if len (file) < 4:
+	    continue
+	if file[-3:] != ".py" and file[-4:-1] != ".py":
+	    continue
+	mainName = string.split(file, ".")[0]
+	if done.has_key(mainName): continue
+	done[mainName] = 1
+
+        try:
+            found = imputil.imp.find_module(mainName)
+        except:
+            log.warning ("module import of %s failed: %s" % (mainName, sys.exc_type))
+            continue
+
+        try:
+            loaded = imputil.imp.load_module(mainName, found[0], found[1], found[2])
+
+            obj = loaded.InstallClass
+
+	    if obj.__dict__.has_key('sortPriority'):
+		sortOrder = obj.sortPriority
+	    else:
+		sortOrder = 0
+
+	    if obj.__dict__.has_key('arch'):
+                if obj.arch != iutil.getArch():
+                    obj.hidden = 1
+                
+            if obj.hidden == 0 or showHidden == 1:
+                list.append(((obj.name, obj, obj.pixmap), sortOrder))
+        except:
+            log.warning ("module import of %s failed: %s" % (mainName, sys.exc_type))
+            if flags.debug: raise
+            else: continue
+
+    list.sort(_ordering)
+    for (item, priority) in list:
+        if showHidden:
+            allClasses_hidden.append(item)
+        else:
+            allClasses.append(item)
+
+    if showHidden:
+        return allClasses_hidden
+    else:
+        return allClasses
+
+def getBaseInstallClass():
+    # figure out what installclass we should base on.
+    allavail = availableClasses(showHidden = 1)
+    avail = availableClasses(showHidden = 0)
+    if len(avail) == 1:
+        (cname, cobject, clogo) = avail[0]
+        log.info("using only installclass %s" %(cname,))
+    elif len(allavail) == 1:
+        (cname, cobject, clogo) = allavail[0]
+        log.info("using only installclass %s" %(cname,))
+
+    # Use the highest priority install class if more than one found.
+    elif len(avail) > 1:
+        (cname, cobject, clogo) = avail.pop()
+        log.info('%s is the highest priority installclass, using it' % cname)
+    elif len(allavail) > 1:
+        (cname, cobject, clogo) = allavail.pop()
+        log.info('%s is the highest priority installclass, using it' % cname)
+
+    # Default to the base installclass if nothing else is found.
+    else:
+        raise RuntimeError, "Unable to find an install class to use!!!"
+
+    return cobject
+
+baseclass = getBaseInstallClass()
+
+# we need to be able to differentiate between this and custom
+class DefaultInstall(baseclass):
+    def __init__(self):
+        baseclass.__init__(self)
diff --git a/pyanaconda/installclasses/Makefile.am b/pyanaconda/installclasses/Makefile.am
new file mode 100644
index 0000000..d7bd1eb
--- /dev/null
+++ b/pyanaconda/installclasses/Makefile.am
@@ -0,0 +1,24 @@
+# installclasses/Makefile.am for anaconda
+#
+# Copyright (C) 2009  Red Hat, Inc.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License as published
+# by the Free Software Foundation; either version 2.1 of the License, or
+# (at your option) any later version.
+#
+# 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 Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+#
+# Author: David Cantrell <dcantrell@xxxxxxxxxx>
+
+pkgpyexecdir = $(pyexecdir)/py$(PACKAGE_NAME)
+installclassesdir = $(pkgpyexecdir)/installclasses
+installclasses_PYTHON = *.py
+
+MAINTAINERCLEANFILES = Makefile.in
diff --git a/pyanaconda/installclasses/fedora.py b/pyanaconda/installclasses/fedora.py
new file mode 100644
index 0000000..189aa2a
--- /dev/null
+++ b/pyanaconda/installclasses/fedora.py
@@ -0,0 +1,127 @@
+#
+# fedora.py
+#
+# Copyright (C) 2007  Red Hat, Inc.  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 as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# 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, see <http://www.gnu.org/licenses/>.
+#
+
+from installclass import BaseInstallClass
+from constants import *
+from product import *
+from flags import flags
+import os, types
+import iutil
+
+import gettext
+_ = lambda x: gettext.ldgettext("anaconda", x)
+
+import installmethod
+import yuminstall
+
+import rpmUtils.arch
+
+class InstallClass(BaseInstallClass):
+    # name has underscore used for mnemonics, strip if you dont need it
+    id = "fedora"
+    name = N_("_Fedora")
+    _description = N_("The default installation of %s includes a set of "
+                      "software applicable for general internet usage. "
+                      "You can optionally select a different set of software "
+                      "now.")
+    _descriptionFields = (productName,)
+    sortPriority = 10000
+    if productName.startswith("Red Hat Enterprise"):
+        hidden = 1
+
+    tasks = [(N_("Graphical Desktop"),
+              ["admin-tools", "base", "base-x", "core", "editors", "fonts",
+               "games", "gnome-desktop", "graphical-internet", "graphics",
+               "hardware-support", "input-methods", "java", "office",
+               "printing", "sound-and-video", "text-internet"]),
+             (N_("Software Development"),
+              ["base", "base-x", "core", "development-libs",
+               "development-tools", "editors", "fonts", "gnome-desktop",
+               "gnome-software-development", "graphical-internet", "graphics",
+               "hardware-support", "input-methods", "java", "text-internet",
+               "x-software-development"]),
+             (N_("Web Server"),
+              ["admin-tools", "base", "base-x", "core", "editors",
+               "gnome-desktop", "graphical-internet", "hardware-support",
+               "java", "text-internet", "web-server"]),
+             (N_("Minimal"), ["core"])]
+
+    def getPackagePaths(self, uri):
+        if not type(uri) == types.ListType:
+            uri = [uri,]
+
+        return {'Installation Repo': uri}
+
+    def configure(self, anaconda):
+	BaseInstallClass.configure(self, anaconda)
+        BaseInstallClass.setDefaultPartitioning(self,
+                                                anaconda.storage,
+                                                anaconda.platform)
+
+    def setGroupSelection(self, anaconda):
+        BaseInstallClass.setGroupSelection(self, anaconda)
+        map(lambda x: anaconda.backend.selectGroup(x), ["core"])
+
+    def setSteps(self, anaconda):
+	BaseInstallClass.setSteps(self, anaconda)
+	anaconda.dispatch.skipStep("partition")
+
+    def getBackend(self):
+        if flags.livecdInstall:
+            import livecd
+            return livecd.LiveCDCopyBackend
+        else:
+            return yuminstall.YumBackend
+
+    def productMatches(self, oldprod):
+        if oldprod is None:
+            return False
+
+        if oldprod.startswith(productName):
+            return True
+
+        productUpgrades = {
+                "Fedora Core": ("Red Hat Linux", ),
+                "Fedora": ("Fedora Core", )
+        }
+
+        if productUpgrades.has_key(productName):
+            acceptable = productUpgrades[productName]
+        else:
+            acceptable = ()
+
+        for p in acceptable:
+            if oldprod.startswith(p):
+                return True
+
+        return False
+
+    def versionMatches(self, oldver):
+        try:
+            oldVer = float(oldver)
+            newVer = float(productVersion)
+        except ValueError:
+            return True
+
+        # This line means we do not support upgrading from anything older
+        # than two versions ago!
+        return newVer > oldVer and newVer - oldVer <= 2
+
+    def __init__(self):
+	BaseInstallClass.__init__(self)
diff --git a/pyanaconda/installclasses/rhel.py b/pyanaconda/installclasses/rhel.py
new file mode 100644
index 0000000..bcb592b
--- /dev/null
+++ b/pyanaconda/installclasses/rhel.py
@@ -0,0 +1,113 @@
+#
+# rhel.py
+#
+# Copyright (C) 2010  Red Hat, Inc.  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 as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# 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, see <http://www.gnu.org/licenses/>.
+#
+
+from installclass import BaseInstallClass
+from constants import *
+from product import *
+from flags import flags
+import os
+import types
+
+import installmethod
+import yuminstall
+
+class InstallClass(BaseInstallClass):
+    # name has underscore used for mnemonics, strip if you dont need it
+    id = "rhel"
+    name = N_("Red Hat Enterprise Linux")
+    _description = N_("The default installation of %s is a minimum install. "
+                     "You can optionally select a different set of software "
+                     "now.")
+    _descriptionFields = (productName,)
+    sortPriority = 10000
+    hidden = 1
+
+    bootloaderTimeoutDefault = 5
+    bootloaderExtraArgs = "crashkernel=auto"
+
+    tasks = [(N_("Minimal"),
+              ["core"])]
+
+    def getPackagePaths(self, uri):
+        if not type(uri) == types.ListType:
+            uri = [uri,]
+
+        return {productName: uri}
+
+    def configure(self, anaconda):
+        BaseInstallClass.configure(self, anaconda)
+        BaseInstallClass.setDefaultPartitioning(self,
+                                                anaconda.storage,
+                                                anaconda.platform)
+
+    def setSteps(self, anaconda):
+        BaseInstallClass.setSteps(self, anaconda)
+        anaconda.dispatch.skipStep("partition")
+
+    def getBackend(self):
+        if flags.livecdInstall:
+            import livecd
+            return livecd.LiveCDCopyBackend
+        else:
+            return yuminstall.YumBackend
+
+    def productMatches(self, oldprod):
+        if oldprod is None:
+            return False
+
+        if oldprod.startswith(productName):
+            return True
+
+        productUpgrades = {
+            "Red Hat Enterprise Linux AS": ("Red Hat Linux Advanced Server", ),
+            "Red Hat Enterprise Linux WS": ("Red Hat Linux Advanced Workstation",),
+            # FIXME: this probably shouldn't be in a release...
+            "Red Hat Enterprise Linux": ("Red Hat Linux Advanced Server",
+                                         "Red Hat Linux Advanced Workstation",
+                                         "Red Hat Enterprise Linux AS",
+                                         "Red Hat Enterprise Linux ES",
+                                         "Red Hat Enterprise Linux WS"),
+            "Red Hat Enterprise Linux Server": ("Red Hat Enterprise Linux AS",
+                                                "Red Hat Enterprise Linux ES",
+                                                "Red Hat Enterprise Linux WS",
+                                                "Red Hat Enterprise Linux"),
+            "Red Hat Enterprise Linux Client": ("Red Hat Enterprise Linux WS",
+                                                "Red Hat Enterprise Linux Desktop",
+                                                "Red Hat Enterprise Linux"),
+        }
+
+        if productUpgrades.has_key(productName):
+            acceptable = productUpgrades[productName]
+        else:
+            acceptable = ()
+
+        for p in acceptable:
+            if oldprod.startswith(p):
+                return True
+
+        return False
+
+    def versionMatches(self, oldver):
+        oldMajor = oldver.split(".")[0]
+        newMajor = productVersion.split(".")[0]
+
+        return oldMajor == newMajor
+
+    def __init__(self):
+        BaseInstallClass.__init__(self)
diff --git a/pyanaconda/installinterfacebase.py b/pyanaconda/installinterfacebase.py
new file mode 100644
index 0000000..1adfd2a
--- /dev/null
+++ b/pyanaconda/installinterfacebase.py
@@ -0,0 +1,76 @@
+#
+# installinterfacebase.py: a baseclass for anaconda interface classes
+#
+# Copyright (C) 2010  Red Hat, Inc.  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 as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# 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, see <http://www.gnu.org/licenses/>.
+#
+# Author(s): Hans de Goede <hdegoede@xxxxxxxxxx>
+
+import gettext
+_ = lambda x: gettext.ldgettext("anaconda", x)
+P_ = lambda x, y, z: gettext.ldngettext("anaconda", x, y, z)
+
+class InstallInterfaceBase(object):
+    def __init__(self):
+        self._warnedUnusedRaidMembers = []
+
+    def messageWindow(self, title, text, type="ok", default = None,
+             custom_buttons=None,  custom_icon=None):
+        raise NotImplementedError
+
+    def detailedMessageWindow(self, title, text, longText=None, type="ok",
+                              default=None, custom_icon=None,
+                              custom_buttons=[], expanded=False):
+        raise NotImplementedError
+
+    def unusedRaidMembersWarning(self, unusedRaidMembers):
+        """Warn about unused BIOS RAID members"""
+        unusedRaidMembers = \
+            filter(lambda m: m not in self._warnedUnusedRaidMembers,
+                   unusedRaidMembers)
+        if unusedRaidMembers:
+            self._warnedUnusedRaidMembers.extend(unusedRaidMembers)
+            unusedRaidMembers.sort()
+            self.messageWindow(_("Warning"),
+                P_("Disk %s contains BIOS RAID metadata, but is not part of "
+                   "any recognized BIOS RAID sets. Ignoring disk %s.",
+                   "Disks %s contain BIOS RAID metadata, but are not part of "
+                   "any recognized BIOS RAID sets. Ignoring disks %s.",
+                   len(unusedRaidMembers)) %
+                   (", ".join(unusedRaidMembers),
+                    ", ".join(unusedRaidMembers)),
+                custom_icon="warning")
+
+    def questionInitializeDASD(self, c, devs):
+        """Ask if unformatted DASD's should be formatted"""
+        title = P_("Unformatted DASD Device Found",
+                   "Unformatted DASD Devices Found", c)
+        msg = P_("Format uninitialized DASD device?\n\n"
+                 "There is %d uninitialized DASD device on this "
+                 "system.  To continue installation, the device must "
+                 "be formatted.  Formatting will remove any data on "
+                 "this device.",
+                 "Format uninitialized DASD devices?\n\n"
+                 "There are %d uninitialized DASD devices on this "
+                 "system.  To continue installation, the devices must "
+                 "be formatted.  Formatting will remove any data on "
+                 "these devices.", c) % c
+        icon = "/usr/share/icons/gnome/32x32/status/dialog-error.png"
+        buttons = [_("_Format"), _("_Ignore")]
+        return self.detailedMessageWindow(title, msg, devs.strip(),
+                                             type="custom",
+                                             custom_icon=icon,
+                                             custom_buttons=buttons,
+                                             expanded=True)
diff --git a/pyanaconda/installmethod.py b/pyanaconda/installmethod.py
new file mode 100644
index 0000000..17f1d3a
--- /dev/null
+++ b/pyanaconda/installmethod.py
@@ -0,0 +1,56 @@
+#
+# installmethod.py - Base class for install methods
+#
+# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007
+# Red Hat, Inc.  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 as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# 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, see <http://www.gnu.org/licenses/>.
+#
+
+import os, shutil, string
+from constants import *
+
+import logging
+log = logging.getLogger("anaconda")
+
+import isys, product
+
+def doMethodComplete(anaconda):
+    def _ejectDevice():
+        # Ejecting the CD/DVD for kickstart is handled only after %post scripts
+        # have been run.
+        if anaconda.ksdata:
+            return None
+
+        if anaconda.mediaDevice:
+            return anaconda.storage.devicetree.getDeviceByName(anaconda.mediaDevice)
+
+        # If we booted off the boot.iso instead of disc 1, eject that as well.
+        if anaconda.stage2 and anaconda.stage2.startswith("cdrom://"):
+            dev = anaconda.stage2[8:].split(':')[0]
+            return anaconda.storage.devicetree.getDeviceByName(dev)
+
+    anaconda.backend.complete(anaconda)
+    dev = _ejectDevice()
+    if dev:
+        dev.eject()
+
+    mtab = "/dev/root / ext3 ro 0 0\n"
+    rootDevice = anaconda.storage.rootDevice
+    if rootDevice:
+        mtab = "/dev/root / %s ro 0 0\n" % rootDevice.format.type
+
+    f = open(anaconda.rootPath + "/etc/mtab", "w+")
+    f.write(mtab)
+    f.close()
diff --git a/pyanaconda/isys/.gitignore b/pyanaconda/isys/.gitignore
new file mode 100644
index 0000000..0b04e81
--- /dev/null
+++ b/pyanaconda/isys/.gitignore
@@ -0,0 +1,6 @@
+*.pyc
+.depend
+*.lo
+*.do
+nfs_mountversion.h
+auditd
diff --git a/pyanaconda/isys/Makefile.am b/pyanaconda/isys/Makefile.am
new file mode 100644
index 0000000..8b5dd00
--- /dev/null
+++ b/pyanaconda/isys/Makefile.am
@@ -0,0 +1,56 @@
+# isys/Makefile.am for anaconda
+#
+# Copyright (C) 2009  Red Hat, Inc.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License as published
+# by the Free Software Foundation; either version 2.1 of the License, or
+# (at your option) any later version.
+#
+# 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 Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+#
+# Author: David Cantrell <dcantrell@xxxxxxxxxx>
+
+pkgpyexecdir = $(pyexecdir)/py$(PACKAGE_NAME)
+
+ISYS_SRCS = devices.c imount.c cpio.c uncpio.c lang.c \
+            isofs.c linkdetect.c vio.c ethtool.c eddsupport.c iface.c \
+            auditd.c log.c
+
+dist_noinst_HEADERS = *.h
+
+ISYS_CFLAGS = -DVERSION='"$(PACKAGE_VERSION)"' $(NFS_CFLAGS) \
+              $(NETWORKMANAGER_CFLAGS) $(LIBNL_CFLAGS) $(LIBNM_GLIB_CFLAGS) \
+              $(SELINUX_CFLAGS)
+ISYS_LIBS   = $(RESOLV_LIBS) $(EXT2FS_LIBS) $(ZLIB_LIBS) \
+              $(DEVMAPPER_LIBS) $(BLKID_LIBS) $(X11_LIBS) $(SELINUX_LIBS) \
+              $(LIBNL_LIBS) $(LIBNM_GLIB_LIBS)
+
+isysdir     = $(pkgpyexecdir)/isys
+isys_PYTHON = *.py
+
+pkgpyexec_LTLIBRARIES = _isys.la
+_isys_la_CFLAGS       = $(PYTHON_INCLUDES) $(ISYS_CFLAGS)
+_isys_la_LDFLAGS      = -module -avoid-version $(PYTHON_LDFLAGS)
+_isys_la_LIBADD       = $(PYTHON_LIBS) $(ISYS_LIBS)
+_isys_la_SOURCES      = isys.c $(ISYS_SRCS)
+
+noinst_LTLIBRARIES    = libisys.la
+libisys_la_CFLAGS     = $(ISYS_CFLAGS)
+libisys_la_LDFLAGS    = -static
+libisys_la_LIBADD     = $(ISYS_LIBS)
+libisys_la_SOURCES    = $(ISYS_SRCS)
+
+auditddir             = $(libexecdir)/$(PACKAGE_NAME)
+auditd_PROGRAMS       = auditd
+auditd_SOURCES        = auditd.c
+auditd_CFLAGS         = -DSTANDALONE $(SELINUX_CFLAGS)
+auditd_LDADD          = $(SELINUX_LIBS) $(LIBNL_LIBS)
+
+MAINTAINERCLEANFILES = Makefile.in
diff --git a/pyanaconda/isys/__init__.py b/pyanaconda/isys/__init__.py
new file mode 100755
index 0000000..d340bf3
--- /dev/null
+++ b/pyanaconda/isys/__init__.py
@@ -0,0 +1,560 @@
+#
+# isys.py - installer utility functions and glue for C module
+#
+# Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007  Red Hat, Inc.
+# 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 as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# 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, see <http://www.gnu.org/licenses/>.
+#
+# Author(s): Matt Wilson <msw@xxxxxxxxxx>
+#            Erik Troan <ewt@xxxxxxxxxx>
+#            Jeremy Katz <katzj@xxxxxxxxxx>
+#
+
+import _isys
+import string
+import os
+import os.path
+import socket
+import stat
+import posix
+import sys
+import ..iutil
+import warnings
+import resource
+import re
+import struct
+import block
+import dbus
+import selinux
+
+import ..logging
+log = logging.getLogger("anaconda")
+
+NM_SERVICE = "org.freedesktop.NetworkManager"
+NM_MANAGER_PATH = "/org/freedesktop/NetworkManager"
+NM_MANAGER_IFACE = "org.freedesktop.NetworkManager"
+NM_ACTIVE_CONNECTION_IFACE = "org.freedesktop.NetworkManager.Connection.Active"
+NM_CONNECTION_IFACE = "org.freedesktop.NetworkManagerSettings.Connection"
+NM_DEVICE_IFACE = "org.freedesktop.NetworkManager.Device"
+
+NM_STATE_UNKNOWN = 0
+NM_STATE_ASLEEP = 1
+NM_STATE_CONNECTING = 2
+NM_STATE_CONNECTED = 3
+NM_STATE_DISCONNECTED = 4
+
+DBUS_PROPS_IFACE = "org.freedesktop.DBus.Properties"
+
+mountCount = {}
+
+MIN_RAM = _isys.MIN_RAM
+MIN_GUI_RAM = _isys.MIN_GUI_RAM
+URL_INSTALL_EXTRA_RAM = _isys.URL_INSTALL_EXTRA_RAM
+EARLY_SWAP_RAM = _isys.EARLY_SWAP_RAM
+
+## Get the amount of free space available under a directory path.
+# @param path The directory path to check.
+# @return The amount of free space available, in 
+def pathSpaceAvailable(path):
+    return _isys.devSpaceFree(path)
+
+## Set up an already existing device node to be used as a loopback device.
+# @param device The full path to a device node to set up as a loopback device.
+# @param file The file to mount as loopback on device.
+# @param readOnly Should this loopback device be used read-only?
+def losetup(device, file, readOnly = 0):
+    # FIXME: implement this as a storage.devices.Device subclass
+    if readOnly:
+	mode = os.O_RDONLY
+    else:
+	mode = os.O_RDWR
+    targ = os.open(file, mode)
+    loop = os.open(device, mode)
+    try:
+        _isys.losetup(loop, targ, file)
+    finally:
+        os.close(loop)
+        os.close(targ)
+
+def lochangefd(device, file):
+    # FIXME: implement this as a storage.devices.Device subclass
+    loop = os.open(device, os.O_RDONLY)
+    targ = os.open(file, os.O_RDONLY)
+    try:
+        _isys.lochangefd(loop, targ)
+    finally:
+        os.close(loop)
+        os.close(targ)
+
+## Disable a previously setup loopback device.
+# @param device The full path to an existing loopback device node.
+def unlosetup(device):
+    # FIXME: implement this as a storage.devices.Device subclass
+    loop = os.open(device, os.O_RDONLY)
+    try:
+        _isys.unlosetup(loop)
+    finally:
+        os.close(loop)
+
+## Mount a filesystem, similar to the mount system call.
+# @param device The device to mount.  If bindMount is True, this should be an
+#               already mounted directory.  Otherwise, it should be a device
+#               name.
+# @param location The path to mount device on.
+# @param fstype The filesystem type on device.  This can be disk filesystems
+#               such as vfat or ext3, or pseudo filesystems such as proc or
+#               selinuxfs.
+# @param readOnly Should this filesystem be mounted readonly?
+# @param bindMount Is this a bind mount?  (see the mount(8) man page)
+# @param remount Are we mounting an already mounted filesystem?
+# @return The return value from the mount system call.
+def mount(device, location, fstype = "ext2", readOnly = False,
+          bindMount = False, remount = False, options = None):
+    flags = None
+    location = os.path.normpath(location)
+    if not options:
+        opts = ["defaults"]
+    else:
+        opts = options.split(",")
+
+    # We don't need to create device nodes for devices that start with '/'
+    # (like '/usbdevfs') and also some special fake devices like 'proc'.
+    # First try to make a device node and if that fails, assume we can
+    # mount without making a device node.  If that still fails, the caller
+    # will have to deal with the exception.
+    # We note whether or not we created a node so we can clean up later.
+
+    if mountCount.has_key(location) and mountCount[location] > 0:
+	mountCount[location] = mountCount[location] + 1
+	return
+
+    if readOnly or bindMount or remount:
+        if readOnly:
+            opts.append("ro")
+        if bindMount:
+            opts.append("bind")
+        if remount:
+            opts.append("remount")
+
+    flags = ",".join(opts)
+
+    log.debug("isys.py:mount()- going to mount %s on %s as %s with options %s" %(device, location, fstype, flags))
+    rc = _isys.mount(fstype, device, location, flags)
+
+    if not rc:
+	mountCount[location] = 1
+
+    return rc
+
+## Unmount a filesystem, similar to the umount system call.
+# @param what The directory to be unmounted.  This does not need to be the
+#             absolute path.
+# @param removeDir Should the mount point be removed after being unmounted?
+# @return The return value from the umount system call.
+def umount(what, removeDir = True):
+    what = os.path.normpath(what)
+
+    if not os.path.isdir(what):
+	raise ValueError, "isys.umount() can only umount by mount point"
+
+    if mountCount.has_key(what) and mountCount[what] > 1:
+	mountCount[what] = mountCount[what] - 1
+	return
+
+    log.debug("isys.py:umount()- going to unmount %s, removeDir = %s" % (what, removeDir))
+    rc = _isys.umount(what)
+
+    if removeDir and os.path.isdir(what):
+        try:
+            os.rmdir(what)
+        except:
+            pass
+
+    if not rc and mountCount.has_key(what):
+	del mountCount[what]
+
+    return rc
+
+## Disable swap.
+# @param path The full path of the swap device to disable.
+def swapoff (path):
+    return _isys.swapoff (path)
+
+## Enable swap.
+# @param path The full path of the swap device to enable.
+def swapon (path):
+    return _isys.swapon (path)
+
+## Load a keyboard layout for text mode installs.
+# @param keymap The keyboard layout to load.  This must be one of the values
+#               from rhpl.KeyboardModels.
+def loadKeymap(keymap):
+    return _isys.loadKeymap (keymap)
+
+def resetResolv():
+    return _isys.resetresolv()
+
+def readFSUuid(device):
+    if not os.path.exists(device):
+        device = "/dev/%s" % device
+
+    label = _isys.getblkid(device, "UUID")
+    return label
+
+def readFSLabel(device):
+    if not os.path.exists(device):
+        device = "/dev/%s" % device
+
+    label = _isys.getblkid(device, "LABEL")
+    return label
+
+def readFSType(device):
+    if not os.path.exists(device):
+        device = "/dev/%s" % device
+
+    fstype = _isys.getblkid(device, "TYPE")
+    if fstype is None:
+        # FIXME: libblkid doesn't show physical volumes as having a filesystem
+        # so let's sniff for that.(#409321)
+        try:
+            fd = os.open(device, os.O_RDONLY)
+            buf = os.read(fd, 2048)
+        except:
+            return fstype
+        finally:
+            try:
+                os.close(fd)
+            except:
+                pass
+
+        if buf.startswith("HM"):
+            return "physical volume (LVM)"
+        for sec in range(0, 4):
+            off = (sec * 512) + 24
+            if len(buf) < off:
+                continue
+            if buf[off:].startswith("LVM2"):
+                return "physical volume (LVM)"
+    elif fstype == "lvm2pv":
+        return "physical volume (LVM)"
+    return fstype
+
+def ext2IsDirty(device):
+    label = _isys.e2dirty(device)
+    return label
+
+def ext2HasJournal(device):
+    hasjournal = _isys.e2hasjournal(device)
+    return hasjournal
+
+def modulesWithPaths():
+    mods = []
+    for modline in open("/proc/modules", "r"):
+        modName = modline.split(" ", 1)[0]
+        modInfo = iutil.execWithCapture("modinfo",
+                ["-F", "filename", modName]).splitlines()
+        modPaths = [ line.strip() for line in modInfo if line!="" ]
+        mods.extend(modPaths)
+    return mods
+
+def driveUsesModule(device, modules):
+    """Returns true if a drive is using a prticular module.  Only works
+       for SCSI devices right now."""
+
+    if not isinstance(modules, ().__class__) and not \
+            isinstance(modules, [].__class__):
+        modules = [modules]
+
+    if device[:2] == "hd":
+        return False
+    rc = False
+    if os.access("/tmp/scsidisks", os.R_OK):
+        sdlist=open("/tmp/scsidisks", "r")
+        sdlines = sdlist.readlines()
+        sdlist.close()
+        for l in sdlines:
+            try:
+                # each line has format of:  <device>  <module>
+                (sddev, sdmod) = string.split(l)
+
+                if sddev == device:
+                    if sdmod in modules:
+                        rc = True
+                        break
+            except:
+                    pass
+    return rc
+
+def vtActivate (num):
+    if iutil.isS390():
+        return
+    _isys.vtActivate (num)
+
+def isPseudoTTY (fd):
+    return _isys.isPseudoTTY (fd)
+
+## Flush filesystem buffers.
+def sync ():
+    return _isys.sync ()
+
+## Determine if a file is an ISO image or not.
+# @param file The full path to a file to check.
+# @return True if ISO image, False otherwise.
+def isIsoImage(file):
+    return _isys.isisoimage(file)
+
+# Return number of network devices
+def getNetworkDeviceCount():
+    bus = dbus.SystemBus()
+    nm = bus.get_object(NM_SERVICE, NM_MANAGER_PATH)
+    devlist = nm.get_dbus_method("GetDevices")()
+    return len(devlist)
+
+# Get a D-Bus interface for the specified device's (e.g., eth0) properties.
+# If dev=None, return a hash of the form 'hash[dev] = props_iface' that
+# contains all device properties for all interfaces that NetworkManager knows
+# about.
+def getDeviceProperties(dev=None):
+    bus = dbus.SystemBus()
+    nm = bus.get_object(NM_SERVICE, NM_MANAGER_PATH)
+    devlist = nm.get_dbus_method("GetDevices")()
+    all = {}
+
+    for path in devlist:
+        device = bus.get_object(NM_SERVICE, path)
+        device_props_iface = dbus.Interface(device, DBUS_PROPS_IFACE)
+
+        device_interface = str(device_props_iface.Get(NM_MANAGER_IFACE, "Interface"))
+
+        if dev is None:
+            all[device_interface] = device_props_iface
+        elif device_interface == dev:
+            return device_props_iface
+
+    if dev is None:
+        return all
+    else:
+        return None
+
+# Return true if method is currently 'dhcp' for the specified device.
+def isDeviceDHCP(dev=None):
+    if dev is None:
+        return False
+
+    bus = dbus.SystemBus()
+    nm = bus.get_object(NM_SERVICE, NM_MANAGER_PATH)
+    nm_props_iface = dbus.Interface(nm, DBUS_PROPS_IFACE)
+    active_connections = nm_props_iface.Get(NM_MANAGER_IFACE, "ActiveConnections")
+
+    for path in active_connections:
+        active = bus.get_object(NM_SERVICE, path)
+        active_props_iface = dbus.Interface(active, DBUS_PROPS_IFACE)
+
+        active_service_name = active_props_iface.Get(NM_ACTIVE_CONNECTION_IFACE, "ServiceName")
+        active_path = active_props_iface.Get(NM_ACTIVE_CONNECTION_IFACE, "Connection")
+        active_devices = active_props_iface.Get(NM_ACTIVE_CONNECTION_IFACE, "Devices")
+
+        device = bus.get_object(NM_SERVICE, active_devices[0])
+        device_props_iface = dbus.Interface(device, DBUS_PROPS_IFACE)
+        iface = device_props_iface.Get(NM_DEVICE_IFACE, "Interface")
+
+        if iface != dev:
+            continue
+
+        connection = bus.get_object(active_service_name, active_path)
+        connection_iface = dbus.Interface(connection, NM_CONNECTION_IFACE)
+        settings = connection_iface.GetSettings()
+
+        ip4_setting = settings.get('ipv4')
+        if not ip4_setting or not ip4_setting['method'] or ip4_setting['method'] == 'auto':
+            return True
+
+    return False
+
+# Get the MAC address for a network device.
+def getMacAddress(dev):
+    if dev == '' or dev is None:
+        return False
+
+    device_props_iface = getDeviceProperties(dev=dev)
+    if device_props_iface is None:
+        return None
+
+    device_macaddr = None
+    try:
+        device_macaddr = device_props_iface.Get(NM_MANAGER_IFACE, "HwAddress").upper()
+    except dbus.exceptions.DBusException as e:
+        if e.get_dbus_name() != 'org.freedesktop.DBus.Error.InvalidArgs':
+            raise
+    return device_macaddr
+
+# Get a description string for a network device (e.g., eth0)
+def getNetDevDesc(dev):
+    from baseudev import udev_get_device
+    desc = "Network Interface"
+
+    if dev == '' or dev is None:
+        return desc
+
+    bus = dbus.SystemBus()
+    nm = bus.get_object(NM_SERVICE, NM_MANAGER_PATH)
+    devlist = nm.get_dbus_method("GetDevices")()
+
+    for path in devlist:
+        device = bus.get_object(NM_SERVICE, path)
+        device_iface = dbus.Interface(device, DBUS_PROPS_IFACE)
+        device_props = device_iface.get_dbus_method("GetAll")(NM_DEVICE_IFACE)
+
+        if dev == device_props['Interface']:
+            # This is the sysfs path (for now).
+            udev_path = device_props['Udi']
+            dev = udev_get_device(udev_path[4:])
+
+            if dev is None:
+                log.debug("weird, we have a None dev with path %s" % path)
+            elif dev.has_key("ID_VENDOR_ENC") and dev.has_key("ID_MODEL_ENC"):
+                desc = "%s %s" % (dev["ID_VENDOR_ENC"], dev["ID_MODEL_ENC"])
+            elif dev.has_key("ID_VENDOR_FROM_DATABASE") and dev.has_key("ID_MODEL_FROM_DATABASE"):
+                desc = "%s %s" % (dev["ID_VENDOR_FROM_DATABASE"], dev["ID_MODEL_FROM_DATABASE"])
+
+            return desc
+
+    return desc
+
+# Determine if a network device is a wireless device.
+def isWireless(dev):
+    if dev == '' or dev is None:
+        return False
+
+    device_props_iface = getDeviceProperties(dev=dev)
+    if device_props_iface is None:
+        return None
+
+    device_type = int(device_props_iface.Get(NM_MANAGER_IFACE, "DeviceType"))
+
+    # from include/NetworkManager.h in the NM source code
+    #    0 == NM_DEVICE_TYPE_UNKNOWN
+    #    1 == NM_DEVICE_TYPE_ETHERNET
+    #    2 == NM_DEVICE_TYPE_WIFI
+    #    3 == NM_DEVICE_TYPE_GSM
+    #    4 == NM_DEVICE_TYPE_CDMA
+    if device_type == 2:
+        return True
+    else:
+        return False
+
+# Get the IP address for a network device.
+def getIPAddress(dev):
+    if dev == '' or dev is None:
+       return None
+
+    device_props_iface = getDeviceProperties(dev=dev)
+    if device_props_iface is None:
+        return None
+
+    # XXX: add support for IPv6 addresses when NM can do that
+    device_ip4addr = device_props_iface.Get(NM_MANAGER_IFACE, "Ip4Address")
+
+    try:
+        tmp = struct.pack('I', device_ip4addr)
+        address = socket.inet_ntop(socket.AF_INET, tmp)
+    except ValueError, e:
+        return None
+
+    return address
+
+## Get the correct context for a file from loaded policy.
+# @param fn The filename to query.
+def matchPathContext(fn):
+    con = None
+    try:
+        con = selinux.matchpathcon(os.path.normpath(fn), 0)[1]
+    except OSError as e:
+        log.info("failed to get default SELinux context for %s: %s" % (fn, e))
+    return con
+
+## Set the SELinux file context of a file
+# @param fn The filename to fix.
+# @param con The context to use.
+# @param instroot An optional root filesystem to look under for fn.
+def setFileContext(fn, con, instroot = '/'):
+    full_path = os.path.normpath("%s/%s" % (instroot, fn))
+    rc = False
+    if con is not None and os.access(full_path, os.F_OK):
+        try:
+            rc = (selinux.lsetfilecon(full_path, con) == 0)
+        except OSError as e:
+            log.info("failed to set SELinux context for %s: %s" % (full_path, e))
+    return rc
+
+## Restore the SELinux file context of a file to its default.
+# @param fn The filename to fix.
+# @param instroot An optional root filesystem to look under for fn.
+def resetFileContext(fn, instroot = '/'):
+    con = matchPathContext(fn)
+    if con:
+        if setFileContext(fn, con, instroot):
+            return con
+    return None
+
+def prefix2netmask(prefix):
+    return _isys.prefix2netmask(prefix)
+
+def netmask2prefix (netmask):
+    prefix = 0
+
+    while prefix < 33:
+        if (prefix2netmask(prefix) == netmask):
+            return prefix
+
+        prefix += 1
+
+    return prefix
+
+isPAE = None
+def isPaeAvailable():
+    global isPAE
+    if isPAE is not None:
+        return isPAE
+
+    isPAE = False
+    if not iutil.isX86():
+        return isPAE
+
+    f = open("/proc/cpuinfo", "r")
+    lines = f.readlines()
+    f.close()
+
+    for line in lines:
+        if line.startswith("flags") and line.find("pae") != -1:
+            isPAE = True
+            break
+
+    return isPAE
+
+def getLinkStatus(dev):
+    return _isys.getLinkStatus(dev)
+
+def getAnacondaVersion():
+    return _isys.getAnacondaVersion()
+
+auditDaemon = _isys.auditdaemon
+
+handleSegv = _isys.handleSegv
+
+printObject = _isys.printObject
+bind_textdomain_codeset = _isys.bind_textdomain_codeset
+isVioConsole = _isys.isVioConsole
+initLog = _isys.initLog
diff --git a/pyanaconda/isys/auditd.c b/pyanaconda/isys/auditd.c
new file mode 100644
index 0000000..2ca6d04
--- /dev/null
+++ b/pyanaconda/isys/auditd.c
@@ -0,0 +1,134 @@
+/*
+ * auditd.c: This is a simple audit daemon that throws all messages away.
+ *
+ * Copyright (C) 2006  Red Hat, Inc.  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 as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ *
+ * Author(s): Peter Jones <pjones@xxxxxxxxxx>
+ */
+
+#define _GNU_SOURCE 1
+
+#include <sys/types.h>
+#include <sys/syscall.h>
+#include <sys/poll.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <signal.h>
+#include <string.h>
+#include <stdlib.h>
+#include <errno.h>
+
+#include <libaudit.h>
+
+#include "auditd.h"
+
+#ifdef USESELINUX
+static int done;
+
+static void sig_done(int sig)
+{
+    done = 1;
+}
+
+static void do_auditd(int fd) {
+    struct audit_reply rep;
+    sigset_t sigs;
+    struct sigaction sa;
+    struct pollfd pds = {
+        .events = POLLIN,
+        .revents = 0,
+        .fd = fd,
+    };
+
+    if (audit_set_pid(fd, getpid(), WAIT_YES) < 0)
+        return;
+
+    if (audit_set_enabled(fd, 1) < 0)
+        return;
+
+    memset(&sa, '\0', sizeof (sa));
+    sa.sa_handler = sig_done;
+    sigaction(SIGTERM, &sa, NULL);
+    sigaction(SIGINT, &sa, NULL);
+    sigaction(SIGHUP, &sa, NULL);
+
+    sigfillset(&sigs);
+    sigdelset(&sigs, SIGTERM);
+    sigdelset(&sigs, SIGINT);
+    sigdelset(&sigs, SIGHUP);
+
+    while (1) {
+        int retval;
+
+        memset(&rep, 0, sizeof(rep));
+
+        do {
+            retval = ppoll(&pds, 1, NULL, &sigs);
+        } while (retval == -1 && errno == EINTR && !done);
+
+        if (done)
+            break;
+
+        if (audit_get_reply(fd, &rep, GET_REPLY_NONBLOCKING, 0) > 0) {
+            /* we don't actually want to do anything here. */
+            ;
+        }
+    }
+    return;
+}
+#endif /* USESELINUX */
+
+int audit_daemonize(void) {
+#ifdef USESELINUX
+    int fd;
+    pid_t child;
+    int i;
+    if ((child = fork()) > 0)
+        return 0;
+
+#ifndef STANDALONE 
+    for (i = 0; i < getdtablesize(); i++)
+        close(i);
+    signal(SIGTTOU, SIG_IGN);
+    signal(SIGTTIN, SIG_IGN);
+    signal(SIGTSTP, SIG_IGN);
+#endif /* !defined(STANDALONE) */
+
+    if ((fd = open("/proc/self/oom_adj", O_RDWR)) >= 0) {
+        i = write(fd, "-17", 3);
+        close(fd);
+    }
+    fd = audit_open();
+    do_auditd(fd);
+    audit_close(fd);
+
+#ifndef STANDALONE
+    exit(0);
+#endif /* !defined(STANDALONE) */
+
+#endif /* USESELINUX */
+    return 0;
+}
+
+#ifdef STANDALONE
+int main(void) {
+    return audit_daemonize();
+}
+#endif /* STANDALONE */
+
+/*
+ * vim:ts=8:sw=4:sts=4:et
+ */
diff --git a/pyanaconda/isys/auditd.h b/pyanaconda/isys/auditd.h
new file mode 100644
index 0000000..55ec5ce
--- /dev/null
+++ b/pyanaconda/isys/auditd.h
@@ -0,0 +1,30 @@
+/*
+ * auditd.h: This is a simple audit daemon that throws all messages away.
+ *
+ * Copyright (C) 2006  Red Hat, Inc.  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 as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ *
+ * Author(s): Peter Jones <pjones@xxxxxxxxxx>
+ */
+
+#ifndef ISYS_AUDIT_H
+#define ISYS_AUDIT_H 1
+
+extern int audit_daemonize(void);
+
+#endif /* ISYS_AUDIT_H */
+/*
+ * vim:ts=8:sw=4:sts=4:et
+ */
diff --git a/pyanaconda/isys/cpio.c b/pyanaconda/isys/cpio.c
new file mode 100644
index 0000000..fd83605
--- /dev/null
+++ b/pyanaconda/isys/cpio.c
@@ -0,0 +1,46 @@
+/*
+ * cpio.c
+ *
+ * Copyright (C) 2007  Red Hat, Inc.  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 as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#include "cpio.h"
+
+int installCpioFile(gzFile fd, char * cpioName, char * outName, int inWin) {
+    struct cpioFileMapping map;
+    int rc;
+    const char * failedFile;
+
+    if (outName) {
+	map.archivePath = cpioName;
+	map.fsPath = outName;
+	map.mapFlags = CPIO_MAP_PATH;
+    }
+
+    rc = myCpioInstallArchive(fd, outName ? &map : NULL, 1, NULL, NULL, 
+			    &failedFile);
+
+    if (rc || access(outName, R_OK)) {
+	return -1;
+    }
+
+    return 0;
+}
diff --git a/pyanaconda/isys/cpio.h b/pyanaconda/isys/cpio.h
new file mode 100644
index 0000000..4cbb7c0
--- /dev/null
+++ b/pyanaconda/isys/cpio.h
@@ -0,0 +1,102 @@
+/*
+ * cpio.h
+ *
+ * Copyright (C) 2007  Red Hat, Inc.  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 as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef H_CPIO
+#define H_CPIO
+
+#include <sys/types.h>
+
+#include "stubs.h"
+
+/* Note the CPIO_CHECK_ERRNO bit is set only if errno is valid. These have to
+   be positive numbers or this setting the high bit stuff is a bad idea. */
+#define CPIOERR_CHECK_ERRNO	0x80000000
+
+#define CPIOERR_BAD_MAGIC	(2			)
+#define CPIOERR_BAD_HEADER	(3			)
+#define CPIOERR_OPEN_FAILED	(4    | CPIOERR_CHECK_ERRNO)
+#define CPIOERR_CHMOD_FAILED	(5    | CPIOERR_CHECK_ERRNO)
+#define CPIOERR_CHOWN_FAILED	(6    | CPIOERR_CHECK_ERRNO)
+#define CPIOERR_WRITE_FAILED	(7    | CPIOERR_CHECK_ERRNO)
+#define CPIOERR_UTIME_FAILED	(8    | CPIOERR_CHECK_ERRNO)
+#define CPIOERR_UNLINK_FAILED	(9    | CPIOERR_CHECK_ERRNO)
+
+#define CPIOERR_SYMLINK_FAILED	(11   | CPIOERR_CHECK_ERRNO)
+#define CPIOERR_STAT_FAILED	(12   | CPIOERR_CHECK_ERRNO)
+#define CPIOERR_MKDIR_FAILED	(13   | CPIOERR_CHECK_ERRNO)
+#define CPIOERR_MKNOD_FAILED	(14   | CPIOERR_CHECK_ERRNO)
+#define CPIOERR_MKFIFO_FAILED	(15   | CPIOERR_CHECK_ERRNO)
+#define CPIOERR_LINK_FAILED	(16   | CPIOERR_CHECK_ERRNO)
+#define CPIOERR_READLINK_FAILED	(17   | CPIOERR_CHECK_ERRNO)
+#define CPIOERR_READ_FAILED	(18   | CPIOERR_CHECK_ERRNO)
+#define CPIOERR_COPY_FAILED	(19   | CPIOERR_CHECK_ERRNO)
+#define CPIOERR_INTERNAL	(20			)
+#define CPIOERR_HDR_SIZE	(21			)
+#define CPIOERR_UNKNOWN_FILETYPE (22			)
+
+
+/* Don't think this behaves just like standard cpio. It's pretty close, but
+   it has some behaviors which are more to RPM's liking. I tried to document
+   them inline in cpio.c, but I may have missed some. */
+
+#define CPIO_MAP_PATH		(1 << 0)
+#define CPIO_MAP_MODE		(1 << 1)
+#define CPIO_MAP_UID		(1 << 2)
+#define CPIO_MAP_GID		(1 << 3)
+#define CPIO_FOLLOW_SYMLINKS	(1 << 4)  /* only for building */
+
+struct cpioFileMapping {
+    char * archivePath;
+    char * fsPath;
+    mode_t finalMode;
+    uid_t finalUid;
+    gid_t finalGid;
+    int mapFlags;
+};
+
+/* on cpio building, only "file" is filled in */
+struct cpioCallbackInfo {
+    char * file;
+    long fileSize;			/* total file size */
+    long fileComplete;			/* amount of file unpacked */
+    long bytesProcessed;		/* bytes in archive read */
+};
+
+typedef void (*cpioCallback)(struct cpioCallbackInfo * filespec, void * data);
+
+/* If no mappings are passed, this installs everything! If one is passed
+   it should be sorted according to cpioFileMapCmp() and only files included
+   in the map are installed. Files are installed relative to the current
+   directory unless a mapping is given which specifies an absolute 
+   directory. The mode mapping is only used for the permission bits, not
+   for the file type. The owner/group mappings are ignored for the nonroot
+   user. If *failedFile is non-NULL on return, it should be free()d. */
+int myCpioInstallArchive(gzFile stream, struct cpioFileMapping * mappings, 
+		       int numMappings, cpioCallback cb, void * cbData,
+		       const char ** failedFile);
+int myCpioFilterArchive(gzFile inStream, gzFile outStream, char ** pattern);
+
+/* This is designed to be qsort/bsearch compatible */
+int myCpioFileMapCmp(const void * a, const void * b);
+
+const char *myCpioStrerror(int rc);
+
+int installCpioFile(gzFile fd, char * cpioName, char * outName, int inWin);
+
+#endif
diff --git a/pyanaconda/isys/devices.c b/pyanaconda/isys/devices.c
new file mode 100644
index 0000000..53130d1
--- /dev/null
+++ b/pyanaconda/isys/devices.c
@@ -0,0 +1,221 @@
+/*
+ * devices.c - various hardware probing functionality
+ *
+ * Copyright (C) 2007  Red Hat, Inc.
+ * 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 as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ *
+ * Author(s): Bill Nottingham <notting@xxxxxxxxxx>
+ */
+
+#include <ctype.h>
+#include <dirent.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <limits.h>
+
+#include "devices.h"
+
+/* for 'disks', to filter out weird stuff */
+#define MINIMUM_INTERESTING_SIZE	32*1024 	/* 32MB */
+
+/* from genhd.h, kernel side */
+#define GENHD_FL_REMOVABLE                      1
+#define GENHD_FL_DRIVERFS                       2
+#define GENHD_FL_MEDIA_CHANGE_NOTIFY            4
+#define GENHD_FL_CD                             8
+#define GENHD_FL_UP                             16
+#define GENHD_FL_SUPPRESS_PARTITION_INFO        32
+#define GENHD_FL_FAIL                           64
+
+
+struct device **getDevices(enum deviceType type) {
+    struct device **ret = NULL;
+    struct device *new;
+    int numdevices = 0;
+
+    if (type & (DEVICE_DISK | DEVICE_CDROM)) {
+        DIR *dir;
+        struct dirent *ent;
+
+        dir = opendir("/sys/block");
+
+        if (!dir) goto storagedone;
+
+        while ((ent = readdir(dir))) {
+            char path[64];
+            char buf[64];
+            int fd, caps, devtype;
+
+            snprintf(path, 64, "/sys/block/%s/capability", ent->d_name);
+            fd = open(path, O_RDONLY);
+            if (fd == -1)
+                continue;
+            if (read(fd, buf, 63) <= 0) {
+                close(fd);
+                continue;
+            }
+
+            close(fd);
+            errno = 0;
+            caps = strtol(buf, NULL, 16);
+
+            if ((errno == ERANGE && (caps == LONG_MIN || caps == LONG_MAX)) ||
+                (errno != 0 && caps == 0)) {
+                return NULL;
+            }
+
+            if (caps & GENHD_FL_CD)
+                devtype = DEVICE_CDROM;
+            else
+                devtype = DEVICE_DISK;
+            if (!(devtype & type))
+                continue;
+
+            if (devtype == DEVICE_DISK && !(caps & GENHD_FL_REMOVABLE)) {
+                int size;
+
+                snprintf(path, 64, "/sys/block/%s/size", ent->d_name);
+                fd = open(path, O_RDONLY);
+
+                if (fd == -1)
+                    continue;
+                if (read(fd, buf, 63) <= 0) {
+                    close(fd);
+                    continue;
+                }
+
+                close(fd);
+                errno = 0;
+                size = strtol(buf, NULL, 10);
+
+                if ((errno == ERANGE && (size == LONG_MIN ||
+                                         size == LONG_MAX)) ||
+                    (errno != 0 && size == 0)) {
+                    return NULL;
+                }
+
+                if (size < MINIMUM_INTERESTING_SIZE)
+                    continue;
+            }
+
+            new = calloc(1, sizeof(struct device));
+            new->device = strdup(ent->d_name);
+            /* FIXME */
+            if (asprintf(&new->description, "Storage device %s",
+                         new->device) == -1) {
+                fprintf(stderr, "%s: %d: %s\n", __func__, __LINE__,
+                        strerror(errno));
+                fflush(stderr);
+                abort();
+            }
+            new->type = devtype;
+            if (caps & GENHD_FL_REMOVABLE) {
+                new->priv.removable = 1;
+            }
+            ret = realloc(ret, (numdevices+2) * sizeof(struct device));
+            ret[numdevices] = new;
+            ret[numdevices+1] = NULL;
+            numdevices++;
+        }
+
+        closedir(dir);
+    }
+storagedone:
+
+    if (type & DEVICE_NETWORK) {
+        DIR *dir;
+        struct dirent *ent;
+
+        dir = opendir("/sys/class/net");
+
+        if (!dir) goto netdone;
+
+        while ((ent = readdir(dir))) {
+            char path[64];
+            int fd, type;
+            char buf[64];
+
+            snprintf(path, 64, "/sys/class/net/%s/type", ent->d_name);
+            fd = open(path, O_RDONLY);
+            if (fd == -1)
+                continue;
+            if (read(fd, buf, 63) <= 0) {
+                close(fd);
+                continue;
+            }
+
+            close(fd);
+            errno = 0;
+            type = strtol(buf, NULL, 10);
+
+            if ((errno == ERANGE && (type == LONG_MIN || type == LONG_MAX)) ||
+                (errno != 0 && type == 0)) {
+                return NULL;
+            }
+
+            if (type != 1)
+                continue;
+
+            new = calloc(1, sizeof(struct device));
+            new->device = strdup(ent->d_name);
+            /* FIXME */
+            snprintf(path, 64, "/sys/class/net/%s/address", ent->d_name);
+            fd = open(path, O_RDONLY);
+            if (fd != -1) {
+                memset(buf, '\0', 64);
+                if (read(fd, buf, 63) > 0) {
+                    int i;
+                    for (i = (strlen(buf)-1); isspace(buf[i]); i--)
+                        buf[i] = '\0';
+                    new->priv.hwaddr = strdup(buf);
+                }
+            }
+
+            if (new->priv.hwaddr) {
+                if (asprintf(&new->description, "Ethernet device %s - %s",
+                             new->device, new->priv.hwaddr) == -1) {
+                    fprintf(stderr, "%s: %d: %s\n", __func__, __LINE__,
+                            strerror(errno));
+                    fflush(stderr);
+                    abort();
+                }
+            } else {
+                if (asprintf(&new->description, "Ethernet device %s",
+                             new->device) == -1) {
+                    fprintf(stderr, "%s: %d: %s\n", __func__, __LINE__,
+                            strerror(errno));
+                    fflush(stderr);
+                    abort();
+                }
+            }
+
+            ret = realloc(ret, (numdevices+2) * sizeof(struct device));
+            ret[numdevices] = new;
+            ret[numdevices+1] = NULL;
+            numdevices++;
+        }
+
+        closedir(dir);
+    }
+netdone:
+    return ret;
+}
+
diff --git a/pyanaconda/isys/devices.h b/pyanaconda/isys/devices.h
new file mode 100644
index 0000000..9428a77
--- /dev/null
+++ b/pyanaconda/isys/devices.h
@@ -0,0 +1,42 @@
+/*
+ * devices.h
+ *
+ * Copyright (C) 2007  Red Hat, Inc.  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 as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef DEVICES_H
+#define DEVICES_H
+
+enum deviceType {
+    DEVICE_ANY = ~0,
+    DEVICE_NETWORK = (1 << 0),
+    DEVICE_DISK = (1 << 1),
+    DEVICE_CDROM = (1 << 2)
+};
+
+struct device {
+    char *device;
+    char *description;
+    enum deviceType type;
+    union {
+        char *hwaddr;
+        int removable;
+    } priv;
+};
+
+struct device **getDevices(enum deviceType type);
+
+#endif
diff --git a/pyanaconda/isys/eddsupport.c b/pyanaconda/isys/eddsupport.c
new file mode 100644
index 0000000..c50278e
--- /dev/null
+++ b/pyanaconda/isys/eddsupport.c
@@ -0,0 +1,339 @@
+/*
+ * eddsupport.c - handling of mapping disk drives in Linux to disk drives
+ * according to the BIOS using the edd kernel module
+ *
+ * Copyright (C) 2004  Dell, Inc.  All rights reserved.
+ * Copyright (C) 2004  Red Hat, Inc.  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 as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ *
+ * Author(s): Rezwanul_Kabir@xxxxxxxx
+ *            Jeremy Katz <katzj@xxxxxxxxxx>
+ */
+
+#include <ctype.h>
+#include <dirent.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/stat.h>
+#include <sys/reboot.h>
+#include <sys/types.h>
+#include <linux/types.h>
+
+
+#include "eddsupport.h"
+#include "devices.h"
+#include "isys.h"
+
+#define EDD_DIR "/sys/firmware/edd"
+#define SIG_FILE "mbr_signature"
+#define MBRSIG_OFFSET 0x1b8
+
+#define HASH_TABLE_SIZE 17
+
+
+struct diskMapEntry{
+    uint32_t key;
+    char *diskname;
+    struct diskMapEntry *next;
+};
+
+struct diskMapTable {
+    struct diskMapEntry **table;
+    int tableSize;
+};
+
+static struct diskMapTable *mbrSigToName = NULL;
+static int diskHashInit = 0;
+
+
+
+static struct diskMapTable*  initializeHashTable(int);
+static int insertHashItem(struct diskMapTable *, struct diskMapEntry *);
+static struct diskMapEntry* lookupHashItem(struct diskMapTable *, uint32_t);
+static int addToHashTable(struct diskMapTable *, uint32_t , char *);
+static struct device ** createDiskList();
+static int mapBiosDisks(struct device ** , const char *);
+static int readDiskSig(char *,  uint32_t *);
+static int readMbrSig(char *, uint32_t *);
+
+/* This is the top level function that creates a disk list present in the
+ * system, checks to see if unique signatures exist on the disks at offset 
+ * 0x1b8.  If a unique signature exists then it will map BIOS disks to their 
+ * corresponding hd/sd device names.  Otherwise, we'll avoid mapping drives.
+ */
+
+int probeBiosDisks() {
+    struct device ** devices = NULL;
+
+    devices = createDiskList();
+    if(!devices){
+#ifdef STANDALONE
+        fprintf(stderr, "No disks!\n");
+#endif
+        return -1;
+    }
+
+    if(!mapBiosDisks(devices, EDD_DIR)){
+#ifdef STANDALONE
+            fprintf(stderr, "WARNING: couldn't map BIOS disks\n");
+#endif
+            return -1;
+    }
+    return 0;
+}
+
+
+static struct device ** createDiskList(){
+    return getDevices (DEVICE_DISK);
+}
+
+static int readDiskSig(char *device, uint32_t *disksig) {
+    int fd, rc;
+    char devnodeName[64];
+
+    snprintf(devnodeName, sizeof(devnodeName), "/dev/%s", device);
+    fd = open(devnodeName, O_RDONLY);
+    if (fd < 0) {
+#ifdef STANDALONE 
+        fprintf(stderr, "Error opening device %s: %s\n ", device, 
+                strerror(errno));
+#endif 
+        return -errno;
+    }
+
+    rc = lseek(fd, MBRSIG_OFFSET, SEEK_SET);
+    if (rc < 0){
+        close(fd);
+
+#ifdef STANDALONE
+        fprintf(stderr, "Error seeking to MBRSIG_OFFSET in %s: %s\n", 
+                device, strerror(errno));
+#endif
+        return -1;
+    }
+
+    rc = read(fd, disksig, sizeof(uint32_t));
+    if (rc < sizeof(uint32_t)) {
+        close(fd);
+
+#ifdef STANDALONE
+        fprintf(stderr, "Failed to read signature from %s\n", device); 
+#endif
+        return -1;
+    }
+
+    close(fd);
+    return 0;
+}
+
+static int mapBiosDisks(struct device** devices,const char *path) {
+    DIR *dirHandle;
+    struct dirent *entry;
+    char * sigFileName;
+    uint32_t mbrSig, biosNum, currentSig;
+    struct device **currentDev, **foundDisk;
+    int i, rc, ret, dm_nr, highest_dm;
+
+    dirHandle = opendir(path);
+    if(!dirHandle){
+#ifdef STANDALONE
+        fprintf(stderr, "Failed to open directory %s: %s\n", path, 
+                strerror(errno));
+#endif
+        return 0;
+    }
+
+    mbrSigToName = initializeHashTable(HASH_TABLE_SIZE);
+    if(!mbrSigToName){
+#ifdef STANDALONE
+        fprintf(stderr, "Error initializing mbrSigToName table\n");
+#endif
+        closedir(dirHandle);
+        return 0;
+    }
+
+    while ((entry = readdir(dirHandle)) != NULL) {
+        if(!strncmp(entry->d_name,".",1) || !strncmp(entry->d_name,"..",2)) {
+            continue;
+        }
+        ret = sscanf((entry->d_name+9), "%x", &biosNum);
+        
+        sigFileName = malloc(strlen(path) + strlen(entry->d_name) + 20);
+        sprintf(sigFileName, "%s/%s/%s", path, entry->d_name, SIG_FILE);
+        if (readMbrSig(sigFileName, &mbrSig) == 0) {
+            for (currentDev = devices, i = 0, foundDisk=NULL, highest_dm=-1;
+                    (*currentDev) != NULL;
+                    currentDev++) {
+                if (!(*currentDev)->device)
+                    continue;
+
+                if ((rc=readDiskSig((*currentDev)->device, &currentSig)) < 0) {
+                    if (rc == -ENOMEDIUM || rc == -ENXIO)
+                        continue;
+                    closedir(dirHandle);
+                    return 0;
+                } 
+
+                if (mbrSig == currentSig) {
+                    /* When we have a fakeraid setup we will find multiple hits
+                       a number for the raw disks (1 when striping, 2 when
+                       mirroring, more with raid on raid like raid 01 or 10)
+                       and a number for the dm devices (normally only one dm
+                       device will match, but more with raid on raid).
+                       Since with raid on raid the last dm device created
+                       will be the top layer raid, we want the highest matching
+                       dm device. */
+                    if (!strncmp((*currentDev)->device, "dm-", 3) &&
+                         sscanf((*currentDev)->device+3, "%d", &dm_nr) == 1) {
+                        if (dm_nr > highest_dm) {
+                            highest_dm = dm_nr;
+                            foundDisk=currentDev;
+                            i = 1;
+                        }
+                    } else if (!foundDisk ||
+                               strncmp((*foundDisk)->device, "dm-", 3)) {
+                        foundDisk=currentDev;
+                        i++;
+                    }
+                }
+            }
+
+            if (i==1) {
+                if(!addToHashTable(mbrSigToName, (uint32_t)biosNum, 
+                               (*foundDisk)->device)) {
+                    closedir(dirHandle);
+                    return 0;
+                }
+            }
+        } 
+    }
+    closedir(dirHandle);
+    return 1;
+} 
+
+
+static int readMbrSig(char *filename, uint32_t *int_sig){
+    FILE* fh;
+
+    fh = fopen(filename,"r");
+    if(fh == NULL) {
+#ifdef STANDALONE
+        fprintf(stderr, "Error opening mbr_signature file %s: %s\n", filename,
+                strerror(errno));
+#endif
+        return -1;
+    }
+    fseek(fh, 0, SEEK_SET);
+    if (fscanf(fh, "%x", int_sig) != 1) {
+#ifdef STANDALONE
+        fprintf(stderr, "Error reading %s\n", filename);
+#endif
+        fclose(fh);
+        return -1;
+    }
+
+    fclose(fh);
+    return 0;
+}                                                   
+
+
+static struct diskMapTable* initializeHashTable(int size) {
+    struct diskMapTable *hashTable;
+
+    hashTable = malloc(sizeof(struct diskMapTable));
+    hashTable->tableSize = size;
+    hashTable->table = malloc(sizeof(struct diskMapEntry *) * size);
+    memset(hashTable->table,0,(sizeof(struct diskMapEntry *) * size));
+    return hashTable;
+}
+
+
+static int insertHashItem(struct diskMapTable *hashTable,
+                          struct diskMapEntry *hashItem) {
+    int index;
+
+    index = (hashItem->key) % (hashTable->tableSize);
+
+    if(hashTable->table[index] == NULL){
+        hashTable->table[index] = hashItem;
+        return index;
+    } else {
+        hashItem->next = hashTable->table[index];
+        hashTable->table[index] = hashItem;
+        return index;
+    }
+}
+
+
+static struct diskMapEntry * lookupHashItem(struct diskMapTable *hashTable,
+                                            uint32_t itemKey) {
+    int index;
+    struct diskMapEntry *hashItem;
+
+    index = itemKey % (hashTable->tableSize);
+    for (hashItem = hashTable->table[index]; 
+         (hashItem != NULL) && (hashItem->key != itemKey); 
+         hashItem = hashItem->next) { 
+        ;
+    }
+    return hashItem;
+}
+
+
+static int addToHashTable(struct diskMapTable *hashTable, 
+                          uint32_t itemKey, char *diskName) {
+    int index;
+    struct diskMapEntry *diskSigToNameEntry;
+
+    diskSigToNameEntry = malloc(sizeof(struct diskMapEntry));
+    diskSigToNameEntry->next = NULL;
+    diskSigToNameEntry->key = itemKey;
+    diskSigToNameEntry->diskname = diskName;
+
+    if ((index = insertHashItem(hashTable, diskSigToNameEntry)) < 0){
+#ifdef STANDALONE
+        fprintf(stderr, "Unable to insert item\n");
+#endif
+        return 0;
+    } else {
+        return 1;
+    }
+}
+
+
+char * getBiosDisk(char *biosStr) {
+    uint32_t biosNum;
+    struct diskMapEntry * disk;
+    int ret;
+
+    if (diskHashInit == 0) {
+        probeBiosDisks();
+        diskHashInit = 1;
+    }
+
+    if (mbrSigToName == NULL)
+        return NULL;
+
+    ret = sscanf(biosStr,"%x",&biosNum);
+    disk = lookupHashItem(mbrSigToName, biosNum);
+    if (disk) return disk->diskname;
+
+    return NULL;
+}
diff --git a/pyanaconda/isys/eddsupport.h b/pyanaconda/isys/eddsupport.h
new file mode 100644
index 0000000..77fc4c4
--- /dev/null
+++ b/pyanaconda/isys/eddsupport.h
@@ -0,0 +1,28 @@
+/*
+ * eddsupport.h
+ *
+ * Copyright (C) 2007  Red Hat, Inc.  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 as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef EDDSUPPORT_H
+#define EDDSUPPORT_H
+
+int probeBiosDisks();
+char* getBiosDisk(char *);
+
+#endif
+
+
diff --git a/pyanaconda/isys/ethtool.c b/pyanaconda/isys/ethtool.c
new file mode 100644
index 0000000..871f1d4
--- /dev/null
+++ b/pyanaconda/isys/ethtool.c
@@ -0,0 +1,119 @@
+/*
+ * ethtool.c - setting of basic ethtool options
+ *
+ * Copyright (C) 2003  Red Hat, Inc.  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 as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ *
+ * Author(s): Jeremy Katz <katzj@xxxxxxxxxx>
+ */
+
+#include <errno.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#include <sys/ioctl.h>
+#include <sys/socket.h>
+#include <sys/types.h>
+#include <net/if.h>
+
+#include <linux/sockios.h>
+#include "ethtool.h"
+
+static int set_intf_up(struct ifreq ifr, int sock) {
+    if (ioctl(sock, SIOCGIFFLAGS, &ifr) < 0) {
+        return (-1);
+    }
+    ifr.ifr_flags |= (IFF_UP | IFF_RUNNING);
+    if (ioctl(sock, SIOCSIFFLAGS, &ifr) < 0) {
+        fprintf(stderr, "failed to bring up interface %s: %s", ifr.ifr_name,
+                strerror(errno));
+        return -1;
+    }
+    return (0);
+}
+
+int setEthtoolSettings(char * dev, ethtool_speed speed, 
+                       ethtool_duplex duplex) {
+    int sock, err;
+    struct ethtool_cmd ecmd;
+    struct ifreq ifr;
+
+    if ((sock = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
+        perror("Unable to create socket");
+        return -1;
+    }
+
+    /* Setup our control structures. */
+    memset(&ifr, 0, sizeof(ifr));
+    strcpy(ifr.ifr_name, dev);
+
+    if (set_intf_up(ifr, sock) == -1) {
+        fprintf(stderr, "unable to bring up interface %s: %s", dev, 
+                strerror(errno));
+        return -1;
+    }
+
+    ecmd.cmd = ETHTOOL_GSET;
+    ifr.ifr_data = (caddr_t)&ecmd;
+    err = ioctl(sock, SIOCETHTOOL, &ifr);
+    if (err < 0) {
+        perror("Unable to get settings via ethtool.  Not setting");
+        return -1;
+    }
+
+    if (speed != ETHTOOL_SPEED_UNSPEC)
+        ecmd.speed = speed;
+    if (duplex != ETHTOOL_DUPLEX_UNSPEC)
+        ecmd.duplex = duplex;
+    if ((duplex != ETHTOOL_DUPLEX_UNSPEC) || (speed != ETHTOOL_SPEED_UNSPEC))
+        ecmd.autoneg = AUTONEG_DISABLE;
+
+    ecmd.cmd = ETHTOOL_SSET;
+    ifr.ifr_data = (caddr_t)&ecmd;
+    err = ioctl(sock, SIOCETHTOOL, &ifr);
+    if (err < 0) {
+        //        perror("Unable to set settings via ethtool.  Not setting");
+        return -1;
+    }
+
+    return 0;
+}
+
+int identifyNIC(char *iface, int seconds) {
+    int sock;
+    struct ethtool_value edata;
+    struct ifreq ifr;
+
+    if ((sock = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
+        perror("Unable to create socket");
+        return -1;
+    }
+
+    memset(&ifr, 0, sizeof(ifr));
+    memset(&edata, 0, sizeof(edata));
+
+    strcpy(ifr.ifr_name, iface);
+    edata.cmd = ETHTOOL_PHYS_ID;
+    edata.data = seconds;
+    ifr.ifr_data = (caddr_t) &edata;
+
+    if (ioctl(sock, SIOCETHTOOL, &ifr) < 0) {
+        perror("Unable to identify NIC");
+    }
+
+    return 0;
+}
diff --git a/pyanaconda/isys/ethtool.h b/pyanaconda/isys/ethtool.h
new file mode 100644
index 0000000..57b4ffc
--- /dev/null
+++ b/pyanaconda/isys/ethtool.h
@@ -0,0 +1,41 @@
+/*
+ * net.h
+ *
+ * Copyright (C) 2007  Red Hat, Inc.  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 as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef ISYSNET_H
+#define ISYSNET_H
+
+#include <linux/types.h>
+#include <linux/ethtool.h>
+
+/* returns 1 for link, 0 for no link, -1 for unknown */
+int get_link_status(char *ifname);
+
+typedef enum ethtool_speed_t { ETHTOOL_SPEED_UNSPEC = -1, 
+                               ETHTOOL_SPEED_10 = SPEED_10, 
+                               ETHTOOL_SPEED_100 = SPEED_100,
+                               ETHTOOL_SPEED_1000 = SPEED_1000 } ethtool_speed;
+typedef enum ethtool_duplex_t { ETHTOOL_DUPLEX_UNSPEC = -1, 
+                                ETHTOOL_DUPLEX_HALF = DUPLEX_HALF,
+                                ETHTOOL_DUPLEX_FULL = DUPLEX_FULL } ethtool_duplex;
+
+/* set ethtool settings */
+int setEthtoolSettings(char * dev, ethtool_speed speed, ethtool_duplex duplex);
+int identifyNIC(char *iface, int seconds);
+
+#endif
diff --git a/pyanaconda/isys/iface.c b/pyanaconda/isys/iface.c
new file mode 100644
index 0000000..5897286
--- /dev/null
+++ b/pyanaconda/isys/iface.c
@@ -0,0 +1,543 @@
+/*
+ * iface.c - Network interface configuration API
+ *
+ * Copyright (C) 2006, 2007, 2008  Red Hat, 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; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ *
+ * Author(s): David Cantrell <dcantrell@xxxxxxxxxx>
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <sys/utsname.h>
+#include <arpa/inet.h>
+#include <dirent.h>
+#include <fcntl.h>
+#include <netdb.h>
+#include <signal.h>
+#include <netinet/in.h>
+
+#include <netlink/netlink.h>
+#include <netlink/socket.h>
+#include <netlink/route/rtnl.h>
+#include <netlink/route/route.h>
+#include <netlink/route/addr.h>
+#include <netlink/route/link.h>
+
+#include <glib.h>
+#include <NetworkManager.h>
+#include <nm-client.h>
+#include <nm-device.h>
+#include <nm-ip4-config.h>
+#include <nm-setting-ip4-config.h>
+
+#include "isys.h"
+#include "iface.h"
+
+/* Internal-only function prototypes. */
+static struct nl_handle *_iface_get_handle(void);
+static struct nl_cache *_iface_get_link_cache(struct nl_handle **);
+static int _iface_have_valid_addr(void *addr, int family, int length);
+static int _iface_redirect_io(char *device, int fd, int mode);
+
+/*
+ * Return a libnl handle for NETLINK_ROUTE.
+ */
+static struct nl_handle *_iface_get_handle(void) {
+    struct nl_handle *handle = NULL;
+
+    if ((handle = nl_handle_alloc()) == NULL) {
+        return NULL;
+    }
+
+    if (nl_connect(handle, NETLINK_ROUTE)) {
+        nl_handle_destroy(handle);
+        return NULL;
+    }
+
+    return handle;
+}
+
+/*
+ * Return an NETLINK_ROUTE cache.
+ */
+static struct nl_cache *_iface_get_link_cache(struct nl_handle **handle) {
+    struct nl_cache *cache = NULL;
+
+    if ((*handle = _iface_get_handle()) == NULL) {
+        return NULL;
+    }
+
+    if ((cache = rtnl_link_alloc_cache(*handle)) == NULL) {
+        nl_close(*handle);
+        nl_handle_destroy(*handle);
+        return NULL;
+    }
+
+    return cache;
+}
+
+/*
+ * Determine if a struct in_addr or struct in6_addr contains a valid address.
+ */
+static int _iface_have_valid_addr(void *addr, int family, int length) {
+    char buf[length+1];
+
+    if ((addr == NULL) || (family != AF_INET && family != AF_INET6)) {
+        return 0;
+    }
+
+    memset(buf, '\0', sizeof(buf));
+
+    if (inet_ntop(family, addr, buf, length) == NULL) {
+        return 0;
+    } else {
+        /* check for unknown addresses */
+        if (family == AF_INET) {
+            if (!strncmp(buf, "0.0.0.0", 7)) {
+                return 0;
+            }
+        } else if (family == AF_INET6) {
+            if (!strncmp(buf, "::", 2)) {
+                return 0;
+            }
+        }
+    }
+
+    return 1;
+}
+
+/*
+ * Redirect I/O to another device (e.g., stdout to /dev/tty5)
+ */
+int _iface_redirect_io(char *device, int fd, int mode) {
+    int io = -1;
+
+    if ((io = open(device, mode)) == -1) {
+        return 1;
+    }
+
+    if (close(fd) == -1) {
+        return 2;
+    }
+
+    if (dup2(io, fd) == -1) {
+        return 3;
+    }
+
+    if (close(io) == -1) {
+        return 4;
+    }
+
+    return 0;
+}
+
+/*
+ * Given an interface name (e.g., eth0) and address family (e.g., AF_INET),
+ * return the IP address in human readable format (i.e., the output from
+ * inet_ntop()).  Return NULL for no match or error.
+ */
+char *iface_ip2str(char *ifname, int family) {
+    int i;
+    NMClient *client = NULL;
+    NMIP4Config *ip4config = NULL;
+    NMIP4Address *ipaddr = NULL;
+    NMDevice *candidate = NULL;
+    struct in_addr tmp_addr;
+    const GPtrArray *devices;
+    const char *iface;
+    char ipstr[INET_ADDRSTRLEN+1];
+
+    if (ifname == NULL) {
+        return NULL;
+    }
+
+    /* DCFIXME: add IPv6 once NM gains support */
+    if (family != AF_INET) {
+        return NULL;
+    }
+
+    g_type_init();
+
+    client = nm_client_new();
+    if (!client) {
+        return NULL;
+    }
+
+    if (nm_client_get_state(client) != NM_STATE_CONNECTED) {
+        g_object_unref(client);
+        return NULL;
+    }
+
+    devices = nm_client_get_devices(client);
+    for (i=0; i < devices->len; i++) {
+        candidate = g_ptr_array_index(devices, i);
+        iface = nm_device_get_iface(candidate);
+
+        if (nm_device_get_state(candidate) != NM_DEVICE_STATE_ACTIVATED)
+            continue;
+
+        if (!iface || strcmp(iface, ifname))
+            continue;
+
+        if (!(ip4config = nm_device_get_ip4_config(candidate)))
+            continue;
+
+        if (!(ipaddr = nm_ip4_config_get_addresses(ip4config)->data))
+            continue;
+
+        memset(&ipstr, '\0', sizeof(ipstr));
+        tmp_addr.s_addr = nm_ip4_address_get_address(ipaddr);
+
+        if (inet_ntop(AF_INET, &tmp_addr, ipstr, INET_ADDRSTRLEN) == NULL) {
+            g_object_unref(client);
+            return NULL;
+        }
+
+        g_object_unref(client);
+        return g_strdup(ipstr);
+    }
+
+    g_object_unref(client);
+    return NULL;
+}
+
+/* Given an interface's MAC address, return the name (e.g., eth0) in human
+ * readable format.  Return NULL for no match
+ */
+char *iface_mac2device(char *mac) {
+    struct nl_handle *handle = NULL;
+    struct nl_cache *cache = NULL;
+    struct rtnl_link *link = NULL;
+    struct nl_addr *mac_as_nl_addr = NULL;
+    char *retval = NULL;
+    int i, n;
+
+    if (mac == NULL) {
+        return NULL;
+    }
+
+    if ((mac_as_nl_addr = nl_addr_parse(mac, AF_LLC)) == NULL) {
+        return NULL;
+    }
+
+    if ((cache = _iface_get_link_cache(&handle)) == NULL) {
+        return NULL;
+    }
+
+    n = nl_cache_nitems(cache);
+    for (i = 0; i <= n; i++) {
+        struct nl_addr *addr;
+
+        if ((link = rtnl_link_get(cache, i)) == NULL) {
+            continue;
+        }
+
+        addr = rtnl_link_get_addr(link);
+
+        if (!nl_addr_cmp(mac_as_nl_addr, addr)) {
+            retval = strdup(rtnl_link_get_name(link));
+            rtnl_link_put(link);
+            break;
+        }
+
+        rtnl_link_put(link);
+    }
+
+    nl_close(handle);
+    nl_handle_destroy(handle);
+
+    return retval;
+}
+
+/*
+ * Given an interface name (e.g., eth0), return the MAC address in human
+ * readable format (e.g., 00:11:52:12:D9:A0).  Return NULL for no match.
+ */
+char *iface_mac2str(char *ifname) {
+    int buflen = 20;
+    char *buf = NULL;
+    struct nl_handle *handle = NULL;
+    struct nl_cache *cache = NULL;
+    struct rtnl_link *link = NULL;
+    struct nl_addr *addr = NULL;
+
+    if (ifname == NULL) {
+        return NULL;
+    }
+
+    if ((cache = _iface_get_link_cache(&handle)) == NULL) {
+        return NULL;
+    }
+
+    if ((link = rtnl_link_get_by_name(cache, ifname)) == NULL) {
+        goto mac2str_error2;
+    }
+
+    if ((addr = rtnl_link_get_addr(link)) == NULL) {
+        goto mac2str_error3;
+    }
+
+    if ((buf = calloc(sizeof(char *), buflen)) == NULL) {
+        goto mac2str_error4;
+    }
+
+    if ((buf = nl_addr2str(addr, buf, buflen)) != NULL) {
+        char *oldbuf = buf;
+        buf = g_ascii_strup(buf, -1);
+        free(oldbuf);
+    }
+
+mac2str_error4:
+    nl_addr_destroy(addr);
+mac2str_error3:
+    rtnl_link_put(link);
+mac2str_error2:
+    nl_close(handle);
+    nl_handle_destroy(handle);
+
+    return buf;
+}
+
+/*
+ * Convert an IPv4 CIDR prefix to a dotted-quad netmask.  Return NULL on
+ * failure.
+ */
+struct in_addr *iface_prefix2netmask(int prefix) {
+    int mask = 0;
+    char *buf = NULL;
+    struct in_addr *ret;
+
+    if ((buf = calloc(sizeof(char *), INET_ADDRSTRLEN + 1)) == NULL) {
+        return NULL;
+    }
+
+    mask = htonl(~((1 << (32 - prefix)) - 1));
+
+    if (inet_ntop(AF_INET, (struct in_addr *) &mask, buf,
+                  INET_ADDRSTRLEN) == NULL) {
+        return NULL;
+    }
+
+    if ((ret = calloc(sizeof(struct in_addr), 1)) == NULL) {
+        return NULL;
+    }
+
+    memcpy(ret, (struct in_addr *) &mask, sizeof(struct in_addr));
+    return ret;
+}
+
+/*
+ * Initialize a new iface_t structure to default values.
+ */
+void iface_init_iface_t(iface_t *iface) {
+    int i;
+
+    memset(&iface->device, '\0', sizeof(iface->device));
+    memset(&iface->ipaddr, 0, sizeof(iface->ipaddr));
+    memset(&iface->netmask, 0, sizeof(iface->netmask));
+    memset(&iface->broadcast, 0, sizeof(iface->broadcast));
+    memset(&iface->ip6addr, 0, sizeof(iface->ip6addr));
+    memset(&iface->gateway, 0, sizeof(iface->gateway));
+    memset(&iface->gateway6, 0, sizeof(iface->gateway6));
+
+    for (i = 0; i < MAXNS; i++) {
+        iface->dns[i] = NULL;
+    }
+
+    iface->macaddr = NULL;
+    iface->ip6prefix = 0;
+    iface->nextserver = NULL;
+    iface->bootfile = NULL;
+    iface->numdns = 0;
+    iface->hostname = NULL;
+    iface->domain = NULL;
+    iface->search = NULL;
+    iface->dhcptimeout = 0;
+    iface->vendorclass = NULL;
+    iface->ssid = NULL;
+    iface->wepkey = NULL;
+    iface->mtu = 0;
+    iface->subchannels = NULL;
+    iface->portname = NULL;
+    iface->peerid = NULL;
+    iface->nettype = NULL;
+    iface->ctcprot = NULL;
+    iface->layer2 = NULL;
+    iface->portno = NULL;
+    iface->flags = 0;
+    iface->ipv4method = IPV4_UNUSED_METHOD;
+    iface->ipv6method = IPV6_UNUSED_METHOD;
+
+    return;
+}
+
+/*
+ * Given a pointer to a struct in_addr, return 1 if it contains a valid
+ * address, 0 otherwise.
+ */
+int iface_have_in_addr(struct in_addr *addr) {
+    return _iface_have_valid_addr(addr, AF_INET, INET_ADDRSTRLEN);
+}
+
+/*
+ * Given a pointer to a struct in6_addr, return 1 if it contains a valid
+ * address, 0 otherwise.
+ */
+int iface_have_in6_addr(struct in6_addr *addr6) {
+    return _iface_have_valid_addr(addr6, AF_INET6, INET6_ADDRSTRLEN);
+}
+
+/* Check if NM has an active connection */
+gboolean is_nm_connected(void) {
+    NMState state;
+    NMClient *client = NULL;
+
+    g_type_init();
+
+    client = nm_client_new();
+    if (!client)
+        return FALSE;
+
+    state = nm_client_get_state(client);
+    g_object_unref(client);
+
+    if (state == NM_STATE_CONNECTED)
+        return TRUE;
+    else
+        return FALSE;
+}
+
+/* Check if NM is already running */
+gboolean is_nm_running(void) {
+    gboolean running;
+    NMClient *client = NULL;
+
+    g_type_init();
+
+    client = nm_client_new();
+    if (!client)
+        return FALSE;
+
+    running = nm_client_get_manager_running(client);
+    g_object_unref(client);
+    return running;
+}
+
+/*
+ * Wait for NetworkManager to appear on the system bus
+ */
+int wait_for_nm(void) {
+    int count = 0;
+
+    /* send message and block until a reply or error comes back */
+    while (count < 45) {
+        if (is_nm_running())
+            return 0;
+
+        sleep(1);
+        count++;
+    }
+
+    return 1;
+}
+
+/*
+ * Start NetworkManager -- requires that you have already written out the
+ * control files in /etc/sysconfig for the interface.
+ */
+int iface_start_NetworkManager(void) {
+    pid_t pid;
+
+    if (is_nm_running())
+        return 0;  /* already running */
+
+    /* Start NetworkManager */
+    pid = fork();
+    if (pid == 0) {
+        if (setpgrp() == -1) {
+            exit(1);
+        }
+
+        if (_iface_redirect_io("/dev/null", STDIN_FILENO, O_RDONLY) ||
+            _iface_redirect_io(OUTPUT_TERMINAL, STDOUT_FILENO, O_WRONLY) ||
+            _iface_redirect_io(OUTPUT_TERMINAL, STDERR_FILENO, O_WRONLY)) {
+            exit(2);
+        }
+
+        if (execl(NETWORKMANAGER, NETWORKMANAGER,
+                  "--pid-file=/var/run/NetworkManager/NetworkManager.pid",
+                  NULL) == -1) {
+            exit(3);
+        }
+    } else if (pid == -1) {
+        return 1;
+    } else {
+        return wait_for_nm();
+    }
+
+    return 0;
+}
+
+/*
+ * Set the MTU on the specified device.
+ */
+int iface_set_interface_mtu(char *ifname, int mtu) {
+    int ret = 0;
+    struct nl_handle *handle = NULL;
+    struct nl_cache *cache = NULL;
+    struct rtnl_link *link = NULL;
+    struct rtnl_link *request = NULL;
+
+    if (ifname == NULL) {
+        return -1;
+    }
+
+    if (mtu <= 0) {
+        return -2;
+    }
+
+    if ((cache = _iface_get_link_cache(&handle)) == NULL) {
+        return -3;
+    }
+
+    if ((link = rtnl_link_get_by_name(cache, ifname)) == NULL) {
+        ret = -4;
+        goto ifacemtu_error1;
+    }
+
+    request = rtnl_link_alloc();
+    rtnl_link_set_mtu(request, mtu);
+
+    if (rtnl_link_change(handle, link, request, 0)) {
+        ret = -5;
+        goto ifacemtu_error2;
+    }
+
+ifacemtu_error2:
+    rtnl_link_put(link);
+ifacemtu_error1:
+    nl_close(handle);
+    nl_handle_destroy(handle);
+
+    return ret;
+}
diff --git a/pyanaconda/isys/iface.h b/pyanaconda/isys/iface.h
new file mode 100644
index 0000000..820d10b
--- /dev/null
+++ b/pyanaconda/isys/iface.h
@@ -0,0 +1,166 @@
+/*
+ * iface.h - Network interface configuration API
+ *
+ * Copyright (C) 2006, 2007, 2008  Red Hat, 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; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ *
+ * Author(s): David Cantrell <dcantrell@xxxxxxxxxx>
+ */
+
+#ifndef ISYSIFACE_H
+#define ISYSIFACE_H
+
+#include <resolv.h>
+#include <net/if.h>
+#include <netlink/cache.h>
+#include <netlink/socket.h>
+#include <glib.h>
+
+/* Enumerated types used in iface.c as well as loader's network code */
+enum { IPUNUSED = -1, IPV4, IPV6 };
+
+enum { IPV4_UNUSED_METHOD, IPV4_DHCP_METHOD, IPV4_MANUAL_METHOD, IPV4_IBFT_METHOD, IPV4_IBFT_DHCP_METHOD };
+enum { IPV6_UNUSED_METHOD, IPV6_AUTO_METHOD, IPV6_DHCP_METHOD,
+       IPV6_MANUAL_METHOD };
+
+#define IPV4_FIRST_METHOD IPV4_DHCP_METHOD
+#define IPV4_LAST_METHOD  IPV4_MANUAL_METHOD
+
+#define IPV6_FIRST_METHOD IPV6_AUTO_METHOD
+#define IPV6_LAST_METHOD  IPV6_MANUAL_METHOD
+
+/* Flags for the iface_t (do we need these?) */
+#define IFACE_FLAGS_NO_WRITE_RESOLV_CONF (((uint64_t) 1) << 0)
+#define IFACE_NO_WRITE_RESOLV_CONF(a)    ((a) & IFACE_FLAGS_NO_WRITE_RESOLV_CONF)
+
+/* Macros for starting NetworkManager */
+#define NETWORKMANAGER  "/usr/sbin/NetworkManager"
+
+/* Per-interface configuration information */
+typedef struct _iface_t {
+    /* device name (e.g., eth0) */
+    char device[IF_NAMESIZE];
+
+    /* MAC address as xx:xx:xx:xx:xx:xx */
+    char *macaddr;
+
+    /* IPv4 (store addresses in in_addr format, use inet_pton() to display) */
+    struct in_addr ipaddr;
+    struct in_addr netmask;
+    struct in_addr broadcast;
+
+    /* IPv6 (store addresses in in6_addr format, prefix is just an int) */
+    struct in6_addr ip6addr;
+    int ip6prefix;
+
+    /* Gateway settings */
+    struct in_addr gateway;
+    struct in6_addr gateway6;
+
+    /* BOOTP (these can be IPv4 or IPv6, store human-readable version as str) */
+    char *nextserver;
+    char *bootfile;
+
+    /* DNS (these can be IPv4 or IPv6, store human-readable version as str) */
+    char *dns[MAXNS];
+    int numdns;
+    char *hostname;
+    char *domain;
+    char *search;
+
+    /* Misc DHCP settings */
+    int dhcptimeout;
+    char *vendorclass;
+
+    /* Wireless settings */
+    char *ssid;
+    char *wepkey;
+
+    /* s390 specifics */
+    int mtu;
+    char *subchannels;
+    char *portname;
+    char *peerid;
+    char *nettype;
+    char *ctcprot;
+    char *layer2;
+    char *portno;
+
+    /* flags */
+    uint64_t flags;
+    int ipv4method;
+    int ipv6method;
+    int isiBFT;
+} iface_t;
+
+/* Function prototypes */
+
+/*
+ * Given an interface name (e.g., eth0) and address family (e.g., AF_INET),
+ * return the IP address in human readable format (i.e., the output from
+ * inet_ntop()).  Return NULL for no match or error.
+ */
+char *iface_ip2str(char *, int);
+
+/*
+ * Given an interface name (e.g., eth0), return the MAC address in human
+ * readable format (e.g., 00:11:52:12:D9:A0).  Return NULL for no match.
+ */
+char *iface_mac2str(char *);
+
+/* Given an interface's MAC address, return the name (e.g., eth0) in human
+ * readable format.  Return NULL for no match
+ */
+char *iface_mac2device(char *);
+
+/*
+ * Convert an IPv4 CIDR prefix to a dotted-quad netmask.  Return NULL on
+ * failure.
+ */
+struct in_addr *iface_prefix2netmask(int);
+
+/*
+ * Initialize a new iface_t structure to default values.
+ */
+void iface_init_iface_t(iface_t *);
+
+/*
+ * Given a pointer to a struct in_addr, return 1 if it contains a valid
+ * address, 0 otherwise.
+ */
+int iface_have_in_addr(struct in_addr *addr);
+
+/*
+ * Given a pointer to a struct in6_addr, return 1 if it contains a valid
+ * address, 0 otherwise.
+ */
+int iface_have_in6_addr(struct in6_addr *addr6);
+
+/*
+ * Checks if NetworkManager has an active connection.
+ */
+gboolean is_nm_connected(void);
+
+/*
+ * Start NetworkManager
+ */
+int iface_start_NetworkManager(void);
+
+/*
+ * Set Maximum Transfer Unit (MTU) on specified interface
+ */
+int iface_set_interface_mtu(char *ifname, int mtu);
+
+#endif /* ISYSIFACE_H */
diff --git a/pyanaconda/isys/imount.c b/pyanaconda/isys/imount.c
new file mode 100644
index 0000000..ed0f5a7
--- /dev/null
+++ b/pyanaconda/isys/imount.c
@@ -0,0 +1,328 @@
+/*
+ * imount.c
+ *
+ * Copyright (C) 2007, 2008, 2009  Red Hat, Inc.  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 as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <errno.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/mount.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <unistd.h>
+
+#include "imount.h"
+#include "log.h"
+
+#define _(foo) foo
+
+static int mkdirIfNone(char * directory);
+
+static int readFD(int fd, char **buf) {
+    char *p;
+    size_t size = 4096;
+    int s, filesize = 0;
+
+    *buf = calloc(4096, sizeof (char));
+    if (*buf == NULL)
+        abort();
+
+    do {
+        p = &(*buf)[filesize];
+        s = read(fd, p, 4096);
+        if (s < 0)
+            break;
+
+        filesize += s;
+        if (s == 0)
+           break;
+
+        size += s;
+        *buf = realloc(*buf, size);
+        if (*buf == NULL)
+            abort();
+    } while (1);
+
+    if (filesize == 0 && s < 0) {
+        free(*buf);
+        *buf = NULL;
+        return -1;
+    }
+
+    return filesize;
+}
+
+static size_t rstrip(char *str) {
+    size_t len = strlen(str);
+    if (len > 0 && str[len-1] == '\n') {
+        str[len-1] = '\0';
+        --len;
+    }
+    return len;
+}
+
+int mountCommandWrapper(int mode, char *dev, char *where, char *fs,
+                        char *options, char **err) {
+    int rc, child, status;
+    int stdout_pipe[2], stderr_pipe[2];
+    char *opts = NULL, *device = NULL, *cmd = NULL;
+
+    switch (mode) {
+    case IMOUNT_MODE_MOUNT:
+    case IMOUNT_MODE_BIND:
+        cmd = "/bin/mount";
+        if (mkdirChain(where))
+            return IMOUNT_ERR_ERRNO;
+        break;
+    case IMOUNT_MODE_UMOUNT:
+        cmd = "/bin/umount";
+        break;
+    default:
+        return IMOUNT_ERR_MODE;
+    }
+
+    if (mode == IMOUNT_MODE_MOUNT) {
+        if (strstr(fs, "nfs")) {
+            if (options) {
+                if (asprintf(&opts, "%s,nolock", options) == -1) {
+                    fprintf(stderr, "%s: %d: %s\n", __func__, __LINE__,
+                            strerror(errno));
+                    fflush(stderr);
+                    abort();
+                }
+            } else {
+                opts = strdup("nolock");
+            }
+
+            device = strdup(dev);
+        } else {
+            if ((options && strstr(options, "bind") == NULL) &&
+                strncmp(dev, "LABEL=", 6) && strncmp(dev, "UUID=", 5) &&
+                *dev != '/') {
+               if (asprintf(&device, "/dev/%s", dev) == -1) {
+                   fprintf(stderr, "%s: %d: %s\n", __func__, __LINE__,
+                           strerror(errno));
+                   fflush(stderr);
+                   abort();
+               }
+            } else {
+               device = strdup(dev);
+            }
+
+            if (options)
+                opts = strdup(options);
+        }
+    }
+
+    if (pipe(stdout_pipe))
+        return IMOUNT_ERR_ERRNO;
+    if (pipe(stderr_pipe))
+        return IMOUNT_ERR_ERRNO;
+
+    if (!(child = fork())) {
+        int tty_fd;
+
+        close(stdout_pipe[0]);
+        close(stderr_pipe[0]);
+
+        /* Pull stdin from /dev/tty5 and redirect stdout and stderr to the pipes
+         *  so we can log the output and put error messages into exceptions.
+         *  We'll only use these messages should mount also return an error
+         *  code.
+         */
+        tty_fd = open("/dev/tty5", O_RDONLY);
+        close(STDIN_FILENO);
+        dup2(tty_fd, STDIN_FILENO);
+        close(tty_fd);
+
+        close(STDOUT_FILENO);
+        dup2(stdout_pipe[1], STDOUT_FILENO);
+        close(STDERR_FILENO);
+        dup2(stderr_pipe[1], STDERR_FILENO);
+
+        if (mode == IMOUNT_MODE_MOUNT) {
+            if (opts) {
+                logProgramMessage(INFO, "Running... %s -n -t %s -o %s %s %s",
+                        cmd, fs, opts, device, where);
+                rc = execl(cmd, cmd,
+                           "-n", "-t", fs, "-o", opts, device, where, NULL);
+                exit(1);
+            } else {
+                logProgramMessage(INFO, "Running... %s -n -t %s %s %s",
+                        cmd, fs, device, where);
+                rc = execl(cmd, cmd, "-n", "-t", fs, device, where, NULL);
+                exit(1);
+            }
+        } else if (mode == IMOUNT_MODE_BIND) {
+            logProgramMessage(INFO, "Running... %s --bind %s %s",
+                              cmd, dev, where);
+            rc = execl(cmd, cmd, "--bind", dev, where, NULL);
+            exit(1);
+        } else if (mode == IMOUNT_MODE_UMOUNT) {
+            logProgramMessage(INFO, "Running... %s %s", cmd, where);
+            rc = execl(cmd, cmd, where, NULL);
+            exit(1);
+        } else {
+            logProgramMessage(ERROR, "Running... Unknown imount mode: %d\n", mode);
+            exit(1);
+        }
+    }
+
+    close(stdout_pipe[1]);
+    close(stderr_pipe[1]);
+
+    char *buffer = NULL;
+    /* In case when when the stderr pipe gets enough data to fill the kernel
+     * buffer we might see a deadlock as this will block the mount program on
+     * its next write(). The buffer size is 65kB though so we should be safe.
+     */
+    rc = readFD(stdout_pipe[0], &buffer);
+    if (rc > 0) {
+        rstrip(buffer);
+        logProgramMessage(INFO, buffer);
+        free(buffer);
+        buffer = NULL;
+    }
+    rc = readFD(stderr_pipe[0], &buffer);
+    if (rc > 0) {
+        rstrip(buffer);
+        logProgramMessage(ERROR, buffer);
+        if (err != NULL)
+            *err = buffer;
+        else
+            free(buffer);
+    }
+    close(stdout_pipe[0]);
+    close(stderr_pipe[0]);
+
+    waitpid(child, &status, 0);
+
+    if (opts) {
+        free(opts);
+    }
+
+    if (device) {
+        free(device);
+    }
+
+    if (!WIFEXITED(status))
+        return IMOUNT_ERR_OTHER;
+    else if ( (rc = WEXITSTATUS(status)) ) {
+        /* Refer to 'man mount' for the meaning of the error codes. */
+        switch (rc) {
+        case 1:
+            return IMOUNT_ERR_PERMISSIONS;
+        case 2:
+            return IMOUNT_ERR_SYSTEM;
+        case 4:
+            return IMOUNT_ERR_MOUNTINTERNAL;
+        case 8:
+            return IMOUNT_ERR_USERINTERRUPT;
+        case 16:
+            return IMOUNT_ERR_MTAB;
+        case 32:
+            return IMOUNT_ERR_MOUNTFAILURE;
+        case 64:
+            return IMOUNT_ERR_PARTIALSUCC;
+        default:
+            return IMOUNT_ERR_OTHER;
+        }
+    }
+
+    return 0;
+}
+
+int doBindMount(char* path, char *where, char **err) {
+    return mountCommandWrapper(IMOUNT_MODE_BIND,
+                               path, where, NULL, NULL, err);
+}
+
+int doPwMount(char *dev, char *where, char *fs, char *options, char **err) {
+    return mountCommandWrapper(IMOUNT_MODE_MOUNT,
+                               dev, where, fs, options, err);
+}
+
+int doPwUmount(char *where, char **err) {
+    return mountCommandWrapper(IMOUNT_MODE_UMOUNT,
+                               NULL, where, NULL, NULL, err);
+}
+
+int mkdirChain(char * origChain) {
+    char * chain;
+    char * chptr;
+
+    chain = alloca(strlen(origChain) + 1);
+    strcpy(chain, origChain);
+    chptr = chain;
+
+    while ((chptr = strchr(chptr, '/'))) {
+	*chptr = '\0';
+	if (mkdirIfNone(chain)) {
+	    *chptr = '/';
+	    return IMOUNT_ERR_ERRNO;
+	}
+
+	*chptr = '/';
+	chptr++;
+    }
+
+    if (mkdirIfNone(chain))
+	return IMOUNT_ERR_ERRNO;
+
+    return 0;
+}
+
+/* Returns true iff it is possible that the mount command that have returned
+ * 'errno' might succeed at a later time (think e.g. not yet initialized USB
+ * device, etc.) */
+int mountMightSucceedLater(int mountRc)
+{
+    int rc;
+    switch (mountRc) {
+    case IMOUNT_ERR_MOUNTFAILURE:
+        rc = 1;
+        break;
+    default:
+        rc = 0;
+    }
+    return rc;
+}
+
+static int mkdirIfNone(char * directory) {
+    int rc, mkerr;
+    char * chptr;
+
+    /* If the file exists it *better* be a directory -- I'm not going to
+       actually check or anything */
+    if (!access(directory, X_OK)) return 0;
+
+    /* if the path is '/' we get ENOFILE not found" from mkdir, rather
+       then EEXIST which is weird */
+    for (chptr = directory; *chptr; chptr++)
+        if (*chptr != '/') break;
+    if (!*chptr) return 0;
+
+    rc = mkdir(directory, 0755);
+    mkerr = errno;
+
+    if (!rc || mkerr == EEXIST) return 0;
+
+    return IMOUNT_ERR_ERRNO;
+}
diff --git a/pyanaconda/isys/imount.h b/pyanaconda/isys/imount.h
new file mode 100644
index 0000000..d1b7cf3
--- /dev/null
+++ b/pyanaconda/isys/imount.h
@@ -0,0 +1,50 @@
+/*
+ * imount.h
+ *
+ * Copyright (C) 2007, 2008, 2009  Red Hat, Inc.  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 as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef H_IMOUNT
+#define H_IMOUNT
+
+#define IMOUNT_ERR_ERRNO          1
+#define IMOUNT_ERR_OTHER          2
+#define IMOUNT_ERR_MODE           3
+#define IMOUNT_ERR_PERMISSIONS    4
+#define IMOUNT_ERR_SYSTEM         5
+#define IMOUNT_ERR_MOUNTINTERNAL  6
+#define IMOUNT_ERR_USERINTERRUPT  7
+#define IMOUNT_ERR_MTAB           8
+#define IMOUNT_ERR_MOUNTFAILURE   9
+#define IMOUNT_ERR_PARTIALSUCC    10
+
+#include <sys/mount.h>		/* for umount() */
+
+#define IMOUNT_RDONLY  1
+#define IMOUNT_BIND    2
+#define IMOUNT_REMOUNT 4
+
+#define IMOUNT_MODE_MOUNT  1
+#define IMOUNT_MODE_UMOUNT 2
+#define IMOUNT_MODE_BIND   3
+
+int doBindMount(char* path, char *where, char **err);
+int doPwMount(char *dev, char *where, char *fs, char *options, char **err);
+int doPwUmount(char *where, char **err);
+int mkdirChain(char * origChain);
+int mountMightSucceedLater(int mountRc);
+
+#endif
diff --git a/pyanaconda/isys/isofs.c b/pyanaconda/isys/isofs.c
new file mode 100644
index 0000000..bb5a44a
--- /dev/null
+++ b/pyanaconda/isys/isofs.c
@@ -0,0 +1,55 @@
+/*
+ * isofs.c
+ *
+ * Copyright (C) 2007  Red Hat, Inc.  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 as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <fcntl.h>
+#include <string.h>
+#include <unistd.h>
+
+#define BLOCK_SIZE 2048
+ 
+/* returns 1 if file is an ISO, 0 otherwise */
+int fileIsIso(const char * file) {
+    int blkNum;
+    char magic[5];
+    int fd;
+
+    fd = open(file, O_RDONLY);
+    if (fd < 0)
+	return 0;
+
+    for (blkNum = 16; blkNum < 100; blkNum++) {
+	if (lseek(fd, blkNum * BLOCK_SIZE + 1, SEEK_SET) < 0) {
+	    close(fd);
+	    return 0;
+	}
+
+	if (read(fd, magic, sizeof(magic)) != sizeof(magic)) {
+	    close(fd);
+	    return 0;
+	}
+
+	if (!strncmp(magic, "CD001", 5)) {
+	    close(fd);
+	    return 1;
+	}
+    }
+
+    close(fd); 
+    return 0;
+}
diff --git a/pyanaconda/isys/isys.c b/pyanaconda/isys/isys.c
new file mode 100644
index 0000000..409170b
--- /dev/null
+++ b/pyanaconda/isys/isys.c
@@ -0,0 +1,701 @@
+/*
+ * isys.c
+ *
+ * Copyright (C) 2007, 2008, 2009  Red Hat, Inc.  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 as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <Python.h>
+
+#include <stdio.h>
+#include <dirent.h>
+#include <errno.h>
+#define u32 __u32
+#include <ext2fs/ext2fs.h>
+#include <fcntl.h>
+/* Need to tell loop.h what the actual dev_t type is. */
+#undef dev_t
+#if defined(__alpha) || (defined(__sparc__) && defined(__arch64__))
+#define dev_t unsigned int
+#else
+#if defined(__x86_64__)
+#define dev_t unsigned long
+#else
+#define dev_t unsigned short
+#endif
+#endif
+#include <linux/loop.h>
+#undef dev_t
+#define dev_t dev_t
+#include <sys/ioctl.h>
+#include <sys/stat.h>
+#include <sys/sysmacros.h>
+#include <sys/time.h>
+#include <sys/utsname.h>
+#include <sys/vfs.h>
+#include <unistd.h>
+#include <resolv.h>
+#include <scsi/scsi.h>
+#include <scsi/scsi_ioctl.h>
+#include <sys/vt.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <arpa/inet.h>
+#include <linux/fb.h>
+#include <libintl.h>
+#include <libgen.h>
+#include <linux/cdrom.h>
+#include <linux/major.h>
+#include <linux/raid/md_u.h>
+#include <linux/raid/md_p.h>
+#include <signal.h>
+#include <execinfo.h>
+
+#include <blkid/blkid.h>
+
+#include <X11/Xlib.h>
+#include <X11/XKBlib.h>
+#include <X11/keysym.h>
+
+#include "iface.h"
+#include "isys.h"
+#include "imount.h"
+#include "ethtool.h"
+#include "lang.h"
+#include "eddsupport.h"
+#include "auditd.h"
+#include "imount.h"
+#include "log.h"
+
+#ifndef CDROMEJECT
+#define CDROMEJECT 0x5309
+#endif
+
+static PyObject * doMount(PyObject * s, PyObject * args);
+static PyObject * doUMount(PyObject * s, PyObject * args);
+static PyObject * doSwapon(PyObject * s, PyObject * args);
+static PyObject * doSwapoff(PyObject * s, PyObject * args);
+static PyObject * doLoSetup(PyObject * s, PyObject * args);
+static PyObject * doUnLoSetup(PyObject * s, PyObject * args);
+static PyObject * doLoChangeFd(PyObject * s, PyObject * args);
+static PyObject * doWipeRaidSuperblock(PyObject * s, PyObject * args);
+static PyObject * doGetRaidChunkSize(PyObject * s, PyObject * args);
+static PyObject * doDevSpaceFree(PyObject * s, PyObject * args);
+static PyObject * doResetResolv(PyObject * s, PyObject * args);
+static PyObject * doLoadKeymap(PyObject * s, PyObject * args);
+static PyObject * doExt2Dirty(PyObject * s, PyObject * args);
+static PyObject * doExt2HasJournal(PyObject * s, PyObject * args);
+static PyObject * doEjectCdrom(PyObject * s, PyObject * args);
+static PyObject * doVtActivate(PyObject * s, PyObject * args);
+static PyObject * doisPseudoTTY(PyObject * s, PyObject * args);
+static PyObject * doisVioConsole(PyObject * s);
+static PyObject * doSync(PyObject * s, PyObject * args);
+static PyObject * doisIsoImage(PyObject * s, PyObject * args);
+static PyObject * printObject(PyObject * s, PyObject * args);
+static PyObject * py_bind_textdomain_codeset(PyObject * o, PyObject * args);
+static PyObject * doSegvHandler(PyObject *s, PyObject *args);
+static PyObject * doAuditDaemon(PyObject *s);
+static PyObject * doPrefixToNetmask(PyObject *s, PyObject *args);
+static PyObject * doGetBlkidData(PyObject * s, PyObject * args);
+static PyObject * doIsCapsLockEnabled(PyObject * s, PyObject * args);
+static PyObject * doGetLinkStatus(PyObject * s, PyObject * args);
+static PyObject * doGetAnacondaVersion(PyObject * s, PyObject * args);
+static PyObject * doInitLog(PyObject * s);
+
+static PyMethodDef isysModuleMethods[] = {
+    { "ejectcdrom", (PyCFunction) doEjectCdrom, METH_VARARGS, NULL },
+    { "e2dirty", (PyCFunction) doExt2Dirty, METH_VARARGS, NULL },
+    { "e2hasjournal", (PyCFunction) doExt2HasJournal, METH_VARARGS, NULL },
+    { "devSpaceFree", (PyCFunction) doDevSpaceFree, METH_VARARGS, NULL },
+    { "wiperaidsb", (PyCFunction) doWipeRaidSuperblock, METH_VARARGS, NULL },
+    { "getraidchunk", (PyCFunction) doGetRaidChunkSize, METH_VARARGS, NULL },
+    { "lochangefd", (PyCFunction) doLoChangeFd, METH_VARARGS, NULL },
+    { "losetup", (PyCFunction) doLoSetup, METH_VARARGS, NULL },
+    { "unlosetup", (PyCFunction) doUnLoSetup, METH_VARARGS, NULL },
+    { "mount", (PyCFunction) doMount, METH_VARARGS, NULL },
+    { "umount", (PyCFunction) doUMount, METH_VARARGS, NULL },
+    { "resetresolv", (PyCFunction) doResetResolv, METH_VARARGS, NULL },
+    { "swapon",  (PyCFunction) doSwapon, METH_VARARGS, NULL },
+    { "swapoff",  (PyCFunction) doSwapoff, METH_VARARGS, NULL },
+    { "loadKeymap", (PyCFunction) doLoadKeymap, METH_VARARGS, NULL },
+    { "vtActivate", (PyCFunction) doVtActivate, METH_VARARGS, NULL},
+    { "isPseudoTTY", (PyCFunction) doisPseudoTTY, METH_VARARGS, NULL},
+    { "isVioConsole", (PyCFunction) doisVioConsole, METH_NOARGS, NULL},
+    { "sync", (PyCFunction) doSync, METH_VARARGS, NULL},
+    { "isisoimage", (PyCFunction) doisIsoImage, METH_VARARGS, NULL},
+    { "printObject", (PyCFunction) printObject, METH_VARARGS, NULL},
+    { "bind_textdomain_codeset", (PyCFunction) py_bind_textdomain_codeset, METH_VARARGS, NULL},
+    { "handleSegv", (PyCFunction) doSegvHandler, METH_VARARGS, NULL },
+    { "auditdaemon", (PyCFunction) doAuditDaemon, METH_NOARGS, NULL },
+    { "prefix2netmask", (PyCFunction) doPrefixToNetmask, METH_VARARGS, NULL },
+    { "getblkid", (PyCFunction) doGetBlkidData, METH_VARARGS, NULL },
+    { "isCapsLockEnabled", (PyCFunction) doIsCapsLockEnabled, METH_VARARGS, NULL },
+    { "getLinkStatus", (PyCFunction) doGetLinkStatus, METH_VARARGS, NULL },
+    { "getAnacondaVersion", (PyCFunction) doGetAnacondaVersion, METH_VARARGS, NULL },
+    { "initLog", (PyCFunction) doInitLog, METH_VARARGS, NULL },
+    { NULL, NULL, 0, NULL }
+} ;
+
+static PyObject * doUnLoSetup(PyObject * s, PyObject * args) {
+    int loopfd;
+
+    if (!PyArg_ParseTuple(args, "i", &loopfd)) return NULL;
+    if (ioctl(loopfd, LOOP_CLR_FD, 0)) {
+	PyErr_SetFromErrno(PyExc_SystemError);
+	return NULL;
+    }
+
+    Py_INCREF(Py_None);
+    return Py_None;
+}
+
+/* XXX - msw */
+#ifndef LOOP_CHANGE_FD
+#define LOOP_CHANGE_FD	0x4C06
+#endif
+
+static PyObject * doLoChangeFd(PyObject * s, PyObject * args) {
+    int loopfd;
+    int targfd;
+
+    if (!PyArg_ParseTuple(args, "ii", &loopfd, &targfd)) 
+	return NULL;
+    if (ioctl(loopfd, LOOP_CHANGE_FD, targfd)) {
+	PyErr_SetFromErrno(PyExc_SystemError);
+	return NULL;
+    }
+
+    Py_INCREF(Py_None);
+    return Py_None;
+}
+
+static PyObject * doLoSetup(PyObject * s, PyObject * args) {
+    int loopfd;
+    int targfd;
+    struct loop_info loopInfo;
+    char * loopName;
+
+    if (!PyArg_ParseTuple(args, "iis", &loopfd, &targfd, &loopName)) 
+	return NULL;
+    if (ioctl(loopfd, LOOP_SET_FD, targfd)) {
+	PyErr_SetFromErrno(PyExc_SystemError);
+	return NULL;
+    }
+
+    memset(&loopInfo, 0, sizeof(loopInfo));
+    strncpy(loopInfo.lo_name, basename(loopName), 63);
+
+    if (ioctl(loopfd, LOOP_SET_STATUS, &loopInfo)) {
+	PyErr_SetFromErrno(PyExc_SystemError);
+	return NULL;
+    }
+
+    Py_INCREF(Py_None);
+    return Py_None;
+}
+
+static PyObject * doUMount(PyObject * s, PyObject * args) {
+    char *err = NULL, *mntpoint = NULL;
+    int rc;
+
+    if (!PyArg_ParseTuple(args, "s", &mntpoint)) {
+        return NULL;
+    }
+
+    rc = doPwUmount(mntpoint, &err);
+    if (rc == IMOUNT_ERR_ERRNO) {
+        PyErr_SetFromErrno(PyExc_SystemError);
+    } else if (rc) {
+        PyObject *tuple = PyTuple_New(2);
+
+        PyTuple_SetItem(tuple, 0, PyInt_FromLong(rc));
+
+        if (err == NULL) {
+            Py_INCREF(Py_None);
+            PyTuple_SetItem(tuple, 1, Py_None);
+        } else {
+            PyTuple_SetItem(tuple, 1, PyString_FromString(err));
+        }
+
+        PyErr_SetObject(PyExc_SystemError, tuple);
+    }
+
+    if (rc) {
+        return NULL;
+    }
+
+    Py_INCREF(Py_None);
+    return Py_None;
+}
+
+static PyObject * doMount(PyObject * s, PyObject * args) {
+    char *err = NULL, *fs, *device, *mntpoint, *flags = NULL;
+    int rc;
+
+    if (!PyArg_ParseTuple(args, "sss|z", &fs, &device, &mntpoint,
+			  &flags)) return NULL;
+
+    rc = doPwMount(device, mntpoint, fs, flags, &err);
+    if (rc == IMOUNT_ERR_ERRNO)
+	PyErr_SetFromErrno(PyExc_SystemError);
+    else if (rc) {
+        PyObject *tuple = PyTuple_New(2);
+
+        PyTuple_SetItem(tuple, 0, PyInt_FromLong(rc));
+
+        if (err == NULL) {
+            Py_INCREF(Py_None);
+            PyTuple_SetItem(tuple, 1, Py_None);
+        } else {
+            PyTuple_SetItem(tuple, 1, PyString_FromString(err));
+        }
+
+        PyErr_SetObject(PyExc_SystemError, tuple);
+    }
+
+    if (rc) return NULL;
+
+    Py_INCREF(Py_None);
+    return Py_None;
+}
+
+#define BOOT_SIGNATURE	0xaa55	/* boot signature */
+#define BOOT_SIG_OFFSET	510	/* boot signature offset */
+
+int swapoff(const char * path);
+int swapon(const char * path, int priorty);
+
+static PyObject * doSwapoff (PyObject * s, PyObject * args) {
+    char * path;
+
+    if (!PyArg_ParseTuple(args, "s", &path)) return NULL;
+
+    if (swapoff (path)) {
+	PyErr_SetFromErrno(PyExc_SystemError);
+	return NULL;
+    }
+    
+    Py_INCREF(Py_None);
+    return Py_None;
+}
+
+static PyObject * doSwapon (PyObject * s, PyObject * args) {
+    char * path;
+
+    if (!PyArg_ParseTuple(args, "s", &path)) return NULL;
+
+    if (swapon (path, 0)) {
+	PyErr_SetFromErrno(PyExc_SystemError);
+	return NULL;
+    }
+    
+    Py_INCREF(Py_None);
+    return Py_None;
+}
+
+void init_isys(void) {
+    PyObject * m, * d;
+
+    m = Py_InitModule("_isys", isysModuleMethods);
+    d = PyModule_GetDict(m);
+
+    PyDict_SetItemString(d, "MIN_RAM", PyInt_FromLong(MIN_RAM));
+    PyDict_SetItemString(d, "MIN_GUI_RAM", PyInt_FromLong(MIN_GUI_RAM));
+    PyDict_SetItemString(d, "URL_INSTALL_EXTRA_RAM", PyInt_FromLong(URL_INSTALL_EXTRA_RAM));
+    PyDict_SetItemString(d, "EARLY_SWAP_RAM", PyInt_FromLong(EARLY_SWAP_RAM));
+}
+
+static PyObject * doPrefixToNetmask (PyObject * s, PyObject * args) {
+    int prefix = 0;
+    struct in_addr *mask = NULL;
+    char dst[INET_ADDRSTRLEN+1];
+
+    if (!PyArg_ParseTuple(args, "i", &prefix))
+        return NULL;
+
+    if ((mask = iface_prefix2netmask(prefix)) == NULL)
+        return NULL;
+
+    if (inet_ntop(AF_INET, mask, dst, INET_ADDRSTRLEN) == NULL)
+        return NULL;
+
+    return Py_BuildValue("s", dst);
+}
+
+static PyObject * doResetResolv(PyObject * s, PyObject * args) {
+    if (!PyArg_ParseTuple(args, "")) {
+        return NULL;
+    }
+
+    /* reinit the resolver so DNS changes take affect */
+    res_init();
+
+    Py_INCREF(Py_None);
+    return Py_None;
+}
+
+static PyObject * doWipeRaidSuperblock(PyObject * s, PyObject * args) {
+    int fd;
+    unsigned long size;
+    struct mdp_super_t * sb;
+
+    if (!PyArg_ParseTuple(args, "i", &fd)) return NULL;
+
+    if (ioctl(fd, BLKGETSIZE, &size)) {
+	PyErr_SetFromErrno(PyExc_SystemError);
+	return NULL;
+    }
+
+    /* put the size in 1k blocks */
+    size >>= 1;
+
+    if (lseek64(fd, ((off64_t) 512) * (off64_t) MD_NEW_SIZE_SECTORS(size), SEEK_SET) < 0) {
+	PyErr_SetFromErrno(PyExc_SystemError);
+	return NULL;
+    } 
+
+    sb = malloc(sizeof(mdp_super_t));
+    sb = memset(sb, '\0', sizeof(mdp_super_t));
+
+    if (write(fd, sb, sizeof(sb)) != sizeof(sb)) {
+	PyErr_SetFromErrno(PyExc_SystemError);
+	return NULL;
+    }
+
+    return Py_None;
+}
+
+static PyObject * doGetRaidChunkSize(PyObject * s, PyObject * args) {
+    int fd;
+    unsigned long size;
+    mdp_super_t sb;
+
+    if (!PyArg_ParseTuple(args, "i", &fd)) return NULL;
+
+    if (ioctl(fd, BLKGETSIZE, &size)) {
+	PyErr_SetFromErrno(PyExc_SystemError);
+	return NULL;
+    }
+
+    /* put the size in 1k blocks */
+    size >>= 1;
+
+    if (lseek64(fd, ((off64_t) 512) * (off64_t) MD_NEW_SIZE_SECTORS(size), SEEK_SET) < 0) {
+	PyErr_SetFromErrno(PyExc_SystemError);
+	return NULL;
+    } 
+
+    if (read(fd, &sb, sizeof(sb)) != sizeof(sb)) {
+	PyErr_SetFromErrno(PyExc_SystemError);
+	return NULL;
+    }
+
+    if (sb.md_magic != MD_SB_MAGIC) {
+	PyErr_SetString(PyExc_ValueError, "bad md magic on device");
+	return NULL;
+    }
+
+    return Py_BuildValue("i", sb.chunk_size / 1024);
+}
+
+static int get_bits(unsigned long long v) {
+    int  b = 0;
+    
+    if ( v & 0xffffffff00000000LLU ) { b += 32; v >>= 32; }
+    if ( v & 0xffff0000LLU ) { b += 16; v >>= 16; }
+    if ( v & 0xff00LLU ) { b += 8; v >>= 8; }
+    if ( v & 0xf0LLU ) { b += 4; v >>= 4; }
+    if ( v & 0xcLLU ) { b += 2; v >>= 2; }
+    if ( v & 0x2LLU ) b++;
+    
+    return v ? b + 1 : b;
+}
+
+static PyObject * doDevSpaceFree(PyObject * s, PyObject * args) {
+    char * path;
+    struct statfs sb;
+    unsigned long long size;
+
+    if (!PyArg_ParseTuple(args, "s", &path)) return NULL;
+
+    if (statfs(path, &sb)) {
+	PyErr_SetFromErrno(PyExc_SystemError);
+	return NULL;
+    }
+
+    /* Calculate a saturated addition to prevent oveflow. */
+    if ( get_bits(sb.f_bfree) + get_bits(sb.f_bsize) <= 64 )
+        size = (unsigned long long)sb.f_bfree * sb.f_bsize;
+    else
+        size = ~0LLU;
+
+    return PyLong_FromUnsignedLongLong(size>>20);
+}
+
+static PyObject * doLoadKeymap (PyObject * s, PyObject * args) {
+    char * keymap;
+    int ret;
+
+    if (!PyArg_ParseTuple(args, "s", &keymap)) return NULL;
+
+    ret = isysLoadKeymap (keymap);
+    if (ret) {
+	errno = -ret;
+	PyErr_SetFromErrno(PyExc_SystemError);
+	return NULL;
+    }
+    
+    Py_INCREF(Py_None);
+    return Py_None;
+}
+
+static PyObject * doExt2Dirty(PyObject * s, PyObject * args) {
+    char * device;
+    ext2_filsys fsys;
+    int rc;
+    int clean;
+
+    if (!PyArg_ParseTuple(args, "s", &device)) return NULL;
+
+    rc = ext2fs_open(device, EXT2_FLAG_FORCE, 0, 0, unix_io_manager,
+		     &fsys);
+    if (rc) {
+	Py_INCREF(Py_None);
+	return Py_None;
+    }
+
+    clean = fsys->super->s_state & EXT2_VALID_FS;
+
+    ext2fs_close(fsys);
+
+    return Py_BuildValue("i", !clean); 
+}
+static PyObject * doExt2HasJournal(PyObject * s, PyObject * args) {
+    char * device;
+    ext2_filsys fsys;
+    int rc;
+    int hasjournal;
+
+    if (!PyArg_ParseTuple(args, "s", &device)) return NULL;
+    rc = ext2fs_open(device, EXT2_FLAG_FORCE, 0, 0, unix_io_manager,
+		     &fsys);
+    if (rc) {
+	Py_INCREF(Py_None);
+	return Py_None;
+    }
+
+    hasjournal = fsys->super->s_feature_compat & EXT3_FEATURE_COMPAT_HAS_JOURNAL;
+
+    ext2fs_close(fsys);
+
+    return Py_BuildValue("i", hasjournal); 
+}
+
+static PyObject * doEjectCdrom(PyObject * s, PyObject * args) {
+    int fd;
+
+    if (!PyArg_ParseTuple(args, "i", &fd)) return NULL;
+
+    /* Ask it to unlock the door and then eject the disc. There's really
+     * nothing to do if unlocking doesn't work, so just eject without
+     * worrying about it. -- pjones
+     */
+    ioctl(fd, CDROM_LOCKDOOR, 0);
+    if (ioctl(fd, CDROMEJECT, 1)) {
+	PyErr_SetFromErrno(PyExc_SystemError);
+	return NULL;
+    }
+
+    Py_INCREF(Py_None);
+    return Py_None;
+}
+
+static PyObject * doVtActivate(PyObject * s, PyObject * args) {
+    int vtnum;
+
+    if (!PyArg_ParseTuple(args, "i", &vtnum)) return NULL;
+
+    if (ioctl(0, VT_ACTIVATE, vtnum)) {
+	PyErr_SetFromErrno(PyExc_SystemError);
+	return NULL;
+    }
+
+    Py_INCREF(Py_None);
+    return Py_None;
+}
+
+static PyObject * doisPseudoTTY(PyObject * s, PyObject * args) {
+    int fd;
+    struct stat sb;
+
+    if (!PyArg_ParseTuple(args, "i", &fd)) return NULL;
+    fstat(fd, &sb);
+
+    /* XXX close enough for now */
+    return Py_BuildValue("i", ((major(sb.st_rdev) >= 136) && (major(sb.st_rdev) <= 143)));
+}
+
+static PyObject * doisVioConsole(PyObject * s) {
+    return Py_BuildValue("i", isVioConsole());
+}
+
+static PyObject * doSync(PyObject * s, PyObject * args) {
+    int fd;
+
+    if (!PyArg_ParseTuple(args, "", &fd)) return NULL;
+    sync();
+
+    Py_INCREF(Py_None);
+    return Py_None;
+}
+
+int fileIsIso(const char * file);
+
+static PyObject * doisIsoImage(PyObject * s, PyObject * args) {
+    char * fn;
+    int rc;
+
+    if (!PyArg_ParseTuple(args, "s", &fn)) return NULL;
+
+    rc = fileIsIso(fn);
+    
+    return Py_BuildValue("i", rc);
+}
+
+static PyObject * printObject (PyObject * o, PyObject * args) {
+    PyObject * obj;
+    char buf[256];
+
+    if (!PyArg_ParseTuple(args, "O", &obj))
+	return NULL;
+    
+    snprintf(buf, 256, "<%s object at %lx>", obj->ob_type->tp_name,
+	     (long) obj);
+
+    return PyString_FromString(buf);
+}
+
+static PyObject *
+py_bind_textdomain_codeset(PyObject * o, PyObject * args) {
+    char *domain, *codeset, *ret;
+	
+    if (!PyArg_ParseTuple(args, "ss", &domain, &codeset))
+	return NULL;
+
+    ret = bind_textdomain_codeset(domain, codeset);
+
+    if (ret)
+	return PyString_FromString(ret);
+
+    PyErr_SetFromErrno(PyExc_SystemError);
+    return NULL;
+}
+
+static PyObject * doSegvHandler(PyObject *s, PyObject *args) {
+    void *array[20];
+    size_t size;
+    char **strings;
+    size_t i;
+
+    signal(SIGSEGV, SIG_DFL); /* back to default */
+    
+    size = backtrace (array, 20);
+    strings = backtrace_symbols (array, size);
+    
+    printf ("Anaconda received SIGSEGV!.  Backtrace:\n");
+    for (i = 0; i < size; i++)
+        printf ("%s\n", strings[i]);
+     
+    free (strings);
+    exit(1);
+}
+
+static PyObject * doAuditDaemon(PyObject *s) {
+    audit_daemonize();
+    Py_INCREF(Py_None);
+    return Py_None;
+}
+
+static PyObject * doGetBlkidData(PyObject * s, PyObject * args) {
+    char * dev, * key;
+    blkid_cache cache;
+    blkid_dev bdev = NULL;
+    blkid_tag_iterate titer;
+    const char * type, * data;
+
+    if (!PyArg_ParseTuple(args, "ss", &dev, &key)) return NULL;
+
+    blkid_get_cache(&cache, NULL);
+
+    bdev = blkid_get_dev(cache, dev, BLKID_DEV_NORMAL);
+    if (bdev == NULL)
+        goto out;
+    titer = blkid_tag_iterate_begin(bdev);
+    while (blkid_tag_next(titer, &type, &data) >= 0) {
+        if (!strcmp(type, key)) {
+            blkid_tag_iterate_end(titer);
+            return Py_BuildValue("s", data);
+        }
+    }
+    blkid_tag_iterate_end(titer);
+
+ out:
+    Py_INCREF(Py_None);
+    return Py_None;
+}
+
+static PyObject * doIsCapsLockEnabled(PyObject * s, PyObject * args) {
+    Display *d = NULL;
+    XkbStateRec state;
+
+    if ((d = XOpenDisplay(NULL)) == NULL) {
+        return NULL;
+    }
+
+    memset(&state, 0, sizeof(state));
+    XkbGetState(d, XkbUseCoreKbd, &state);
+
+    if (XCloseDisplay(d)) {
+        return NULL;
+    }
+
+    return PyBool_FromLong(state.locked_mods & LockMask);
+}
+
+static PyObject * doGetLinkStatus(PyObject * s, PyObject * args) {
+    char *dev = NULL;
+
+    if (!PyArg_ParseTuple(args, "s", &dev)) {
+        return NULL;
+    }
+
+    if (get_link_status(dev) == 1) {
+        return PyBool_FromLong(1);
+    }
+
+    return PyBool_FromLong(0);
+}
+
+static PyObject * doGetAnacondaVersion(PyObject * s, PyObject * args) {
+    return Py_BuildValue("s", VERSION);
+}
+
+static PyObject * doInitLog(PyObject * s) {
+    openLog();
+    Py_INCREF(Py_None);
+    return Py_None;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4: */
diff --git a/pyanaconda/isys/isys.h b/pyanaconda/isys/isys.h
new file mode 100644
index 0000000..e3cb1fc
--- /dev/null
+++ b/pyanaconda/isys/isys.h
@@ -0,0 +1,39 @@
+/*
+ * isys.h
+ *
+ * Copyright (C) 2007  Red Hat, Inc.  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 as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef H_ISYS
+#define H_ISYS
+
+#define MIN_RAM			262144 // 256 MB
+#define MIN_GUI_RAM		524288 // 512 MB
+#define URL_INSTALL_EXTRA_RAM   131072 // 128 MB
+#define EARLY_SWAP_RAM		524288
+
+#define OUTPUT_TERMINAL "/dev/tty5"
+
+int insmod(char * modName, char * path, char ** args);
+int rmmod(char * modName);
+
+/* returns 0 for true, !0 for false */
+int fileIsIso(const char * file);
+
+/* returns 1 if on an iSeries vio console, 0 otherwise */
+int isVioConsole(void);
+
+#endif
diff --git a/pyanaconda/isys/lang.c b/pyanaconda/isys/lang.c
new file mode 100644
index 0000000..b6e2a36
--- /dev/null
+++ b/pyanaconda/isys/lang.c
@@ -0,0 +1,207 @@
+/*
+ * lang.c
+ *
+ * Copyright (C) 2007  Red Hat, Inc.  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 as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <alloca.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/ioctl.h>
+#include <sys/stat.h>
+#include <unistd.h>
+
+#include <linux/keyboard.h>
+#ifdef NR_KEYS
+#undef NR_KEYS
+#define NR_KEYS 128
+#endif
+
+#include "linux/kd.h"
+
+#include "cpio.h"
+#include "isys.h"
+#include "lang.h"
+#include "stubs.h"
+
+int isysLoadFont(void) {
+    unsigned char font[65536];
+    struct console_font_op cfo;
+    unsigned short map[E_TABSZ];
+    struct unimapdesc d;
+    struct unimapinit u;
+    struct unipair desc[2048];
+    gzFile stream;
+    int rc;
+
+#if defined (__s390__) || defined (__s390x__)
+    return 0;
+#endif
+    stream = gunzip_open("/etc/screenfont.gz");
+    if (!stream)
+	return -EACCES;
+
+    gunzip_read(stream, &cfo, sizeof(cfo));
+    gunzip_read(stream, font, sizeof(font));
+    gunzip_read(stream, map, sizeof(map));
+    gunzip_read(stream, &d.entry_ct, sizeof(d.entry_ct));
+    d.entries = desc;
+    gunzip_read(stream, desc, d.entry_ct * sizeof(desc[0]));
+    gunzip_close(stream);
+
+    cfo.data = font;
+    cfo.op = KD_FONT_OP_SET;
+
+    rc = ioctl(1, KDFONTOP, &cfo);
+    if (rc) return rc;
+    rc = ioctl(1, PIO_UNIMAPCLR, &u);
+    if (rc) return rc;
+    rc = ioctl(1, PIO_UNIMAP, &d);
+    if (rc) return rc;
+    rc = ioctl(1, PIO_UNISCRNMAP, map);
+    if (rc) return rc;
+    /* activate the font map */
+    fprintf(stderr, "\033(K");
+    return 0;
+}
+
+int isysSetUnicodeKeymap(void) {
+    int console;
+
+#if defined (__s390__) || defined (__s390x__)
+    return 0;
+#endif
+    console = open("/dev/console", O_RDWR);
+    if (console < 0)
+	return -EACCES;
+
+    /* place keyboard in unicode mode */
+    ioctl(console, KDSKBMODE, K_UNICODE);
+    close(console);
+    return 0;
+}
+
+/* the file pointer must be at the beginning of the section already! */
+int loadKeymap(gzFile stream) {
+    int console;
+    int kmap, key;
+    struct kbentry entry;
+    int keymaps[MAX_NR_KEYMAPS];
+    int count = 0;
+    unsigned int magic;
+    short keymap[NR_KEYS];
+    struct stat sb;
+
+#if defined (__s390__) || defined (__s390x__)
+    return 0;
+#endif
+    if (isVioConsole())
+        return 0;
+
+    /* assume that if we're already on a pty loading a keymap is silly */
+    fstat(0, &sb);
+    if (major(sb.st_rdev) == 3 || major(sb.st_rdev) == 136)
+	return 0;
+
+    if (gunzip_read(stream, &magic, sizeof(magic)) != sizeof(magic))
+	return -EIO;
+
+    if (magic != KMAP_MAGIC) return -EINVAL;
+
+    if (gunzip_read(stream, keymaps, sizeof(keymaps)) != sizeof(keymaps))
+	return -EINVAL;
+
+    console = open("/dev/tty0", O_RDWR);
+    if (console < 0)
+	return -EACCES;
+
+    for (kmap = 0; kmap < MAX_NR_KEYMAPS; kmap++) {
+	if (!keymaps[kmap]) continue;
+
+	if (gunzip_read(stream, keymap, sizeof(keymap)) != sizeof(keymap)) {
+	    close(console);
+	    return -EIO;
+	}
+
+	count++;
+	for (key = 0; key < NR_KEYS; key++) {
+	    entry.kb_index = key;
+	    entry.kb_table = kmap;
+	    entry.kb_value = keymap[key];
+	    if (KTYP(entry.kb_value) != KT_SPEC) {
+		if (ioctl(console, KDSKBENT, &entry)) {
+		    int ret = errno;
+		    close(console);
+		    return ret;
+		}
+	    }
+	}
+    }
+    close(console);
+    return 0;
+}
+
+int isysLoadKeymap(char * keymap) {
+    int num = -1;
+    int rc;
+    gzFile f;
+    struct kmapHeader hdr;
+    struct kmapInfo * infoTable;
+    char buf[16384]; 			/* I hope this is big enough */
+    int i;
+
+    f = gunzip_open("/etc/keymaps.gz");
+    if (!f) return -EACCES;
+
+    if (gunzip_read(f, &hdr, sizeof(hdr)) != sizeof(hdr)) {
+	gunzip_close(f);
+	return -EINVAL;
+    }
+
+    i = hdr.numEntries * sizeof(*infoTable);
+    infoTable = alloca(i);
+    if (gunzip_read(f, infoTable, i) != i) {
+	gunzip_close(f);
+	return -EIO;
+    }
+
+    for (i = 0; i < hdr.numEntries; i++)
+	if (!strcmp(infoTable[i].name, keymap)) {
+	    num = i;
+	    break;
+	}
+
+    if (num == -1) {
+	gunzip_close(f);
+	return -ENOENT;
+    }
+
+    for (i = 0; i < num; i++) {
+	if (gunzip_read(f, buf, infoTable[i].size) != infoTable[i].size) {
+	    gunzip_close(f);
+	    return -EIO;
+	}
+    }
+
+    rc = loadKeymap(f);
+
+    gunzip_close(f);
+
+    return rc;
+}
diff --git a/pyanaconda/isys/lang.h b/pyanaconda/isys/lang.h
new file mode 100644
index 0000000..a08adbd
--- /dev/null
+++ b/pyanaconda/isys/lang.h
@@ -0,0 +1,44 @@
+/*
+ * lang.h
+ *
+ * Copyright (C) 2007  Red Hat, Inc.  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 as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef ISYS_LANG_H
+#define ISYS_LANG_H
+
+#include "stubs.h"
+
+/* define ask johnsonm@xxxxxxxxxx where this came from */
+#define KMAP_MAGIC 0x8B39C07F
+#define KMAP_NAMELEN 40         /* including '\0' */
+
+struct kmapHeader {
+    int magic;
+    int numEntries;
+};
+        
+struct kmapInfo {
+    int size;
+    char name[KMAP_NAMELEN];
+};
+
+int loadKeymap(gzFile stream);
+int isysLoadFont(void);
+int isysLoadKeymap(char * keymap);
+int isysSetUnicodeKeymap(void);
+
+#endif
diff --git a/pyanaconda/isys/linkdetect.c b/pyanaconda/isys/linkdetect.c
new file mode 100644
index 0000000..f97a291
--- /dev/null
+++ b/pyanaconda/isys/linkdetect.c
@@ -0,0 +1,202 @@
+/*
+ * linkdetect.c - simple link detection
+ *
+ * pulls code from mii-tool.c in net-toools and ethtool so
+ * that we can do everything that jgarzik says we should check
+ *
+ * Copyright (C) 2002, 2003  Red Hat, Inc.  All rights reserved.
+ * Portions Copyright (C) 2000 David A. Hinds -- dhinds@xxxxxxxxxxxxxxxxxxxxxx
+ *
+ * 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; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ *
+ * Author(s): Jeremy Katz <katzj@xxxxxxxxxx>
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <sys/ioctl.h>
+#include <string.h>
+#include <unistd.h>
+#include <errno.h>
+
+#include <sys/socket.h>
+#include <sys/types.h>
+#include <net/if.h>
+
+#include <linux/sockios.h>
+#include <linux/mii.h>
+#include <linux/ethtool.h>
+#include "ethtool.h"
+
+static struct ifreq ifr;
+
+static int mdio_read(int skfd, uint16_t location)
+{
+    struct mii_ioctl_data mii;
+
+    memset(&mii, 0, sizeof(mii));
+    memcpy(&mii, &ifr.ifr_data, sizeof(mii));
+    mii.reg_num = location;
+    memcpy(&ifr.ifr_data, &mii, sizeof(mii));
+
+    if (ioctl(skfd, SIOCGMIIREG, &ifr) < 0) {
+#ifdef STANDALONE
+        fprintf(stderr, "SIOCGMIIREG on %s failed: %s\n", ifr.ifr_name,
+                strerror(errno));
+#endif
+        return -1;
+    } else {
+        memcpy(&mii, &ifr.ifr_data, sizeof(mii));
+    }
+
+    return mii.val_out;
+}
+
+/* we don't need writing right now */
+#if 0
+static void mdio_write(int skfd, int location, int value)
+{
+    struct mii_ioctl_data *mii = (struct mii_ioctl_data *)&ifr.ifr_data;
+    mii->reg_num = location;
+    mii->val_in = value;
+    if (ioctl(skfd, SIOCSMIIREG, &ifr) < 0) {
+#ifdef STANDALONE
+	fprintf(stderr, "SIOCSMIIREG on %s failed: %s\n", ifr.ifr_name,
+		strerror(errno));
+#endif
+    }
+}
+#endif
+
+
+
+static int get_mii_link_status(int sock) {
+    int i, mii_val[32];
+
+    if (ioctl(sock, SIOCGMIIPHY, &ifr) < 0) {
+	if (errno != ENODEV)
+#ifdef STANDALONE
+	    fprintf(stderr, "SIOCGMIIPHY on '%s' failed: %s\n",
+		    ifr.ifr_name, strerror(errno));
+#endif
+	return -1;
+    }
+
+    /* Some bits in the BMSR are latched, but we can't rely on being
+       the only reader, so only the current values are meaningful */
+    mdio_read(sock, MII_BMSR);
+    for (i = 0; i < 8; i++)
+	mii_val[i] = mdio_read(sock, i);
+
+    if (mii_val[MII_BMCR] == 0xffff) {
+#ifdef STANDALONE
+	fprintf(stderr, "  No MII transceiver present!.\n");
+#endif
+	return -1;
+    }
+
+    if (mii_val[MII_BMSR] & BMSR_LSTATUS)
+        return 1;
+    else
+        return 0;
+}
+
+static int get_ethtool_link_status(int sock) {
+    struct ethtool_value edata;
+    int rc;
+
+    edata.cmd = ETHTOOL_GLINK;
+    ifr.ifr_data = (caddr_t)&edata;
+    rc = ioctl(sock, SIOCETHTOOL, &ifr);
+    if (rc == 0) {
+        return edata.data;
+    } else if (errno != EOPNOTSUPP) {
+#ifdef STANDALONE
+        fprintf(stderr, "Cannot get link status (%d): %s\n", errno, strerror(errno));
+#endif
+    }
+
+    return -1;
+}
+
+
+
+int get_link_status(char * devname) {
+    int sock, rc;
+
+    if ((sock = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
+#ifdef STANDALONE
+        fprintf(stderr, "Error creating socket: %s\n", strerror(errno));
+#endif
+        return -1;
+    }
+
+    /* make sure interface is up and activated */
+    memset(&ifr, 0, sizeof(ifr));
+    strcpy(ifr.ifr_name, devname);
+
+    if (ioctl(sock, SIOCGIFFLAGS, &ifr) < 0) {
+        return -1;
+    }
+
+    ifr.ifr_flags |= (IFF_UP | IFF_RUNNING);
+
+    if (ioctl(sock, SIOCSIFFLAGS, &ifr) < 0) {
+        return -1;
+    }
+
+    /* Setup our control structures. */
+    memset(&ifr, 0, sizeof(ifr));
+    strcpy(ifr.ifr_name, devname);
+
+    /* check for link with both ethtool and mii registers.  ethtool is
+     * supposed to be the One True Way (tm), but it seems to not work
+     * with much yet :/ */
+
+    rc = get_ethtool_link_status(sock);
+#ifdef STANDALONE
+    printf("ethtool link status of %s is: %d\n", devname, rc);
+#endif
+    if (rc == 1) {
+        close(sock);
+        return 1;
+    }
+
+    rc = get_mii_link_status(sock);
+#ifdef STANDALONE
+    printf("MII link status of %s is: %d\n", devname, rc);
+#endif
+    if (rc == 1) {
+        close(sock);
+        return 1;
+    }
+
+    return 0;
+}
+
+#ifdef STANDALONE
+/* hooray for stupid test programs! */
+int main(int argc, char **argv) {
+    char * dev;
+
+    if (argc >= 2) 
+        dev = argv[1];
+    else
+        dev = strdup("eth0");
+
+    printf("link status of %s is %d\n", dev, get_link_status(dev));
+    return 0;
+}
+#endif
diff --git a/pyanaconda/isys/log.c b/pyanaconda/isys/log.c
new file mode 100644
index 0000000..da39c7b
--- /dev/null
+++ b/pyanaconda/isys/log.c
@@ -0,0 +1,224 @@
+/*
+ * log.c - logging functionality
+ *
+ * Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002  Red Hat, Inc.
+ * 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 as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ *
+ * Author(s): Erik Troan <ewt@xxxxxxxxxx>
+ *            Matt Wilson <msw@xxxxxxxxxx>
+ *            Michael Fulbright <msf@xxxxxxxxxx>
+ *            Jeremy Katz <katzj@xxxxxxxxxx>
+ */
+
+#include <fcntl.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <time.h>
+#include <unistd.h>
+#include <sys/time.h>
+#include <syslog.h>
+
+#include "log.h"
+
+static FILE * main_log_tty = NULL;
+static FILE * main_log_file = NULL;
+static FILE * program_log_file = NULL;
+static int minLevel = INFO;
+static const char * main_tag = "loader";
+static const char * program_tag = "program";
+static const int syslog_facility = LOG_LOCAL0;
+
+/* maps our loglevel to syslog loglevel */
+static int mapLogLevel(int level)
+{
+    switch (level) {
+    case DEBUGLVL:
+        return LOG_DEBUG;
+    case INFO:
+        return LOG_INFO;
+    case WARNING:
+        return LOG_WARNING;
+    case CRITICAL:
+        return LOG_CRIT;
+    case ERROR:
+    default:
+        /* if someone called us with an invalid level value, log it as an error
+           too. */
+        return LOG_ERR;
+    }
+}
+
+static void printLogHeader(int level, const char *tag, FILE *outfile) {
+    struct timeval current_time;
+    struct tm *t;
+    int msecs;
+
+    gettimeofday(&current_time, NULL);
+    t = gmtime(&current_time.tv_sec);
+    msecs = current_time.tv_usec / 1000;
+    switch (level) {
+        case DEBUGLVL:
+            fprintf (outfile, "%02d:%02d:%02d,%03d DEBUG %s: ", t->tm_hour,
+                     t->tm_min, t->tm_sec, msecs, tag);
+            break;
+
+        case INFO:
+            fprintf (outfile, "%02d:%02d:%02d,%03d INFO %s: ", t->tm_hour,
+                     t->tm_min, t->tm_sec, msecs, tag);
+            break;
+
+        case WARNING:
+            fprintf (outfile, "%02d:%02d:%02d,%03d WARNING %s: ", t->tm_hour,
+                     t->tm_min, t->tm_sec, msecs, tag);
+            break;
+
+        case ERROR:
+            fprintf (outfile, "%02d:%02d:%02d,%03d ERROR %s: ", t->tm_hour,
+                     t->tm_min, t->tm_sec, msecs, tag);
+            break;
+
+        case CRITICAL:
+            fprintf (outfile, "%02d:%02d:%02d,%03d CRITICAL %s: ", t->tm_hour,
+                     t->tm_min, t->tm_sec, msecs, tag);
+            break;
+    }
+}
+
+static void printLogMessage(int level, const char *tag, FILE *outfile, const char *s, va_list ap)
+{
+    printLogHeader(level, tag, outfile);
+
+    va_list apc;
+    va_copy(apc, ap);
+    vfprintf(outfile, s, apc);
+    va_end(apc);
+
+    fprintf(outfile, "\n");
+    fflush(outfile);
+}
+
+static void retagSyslog(const char* new_tag)
+{
+    closelog();
+    openlog(new_tag, 0, syslog_facility);
+}
+
+void logMessageV(enum logger_t logger, int level, const char * s, va_list ap) {
+    FILE *log_tty = main_log_tty;
+    FILE *log_file = main_log_file;
+    const char *tag = main_tag;
+    if (logger == PROGRAM_LOG) {
+        /* tty output is done directly for programs */
+        log_tty = NULL;
+        log_file = program_log_file;
+        tag = program_tag;
+        /* close and reopen syslog so we get the tagging right */
+        retagSyslog(tag);
+    }
+
+    va_list apc;
+    /* Log everything into syslog */
+    va_copy(apc, ap);
+    vsyslog(mapLogLevel(level), s, apc);
+    va_end(apc);
+
+    /* Only log to the screen things that are above the minimum level. */
+    if (main_log_tty && level >= minLevel && log_tty) {
+        printLogMessage(level, tag, log_tty, s, ap);
+    }
+
+    /* But log everything to the file. */
+    if (main_log_file) {
+        printLogMessage(level, tag, log_file, s, ap);
+    }
+
+    /* change the syslog tag back to the default again */
+    if (logger == PROGRAM_LOG)
+        retagSyslog(main_tag);
+}
+
+void logMessage(int level, const char * s, ...) {
+    va_list args;
+
+    va_start(args, s);
+    logMessageV(MAIN_LOG, level, s, args);
+    va_end(args);
+}
+
+void logProgramMessage(int level, const char * s, ...) {
+    va_list args;
+
+    va_start(args, s);
+    logMessageV(PROGRAM_LOG, level, s, args);
+    va_end(args);
+}
+
+int tty_logfd = -1;
+int file_logfd = -1;
+
+void openLog() {
+    /* init syslog logging (so loader messages can also be forwarded to a remote
+       syslog daemon */
+    openlog(main_tag, 0, syslog_facility);
+
+    int flags;
+    main_log_tty = fopen("/dev/tty3", "a");
+    main_log_file = fopen("/tmp/anaconda.log", "a");
+    program_log_file = fopen("/tmp/program.log", "a");
+
+    if (main_log_tty) {
+        tty_logfd = fileno(main_log_tty);
+        flags = fcntl(tty_logfd, F_GETFD, 0) | FD_CLOEXEC;
+        fcntl(tty_logfd, F_SETFD, flags);
+    }
+
+    if (main_log_file) {
+        file_logfd = fileno(main_log_file);
+        flags = fcntl(file_logfd, F_GETFD, 0) | FD_CLOEXEC;
+        fcntl(file_logfd, F_SETFD, flags);
+    }
+    
+    if (program_log_file) {
+        int fd;
+        fd = fileno(program_log_file);
+        flags = fcntl(fd, F_GETFD, 0) | FD_CLOEXEC;
+        fcntl(file_logfd, F_SETFD, flags);
+    }
+}
+
+void closeLog(void) {
+    if (main_log_tty)
+        fclose(main_log_tty);
+    if (main_log_file)
+        fclose(main_log_file);
+    if (program_log_file)
+        fclose(program_log_file);
+    
+    /* close syslog logger */
+    closelog();
+}
+
+/* set the level.  higher means you see more verbosity */
+void setLogLevel(int level) {
+    minLevel = level;
+}
+
+int getLogLevel(void) {
+    return minLevel;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4: */
diff --git a/pyanaconda/isys/log.h b/pyanaconda/isys/log.h
new file mode 100644
index 0000000..51de2de
--- /dev/null
+++ b/pyanaconda/isys/log.h
@@ -0,0 +1,51 @@
+/*
+ * log.h
+ *
+ * Copyright (C) 2007  Red Hat, Inc.  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 as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _LOG_H_
+#define _LOG_H_
+
+#include <stdio.h>
+#include <stdarg.h>
+
+#define DEBUGLVL 10
+#define INFO     20
+#define WARNING  30
+#define ERROR    40
+#define CRITICAL 50
+
+enum logger_t {
+    MAIN_LOG = 1,
+    PROGRAM_LOG = 2
+};
+
+void logMessageV(enum logger_t logger, int level, const char * s, va_list ap)
+    __attribute__ ((format (printf, 3, 0)));
+void logMessage(int level, const char * s, ...)
+    __attribute__ ((format (printf, 2, 3)));
+void logProgramMessage(int level, const char * s, ...)
+    __attribute__ ((format (printf, 2, 3)));
+void openLog();
+void closeLog(void);
+void setLogLevel(int minLevel);
+int getLogLevel(void);
+
+extern int tty_logfd;
+extern int file_logfd;
+
+#endif /* _LOG_H_ */
diff --git a/pyanaconda/isys/stubs.h b/pyanaconda/isys/stubs.h
new file mode 100644
index 0000000..40ecb22
--- /dev/null
+++ b/pyanaconda/isys/stubs.h
@@ -0,0 +1,44 @@
+/*
+ * stubs.h
+ *
+ * Copyright (C) 2007  Red Hat, Inc.  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 as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ */
+
+/* we use gzlib when linked against dietlibc, but otherwise, we should use
+   zlib.  it would make more sense to do the defines in the other direction, 
+   but that causes symbol wackiness because both gunzip_open and gzip_open in
+   gzlib are gzopen from zlib
+*/
+
+#ifndef ISYS_STUB
+#define ISYS_STUB
+
+#ifndef GZLIB
+#include <zlib.h>
+
+#define gunzip_open(x) gzopen(x, "r")
+#define gunzip_dopen gzdopen(x, "r")
+#define gunzip_close gzclose
+#define gunzip_read gzread
+#define gzip_write gzwrite
+#define gzip_open(x, y, z) gzopen(x, "w")
+
+#else
+#include "gzlib/gzlib.h"
+
+#endif
+
+#endif
diff --git a/pyanaconda/isys/uncpio.c b/pyanaconda/isys/uncpio.c
new file mode 100644
index 0000000..171eb6b
--- /dev/null
+++ b/pyanaconda/isys/uncpio.c
@@ -0,0 +1,798 @@
+/*
+ * uncpio.c
+ *
+ * Copyright (C) 2007  Red Hat, Inc.  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 as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#define HAVE_ALLOCA_H 1
+#define MAJOR_IN_SYSMACROS 1
+
+#if HAVE_ALLOCA_H
+# include <alloca.h>
+#endif
+
+#define _(foo) (foo)
+
+#include <errno.h>
+#include <fcntl.h>
+#include <fnmatch.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <utime.h>
+
+#include "cpio.h"
+#include "stubs.h"
+
+#if MAJOR_IN_SYSMACROS 
+#include <sys/sysmacros.h>
+#elif MAJOR_IN_MKDEV 
+#include <sys/mkdev.h>
+#endif
+
+#define CPIO_NEWC_MAGIC	"070701"
+#define CPIO_CRC_MAGIC	"070702"
+#define TRAILER		"TRAILER!!!"
+
+/* FIXME: We don't translate between cpio and system mode bits! These
+   should both be the same, but really odd things are going to happen if
+   that's not true! */
+
+/* We need to maintain our oun file pointer to allow padding */
+struct ourfd {
+    gzFile fd;
+    size_t pos;
+};
+
+struct hardLink {
+    struct hardLink * next;
+    char ** files;		/* there are nlink of these, used by install */
+    int * fileMaps;		/* used by build */
+    dev_t dev;
+    ino_t inode;
+    int nlink;			
+    int linksLeft;
+    int createdPath;
+    struct stat sb;
+};
+
+struct cpioCrcPhysicalHeader {
+    char magic[6];
+    char inode[8];
+    char mode[8];
+    char uid[8];
+    char gid[8];
+    char nlink[8];
+    char mtime[8];
+    char filesize[8];
+    char devMajor[8];
+    char devMinor[8];
+    char rdevMajor[8];
+    char rdevMinor[8];
+    char namesize[8];
+    char checksum[8];			/* ignored !! */
+};
+
+#define PHYS_HDR_SIZE	110		/* don't depend on sizeof(struct) */
+
+struct cpioHeader {
+    ino_t inode;
+    mode_t mode;
+    uid_t uid;
+    gid_t gid;
+    int nlink;
+    time_t mtime;
+    unsigned long size;
+    dev_t dev, rdev;
+    char * path;
+};
+
+static inline off_t ourread(struct ourfd * thefd, void * buf, size_t size) {
+    off_t i;
+
+    i = gunzip_read(thefd->fd, buf, size);
+    thefd->pos += i;
+    
+    return i;
+}
+
+static inline void padinfd(struct ourfd * fd, int modulo) {
+    int buf[10];
+    int amount;
+    
+    amount = (modulo - fd->pos % modulo) % modulo;
+    ourread(fd, buf, amount);
+}
+
+static inline int padoutfd(struct ourfd * fd, size_t * where, int modulo) {
+    /*static int buf[10] = { '\0', '\0', '\0', '\0', '\0', 
+			   '\0', '\0', '\0', '\0', '\0' };*/
+    int amount;
+    static int buf[512];
+
+    amount = (modulo - *where % modulo) % modulo;
+    *where += amount;
+
+    if (gzip_write(fd->fd, buf, amount) != amount)
+	return CPIOERR_WRITE_FAILED;
+
+    return 0;
+}
+
+static int strntoul(const char * str, char ** endptr, int base, int num) {
+    char * buf, * end;
+    unsigned long ret;
+
+    buf = alloca(num + 1);
+    strncpy(buf, str, num);
+    buf[num] = '\0';
+
+    ret = strtoul(buf, &end, base);
+    if (*end)
+	*endptr = (char *)(str + (end - buf));	/* XXX discards const */
+    else
+	*endptr = "";
+
+    return strtoul(buf, endptr, base);
+}
+
+#define GET_NUM_FIELD(phys, log) \
+	log = strntoul(phys, &end, 16, sizeof(phys)); \
+	if (*end) return CPIOERR_BAD_HEADER;
+#define SET_NUM_FIELD(phys, val, space) \
+	sprintf(space, "%8.8lx", (unsigned long) (val)); \
+	memcpy(phys, space, 8);
+
+static int getNextHeader(struct ourfd * fd, struct cpioHeader * chPtr,
+			 struct cpioCrcPhysicalHeader * physHeaderPtr) {
+    struct cpioCrcPhysicalHeader physHeader;
+    int nameSize;
+    char * end;
+    int major, minor;
+
+    if (ourread(fd, &physHeader, PHYS_HDR_SIZE) != PHYS_HDR_SIZE) 
+	return CPIOERR_READ_FAILED;
+
+    if (physHeaderPtr)
+	memcpy(physHeaderPtr, &physHeader, PHYS_HDR_SIZE);
+
+    if (strncmp(CPIO_CRC_MAGIC, physHeader.magic, strlen(CPIO_CRC_MAGIC)) &&
+	strncmp(CPIO_NEWC_MAGIC, physHeader.magic, strlen(CPIO_NEWC_MAGIC)))
+	return CPIOERR_BAD_MAGIC;
+
+    GET_NUM_FIELD(physHeader.inode, chPtr->inode);
+    GET_NUM_FIELD(physHeader.mode, chPtr->mode);
+    GET_NUM_FIELD(physHeader.uid, chPtr->uid);
+    GET_NUM_FIELD(physHeader.gid, chPtr->gid);
+    GET_NUM_FIELD(physHeader.nlink, chPtr->nlink);
+    GET_NUM_FIELD(physHeader.mtime, chPtr->mtime);
+    GET_NUM_FIELD(physHeader.filesize, chPtr->size);
+
+    GET_NUM_FIELD(physHeader.devMajor, major);
+    GET_NUM_FIELD(physHeader.devMinor, minor);
+    chPtr->dev = makedev(major, minor);
+
+    GET_NUM_FIELD(physHeader.rdevMajor, major);
+    GET_NUM_FIELD(physHeader.rdevMinor, minor);
+    chPtr->rdev = makedev(major, minor);
+
+    GET_NUM_FIELD(physHeader.namesize, nameSize);
+
+    chPtr->path = malloc(nameSize + 1);
+    if (ourread(fd, chPtr->path, nameSize) != nameSize) {
+	free(chPtr->path);
+	return CPIOERR_BAD_HEADER;
+    }
+
+    /* this is unecessary chPtr->path[nameSize] = '\0'; */
+
+    padinfd(fd, 4);
+
+    return 0;
+}
+
+int myCpioFileMapCmp(const void * a, const void * b) {
+    const struct cpioFileMapping * first = a;
+    const struct cpioFileMapping * second = b;
+
+    return (strcmp(first->archivePath, second->archivePath));
+}
+
+/* This could trash files in the path! I'm not sure that's a good thing */
+static int createDirectory(char * path, mode_t perms) {
+    struct stat sb;
+    int dounlink;
+
+    if (!lstat(path, &sb)) {
+	if (S_ISDIR(sb.st_mode)) {
+	    return 0;
+	} else if (S_ISLNK(sb.st_mode)) {
+	    if (stat(path, &sb)) {
+		if (errno != ENOENT) 
+		    return CPIOERR_STAT_FAILED;
+		dounlink = 1;
+	    } else {
+		if (S_ISDIR(sb.st_mode))
+		    return 0;
+		dounlink = 1;
+	    }
+	} else {
+	    dounlink = 1;
+	}
+
+	if (dounlink && unlink(path)) {
+	    return CPIOERR_UNLINK_FAILED;
+	}
+    }
+
+    if (mkdir(path, 000))
+	return CPIOERR_MKDIR_FAILED;
+
+    if (chmod(path, perms))
+	return CPIOERR_CHMOD_FAILED;
+
+    return 0;
+}
+
+static int setInfo(struct cpioHeader * hdr) {
+    int rc = 0;
+    struct utimbuf stamp;
+
+    stamp.actime = hdr->mtime; 
+    stamp.modtime = hdr->mtime;
+
+    if (!S_ISLNK(hdr->mode)) {
+	if (!getuid() && chown(hdr->path, hdr->uid, hdr->gid))
+	    rc = CPIOERR_CHOWN_FAILED;
+	if (!rc && chmod(hdr->path, hdr->mode & 07777))
+	    rc = CPIOERR_CHMOD_FAILED;
+	if (!rc && utime(hdr->path, &stamp))
+	    rc = CPIOERR_UTIME_FAILED;
+    } else {
+#       if ! CHOWN_FOLLOWS_SYMLINK
+	    if (!getuid() && !rc && lchown(hdr->path, hdr->uid, hdr->gid))
+		rc = CPIOERR_CHOWN_FAILED;
+#       endif
+    }
+
+    return rc;
+}
+
+static int checkDirectory(char * filename) {
+    static char * lastDir = NULL;
+    static int lastDirLength = 0;
+    static int lastDirAlloced = 0;
+    int length = strlen(filename);
+    char * buf;
+    char * chptr;
+    int rc = 0;
+
+    buf = alloca(length + 1);
+    strcpy(buf, filename);
+
+    for (chptr = buf + length - 1; chptr > buf; chptr--) {
+	if (*chptr == '/') break;
+    }
+
+    if (chptr == buf) return 0;     /* /filename - no directories */
+
+    *chptr = '\0';                  /* buffer is now just directories */
+
+    length = strlen(buf);
+    if (lastDirLength == length && !strcmp(buf, lastDir)) return 0;
+
+    if (lastDirAlloced < (length + 1)) {
+	lastDirAlloced = length + 100;
+	lastDir = realloc(lastDir, lastDirAlloced);
+    }
+
+    strcpy(lastDir, buf);
+    lastDirLength = length;
+
+    for (chptr = buf + 1; *chptr; chptr++) {
+	if (*chptr == '/') {
+	    *chptr = '\0';
+	    rc = createDirectory(buf, 0755);
+	    *chptr = '/';
+	    if (rc) return rc;
+	}
+    }
+    rc = createDirectory(buf, 0755);
+
+    return rc;
+}
+
+static int expandRegular(struct ourfd * fd, struct cpioHeader * hdr,
+			 cpioCallback cb, void * cbData) {
+    int out;
+    char buf[8192];
+    int bytesRead;
+    unsigned long left = hdr->size;
+    int rc = 0;
+    struct cpioCallbackInfo cbInfo;
+    struct stat sb;
+
+    if (!lstat(hdr->path, &sb))
+	if (unlink(hdr->path))
+	    return CPIOERR_UNLINK_FAILED;
+
+    out = open(hdr->path, O_CREAT | O_WRONLY, 0);
+    if (out < 0) 
+	return CPIOERR_OPEN_FAILED;
+
+    cbInfo.file = hdr->path;
+    cbInfo.fileSize = hdr->size;
+
+    while (left) {
+	bytesRead = ourread(fd, buf, left < sizeof(buf) ? left : sizeof(buf));
+	if (bytesRead <= 0) {
+	    rc = CPIOERR_READ_FAILED;
+	    break;
+	}
+
+	if (write(out, buf, bytesRead) != bytesRead) {
+	    rc = CPIOERR_COPY_FAILED;
+	    break;
+	}
+
+	left -= bytesRead;
+
+	/* don't call this with fileSize == fileComplete */
+	if (!rc && cb && left) {
+	    cbInfo.fileComplete = hdr->size - left;
+	    cbInfo.bytesProcessed = fd->pos;
+	    cb(&cbInfo, cbData);
+	}
+    }
+
+    close(out);
+    
+    return rc;
+}
+
+static int expandSymlink(struct ourfd * fd, struct cpioHeader * hdr) {
+    char buf[2048], buf2[2048];
+    struct stat sb;
+    int len;
+
+    if ((hdr->size + 1)> sizeof(buf))
+	return CPIOERR_INTERNAL;
+
+    if (ourread(fd, buf, hdr->size) != hdr->size)
+	return CPIOERR_READ_FAILED;
+
+    buf[hdr->size] = '\0';
+
+    if (!lstat(hdr->path, &sb)) {
+	if (S_ISLNK(sb.st_mode)) {
+	    len = readlink(hdr->path, buf2, sizeof(buf2) - 1);
+	    if (len > 0) {
+		buf2[len] = '\0';
+		if (!strcmp(buf, buf2)) return 0;
+	    }
+	}
+
+	if (unlink(hdr->path))
+	    return CPIOERR_UNLINK_FAILED;
+    }
+
+    if (symlink(buf, hdr->path) < 0)
+	return CPIOERR_SYMLINK_FAILED;
+
+    return 0;
+}
+
+static int expandFifo(struct ourfd * fd, struct cpioHeader * hdr) {
+    struct stat sb;
+
+    if (!lstat(hdr->path, &sb)) {
+	if (S_ISFIFO(sb.st_mode)) return 0;
+
+	if (unlink(hdr->path))
+	    return CPIOERR_UNLINK_FAILED;
+    }
+
+    if (mkfifo(hdr->path, 0))
+	return CPIOERR_MKFIFO_FAILED;
+
+    return 0; 
+}
+
+static int expandDevice(struct ourfd * fd, struct cpioHeader * hdr) {
+    struct stat sb;
+
+    if (!lstat(hdr->path, &sb)) {
+	if ((S_ISCHR(sb.st_mode) || S_ISBLK(sb.st_mode)) && 
+		(sb.st_rdev == hdr->rdev))
+	    return 0;
+	if (unlink(hdr->path))
+	    return CPIOERR_UNLINK_FAILED;
+    }
+
+    if (mknod(hdr->path, hdr->mode & (~0777), hdr->rdev))
+	return CPIOERR_MKNOD_FAILED;
+    
+    return 0;
+}
+
+static void freeLink(struct hardLink * li) {
+    int i;
+
+    for (i = 0; i < li->nlink; i++) {
+	if (li->files[i]) free(li->files[i]);
+    }
+    free(li->files);
+}
+
+static int createLinks(struct hardLink * li, const char ** failedFile) {
+    int i;
+    struct stat sb;
+
+    for (i = 0; i < li->nlink; i++) {
+	if (i == li->createdPath) continue;
+	if (!li->files[i]) continue;
+
+	if (!lstat(li->files[i], &sb)) {
+	    if (unlink(li->files[i])) {
+		*failedFile = strdup(li->files[i]);
+		return CPIOERR_UNLINK_FAILED;
+	    }
+	}
+
+	if (link(li->files[li->createdPath], li->files[i])) {
+	    *failedFile = strdup(li->files[i]);
+	    return CPIOERR_LINK_FAILED;
+	}
+
+	free(li->files[i]);
+	li->files[i] = NULL;
+	li->linksLeft--;
+    }
+
+    return 0;
+}
+
+static int eatBytes(struct ourfd * fd, unsigned long amount) {
+    char buf[4096];
+    unsigned long bite;
+   
+    while (amount) {
+	bite = (amount > sizeof(buf)) ? sizeof(buf) : amount;
+	if (ourread(fd, buf, bite) != bite)
+	    return CPIOERR_READ_FAILED;
+	amount -= bite;
+    }
+
+    return 0;
+}
+
+int myCpioInstallArchive(gzFile stream, struct cpioFileMapping * mappings, 
+		       int numMappings, cpioCallback cb, void * cbData,
+		       const char ** failedFile) {
+    struct cpioHeader ch;
+    struct ourfd fd;
+    int rc = 0;
+    int linkNum = 0;
+    struct cpioFileMapping * map = NULL;
+    struct cpioFileMapping needle;
+    mode_t cpioMode;
+    int olderr;
+    struct cpioCallbackInfo cbInfo;
+    struct hardLink * links = NULL;
+    struct hardLink * li = NULL;
+
+    fd.fd = stream;
+    fd.pos = 0;
+
+    *failedFile = NULL;
+
+    do {
+	if ((rc = getNextHeader(&fd, &ch, NULL))) {
+	    fprintf(stderr, _("error %d reading header: %s\n"), rc, 
+		    myCpioStrerror(rc));
+	    return CPIOERR_BAD_HEADER;
+	}
+
+	if (!strcmp(ch.path, TRAILER)) {
+	    free(ch.path);
+	    break;
+	}
+
+	if (mappings) {
+	    needle.archivePath = ch.path;
+	    map = bsearch(&needle, mappings, numMappings, sizeof(needle),
+			  myCpioFileMapCmp);
+	}
+
+	if (mappings && !map) {
+	    eatBytes(&fd, ch.size);
+	} else {
+	    cpioMode = ch.mode;
+
+	    if (map) {
+		if (map->mapFlags & CPIO_MAP_PATH) {
+		    free(ch.path);
+		    ch.path = strdup(map->fsPath);
+		} 
+
+		if (map->mapFlags & CPIO_MAP_MODE)
+		    ch.mode = map->finalMode;
+		if (map->mapFlags & CPIO_MAP_UID)
+		    ch.uid = map->finalUid;
+		if (map->mapFlags & CPIO_MAP_GID)
+		    ch.gid = map->finalGid;
+	    }
+
+	    /* This won't get hard linked symlinks right, but I can't seem 
+	       to create those anyway */
+
+	    if (S_ISREG(ch.mode) && ch.nlink > 1) {
+		li = links;
+		for (li = links; li; li = li->next) {
+		    if (li->inode == ch.inode && li->dev == ch.dev) break;
+		}
+
+		if (!li) {
+		    li = malloc(sizeof(*li));
+		    li->inode = ch.inode;
+		    li->dev = ch.dev;
+		    li->nlink = ch.nlink;
+		    li->linksLeft = ch.nlink;
+		    li->createdPath = -1;
+		    li->files = calloc(sizeof(char *), li->nlink);
+		    li->next = links;
+		    links = li;
+		}
+
+		for (linkNum = 0; linkNum < li->nlink; linkNum++)
+		    if (!li->files[linkNum]) break;
+		li->files[linkNum] = strdup(ch.path);
+	    }
+		
+	    if ((ch.nlink > 1) && S_ISREG(ch.mode) && !ch.size &&
+		li->createdPath == -1) {
+		/* defer file creation */
+	    } else if ((ch.nlink > 1) && S_ISREG(ch.mode) && 
+		       (li->createdPath != -1)) {
+		createLinks(li, failedFile);
+
+		/* this only happens for cpio archives which contain
+		   hardlinks w/ the contents of each hardlink being
+		   listed (intead of the data being given just once. This
+		   shouldn't happen, but I've made it happen w/ buggy
+		   code, so what the heck? GNU cpio handles this well fwiw */
+		if (ch.size) eatBytes(&fd, ch.size);
+	    } else {
+		rc = checkDirectory(ch.path);
+
+		if (!rc) {
+		    if (S_ISREG(ch.mode))
+			rc = expandRegular(&fd, &ch, cb, cbData);
+		    else if (S_ISDIR(ch.mode))
+			rc = createDirectory(ch.path, 000);
+		    else if (S_ISLNK(ch.mode))
+			rc = expandSymlink(&fd, &ch);
+		    else if (S_ISFIFO(ch.mode))
+			rc = expandFifo(&fd, &ch);
+		    else if (S_ISCHR(ch.mode) || S_ISBLK(ch.mode))
+			rc = expandDevice(&fd, &ch);
+		    else if (S_ISSOCK(ch.mode)) {
+			/* this mimicks cpio but probably isnt' right */
+			rc = expandFifo(&fd, &ch);
+		    } else {
+			rc = CPIOERR_INTERNAL;
+		    }
+		}
+
+		if (!rc)
+		    rc = setInfo(&ch);
+
+		if (S_ISREG(ch.mode) && ch.nlink > 1) {
+		    li->createdPath = linkNum;
+		    li->linksLeft--;
+		    rc = createLinks(li, failedFile);
+		}
+	    }
+
+	    if (rc && !*failedFile) {
+		*failedFile = strdup(ch.path);
+
+		olderr = errno;
+		unlink(ch.path);
+		errno = olderr;
+	    }
+	}
+
+	padinfd(&fd, 4);
+
+	if (!rc && cb) {
+	    cbInfo.file = ch.path;
+	    cbInfo.fileSize = ch.size;
+	    cbInfo.fileComplete = ch.size;
+	    cbInfo.bytesProcessed = fd.pos;
+	    cb(&cbInfo, cbData);
+	}
+
+	free(ch.path);
+    } while (1 && !rc);
+
+    li = links;
+    while (li && !rc) {
+	if (li->linksLeft) {
+	    if (li->createdPath == -1)
+		rc = CPIOERR_INTERNAL;
+	    else 
+		rc = createLinks(li, failedFile);
+	}
+
+	freeLink(li);
+
+	links = li;
+	li = li->next;
+	free(links);
+	links = li;
+    }
+
+    li = links;
+    /* if an error got us here links will still be eating some memory */
+    while (li) {
+	freeLink(li);
+	links = li;
+	li = li->next;
+	free(links);
+    }
+
+    return rc;
+}
+
+const char * myCpioStrerror(int rc)
+{
+    static char msg[256];
+    char *s;
+    int l, myerrno = errno;
+
+    strcpy(msg, "cpio: ");
+    switch (rc) {
+    default:
+	s = msg + strlen(msg);
+	sprintf(s, _("(error 0x%x)"), rc);
+	s = NULL;
+	break;
+    case CPIOERR_BAD_MAGIC:	s = _("Bad magic");		break;
+    case CPIOERR_BAD_HEADER:	s = _("Bad header");		break;
+
+    case CPIOERR_OPEN_FAILED:	s = "open";	break;
+    case CPIOERR_CHMOD_FAILED:	s = "chmod";	break;
+    case CPIOERR_CHOWN_FAILED:	s = "chown";	break;
+    case CPIOERR_WRITE_FAILED:	s = "write";	break;
+    case CPIOERR_UTIME_FAILED:	s = "utime";	break;
+    case CPIOERR_UNLINK_FAILED:	s = "unlink";	break;
+    case CPIOERR_SYMLINK_FAILED: s = "symlink";	break;
+    case CPIOERR_STAT_FAILED:	s = "stat";	break;
+    case CPIOERR_MKDIR_FAILED:	s = "mkdir";	break;
+    case CPIOERR_MKNOD_FAILED:	s = "mknod";	break;
+    case CPIOERR_MKFIFO_FAILED:	s = "mkfifo";	break;
+    case CPIOERR_LINK_FAILED:	s = "link";	break;
+    case CPIOERR_READLINK_FAILED: s = "readlink";	break;
+    case CPIOERR_READ_FAILED:	s = "read";	break;
+    case CPIOERR_COPY_FAILED:	s = "copy";	break;
+
+    case CPIOERR_INTERNAL:	s = _("Internal error");	break;
+    case CPIOERR_HDR_SIZE:	s = _("Header size too big");	break;
+    case CPIOERR_UNKNOWN_FILETYPE: s = _("Unknown file type");	break;
+    }
+
+    l = sizeof(msg) - strlen(msg) - 1;
+    if (s != NULL) {
+	if (l > 0) strncat(msg, s, l);
+	l -= strlen(s);
+    }
+    if (rc & CPIOERR_CHECK_ERRNO) {
+	s = _(" failed - ");
+	if (l > 0) strncat(msg, s, l);
+	l -= strlen(s);
+	if (l > 0) strncat(msg, strerror(myerrno), l);
+    }
+    return msg;
+}
+
+static int copyFile(struct ourfd * inFd, struct ourfd * outFd, 
+	     struct cpioHeader * chp, struct cpioCrcPhysicalHeader * pHdr) {
+    char buf[8192];
+    int amount;
+    size_t size = chp->size;
+
+    amount = strlen(chp->path) + 1;
+    memcpy(pHdr->magic, CPIO_NEWC_MAGIC, sizeof(pHdr->magic));
+
+    gzip_write(outFd->fd, pHdr, PHYS_HDR_SIZE);
+    gzip_write(outFd->fd, chp->path, amount);
+
+    outFd->pos += PHYS_HDR_SIZE + amount;
+
+    padoutfd(outFd, &outFd->pos, 4);
+
+    while (size) {
+	amount = ourread(inFd, buf, size > sizeof(buf) ? sizeof(buf) : size);
+	gzip_write(outFd->fd, buf, amount);
+	size -= amount;
+    }
+
+    outFd->pos += chp->size;
+
+    padoutfd(outFd, &outFd->pos, 4);
+
+    return 0;
+}
+
+int myCpioFilterArchive(gzFile inStream, gzFile outStream, char ** patterns) {
+    struct ourfd inFd, outFd;
+    char ** aPattern;
+    struct cpioHeader ch;
+    int rc;
+    struct cpioCrcPhysicalHeader pHeader;
+
+    inFd.fd = inStream;
+    inFd.pos = 0;
+    outFd.fd = outStream;
+    outFd.pos = 0;
+
+    do {
+	if ((rc = getNextHeader(&inFd, &ch, &pHeader))) {
+	    fprintf(stderr, _("error %d reading header: %s\n"), rc, 
+		    myCpioStrerror(rc));
+	    return CPIOERR_BAD_HEADER;
+	}
+
+	if (!strcmp(ch.path, TRAILER)) {
+	    free(ch.path);
+	    break;
+	}
+
+	for (aPattern = patterns; *aPattern; aPattern++)
+	    if (!fnmatch(*aPattern, ch.path, FNM_PATHNAME | FNM_PERIOD))
+		break;
+
+	if (!*aPattern)
+	    eatBytes(&inFd, ch.size);
+	else
+	    copyFile(&inFd, &outFd, &ch, &pHeader);
+
+	padinfd(&inFd, 4);
+
+	free(ch.path);
+    } while (1 && !rc);
+
+    memset(&pHeader, '0', sizeof(pHeader));
+    memcpy(pHeader.magic, CPIO_NEWC_MAGIC, sizeof(pHeader.magic));
+    memcpy(pHeader.nlink, "00000001", 8);
+    memcpy(pHeader.namesize, "0000000b", 8);
+    gzip_write(outFd.fd, &pHeader, PHYS_HDR_SIZE);
+    gzip_write(outFd.fd, "TRAILER!!!", 11);
+
+    outFd.pos += PHYS_HDR_SIZE + 11;
+
+    if ((rc = padoutfd(&outFd, &outFd.pos, 4)))
+	return rc;
+
+    if ((rc = padoutfd(&outFd, &outFd.pos, 512)))
+	return rc;
+
+    return 0;
+}
diff --git a/pyanaconda/isys/vio.c b/pyanaconda/isys/vio.c
new file mode 100644
index 0000000..9b06a3e
--- /dev/null
+++ b/pyanaconda/isys/vio.c
@@ -0,0 +1,106 @@
+/*
+ * vio.c - probing for vio devices on the iSeries (viocd and viodasd)
+ *
+ * Copyright (C) 2003  Red Hat, Inc.  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 as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ *
+ * Author(s): Jeremy Katz <katzj@xxxxxxxxxx>
+ */
+
+#include <ctype.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#if defined(__powerpc__)
+static int readFD (int fd, char **buf)
+{
+    char *p;
+    size_t size = 4096;
+    int s, filesize;
+
+    *buf = malloc (size);
+    if (*buf == 0)
+	return -1;
+
+    filesize = 0;
+    do {
+	p = &(*buf) [filesize];
+	s = read (fd, p, 4096);
+	if (s < 0)
+	    break;
+	filesize += s;
+	if (s == 0)
+	    break;
+	size += 4096;
+	*buf = realloc (*buf, size);
+    } while (1);
+
+    if (filesize == 0 && s < 0) {
+	free (*buf);
+	*buf = NULL;
+	return -1;
+    }
+
+    return filesize;
+}
+#endif
+
+int isVioConsole(void) {
+#if !defined(__powerpc__)
+    return 0;
+#else
+    int fd, i;
+    char *buf, *start;
+    char driver[50], device[50];
+    static int isviocons = -1;
+
+    if (isviocons != -1)
+	return isviocons;
+    
+    fd = open("/proc/tty/drivers", O_RDONLY);
+    if (fd < 0) {
+	fprintf(stderr, "failed to open /proc/tty/drivers!\n");
+	return 0;
+    }
+    i = readFD(fd, &buf);
+    if (i < 1) {
+        close(fd);
+	fprintf(stderr, "error reading /proc/tty/drivers!\n");
+        return 0;
+    }
+    close(fd);
+    buf[i] = '\0';
+
+    isviocons = 0;
+    start = buf;
+    while (start && *start) {
+	if (sscanf(start, "%s %s", (char *) &driver, (char *) &device) == 2) {
+	    if (!strcmp(driver, "vioconsole") && !strcmp(device, "/dev/tty")) {
+		isviocons = 1;
+		break;
+	    }
+	}		
+        start = strchr(start, '\n');
+        if (start)
+	    start++;
+    }
+    free(buf);
+    return isviocons;
+#endif
+}
diff --git a/pyanaconda/iutil.py b/pyanaconda/iutil.py
new file mode 100644
index 0000000..b2dabd1
--- /dev/null
+++ b/pyanaconda/iutil.py
@@ -0,0 +1,1073 @@
+#
+# iutil.py - generic install utility functions
+#
+# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007
+# Red Hat, Inc.  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 as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# 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, see <http://www.gnu.org/licenses/>.
+#
+# Author(s): Erik Troan <ewt@xxxxxxxxxx>
+#
+
+import glob
+import os, string, stat, sys
+import signal
+import os.path
+from errno import *
+import warnings
+import subprocess
+from flags import flags
+from constants import *
+import re
+import threading
+
+import gettext
+_ = lambda x: gettext.ldgettext("anaconda", x)
+
+import logging
+log = logging.getLogger("anaconda")
+program_log = logging.getLogger("program")
+
+#Python reimplementation of the shell tee process, so we can
+#feed the pipe output into two places at the same time
+class tee(threading.Thread):
+    def __init__(self, inputdesc, outputdesc, logmethod):
+        threading.Thread.__init__(self)
+        self.inputdesc = os.fdopen(inputdesc, "r")
+        self.outputdesc = outputdesc
+        self.logmethod = logmethod
+        self.running = True
+
+    def run(self):
+        while self.running:
+            data = self.inputdesc.readline()
+            if data == "":
+                self.running = False
+            else:
+                self.logmethod(data.rstrip('\n'))
+                os.write(self.outputdesc, data)
+
+    def stop(self):
+        self.running = False
+        return self
+
+## Run an external program and redirect the output to a file.
+# @param command The command to run.
+# @param argv A list of arguments.
+# @param stdin The file descriptor to read stdin from.
+# @param stdout The file descriptor to redirect stdout to.
+# @param stderr The file descriptor to redirect stderr to.
+# @param root The directory to chroot to before running command.
+# @return The return code of command.
+def execWithRedirect(command, argv, stdin = None, stdout = None,
+                     stderr = None, root = '/'):
+    def chroot ():
+        os.chroot(root)
+
+    stdinclose = stdoutclose = stderrclose = lambda : None
+
+    argv = list(argv)
+    if isinstance(stdin, str):
+        if os.access(stdin, os.R_OK):
+            stdin = os.open(stdin, os.O_RDONLY)
+            stdinclose = lambda : os.close(stdin)
+        else:
+            stdin = sys.stdin.fileno()
+    elif isinstance(stdin, int):
+        pass
+    elif stdin is None or not isinstance(stdin, file):
+        stdin = sys.stdin.fileno()
+
+    if isinstance(stdout, str):
+        stdout = os.open(stdout, os.O_RDWR|os.O_CREAT)
+        stdoutclose = lambda : os.close(stdout)
+    elif isinstance(stdout, int):
+        pass
+    elif stdout is None or not isinstance(stdout, file):
+        stdout = sys.stdout.fileno()
+
+    if isinstance(stderr, str):
+        stderr = os.open(stderr, os.O_RDWR|os.O_CREAT)
+        stderrclose = lambda : os.close(stderr)
+    elif isinstance(stderr, int):
+        pass
+    elif stderr is None or not isinstance(stderr, file):
+        stderr = sys.stderr.fileno()
+
+    program_log.info("Running... %s" % (" ".join([command] + argv),))
+
+    #prepare os pipes for feeding tee proceses
+    pstdout, pstdin = os.pipe()
+    perrout, perrin = os.pipe()
+   
+    env = os.environ.copy()
+    env.update({"LC_ALL": "C"})
+
+    try:
+        #prepare tee proceses
+        proc_std = tee(pstdout, stdout, program_log.info)
+        proc_err = tee(perrout, stderr, program_log.error)
+
+        #start monitoring the outputs
+        proc_std.start()
+        proc_err.start()
+
+        proc = subprocess.Popen([command] + argv, stdin=stdin,
+                                stdout=pstdin,
+                                stderr=perrin,
+                                preexec_fn=chroot, cwd=root,
+                                env=env)
+
+        proc.wait()
+        ret = proc.returncode
+
+        #close the input ends of pipes so we get EOF in the tee processes
+        os.close(pstdin)
+        os.close(perrin)
+
+        #wait for the output to be written and destroy them
+        proc_std.join()
+        del proc_std
+
+        proc_err.join()
+        del proc_err
+
+        stdinclose()
+        stdoutclose()
+        stderrclose()
+    except OSError as e:
+        errstr = "Error running %s: %s" % (command, e.strerror)
+        log.error(errstr)
+        program_log.error(errstr)
+        #close the input ends of pipes so we get EOF in the tee processes
+        os.close(pstdin)
+        os.close(perrin)
+        proc_std.join()
+        proc_err.join()
+
+        stdinclose()
+        stdoutclose()
+        stderrclose()
+        raise RuntimeError, errstr
+
+    return ret
+
+## Run an external program and capture standard out.
+# @param command The command to run.
+# @param argv A list of arguments.
+# @param stdin The file descriptor to read stdin from.
+# @param stderr The file descriptor to redirect stderr to.
+# @param root The directory to chroot to before running command.
+# @return The output of command from stdout.
+def execWithCapture(command, argv, stdin = None, stderr = None, root='/'):
+    def chroot():
+        os.chroot(root)
+
+    def closefds ():
+        stdinclose()
+        stderrclose()
+
+    stdinclose = stderrclose = lambda : None
+    rc = ""
+    argv = list(argv)
+
+    if isinstance(stdin, str):
+        if os.access(stdin, os.R_OK):
+            stdin = os.open(stdin, os.O_RDONLY)
+            stdinclose = lambda : os.close(stdin)
+        else:
+            stdin = sys.stdin.fileno()
+    elif isinstance(stdin, int):
+        pass
+    elif stdin is None or not isinstance(stdin, file):
+        stdin = sys.stdin.fileno()
+
+    if isinstance(stderr, str):
+        stderr = os.open(stderr, os.O_RDWR|os.O_CREAT)
+        stderrclose = lambda : os.close(stderr)
+    elif isinstance(stderr, int):
+        pass
+    elif stderr is None or not isinstance(stderr, file):
+        stderr = sys.stderr.fileno()
+
+    program_log.info("Running... %s" % (" ".join([command] + argv),))
+
+    env = os.environ.copy()
+    env.update({"LC_ALL": "C"})
+
+    try:
+        proc = subprocess.Popen([command] + argv, stdin=stdin,
+                                stdout=subprocess.PIPE,
+                                stderr=subprocess.PIPE,
+                                preexec_fn=chroot, cwd=root,
+                                env=env)
+
+        while True:
+            (outStr, errStr) = proc.communicate()
+            if outStr:
+                map(program_log.info, outStr.splitlines())
+                rc += outStr
+            if errStr:
+                map(program_log.error, errStr.splitlines())
+                os.write(stderr, errStr)
+
+            if proc.returncode is not None:
+                break
+    except OSError as e:
+        log.error ("Error running " + command + ": " + e.strerror)
+        closefds()
+        raise RuntimeError, "Error running " + command + ": " + e.strerror
+
+    closefds()
+    return rc
+
+def execWithCallback(command, argv, stdin = None, stdout = None,
+                     stderr = None, echo = True, callback = None,
+                     callback_data = None, root = '/'):
+    def chroot():
+        os.chroot(root)
+
+    def closefds ():
+        stdinclose()
+        stdoutclose()
+        stderrclose()
+
+    stdinclose = stdoutclose = stderrclose = lambda : None
+
+    argv = list(argv)
+    if isinstance(stdin, str):
+        if os.access(stdin, os.R_OK):
+            stdin = os.open(stdin, os.O_RDONLY)
+            stdinclose = lambda : os.close(stdin)
+        else:
+            stdin = sys.stdin.fileno()
+    elif isinstance(stdin, int):
+        pass
+    elif stdin is None or not isinstance(stdin, file):
+        stdin = sys.stdin.fileno()
+
+    if isinstance(stdout, str):
+        stdout = os.open(stdout, os.O_RDWR|os.O_CREAT)
+        stdoutclose = lambda : os.close(stdout)
+    elif isinstance(stdout, int):
+        pass
+    elif stdout is None or not isinstance(stdout, file):
+        stdout = sys.stdout.fileno()
+
+    if isinstance(stderr, str):
+        stderr = os.open(stderr, os.O_RDWR|os.O_CREAT)
+        stderrclose = lambda : os.close(stderr)
+    elif isinstance(stderr, int):
+        pass
+    elif stderr is None or not isinstance(stderr, file):
+        stderr = sys.stderr.fileno()
+
+    program_log.info("Running... %s" % (" ".join([command] + argv),))
+
+    p = os.pipe()
+    p_stderr = os.pipe()
+    childpid = os.fork()
+    if not childpid:
+        os.close(p[0])
+        os.close(p_stderr[0])
+        os.dup2(p[1], 1)
+        os.dup2(p_stderr[1], 2)
+        os.dup2(stdin, 0)
+        os.close(stdin)
+        os.close(p[1])
+        os.close(p_stderr[1])
+
+        os.execvp(command, [command] + argv)
+        os._exit(1)
+
+    os.close(p[1])
+    os.close(p_stderr[1])
+
+    logline = ''
+    while 1:
+        try:
+            s = os.read(p[0], 1)
+        except OSError as e:
+            if e.errno != 4:
+                raise IOError, e.args
+
+        if echo:
+            os.write(stdout, s)
+
+        if s == '\n':
+            program_log.info(logline)
+            logline = ''
+        else:
+            logline += s
+
+        if callback:
+            callback(s, callback_data=callback_data)
+
+        # break out early if the sub-process changes status.
+        # no need to flush the stream if the process has exited
+        try:
+            (pid, status) = os.waitpid(childpid,os.WNOHANG)
+            if pid != 0:
+                break
+        except OSError as e:
+            log.critical("exception from waitpid: %s %s" %(e.errno, e.strerror))
+
+        if len(s) < 1:
+            break
+    if len(logline) > 0:
+        program_log.info(logline)
+
+    log_errors = ''
+    while 1:
+        try:
+            err = os.read(p_stderr[0], 128)
+        except OSError as e:
+            if e.errno != 4:
+                raise IOError, e.args
+            break
+        log_errors += err
+        if len(err) < 1:
+            break
+    map(program_log.error, log_errors.splitlines())
+    os.close(p[0])
+    os.close(p_stderr[0])
+
+    try:
+        #if we didn't already get our child's exit status above, do so now.
+        if not pid:
+            (pid, status) = os.waitpid(childpid, 0)
+    except OSError as e:
+        log.critical("exception from waitpid: %s %s" %(e.errno, e.strerror))
+
+    closefds()
+    # *shrug*  no clue why this would happen, but hope that things are fine
+    if status is None:
+        return 0
+
+    if os.WIFEXITED(status):
+        return os.WEXITSTATUS(status)
+
+    return 1
+
+def _pulseProgressCallback(data, callback_data=None):
+    if callback_data:
+        callback_data.pulse()
+
+def execWithPulseProgress(command, argv, stdin = None, stdout = None,
+                          stderr = None, echo = True, progress = None,
+                          root = '/'):
+    return execWithCallback(command, argv, stdin=stdin, stdout=stdout,
+                     stderr=stderr, echo=echo, callback=_pulseProgressCallback,
+                     callback_data=progress, root=root)
+
+## Run a shell.
+def execConsole():
+    try:
+        proc = subprocess.Popen(["/bin/sh"])
+        proc.wait()
+    except OSError as e:
+        raise RuntimeError, "Error running /bin/sh: " + e.strerror
+
+## Get the size of a directory and all its subdirectories.
+# @param dir The name of the directory to find the size of.
+# @return The size of the directory in kilobytes.
+def getDirSize(dir):
+    def getSubdirSize(dir):
+	# returns size in bytes
+        mydev = os.lstat(dir)[stat.ST_DEV]
+
+        dsize = 0
+        for f in os.listdir(dir):
+	    curpath = '%s/%s' % (dir, f)
+	    sinfo = os.lstat(curpath)
+            if stat.S_ISDIR(sinfo[stat.ST_MODE]):
+                if mydev == sinfo[stat.ST_DEV]:
+                    dsize += getSubdirSize(curpath)
+            elif stat.S_ISREG(sinfo[stat.ST_MODE]):
+                dsize += sinfo[stat.ST_SIZE]
+            else:
+                pass
+
+        return dsize
+    return getSubdirSize(dir)/1024
+
+## Get the amount of RAM not used by /tmp.
+# @return The amount of available memory in kilobytes.
+def memAvailable():
+    tram = memInstalled()
+
+    ramused = getDirSize("/tmp")
+    return tram - ramused
+
+## Get the amount of RAM installed in the machine.
+# @return The amount of installed memory in kilobytes.
+def memInstalled():
+    f = open("/proc/meminfo", "r")
+    lines = f.readlines()
+    f.close()
+
+    for l in lines:
+        if l.startswith("MemTotal:"):
+            fields = string.split(l)
+            mem = fields[1]
+            break
+
+    return int(mem)
+
+## Suggest the size of the swap partition that will be created.
+# @param quiet Should size information be logged?
+# @return A tuple of the minimum and maximum swap size, in megabytes.
+def swapSuggestion(quiet=0):
+    mem = memInstalled()/1024
+    mem = ((mem/16)+1)*16
+    if not quiet:
+	log.info("Detected %sM of memory", mem)
+	
+    if mem <= 256:
+        minswap = 256
+        maxswap = 512
+    else:
+        if mem > 2048:
+            minswap = 1024
+            maxswap = 2048 + mem
+        else:
+            minswap = mem
+            maxswap = 2*mem
+
+    if isS390():
+        minswap = 1
+
+    if not quiet:
+	log.info("Swap attempt of %sM to %sM", minswap, maxswap)
+
+    return (minswap, maxswap)
+
+## Create a directory path.  Don't fail if the directory already exists.
+# @param dir The directory path to create.
+def mkdirChain(dir):
+    try:
+        os.makedirs(dir, 0755)
+    except OSError as e:
+        try:
+            if e.errno == EEXIST and stat.S_ISDIR(os.stat(dir).st_mode):
+                return
+        except:
+            pass
+
+        log.error("could not create directory %s: %s" % (dir, e.strerror))
+
+## Get the total amount of swap memory.
+# @return The total amount of swap memory in kilobytes, or 0 if unknown.
+def swapAmount():
+    f = open("/proc/meminfo", "r")
+    lines = f.readlines()
+    f.close()
+
+    for l in lines:
+        if l.startswith("SwapTotal:"):
+            fields = string.split(l)
+            return int(fields[1])
+    return 0
+
+## Copy a device node.
+# Copies a device node by looking at the device type, major and minor device
+# numbers, and doing a mknod on the new device name.
+#
+# @param src The name of the source device node.
+# @param dest The name of the new device node to create.
+def copyDeviceNode(src, dest):
+    filestat = os.lstat(src)
+    mode = filestat[stat.ST_MODE]
+    if stat.S_ISBLK(mode):
+        type = stat.S_IFBLK
+    elif stat.S_ISCHR(mode):
+        type = stat.S_IFCHR
+    else:
+        # XXX should we just fallback to copying normally?
+        raise RuntimeError, "Tried to copy %s which isn't a device node" % (src,)
+
+    os.mknod(dest, mode | type, filestat.st_rdev)
+
+## Get the SPARC machine variety type.
+# @return The SPARC machine type, or 0 if not SPARC.
+def getSparcMachine():
+    if not isSparc():
+        return 0
+
+    machine = None
+
+
+    f = open('/proc/cpuinfo', 'r')
+    lines = f.readlines()
+    f.close()
+    for line in lines:
+        if line.find('type') != -1:
+            machine = line.split(':')[1].strip()
+            return machine
+
+    return None
+
+## Get the PPC machine variety type.
+# @return The PPC machine type, or 0 if not PPC.
+def getPPCMachine():
+    if not isPPC():
+        return 0
+
+    ppcMachine = None
+    machine = None
+    platform = None
+
+    # ppc machine hash
+    ppcType = { 'Mac'      : 'PMac',
+                'Book'     : 'PMac',
+                'CHRP IBM' : 'pSeries',
+                'Pegasos'  : 'Pegasos',
+                'Efika'    : 'Efika',
+                'iSeries'  : 'iSeries',
+                'pSeries'  : 'pSeries',
+                'PReP'     : 'PReP',
+                'CHRP'     : 'pSeries',
+                'Amiga'    : 'APUS',
+                'Gemini'   : 'Gemini',
+                'Shiner'   : 'ANS',
+                'BRIQ'     : 'BRIQ',
+                'Teron'    : 'Teron',
+                'AmigaOne' : 'Teron',
+                'Maple'    : 'pSeries',
+                'Cell'     : 'pSeries',
+                'Momentum' : 'pSeries',
+                'PS3'      : 'PS3'
+                }
+
+    f = open('/proc/cpuinfo', 'r')
+    lines = f.readlines()
+    f.close()
+    for line in lines:
+        if line.find('machine') != -1:
+            machine = line.split(':')[1]
+        elif line.find('platform') != -1:
+            platform = line.split(':')[1]
+
+    for part in (machine, platform):
+        if ppcMachine is None and part is not None:
+            for type in ppcType.items():
+                if part.find(type[0]) != -1:
+                    ppcMachine = type[1]
+
+    if ppcMachine is None:
+        log.warning("Unable to find PowerPC machine type")
+    elif ppcMachine == 0:
+        log.warning("Unknown PowerPC machine type: %s" %(ppcMachine,))
+
+    return ppcMachine
+
+## Get the powermac machine ID.
+# @return The powermac machine id, or 0 if not PPC.
+def getPPCMacID():
+    machine = None
+
+    if not isPPC():
+        return 0
+    if getPPCMachine() != "PMac":
+        return 0
+
+    f = open('/proc/cpuinfo', 'r')
+    lines = f.readlines()
+    f.close()
+    for line in lines:
+      if line.find('machine') != -1:
+        machine = line.split(':')[1]
+        machine = machine.strip()
+        return machine
+
+    log.warning("No Power Mac machine id")
+    return 0
+
+## Get the powermac generation.
+# @return The powermac generation, or 0 if not powermac.
+def getPPCMacGen():
+    # XXX: should NuBus be here?
+    pmacGen = ['OldWorld', 'NewWorld', 'NuBus']
+
+    if not isPPC():
+        return 0
+    if getPPCMachine() != "PMac":
+        return 0
+
+    f = open('/proc/cpuinfo', 'r')
+    lines = f.readlines()
+    f.close()
+    gen = None
+    for line in lines:
+      if line.find('pmac-generation') != -1:
+        gen = line.split(':')[1]
+        break
+
+    if gen is None:
+        log.warning("Unable to find pmac-generation")
+
+    for type in pmacGen:
+      if gen.find(type) != -1:
+          return type
+
+    log.warning("Unknown Power Mac generation: %s" %(gen,))
+    return 0
+
+## Determine if the hardware is an iBook or PowerBook
+# @return 1 if so, 0 otherwise.
+def getPPCMacBook():
+    if not isPPC():
+        return 0
+    if getPPCMachine() != "PMac":
+        return 0
+
+    f = open('/proc/cpuinfo', 'r')
+    lines = f.readlines()
+    f.close()
+
+    for line in lines:
+      if not string.find(string.lower(line), 'book') == -1:
+        return 1
+    return 0
+
+cell = None
+## Determine if the hardware is the Cell platform.
+# @return True if so, False otherwise.
+def isCell():
+    global cell
+    if cell is not None:
+        return cell
+
+    cell = False
+    if not isPPC():
+        return cell
+
+    f = open('/proc/cpuinfo', 'r')
+    lines = f.readlines()
+    f.close()
+
+    for line in lines:
+      if not string.find(line, 'Cell') == -1:
+          cell = True
+
+    return cell
+
+mactel = None
+## Determine if the hardware is an Intel-based Apple Mac.
+# @return True if so, False otherwise.
+def isMactel():
+    global mactel
+    if mactel is not None:
+        return mactel
+
+    if not isX86():
+        mactel = False
+    elif not os.path.exists("/usr/sbin/dmidecode"):
+        mactel = False
+    else:
+        buf = execWithCapture("/usr/sbin/dmidecode",
+                              ["dmidecode", "-s", "system-manufacturer"])
+        if buf.lower().find("apple") != -1:
+            mactel = True
+        else:
+            mactel = False
+    return mactel
+
+efi = None
+## Determine if the hardware supports EFI.
+# @return True if so, False otherwise.
+def isEfi():
+    global efi
+    if efi is not None:
+        return efi
+
+    efi = False
+    # XXX need to make sure efivars is loaded...
+    if os.path.exists("/sys/firmware/efi"):
+        efi = True
+
+    return efi
+
+## Generate the /etc/rpm/macros file.
+# @param root The root of the filesystem to create the files in.
+def writeRpmPlatform(root="/"):
+    import rpmUtils.arch
+
+    if os.access("%s/etc/rpm/platform" %(root,), os.R_OK):
+        return
+    if not os.access("%s/etc/rpm" %(root,), os.X_OK):
+        os.mkdir("%s/etc/rpm" %(root,))
+
+    myarch = rpmUtils.arch.canonArch
+
+    # now allow an override with rpmarch=i586 on the command line (#101971)
+    if flags.targetarch != None:
+        myarch = flags.targetarch
+
+    # now make the current install believe it, too
+    rpmUtils.arch.canonArch = myarch
+
+    # FIXME: writing /etc/rpm/macros feels wrong somehow
+    # temporary workaround for #92285
+    if not (myarch.startswith("ppc64") or
+            myarch in ("s390x", "sparc64", "x86_64", "ia64")):
+        return
+    if os.access("%s/etc/rpm/macros" %(root,), os.R_OK):
+        if myarch.startswith("ppc64") or myarch == "sparc64":
+            f = open("%s/etc/rpm/macros" %(root,), 'r+')
+            lines = f.readlines()
+            addPrefer = True
+            for line in lines:
+                if line.startswith("%_prefer_color"):
+                    addPrefer = False
+            if addPrefer:    
+                f.write("%_prefer_color   1\n")
+            f.close()
+            return
+        else:
+            return
+
+    f = open("%s/etc/rpm/macros" %(root,), 'w+')
+    f.write("%_transaction_color   3\n")
+    if myarch.startswith("ppc64") or myarch == "sparc64":
+        f.write("%_prefer_color   1\n")
+
+    f.close()
+
+# Architecture checking functions
+
+def isX86(bits=None):
+    arch = os.uname()[4]
+
+    # x86 platforms include:
+    #     i*86
+    #     athlon*
+    #     x86_64
+    #     amd*
+    #     ia32e
+    if bits is None:
+        if (arch.startswith('i') and arch.endswith('86')) or \
+           arch.startswith('athlon') or arch.startswith('amd') or \
+           arch == 'x86_64' or arch == 'ia32e':
+            return True
+    elif bits == 32:
+        if arch.startswith('i') and arch.endswith('86'):
+            return True
+    elif bits == 64:
+        if arch.startswith('athlon') or arch.startswith('amd') or \
+           arch == 'x86_64' or arch == 'ia32e':
+            return True
+
+    return False
+
+def isPPC():
+    return os.uname()[4].startswith('ppc')
+
+def isS390():
+    return os.uname()[4].startswith('s390')
+
+def isIA64():
+    return os.uname()[4] == 'ia64'
+
+def isAlpha():
+    return os.uname()[4].startswith('alpha')
+
+def isSparc():
+    return os.uname()[4].startswith('sparc')
+
+def getArch():
+    if isX86(bits=32):
+        return 'i386'
+    elif isX86(bits=64):
+        return 'x86_64'
+    elif isPPC():
+        return 'ppc'
+    elif isAlpha():
+        return 'alpha'
+    elif isSparc():
+        return 'sparc'
+    else:
+        return os.uname()[4]
+
+def isConsoleOnVirtualTerminal():
+    # XXX PJFIX is there some way to ask the kernel this instead?
+    if isS390():
+        return False
+    return not flags.serial
+
+def strip_markup(text):
+    if text.find("<") == -1:
+        return text
+    r = ""
+    inTag = False
+    for c in text:
+        if c == ">" and inTag:
+            inTag = False
+            continue
+        elif c == "<" and not inTag:
+            inTag = True
+            continue
+        elif not inTag:
+            r += c
+    return r.encode("utf-8")
+
+def notify_kernel(path, action="change"):
+    """ Signal the kernel that the specified device has changed. """
+    log.debug("notifying kernel of '%s' event on device %s" % (action, path))
+    path = os.path.join(path, "uevent")
+    if not path.startswith("/sys/") or not os.access(path, os.W_OK):
+        log.debug("sysfs path '%s' invalid" % path)
+        raise ValueError("invalid sysfs path")
+
+    f = open(path, "a")
+    f.write("%s\n" % action)
+    f.close()
+
+def get_sysfs_path_by_name(dev_name, class_name="block"):
+    dev_name = os.path.basename(dev_name)
+    sysfs_class_dir = "/sys/class/%s" % class_name
+    dev_path = os.path.join(sysfs_class_dir, dev_name)
+    if os.path.exists(dev_path):
+        return dev_path
+
+def numeric_type(num):
+    """ Verify that a value is given as a numeric data type.
+
+        Return the number if the type is sensible or raise ValueError
+        if not.
+    """
+    if num is None:
+        num = 0
+    elif not (isinstance(num, int) or \
+              isinstance(num, long) or \
+              isinstance(num, float)):
+        raise ValueError("value (%s) must be either a number or None" % num)
+
+    return num
+
+def writeReiplMethod(reipl_path, reipl_type):
+    filename = "%s/reipl_type" % (reipl_path,)
+
+    try:
+        f = open(filename, "w")
+    except Exception, e:
+        message = _("Error: On open, cannot set reIPL method to %(reipl_type)s "
+                    "(%(filename)s: %(e)s)" % {'reipl_type': reipl_type,
+                                               'filename': filename,
+                                               'e': e})
+        log.warning(message)
+        raise Exception (message)
+
+    try:
+        f.write(reipl_type)
+        f.flush()
+    except Exception, e:
+        message = _("Error: On write, cannot set reIPL method to "
+                    "%(reipl_type)s (%(filename)s: %(e)s)" \
+                  % {'reipl_type': reipl_type, 'filename': filename, 'e': e})
+        log.warning(message)
+        raise Exception (message)
+
+    try:
+        f.close()
+    except Exception, e:
+        message = _("Error: On close, cannot set reIPL method to "
+                    "%(reipl_type)s (%(filename)s: %(e)s)" \
+                  % {'reipl_type': reipl_type, 'filename': filename, 'e': e})
+        log.warning(message)
+        raise Exception (message)
+
+def reIPLonCCW(iplsubdev, reipl_path):
+    device = "<unknown>"
+
+    try:
+        device = os.readlink("/sys/block/" + iplsubdev + "/device").split('/')[-1]
+
+        writeReiplMethod(reipl_path, 'ccw')
+
+        try:
+            f = open("%s/ccw/device" % (reipl_path,), "w")
+            f.write(device)
+            f.close()
+        except Exception, e:
+            message = _("Error: Could not set %(device)s as reIPL device "
+                        "(%(e)s)" % {'device': device, 'e': e})
+            log.warning(message)
+            raise Exception (message)
+
+        try:
+            f = open("%s/ccw/loadparm" % (reipl_path,), "w")
+            f.write("\n")
+            f.close()
+        except Exception, e:
+            message = _("Error: Could not reset loadparm (%s)" % (e,))
+            log.warning(message)
+            raise Exception (message)
+
+        try:
+            f = open("%s/ccw/parm" % (reipl_path,), "w")
+            f.write("\n")
+            f.close()
+        except Exception, e:
+            message = _("Warning: Could not reset parm (%s)" % (e,))
+            log.warning(message)
+            # do NOT raise an exception since this might not exist or not be writable
+
+        log.info("ccw reIPL using DASD %s" % (device,))
+
+    except Exception, e:
+        try:
+            message = e.args[0]
+        except:
+            message = e.__str__ ()
+        log.info("Caught exception %s", (message,))
+        return (message,
+                (_("After shutdown, please perform a manual IPL from DASD device %s to continue "
+                   "installation") % (device,)))
+
+    return None
+
+def reIPLonFCP(iplsubdev, reipl_path):
+    fcpvalue = { "device": "<unknown>", "wwpn": "<unknown>", "lun": "<unknown>" }
+
+    try:
+        syspath = "/sys/block/" + iplsubdev + "/device"
+
+        fcpprops = [ ("hba_id", "device"), ("wwpn", "wwpn"), ("fcp_lun", "lun") ]
+
+        # Read in values to change.
+        # This way, if we can't set FCP mode, we can tell the user what to manually reboot to.
+        for (syspath_property, reipl_property) in fcpprops:
+            try:
+                f = open(syspath + "/" + syspath_property, "r")
+                value = f.read().strip()
+                fcpvalue[reipl_property] = value
+                f.close()
+            except Exception, e:
+                message = _("Error: reading FCP property %(syspath_property)s "
+                            "for reIPL (%(e)s)" \
+                          % {'syspath_property': syspath_property, 'e': e})
+                log.warning(message)
+                raise Exception (message)
+
+        writeReiplMethod(reipl_path, 'fcp')
+
+        # Write out necessary parameters.
+        for (syspath_property, reipl_property) in fcpprops:
+            try:
+                f = open("%s/fcp/%s" % (reipl_path, reipl_property,), "w")
+                f.write(fcpvalue[reipl_property])
+                f.close()
+            except Exception, e:
+                message = _("Error: writing FCP property %(reipl_property)s "
+                            "for reIPL (%(e)s)" \
+                          % {'reipl_property': reipl_property, 'e': e})
+                log.warning(message)
+                raise Exception (message)
+
+        defaultprops = [ ("bootprog", "0"), ("br_lba", "0") ]
+
+        # Write out default parameters.
+        for (reipl_property, default_value) in defaultprops:
+            try:
+                f = open("%s/fcp/%s" % (reipl_path, reipl_property,), "w")
+                f.write (default_value)
+                f.close()
+            except Exception, e:
+                message = _("Error: writing default FCP property "
+                            "%(reipl_property)s for reIPL (%(e)s)" \
+                          % {'reipl_property': reipl_property, 'e': e})
+                log.warning(message)
+                raise Exception (message)
+
+        log.info("fcp reIPL using FCP %(device)s, WWPN %(wwpn)s, LUN %(lun)s" % (fcpvalue))
+
+    except Exception, e:
+        try:
+            message = e.args[0]
+        except:
+            message = e.__str__ ()
+        log.info("Caught exception %s", (message,))
+        return (message,
+                (_("After shutdown, please perform a manual IPL from FCP %(device)s with WWPN %(wwpn)s "
+                   "and LUN %(lun)s to continue installation") % (fcpvalue)))
+
+    return None
+
+
+def reIPLtrigger(anaconda):
+    if not isS390():
+        return
+    if anaconda.canReIPL:
+        log.info("reIPL configuration successful => reboot")
+        os.kill(os.getppid(), signal.SIGUSR2)
+    else:
+        log.info("reIPL configuration failed => halt")
+        os.kill(os.getppid(), signal.SIGUSR1)
+
+def reIPL(anaconda, loader_pid):
+    instruction = _("After shutdown, please perform a manual IPL from the device "
+                    "now containing /boot to continue installation")
+
+    reipl_path = "/sys/firmware/reipl"
+
+    try:
+        ipldev = anaconda.platform.bootDevice().disk.name
+    except:
+        ipldev = None
+
+    if ipldev is None:
+        message = _("Error determining boot device's disk name")
+        log.warning(message)
+        return (message, instruction)
+
+    message = (_("The mount point /boot or / is on a disk that we are not familiar with"), instruction)
+    if ipldev.startswith("dasd"):
+        message = reIPLonCCW(ipldev, reipl_path)
+    elif ipldev.startswith("sd"):
+        message = reIPLonFCP(ipldev, reipl_path)
+
+    if message is None:
+        anaconda.canReIPL = True
+    else:
+        anaconda.canReIPL = False
+        log.info(message)
+
+    reIPLtrigger(anaconda)
+
+    # the final return is either None if reipl configuration worked (=> reboot),
+    # or a two-item list with errorMessage and rebootInstr (=> shutdown)
+    return message
+
+def resetRpmDb(rootdir):
+    for rpmfile in glob.glob("%s/var/lib/rpm/__db.*" % rootdir):
+        try:
+            os.unlink(rpmfile)
+        except Exception, e:
+            log.debug("error %s removing file: %s" %(e,rpmfile))
+
+def parseNfsUrl(nfsurl):
+    options = ''
+    host = ''
+    path = ''
+    if nfsurl:
+        s = nfsurl.split(":")
+        s.pop(0)
+        if len(s) >= 3:
+            (options, host, path) = s[:3]
+        elif len(s) == 2:
+            (host, path) = s
+        else:
+            host = s[0]
+    return (options, host, path)
diff --git a/pyanaconda/iw/DeviceSelector.py b/pyanaconda/iw/DeviceSelector.py
new file mode 100644
index 0000000..33a7fe3
--- /dev/null
+++ b/pyanaconda/iw/DeviceSelector.py
@@ -0,0 +1,217 @@
+#
+# Filtering UI for the simple path through the storage code.
+#
+# Copyright (C) 2009  Red Hat, Inc.
+# 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 as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# 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, see <http://www.gnu.org/licenses/>.
+#
+
+import gtk, gobject
+import gtk.glade
+import gui
+
+import gettext
+_ = lambda x: gettext.ldgettext("anaconda", x)
+
+# The column that holds a python object containing information about the
+# device in each row.  This value really shouldn't be overridden.
+OBJECT_COL = 0
+
+# These columns can be overridden with the active= and visible= parameters to
+# __init__.  active indicates which column tracks whether the row is checked
+# by default, and visible indicates which column tracks whether the row is
+# seen or not.
+VISIBLE_COL = 1
+ACTIVE_COL = 2
+
+# This should not be overridden.  It controls whether or not a row may be
+# deselected.  Rows with this column set will stay in selected or not
+# (whichever they were initialized to) permanently.
+IMMUTABLE_COL = 3
+
+class DeviceDisplayer(object):
+    def _column_toggled(self, menuItem, col):
+        # This is called when a selection is made in the column visibility drop
+        # down menu, and obviously makes a column visible (or not).
+        col.set_visible(not col.get_visible())
+
+    def __init__(self, store, model, view, active=ACTIVE_COL, visible=VISIBLE_COL):
+        self.store = store
+        self.model = model
+        self.view = view
+
+        self.menu = None
+
+        self.active = active
+        self.visible = visible
+
+    def addColumn(self, title, num, displayed=True):
+        cell = gtk.CellRendererText()
+        cell.set_property("yalign", 0)
+
+        col = gtk.TreeViewColumn(title, cell, text=num, active=self.active)
+        col.set_visible(displayed)
+        col.set_expand(True)
+        col.set_resizable(True)
+        self.view.append_column(col)
+
+        # This needs to be set on all columns or it will be impossible to sort
+        # by that column.
+        col.set_sort_column_id(num)
+
+        if self.menu:
+            # Add a new entry to the drop-down menu.
+            item = gtk.CheckMenuItem(title)
+            item.set_active(displayed)
+            item.connect("toggled", self._column_toggled, col)
+            item.show()
+            self.menu.append(item)
+
+    def createMenu(self):
+        self.menu = gtk.Menu()
+
+        # Add a blank column at the (current) end of the view.  This column
+        # exists only so we can have a header to click on and display the
+        # drop down allowing column configuration.
+        menuCol = gtk.TreeViewColumn("")
+        menuCol.set_clickable(True)
+        menuCol.set_sizing(gtk.TREE_VIEW_COLUMN_FIXED)
+        menuCol.set_fixed_width(30)
+        menuCol.connect("clicked", lambda col, menu: menu.popup(None, None, None, 0, 0),
+                        self.menu)
+
+        image = gui.readImageFromFile("filter-menu.png")
+        image.show_all()
+        menuCol.set_widget(image)
+
+        # Make sure the menu column gets added after all other columns so it
+        # will be on the far right edge.
+        self.view.connect("show", lambda x: self.view.append_column(menuCol))
+
+    def getStoreIter(self, row, model=None):
+        """Get an iter on the underlying store that maps to a row on the
+           provided model.  If model is None, use the default.
+        """
+        if not model:
+            model = self.model
+
+        iter = model.get_iter(row)
+        if not iter:
+            return None
+
+        while not self.store.iter_is_valid(iter):
+            if isinstance(model, gtk.TreeModelFilter):
+                iter = model.convert_iter_to_child_iter(iter)
+            elif isinstance(model, gtk.TreeModelSort):
+                iter = model.convert_iter_to_child_iter(None, iter)
+
+            model = model.get_model()
+
+        return iter
+
+    def getSelected(self):
+        """Return a list of all the items currently checked in the UI, or
+           an empty list if nothing is selected.
+        """
+        return filter(lambda row: row[self.active], self.store)
+
+    def getNVisible(self):
+        """Return the number of items currently visible in the UI."""
+        return len(filter(lambda row: row[self.visible], self.store))
+
+class DeviceSelector(DeviceDisplayer):
+    def createSelectionCol(self, title="", radioButton=False, toggledCB=None,
+                           membershipCB=None):
+        # Add a column full of checkboxes/radiobuttons in the first column of the view.
+        crt = gtk.CellRendererToggle()
+        crt.set_property("activatable", True)
+        crt.set_property("yalign", 0)
+        crt.set_radio(radioButton)
+
+        crt.connect("toggled", self._device_toggled, toggledCB, radioButton)
+
+        col = gtk.TreeViewColumn(title, crt, active=self.active)
+        col.set_alignment(0.75)
+
+        if not radioButton:
+            self.allButton = gtk.ToggleButton()
+            col.connect("clicked", lambda *args: self.allButton.set_active(not self.allButton.get_active()))
+
+            col.set_widget(self.allButton)
+            self.allButton.show_all()
+
+            self.allButton.connect("toggled", self._all_clicked, toggledCB, membershipCB)
+
+        self.view.append_column(col)
+        self.view.set_headers_clickable(True)
+        self._activated_id = self.view.connect("row-activated", self._row_activated, toggledCB, radioButton)
+
+    def _all_clicked(self, button, toggledCB=None, membershipCB=None):
+        # This is called when the Add/Remove all button is checked and does
+        # the obvious.
+        def _toggle_all(model, path, iter, set):
+            # Don't check the boxes of rows that aren't visible or aren't part
+            # of the currently displayed page.  We'd like the all button to
+            # only operate on the current page, after all.
+            if not model[path][self.visible] or model[path][IMMUTABLE_COL] or \
+                (membershipCB and not membershipCB(model[path][OBJECT_COL])):
+                return
+
+            # Don't try to set a row to active if it's already been checked.
+            # This prevents devices that have been checked before the all
+            # button was checked from getting double counted.
+            if model[path][self.active] == set:
+                return
+
+            model[path][self.active] = set
+
+            if toggledCB:
+                toggledCB(set, model[path][OBJECT_COL])
+
+        set = button.get_active()
+        self.store.foreach(_toggle_all, set)
+
+    def _row_activated(self, view, row, col, cb, isRadio):
+        # This is called when a row is double-clicked, or selected via space or
+        # enter.  We just want to do the same as if the checkbox were clicked.
+        self._device_toggled(None, row, cb, isRadio)
+
+    def _device_toggled(self, button, row, cb, isRadio):
+        # This is called when the checkbox for a device is clicked or unclicked.
+        iter = self.getStoreIter(row)
+        if not iter:
+            return
+
+        storeRow = self.store.get_path(iter)
+        if self.store[storeRow][IMMUTABLE_COL]:
+            return
+
+        if isRadio:
+            # This is lame, but there's no other way to do it.  First we have
+            # to uncheck everything in the store, then we check the one that
+            # was clicked on.
+            for r in self.store:
+                r[self.active] = False
+
+            self.store[storeRow][self.active] = True
+
+            if cb:
+                cb(True, self.store[storeRow][OBJECT_COL])
+        else:
+            is_checked = self.store[storeRow][self.active]
+            self.store[storeRow][self.active] = not is_checked
+
+            if cb:
+                cb(not is_checked, self.store[storeRow][OBJECT_COL])
diff --git a/pyanaconda/iw/GroupSelector.py b/pyanaconda/iw/GroupSelector.py
new file mode 100644
index 0000000..4d64e59
--- /dev/null
+++ b/pyanaconda/iw/GroupSelector.py
@@ -0,0 +1,620 @@
+# Copyright 2005-2007 Red Hat, Inc.
+#
+# Jeremy Katz <katzj@xxxxxxxxxx>
+#
+# 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 only
+#
+# 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 Library 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
+import logging
+import gettext
+
+import gtk
+import gtk.glade
+import gtk.gdk as gdk
+import gobject
+
+import yum
+import yum.Errors
+try:
+    import repomd.mdErrors as mdErrors
+except ImportError: # yum 2.9.x
+    mdErrors = yum.Errors
+from yum.constants import *
+from compssort import *
+
+I18N_DOMAIN="anaconda"
+
+import rpm
+
+def sanitizeString(s, translate = True):
+    if len(s) == 0:
+        return s
+
+    if not translate:
+        i18ndomains = []
+    elif hasattr(rpm, "expandMacro"):
+        i18ndomains = rpm.expandMacro("%_i18ndomains").split(":")
+    else:
+        i18ndomains = ["redhat-dist"]
+        
+    # iterate over i18ndomains to find the translation
+    for d in i18ndomains:
+        r = gettext.dgettext(d, s)
+        if r != s:
+            s = r
+            break
+        
+    s = s.replace("\n\n", "\x00")
+    s = s.replace("\n", " ")
+    s = s.replace("\x00", "\n\n")
+    s = s.replace("&", "&amp;")
+    s = s.replace("<", "&lt;")
+    s = s.replace(">", "&gt;")
+    if type(s) != unicode:
+        try:
+            s = unicode(s, "utf-8")
+        except UnicodeDecodeError, e:
+            sys.stderr.write("Unable to convert %s to a unicode object: %s\n" % (s, e))
+            return ""
+    return s
+
+# given a package object, spit out a string reasonable for the list widgets
+def listEntryString(po):
+    desc = po.returnSimple('summary') or ''
+    pkgStr = "%s-%s-%s.%s" % (po.name, po.version, po.release, po.arch)
+    desc = "<b>%s</b> - %s" %(pkgStr, sanitizeString(desc))
+    return desc
+
+GLADE_FILE = "GroupSelector.glade"
+
+def _getgladefile(fn):
+    if os.path.exists(fn):
+        return fn
+    elif os.path.exists("data/%s" %(fn,)):
+        return "data/%s" %(fn,)
+    else:
+        return "/usr/share/pirut/ui/%s" %(fn,)
+
+t = gettext.translation(I18N_DOMAIN, "/usr/share/locale", fallback = True)
+_ = t.lgettext
+
+
+def _deselectPackage(ayum, group, pkg):
+    grpid = group.groupid
+    try:
+        pkgs = ayum.pkgSack.returnNewestByName(pkg)
+    except mdErrors.PackageSackError:
+        log = logging.getLogger("yum.verbose")
+        log.debug("no such package %s from group %s" % (pkg, grpid))
+    if pkgs:
+        pkgs = ayum.bestPackagesFromList(pkgs)
+    for po in pkgs:
+        txmbrs = ayum.tsInfo.getMembers(pkgtup = po.pkgtup)
+        for txmbr in txmbrs:
+            try:
+                txmbr.groups.remove(grpid)
+            except ValueError:
+                log = logging.getLogger("yum.verbose")                
+                log.debug("package %s was not marked in group %s" %(po, grpid))
+            if len(txmbr.groups) == 0:
+                ayum.tsInfo.remove(po.pkgtup)
+
+def _selectPackage(ayum, group, pkg):
+    grpid = group.groupid
+    try:
+        txmbrs = ayum.install(name = pkg)
+    except yum.Errors.InstallError, e:
+        log = logging.getLogger("yum.verbose")
+        log.info("No package named %s available to be installed: %s" %(pkg, e))
+    else:
+        map(lambda x: x.groups.append(grpid), txmbrs)
+
+def _catHasGroupWithPackages(cat, ayum):
+    grps = map(lambda x: ayum.comps.return_group(x),
+                   filter(lambda x: ayum.comps.has_group(x), cat.groups))
+    for g in grps:
+        if ayum._groupHasPackages(g):
+            return True
+    return False
+
+class OptionalPackageSelector:
+    def __init__(self, yumobj, group, parent = None, getgladefunc = None):
+        self.ayum = yumobj
+        self.group = group
+
+        if getgladefunc:
+            xmlfn = getgladefunc(GLADE_FILE)
+        else:
+            xmlfn = _getgladefile(GLADE_FILE)
+
+        self.xml = gtk.glade.XML(xmlfn, "groupDetailsDialog",
+                                 domain=I18N_DOMAIN)
+
+        self.window = self.xml.get_widget("groupDetailsDialog")
+        if parent:
+            self.window.set_transient_for(parent)
+        self.window.set_title(_("Packages in %s") %
+                               xmltrans(group.name, group.translated_name))
+        self.window.set_position(gtk.WIN_POS_CENTER_ON_PARENT)
+        self.window.set_size_request(600, 400)
+        self._createStore()
+        self._populate()
+
+    def __search_pkgs(self, model, col, key, i):
+        val = model.get_value(i, 2).returnSimple('name')
+        if val.lower().startswith(key.lower()):
+            return False
+        return True
+
+    def _createStore(self):
+        self.pkgstore = gtk.ListStore(gobject.TYPE_BOOLEAN,
+                                      gobject.TYPE_STRING,
+                                      gobject.TYPE_PYOBJECT)
+        tree = self.xml.get_widget("packageList")
+        tree.set_model(self.pkgstore)
+
+        column = gtk.TreeViewColumn(None, None)
+        cbr = gtk.CellRendererToggle()
+        cbr.connect ("toggled", self._pkgToggled)
+        column.pack_start(cbr, False)
+        column.add_attribute(cbr, 'active', 0)
+        tree.append_column(column)
+        
+        column = gtk.TreeViewColumn(None, None)
+        renderer = gtk.CellRendererText()
+        column.pack_start(renderer, True)
+        column.add_attribute(renderer, 'markup', 1)
+        tree.append_column(column)
+        tree.set_search_equal_func(self.__search_pkgs)
+        tree.connect("row-activated", self._rowToggle)
+
+        self.pkgstore.set_sort_column_id(1, gtk.SORT_ASCENDING)
+
+    def _rowToggle(self, tree, path, col):
+        self._pkgToggled(None, path)
+
+    def _pkgToggled(self, widget, path):
+        if type(path) == type(str):
+            i = self.pkgstore.get_iter_from_string(path)
+        else:
+            i = self.pkgstore.get_iter(path)
+        sel = self.pkgstore.get_value(i, 0)
+        pkg = self.pkgstore.get_value(i, 2).returnSimple('name')
+        if sel and not self.ayum.simpleDBInstalled(name = pkg):
+            _deselectPackage(self.ayum, self.group, pkg)
+        elif sel:
+            self.ayum.remove(name = pkg)
+        elif self.ayum.simpleDBInstalled(name = pkg):
+            txmbrs = self.ayum.tsInfo.matchNaevr(name = pkg)
+            for tx in txmbrs:
+                if tx.output_state == TS_ERASE:
+                    self.ayum.tsInfo.remove(tx.pkgtup)
+        else:
+            _selectPackage(self.ayum, self.group, pkg)
+        self.pkgstore.set_value(i, 0, not sel)
+            
+
+    def __getPackageObject(self, pkgname):
+        pos = self.ayum.pkgSack.searchNevra(name=pkgname)
+        if len(pos) > 0:
+            return pos[0]
+        return None
+
+    def _populate(self):
+        pkgs = self.group.default_packages.keys() + \
+               self.group.optional_packages.keys()
+        for pkg in pkgs:
+            po = self.__getPackageObject(pkg)
+            if not po:
+                continue
+
+            # Don't display obsolete packages in the UI
+            if self.ayum.up.checkForObsolete([po.pkgtup]).has_key(po.pkgtup):
+                continue
+
+            self.pkgstore.append([self.ayum.isPackageInstalled(pkg), listEntryString(po), po])
+
+    def run(self):
+        self.window.show_all()
+        return self.window.run()
+
+    def destroy(self):
+        return self.window.destroy()
+
+# the GroupSelector requires a YumBase object which also implements the
+# following additional methods:
+# * isPackageInstalled(p): is there a package named p installed or selected
+# * isGroupInstalled(grp): is there a group grp installed or selected
+class GroupSelector:
+    def __init__(self, yumobj, getgladefunc = None, framefunc = None):
+        self.ayum = yumobj
+
+        self.getgladefunc = getgladefunc
+        self.framefunc = framefunc
+        if getgladefunc:
+            xmlfn = getgladefunc(GLADE_FILE)
+        else:
+            xmlfn = _getgladefile(GLADE_FILE)
+
+        self.xml = gtk.glade.XML(xmlfn, "groupSelectionBox",
+                                 domain=I18N_DOMAIN)
+        self.vbox = self.xml.get_widget("groupSelectionBox")
+        self.xml.get_widget("detailsButton").set_sensitive(False)
+
+        self.menuxml = gtk.glade.XML(xmlfn, "groupPopupMenu",
+                                     domain=I18N_DOMAIN)
+        self.groupMenu = self.menuxml.get_widget("groupPopupMenu")
+
+        self._connectSignals()
+        self._createStores()
+        self.vbox.show()
+
+    def _connectSignals(self):
+        sigs = { "on_detailsButton_clicked": self._optionalPackagesDialog,
+                 "on_groupList_button_press": self._groupListButtonPress,
+                 "on_groupList_popup_menu": self._groupListPopup, }
+        self.xml.signal_autoconnect(sigs)
+
+        menusigs = { "on_select_activate": self._selectAllPackages,
+                     "on_selectgrp_activate": self._groupSelect,
+                     "on_deselectgrp_activate": self._groupDeselect,
+                     "on_deselect_activate": self._deselectAllPackages }
+        self.menuxml.signal_autoconnect(menusigs)
+
+    def _createStores(self):
+        self._createCategoryStore()
+        self._createGroupStore()
+
+        b = gtk.TextBuffer()
+        self.xml.get_widget("groupDescriptionTextView").set_buffer(b)
+
+    def _createCategoryStore(self):        
+        # display string, category object
+        self.catstore = gtk.TreeStore(gobject.TYPE_STRING,
+                                      gobject.TYPE_PYOBJECT)
+        tree = self.xml.get_widget("categoryList")
+        tree.set_model(self.catstore)
+
+        renderer = gtk.CellRendererText()
+        column = gtk.TreeViewColumn('Text', renderer, markup=0)
+        column.set_clickable(False)
+        tree.append_column(column)
+        tree.columns_autosize()
+        tree.set_enable_search(False)
+
+        selection = tree.get_selection()
+        selection.connect("changed", self._categorySelected)
+
+    def _createGroupStore(self):
+        # checkbox, display string, object
+        self.groupstore = gtk.TreeStore(gobject.TYPE_BOOLEAN,
+                                        gobject.TYPE_STRING,
+                                        gobject.TYPE_PYOBJECT,
+                                        gobject.TYPE_OBJECT)
+        tree = self.xml.get_widget("groupList")
+        tree.set_model(self.groupstore)
+
+        column = gtk.TreeViewColumn(None, None)
+        column.set_clickable(True)
+        pixr = gtk.CellRendererPixbuf()
+        pixr.set_property('stock-size', 1)
+        column.pack_start(pixr, False)
+        column.add_attribute(pixr, 'pixbuf', 3)
+        cbr = gtk.CellRendererToggle()
+        column.pack_start(cbr, False)
+        column.add_attribute(cbr, 'active', 0)
+        cbr.connect ("toggled", self._groupToggled)
+        tree.append_column(column)
+        
+        renderer = gtk.CellRendererText()
+        column = gtk.TreeViewColumn('Text', renderer, markup=1)
+        column.set_clickable(False)
+        tree.append_column(column)
+        tree.columns_autosize()
+        tree.set_enable_search(False)
+        tree.grab_focus()
+
+        selection = tree.get_selection()
+        selection.connect("changed", self._groupSelected)
+        selection.set_mode(gtk.SELECTION_MULTIPLE)
+
+    def _get_pix(self, fn):
+        imgsize = 24
+        pix = gtk.gdk.pixbuf_new_from_file(fn)
+        if pix.get_height() != imgsize or pix.get_width() != imgsize:
+            pix = pix.scale_simple(imgsize, imgsize,
+                                   gtk.gdk.INTERP_BILINEAR)
+        return pix
+
+    def _categorySelected(self, selection):
+        self.groupstore.clear()
+        (model, i) = selection.get_selected()
+        if not i:
+            return
+        cat = model.get_value(i, 1)
+
+        # fall back to the category pixbuf
+        fbpix = None
+        fn = "/usr/share/pixmaps/comps/%s.png" %(cat.categoryid,)
+        if os.access(fn, os.R_OK):
+            fbpix = self._get_pix(fn)
+        self._populateGroups(cat.groups, fbpix)
+
+    def _populateGroups(self, groups, defaultpix = None):
+        grps = map(lambda x: self.ayum.comps.return_group(x),
+                   filter(lambda x: self.ayum.comps.has_group(x), groups))
+        grps.sort(ui_comps_sort)
+        for grp in grps:
+            if not self.ayum._groupHasPackages(grp):
+                continue
+            s = "<span size=\"large\" weight=\"bold\">%s</span>" % xmltrans(grp.name, grp.translated_name)
+
+            fn = "/usr/share/pixmaps/comps/%s.png" % grp.groupid
+            if os.access(fn, os.R_OK):
+                pix = self._get_pix(fn)
+            elif defaultpix:
+                pix = defaultpix
+            else:
+                pix = None
+            self.groupstore.append(None,
+                                   [self.ayum.isGroupInstalled(grp),s,grp,pix])
+
+        tree = self.xml.get_widget("groupList")
+        gobject.idle_add(lambda x: x.flags() & gtk.REALIZED and x.scroll_to_point(0, 0), tree)
+        self.xml.get_widget("optionalLabel").set_text("")
+        self.xml.get_widget("detailsButton").set_sensitive(False)
+
+        # select the first group
+        i = self.groupstore.get_iter_first()
+        if i is not None:
+            sel = self.xml.get_widget("groupList").get_selection()
+            sel.select_iter(i)
+
+    def _groupSelected(self, selection):
+        if selection.count_selected_rows() != 1:
+            # if we have more groups (or no group) selected, then
+            # we can't show a description or allow selecting optional
+            self.__setGroupDescription(None)
+            return
+        (model, paths) = selection.get_selected_rows()
+        grp = model.get_value(model.get_iter(paths[0]), 2)
+        self.__setGroupDescription(grp)
+
+    def __setGroupDescription(self, grp):
+        b = self.xml.get_widget("groupDescriptionTextView").get_buffer()
+        b.set_text("")
+        if grp is None:
+            return
+        
+        if grp.description:
+            txt = xmltrans(grp.description, grp.translated_description)
+        else:
+            txt = xmltrans(grp.name, grp.translated_name)
+
+        inst = 0
+        cnt = 0
+        pkgs = grp.default_packages.keys() + grp.optional_packages.keys()
+        for p in pkgs:
+            if self.ayum.isPackageInstalled(p):
+                cnt += 1
+                inst += 1
+            elif self.ayum.pkgSack.searchNevra(name=p):
+                cnt += 1
+            else:
+                log = logging.getLogger("yum.verbose")
+                log.debug("no such package %s for %s" %(p, grp.groupid))
+
+        b.set_text(txt)
+        if cnt == 0 or not self.ayum.isGroupInstalled(grp):
+            self.xml.get_widget("detailsButton").set_sensitive(False)
+            self.xml.get_widget("optionalLabel").set_text("")
+        else:
+            self.xml.get_widget("detailsButton").set_sensitive(True)
+            txt = _("Optional packages selected: %(inst)d of %(cnt)d") \
+                    % {'inst': inst, 'cnt': cnt}
+            self.xml.get_widget("optionalLabel").set_markup(_("<i>%s</i>") %(txt,))
+
+    def _groupToggled(self, widget, path, sel = None, updateText = True):
+        if type(path) == type(str):
+            i = self.groupstore.get_iter_from_string(path)
+        else:
+            i = self.groupstore.get_iter(path)
+        if sel is None:
+            sel = not self.groupstore.get_value(i, 0)
+            
+        self.groupstore.set_value(i, 0, sel)
+        grp = self.groupstore.get_value(i, 2)
+
+        self.vbox.window.set_cursor(gdk.Cursor(gdk.WATCH))
+        
+        if sel:
+            self.ayum.selectGroup(grp.groupid)
+        else:
+            self.ayum.deselectGroup(grp.groupid)
+            # FIXME: this doesn't mark installed packages for removal.
+            # we probably want that behavior with s-c-p, but not anaconda
+
+        if updateText:
+            self.__setGroupDescription(grp)
+
+        self.vbox.window.set_cursor(None)
+
+    def populateCategories(self):
+        self.catstore.clear()
+        cats = self.ayum.comps.categories
+        cats.sort(ui_comps_sort)
+        for cat in cats:
+            if not _catHasGroupWithPackages(cat, self.ayum):
+                continue
+            s = "<span size=\"large\" weight=\"bold\">%s</span>" % xmltrans(cat.name, cat.translated_name)
+            self.catstore.append(None, [s, cat])
+
+        # select the first category
+        i = self.catstore.get_iter_first()
+        if i is not None:
+            sel = self.xml.get_widget("categoryList").get_selection()
+            sel.select_iter(i)
+
+    def _setupCatchallCategory(self):
+        # FIXME: this is a bad hack, but catch groups which aren't in
+        # a category yet are supposed to be user-visible somehow.
+        # conceivably should be handled by yum
+        grps = {}
+        for g in self.ayum.comps.groups:
+            if g.user_visible and self.ayum._groupHasPackages(g):
+                grps[g.groupid] = g
+
+        for cat in self.ayum.comps.categories:
+            for g in cat.groups:
+                if grps.has_key(g):
+                    del grps[g]
+
+        if len(grps.keys()) == 0:
+            return
+        c = yum.comps.Category()
+        c.name = _("Uncategorized")
+        c._groups = grps
+        c.categoryid = "uncategorized"
+
+        self.ayum.comps._categories[c.categoryid] = c
+
+    def doRefresh(self):
+        if len(self.ayum.comps.categories) == 0:
+            self.xml.get_widget("categorySW").hide()
+            self._populateGroups(map(lambda x: x.groupid,
+                                     self.ayum.comps.groups))
+        else:
+            self._setupCatchallCategory()
+            self.populateCategories()
+
+    def _getSelectedGroup(self):
+        """Return the selected group.
+        NOTE: this only ever returns one group."""
+        selection = self.xml.get_widget("groupList").get_selection()
+        (model, paths) = selection.get_selected_rows()
+        for p in paths:
+            return model.get_value(model.get_iter(p), 2)
+        return None
+    
+    def _optionalPackagesDialog(self, *args):
+        group = self._getSelectedGroup()
+        if group is None:
+            return
+
+        pwin = self.vbox.get_parent() # hack to find the parent window...
+        while not isinstance(pwin, gtk.Window):
+            pwin = pwin.get_parent()
+        d = OptionalPackageSelector(self.ayum, group, pwin, self.getgladefunc)
+        if self.framefunc:
+            self.framefunc(d.window)
+        rc = d.run()
+        d.destroy()
+        self.__setGroupDescription(group)
+
+    def _groupSelect(self, *args):
+        selection = self.xml.get_widget("groupList").get_selection()
+        if selection.count_selected_rows() == 0:
+            return
+
+        (model, paths) = selection.get_selected_rows()
+        for p in paths:
+            self._groupToggled(model, p, True, updateText=(len(paths) == 1))
+
+    def _groupDeselect(self, *args):
+        selection = self.xml.get_widget("groupList").get_selection()
+        if selection.count_selected_rows() == 0:
+            return
+
+        (model, paths) = selection.get_selected_rows()
+        for p in paths:
+            self._groupToggled(model, p, False, updateText=(len(paths) == 1))
+
+    def _selectAllPackages(self, *args):
+        selection = self.xml.get_widget("groupList").get_selection()
+        if selection.count_selected_rows() == 0:
+            return
+        (model, paths) = selection.get_selected_rows()
+
+        self.vbox.window.set_cursor(gdk.Cursor(gdk.WATCH))
+
+        for p in paths:
+            i = model.get_iter(p)
+            grp = model.get_value(i, 2)
+
+            # ensure the group is selected
+            self.ayum.selectGroup(grp.groupid)
+            model.set_value(i, 0, True)
+        
+            for pkg in grp.default_packages.keys() + \
+                    grp.optional_packages.keys():
+                if self.ayum.isPackageInstalled(pkg):
+                    continue
+                elif self.ayum.simpleDBInstalled(name = pkg):
+                    txmbrs = self.ayum.tsInfo.matchNaevr(name = pkg)
+                    for tx in txmbrs:
+                        if tx.output_state == TS_ERASE:
+                            self.ayum.tsInfo.remove(tx.pkgtup)
+                else:
+                    _selectPackage(self.ayum, grp, pkg)
+
+        if len(paths) == 1:
+            self.__setGroupDescription(grp)
+        self.vbox.window.set_cursor(None)
+
+    def _deselectAllPackages(self, *args):
+        selection = self.xml.get_widget("groupList").get_selection()
+        if selection.count_selected_rows() == 0:
+            return
+        (model, paths) = selection.get_selected_rows()
+        
+        for p in paths:
+            i = model.get_iter(p)
+            grp = model.get_value(i, 2)
+
+            for pkg in grp.default_packages.keys() + \
+                    grp.optional_packages.keys():
+                if not self.ayum.isPackageInstalled(pkg):
+                    continue
+                elif self.ayum.simpleDBInstalled(name=pkg):
+                    self.ayum.remove(name=pkg)
+                else:
+                    _deselectPackage(self.ayum, grp, pkg)
+        if len(paths) == 1:
+            self.__setGroupDescription(grp)
+
+    def __doGroupPopup(self, button, time):
+        menu = self.groupMenu
+        menu.popup(None, None, None, button, time)
+        menu.show_all()
+
+    def _groupListButtonPress(self, widget, event):
+        if event.button == 3:
+            x = int(event.x)
+            y = int(event.y)
+            pthinfo = widget.get_path_at_pos(x, y)
+            if pthinfo is not None:
+                sel = widget.get_selection()
+                if sel.count_selected_rows() == 1:
+                    path, col, cellx, celly = pthinfo                    
+                    widget.grab_focus()
+                    widget.set_cursor(path, col, 0)
+                self.__doGroupPopup(event.button, event.time)
+            return 1
+
+    def _groupListPopup(self, widget):
+        sel = widget.get_selection()
+        if sel.count_selected_rows() > 0:
+            self.__doGroupPopup(0, 0)
+        
+        
diff --git a/pyanaconda/iw/Makefile.am b/pyanaconda/iw/Makefile.am
new file mode 100644
index 0000000..da0b579
--- /dev/null
+++ b/pyanaconda/iw/Makefile.am
@@ -0,0 +1,24 @@
+# iw/Makefile.am for anaconda
+#
+# Copyright (C) 2009  Red Hat, Inc.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License as published
+# by the Free Software Foundation; either version 2.1 of the License, or
+# (at your option) any later version.
+#
+# 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 Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+#
+# Author: David Cantrell <dcantrell@xxxxxxxxxx>
+
+pkgpyexecdir = $(pyexecdir)/py$(PACKAGE_NAME)
+iwdir = $(pkgpyexecdir)/iw
+iw_PYTHON = *.py
+
+MAINTAINERCLEANFILES = Makefile.in
diff --git a/pyanaconda/iw/account_gui.py b/pyanaconda/iw/account_gui.py
new file mode 100644
index 0000000..7f3a964
--- /dev/null
+++ b/pyanaconda/iw/account_gui.py
@@ -0,0 +1,148 @@
+#
+# account_gui.py: gui root password and crypt algorithm dialog
+#
+# Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005,  Red Hat Inc.
+#               2006, 2007, 2008
+# 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 as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# 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, see <http://www.gnu.org/licenses/>.
+#
+
+import gtk
+import string
+import gui
+from iw_gui import *
+from flags import flags
+from constants import *
+import cracklib
+import _isys
+
+import gettext
+_ = lambda x: gettext.ldgettext("anaconda", x)
+
+class AccountWindow (InstallWindow):
+    def getScreen(self, anaconda):
+        self.anaconda = anaconda
+        self.intf = anaconda.intf
+
+        (self.xml, self.align) = gui.getGladeWidget("account.glade",
+                                                    "account_align")
+        self.icon = self.xml.get_widget("icon")
+        self.capslock = self.xml.get_widget("capslock")
+        self.pwlabel = self.xml.get_widget("pwlabel")
+        self.pw = self.xml.get_widget("pw")
+        self.confirmlabel = self.xml.get_widget("confirmlabel")
+        self.confirm = self.xml.get_widget("confirm")
+
+        # load the icon
+        gui.readImageFromFile("root-password.png", image=self.icon)
+
+        # connect hotkeys
+        self.pwlabel.set_text_with_mnemonic(_("Root _Password:"))
+        self.pwlabel.set_mnemonic_widget(self.pw)
+        self.confirmlabel.set_text_with_mnemonic(_("_Confirm:"))
+        self.confirmlabel.set_mnemonic_widget(self.confirm)
+
+        # watch for Caps Lock so we can warn the user
+        self.intf.icw.window.connect("key-release-event",
+            lambda w, e: self.handleCapsLockRelease(w, e, self.capslock))
+
+        # we might have a root password already
+        if not self.anaconda.users.rootPassword['isCrypted']:
+            self.pw.set_text(self.anaconda.users.rootPassword['password'])
+            self.confirm.set_text(self.anaconda.users.rootPassword['password'])
+
+        # pressing Enter in confirm == clicking Next
+        vbox = self.xml.get_widget("account_box")
+        self.confirm.connect("activate", lambda widget,
+                             vbox=vbox: self.ics.setGrabNext(1))
+
+        # set initial caps lock label text
+        self.setCapsLockLabel()
+
+        return self.align
+
+    def focus(self):
+        self.pw.grab_focus()
+
+    def passwordError(self):
+        self.pw.set_text("")
+        self.confirm.set_text("")
+        self.pw.grab_focus()
+        raise gui.StayOnScreen
+
+    def handleCapsLockRelease(self, window, event, label):
+        if event.keyval == gtk.keysyms.Caps_Lock and \
+           event.state & gtk.gdk.LOCK_MASK:
+            self.setCapsLockLabel()
+
+    def setCapsLockLabel(self):
+        if _isys.isCapsLockEnabled():
+            self.capslock.set_text("<b>" + _("Caps Lock is on.") + "</b>")
+            self.capslock.set_use_markup(True)
+        else:
+            self.capslock.set_text("")
+
+    def getNext (self):
+        pw = self.pw.get_text()
+        confirm = self.confirm.get_text()
+
+        if not pw or not confirm:
+            self.intf.messageWindow(_("Error with Password"),
+                                    _("You must enter your root password "
+                                      "and confirm it by typing it a second "
+                                      "time to continue."),
+                                    custom_icon="error")
+            self.passwordError()
+
+        if pw != confirm:
+            self.intf.messageWindow(_("Error with Password"),
+                                    _("The passwords you entered were "
+                                      "different.  Please try again."),
+                                    custom_icon="error")
+            self.passwordError()
+
+        if len(pw) < 6:
+            self.intf.messageWindow(_("Error with Password"),
+                                    _("The root password must be at least "
+                                      "six characters long."),
+                                    custom_icon="error")
+            self.passwordError()
+
+        try:
+            cracklib.FascistCheck(pw)
+        except ValueError, e:
+            msg = gettext.ldgettext("cracklib", e)
+            ret = self.intf.messageWindow(_("Weak Password"),
+                                          _("You have provided a weak password: %s") % msg,
+                                          type="custom", custom_icon="error",
+                                          default=0,
+                                          custom_buttons=[_("Cancel"), _("Use Anyway")])
+            if ret == 0:
+                self.passwordError()
+
+        legal = string.digits + string.ascii_letters + string.punctuation + " "
+        for letter in pw:
+            if letter not in legal:
+                self.intf.messageWindow(_("Error with Password"),
+                                        _("Requested password contains "
+                                          "non-ASCII characters, which are "
+                                          "not allowed."),
+                                        custom_icon="error")
+                self.passwordError()
+
+        self.anaconda.users.rootPassword["password"] = self.pw.get_text()
+        self.anaconda.users.rootPassword["isCrypted"] = False
+
+        return None
diff --git a/pyanaconda/iw/advanced_storage.py b/pyanaconda/iw/advanced_storage.py
new file mode 100644
index 0000000..902d8ac
--- /dev/null
+++ b/pyanaconda/iw/advanced_storage.py
@@ -0,0 +1,256 @@
+#
+# Copyright (C) 2009  Red Hat, Inc.  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 as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# 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, see <http://www.gnu.org/licenses/>.
+#
+
+import gettext
+_ = lambda x: gettext.ldgettext("anaconda", x)
+
+# UI methods for supporting adding advanced storage devices.
+import gobject
+import gtk
+import gtk.glade
+import gui
+import iutil
+import network
+import storage.fcoe
+import storage.iscsi
+from netconfig_dialog import NetworkConfigurator
+
+def addFcoeDrive(anaconda):
+    (dxml, dialog) = gui.getGladeWidget("fcoe-config.glade", "fcoeDialog")
+    combo = dxml.get_widget("fcoeNicCombo")
+    dcb_cb = dxml.get_widget("dcbCheckbutton")
+
+    # Populate the combo
+    cell = gtk.CellRendererText()
+    combo.pack_start(cell, True)
+    combo.set_attributes(cell, text = 0)
+    cell.set_property("wrap-width", 525)
+    combo.set_size_request(480, -1)
+    store = gtk.TreeStore(gobject.TYPE_STRING, gobject.TYPE_STRING)
+    combo.set_model(store)
+
+    netdevs = anaconda.network.available()
+    keys = netdevs.keys()
+    keys.sort()
+    selected_interface = None
+    for dev in keys:
+        # Skip NICs which are connected (iow in use for a net install)
+        if dev in network.getActiveNetDevs():
+            continue
+
+        i = store.append(None)
+        desc = netdevs[dev].get("DESC")
+        if desc:
+            desc = "%s - %s" %(dev, desc)
+        else:
+            desc = "%s" %(dev,)
+
+        mac = netdevs[dev].get("HWADDR")
+        if mac:
+            desc = "%s - %s" %(desc, mac)
+
+        if selected_interface is None:
+            selected_interface = i
+
+        store[i] = (desc, dev)
+
+    if selected_interface:
+        combo.set_active_iter(selected_interface)
+    else:
+        combo.set_active(0)
+
+    # Show the dialog
+    gui.addFrame(dialog)
+    dialog.show_all()
+    sg = gtk.SizeGroup(gtk.SIZE_GROUP_HORIZONTAL)
+    sg.add_widget(dxml.get_widget("fcoeNicCombo"))
+
+    while True:
+        rc = dialog.run()
+
+        if rc in [gtk.RESPONSE_CANCEL, gtk.RESPONSE_DELETE_EVENT]:
+            break
+
+        iter = combo.get_active_iter()
+        if iter is None:
+            anaconda.intf.messageWindow(_("Error"),
+                                        _("You must select a NIC to use."),
+                                        type="warning", custom_icon="error")
+            continue
+
+        try:
+            anaconda.storage.fcoe.addSan(store.get_value(iter, 1),
+                                         dcb=dcb_cb.get_active(),
+                                         intf=anaconda.intf)
+        except IOError as e:
+            anaconda.intf.messageWindow(_("Error"), str(e))
+            rc = gtk.RESPONSE_CANCEL
+
+        break
+
+    dialog.destroy()
+    return rc
+
+def addIscsiDrive(anaconda):
+    if not network.hasActiveNetDev():
+        net = NetworkConfigurator(anaconda.network)
+        ret = net.run()
+        net.destroy()
+        if ret != gtk.RESPONSE_OK:
+            return ret
+
+    (dxml, dialog) = gui.getGladeWidget("iscsi-config.glade", "iscsiDialog")
+    gui.addFrame(dialog)
+    dialog.show_all()
+    sg = gtk.SizeGroup(gtk.SIZE_GROUP_HORIZONTAL)
+    for w in ["iscsiAddrEntry", "iscsiInitiatorEntry", "userEntry",
+              "passEntry", "userinEntry", "passinEntry"]:
+        sg.add_widget(dxml.get_widget(w))
+
+    # get the initiator name if it exists and don't allow changing
+    # once set
+    e = dxml.get_widget("iscsiInitiatorEntry")
+    e.set_text(anaconda.storage.iscsi.initiator)
+    if anaconda.storage.iscsi.initiatorSet:
+        e.set_sensitive(False)
+
+    while True:
+        rc = dialog.run()
+        if rc in [gtk.RESPONSE_CANCEL, gtk.RESPONSE_DELETE_EVENT]:
+            break
+
+        initiator = e.get_text().strip()
+        if len(initiator) == 0:
+            anaconda.intf.messageWindow(_("Invalid Initiator Name"),
+                                        _("You must provide an initiator name."))
+            continue
+
+        anaconda.storage.iscsi.initiator = initiator
+
+        target = dxml.get_widget("iscsiAddrEntry").get_text().strip()
+        user = dxml.get_widget("userEntry").get_text().strip()
+        pw = dxml.get_widget("passEntry").get_text().strip()
+        user_in = dxml.get_widget("userinEntry").get_text().strip()
+        pw_in = dxml.get_widget("passinEntry").get_text().strip()
+
+        try:
+            count = len(target.split(":"))
+            idx = target.rfind("]:")
+            # Check for IPV6 [IPV6-ip]:port
+            if idx != -1:
+                ip = target[1:idx]
+                port = target[idx+2:]
+            # Check for IPV4 aaa.bbb.ccc.ddd:port
+            elif count == 2:
+                idx = target.rfind(":")
+                ip = target[:idx]
+                port = target[idx+1:]
+            else:
+                ip = target
+                port = "3260"
+
+            network.sanityCheckIPString(ip)
+        except (network.IPMissing, network.IPError) as msg:
+            anaconda.intf.messageWindow(_("Error with Data"), msg)
+            continue
+
+        try:
+            anaconda.storage.iscsi.addTarget(ip, port, user, pw,
+                                             user_in, pw_in,
+                                             anaconda.intf)
+        except ValueError as e:
+            anaconda.intf.messageWindow(_("Error"), str(e))
+            continue
+        except IOError as e:
+            anaconda.intf.messageWindow(_("Error"), str(e))
+            rc = gtk.RESPONSE_CANCEL
+
+        break
+
+    dialog.destroy()
+    return rc
+
+def addZfcpDrive(anaconda):
+    (dxml, dialog) = gui.getGladeWidget("zfcp-config.glade", "zfcpDialog")
+    gui.addFrame(dialog)
+    dialog.show_all()
+    sg = gtk.SizeGroup(gtk.SIZE_GROUP_HORIZONTAL)
+    for w in ["devnumEntry", "wwpnEntry", "fcplunEntry"]:
+        sg.add_widget(dxml.get_widget(w))
+
+    while True:
+        rc = dialog.run()
+        if rc != gtk.RESPONSE_APPLY:
+            break
+
+        devnum = dxml.get_widget("devnumEntry").get_text().strip()
+        wwpn = dxml.get_widget("wwpnEntry").get_text().strip()
+        fcplun = dxml.get_widget("fcplunEntry").get_text().strip()
+
+        try:
+            anaconda.storage.zfcp.addFCP(devnum, wwpn, fcplun)
+        except ValueError as e:
+            anaconda.intf.messageWindow(_("Error"), str(e))
+            continue
+
+        break
+
+    dialog.destroy()
+    return rc
+
+def addDrive(anaconda):
+    (dxml, dialog) = gui.getGladeWidget("adddrive.glade", "addDriveDialog")
+    gui.addFrame(dialog)
+    dialog.show_all()
+    if not iutil.isS390():
+        dxml.get_widget("zfcpRadio").hide()
+        dxml.get_widget("zfcpRadio").set_group(None)
+
+    if not storage.iscsi.has_iscsi():
+        dxml.get_widget("iscsiRadio").set_sensitive(False)
+        dxml.get_widget("iscsiRadio").set_active(False)
+
+    if not storage.fcoe.has_fcoe():
+        dxml.get_widget("fcoeRadio").set_sensitive(False)
+        dxml.get_widget("fcoeRadio").set_active(False)
+
+    #figure out what advanced devices we have available and set sensible default
+    group = dxml.get_widget("iscsiRadio").get_group()
+    for button in group:
+        if button is not None and button.get_property("sensitive"):
+            button.set_active(True)
+            break
+
+    rc = dialog.run()
+    dialog.hide()
+
+    if rc in [gtk.RESPONSE_CANCEL, gtk.RESPONSE_DELETE_EVENT]:
+        return False
+
+    if dxml.get_widget("iscsiRadio").get_active() and storage.iscsi.has_iscsi():
+        rc = addIscsiDrive(anaconda)
+    elif dxml.get_widget("fcoeRadio").get_active() and storage.fcoe.has_fcoe():
+        rc = addFcoeDrive(anaconda)
+    elif dxml.get_widget("zfcpRadio") is not None and dxml.get_widget("zfcpRadio").get_active():
+        rc = addZfcpDrive(anaconda)
+
+    dialog.destroy()
+
+    if rc in [gtk.RESPONSE_CANCEL, gtk.RESPONSE_DELETE_EVENT]:
+        return False
+    else:
+        return True
diff --git a/pyanaconda/iw/autopart_type.py b/pyanaconda/iw/autopart_type.py
new file mode 100644
index 0000000..2ba1075
--- /dev/null
+++ b/pyanaconda/iw/autopart_type.py
@@ -0,0 +1,284 @@
+#
+# autopart_type.py: Allows the user to choose how they want to partition
+#
+# Copyright (C) 2005, 2006  Red Hat, Inc.  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 as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# 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, see <http://www.gnu.org/licenses/>.
+#
+# Author(s): Jeremy Katz <katzj@xxxxxxxxxx>
+#
+
+import gtk
+import gobject
+import math
+
+from constants import *
+import gui
+from partition_ui_helpers_gui import *
+from pixmapRadioButtonGroup_gui import pixmapRadioButtonGroup
+
+from iw_gui import *
+from flags import flags
+from storage.deviceaction import *
+
+import gettext
+_ = lambda x: gettext.ldgettext("anaconda", x)
+
+def whichToShrink(storage, intf):
+    def getActive(combo):
+        act = combo.get_active_iter()
+        return combo.get_model().get_value(act, 1)
+
+    def comboCB(combo, shrinkSB):
+        # partition to resize changed, let's update our spinbutton
+        newSize = shrinkSB.get_value_as_int()
+
+        part = getActive(combo)
+        reqlower = long(math.ceil(part.format.minSize))
+        requpper = long(math.floor(part.format.currentSize))
+
+        adj = shrinkSB.get_adjustment()
+        adj.lower = reqlower
+        adj.upper = requpper
+        adj.set_value(reqlower)
+
+
+    (dxml, dialog) = gui.getGladeWidget("autopart.glade", "shrinkDialog")
+
+    store = gtk.TreeStore(gobject.TYPE_STRING, gobject.TYPE_PYOBJECT)
+    combo = dxml.get_widget("shrinkPartCombo")
+    combo.set_model(store)
+    crt = gtk.CellRendererText()
+    combo.pack_start(crt, True)
+    combo.set_attributes(crt, text = 0)
+    combo.connect("changed", comboCB, dxml.get_widget("shrinkSB"))
+
+    biggest = -1
+    for part in storage.partitions:
+        if not part.exists:
+            continue
+
+        entry = None
+        if part.resizable and part.format.resizable:
+            entry = ("%s (%s, %d MB)" % (part.name,
+                                         part.format.name,
+                                         math.floor(part.format.size)),
+                     part)
+
+        if entry:
+            i = store.append(None)
+            store[i] = entry
+            combo.set_active_iter(i)
+
+            if biggest == -1:
+                biggest = i
+            else:
+                current = store.get_value(biggest, 1)
+                if part.format.targetSize > current.format.targetSize:
+                    biggest = i
+
+    if biggest > -1:
+        combo.set_active_iter(biggest)
+
+    if len(store) == 0:
+        dialog.destroy()
+        intf.messageWindow(_("Error"),
+                           _("No partitions are available to resize.  Only "
+                             "physical partitions with specific filesystems "
+                             "can be resized."),
+                             type="warning", custom_icon="error")
+        return (gtk.RESPONSE_CANCEL, [])
+
+    gui.addFrame(dialog)
+    dialog.show_all()
+    runResize = True
+
+    while runResize:
+        rc = dialog.run()
+        if rc != gtk.RESPONSE_OK:
+            dialog.destroy()
+            return (rc, [])
+
+        request = getActive(combo)
+        newSize = dxml.get_widget("shrinkSB").get_value_as_int()
+        actions = []
+
+        try:
+            actions.append(ActionResizeFormat(request, newSize))
+        except ValueError as e:
+            intf.messageWindow(_("Resize FileSystem Error"),
+                               _("%(device)s: %(msg)s")
+                                 % {'device': request.format.device,
+                                    'msg': e.message},
+                               type="warning", custom_icon="error")
+            continue
+
+        try:
+            actions.append(ActionResizeDevice(request, newSize))
+        except ValueError as e:
+            intf.messageWindow(_("Resize Device Error"),
+                               _("%(name)s: %(msg)s")
+                                 % {'name': request.name, 'msg': e.message},
+                               type="warning", custom_icon="error")
+            continue
+
+        runResize = False
+
+    dialog.destroy()
+    return (rc, actions)
+
+class PartitionTypeWindow(InstallWindow):
+    def __init__(self, ics):
+        InstallWindow.__init__(self, ics)
+        ics.setTitle("Automatic Partitioning")
+        ics.setNextEnabled(True)
+
+    def getNext(self):
+        if self.storage.checkNoDisks():
+            raise gui.StayOnScreen
+
+        if self.buttonGroup.getCurrent() == "custom":
+            self.dispatch.skipStep("autopartitionexecute", skip = 1)
+            self.dispatch.skipStep("partition", skip = 0)
+            self.dispatch.skipStep("bootloader", skip = 0)
+
+            self.storage.clearPartType = CLEARPART_TYPE_NONE
+        else:
+            if self.buttonGroup.getCurrent() == "shrink":
+                (rc, actions) = whichToShrink(self.storage, self.intf)
+                if rc == gtk.RESPONSE_OK:
+                    for action in actions:
+                        self.storage.devicetree.registerAction(action)
+                else:
+                    raise gui.StayOnScreen
+
+                # we're not going to delete any partitions in the resize case
+                self.storage.clearPartType = CLEARPART_TYPE_NONE
+            elif self.buttonGroup.getCurrent() == "all":
+                self.storage.clearPartType = CLEARPART_TYPE_ALL
+            elif self.buttonGroup.getCurrent() == "replace":
+                self.storage.clearPartType = CLEARPART_TYPE_LINUX
+            elif self.buttonGroup.getCurrent() == "freespace":
+                self.storage.clearPartType = CLEARPART_TYPE_NONE
+
+            self.dispatch.skipStep("autopartitionexecute", skip = 0)
+
+            if self.encryptButton.get_active():
+                self.storage.encryptedAutoPart = True
+            else:
+                self.storage.encryptionPassphrase = ""
+                self.storage.retrofitPassphrase = False
+                self.storage.encryptedAutoPart = False
+
+            self.storage.doAutoPart = True
+
+            if self.reviewButton.get_active():
+                self.dispatch.skipStep("partition", skip = 0)
+                self.dispatch.skipStep("bootloader", skip = 0)
+            else:
+                self.dispatch.skipStep("partition")
+                self.dispatch.skipStep("bootloader")
+                self.dispatch.skipStep("bootloaderadvanced")
+
+        return None
+
+    def typeChanged(self, *args):
+        if self.buttonGroup.getCurrent() == "custom":
+            if not self.prevrev:
+                self.prevrev = self.reviewButton.get_active()
+
+            self.reviewButton.set_active(True)
+            self.reviewButton.set_sensitive(False)
+            self.encryptButton.set_sensitive(False)
+        else:
+            if self.prevrev:
+                self.reviewButton.set_active(self.prevrev)
+                self.prevrev = None
+
+            self.reviewButton.set_sensitive(True)
+            self.encryptButton.set_sensitive(True)
+
+    def getScreen(self, anaconda):
+        self.anaconda = anaconda
+        self.storage = anaconda.storage
+        self.intf = anaconda.intf
+        self.dispatch = anaconda.dispatch
+
+        (self.xml, vbox) = gui.getGladeWidget("autopart.glade", "parttypeTable")
+        self.encryptButton = self.xml.get_widget("encryptButton")
+        self.reviewButton = self.xml.get_widget("reviewButton")
+        self.table = self.xml.get_widget("parttypeTable")
+
+        self.prevrev = None
+        self.reviewButton.set_active(not self.dispatch.stepInSkipList("partition"))
+        self.encryptButton.set_active(self.storage.encryptedAutoPart)
+
+        self.buttonGroup = pixmapRadioButtonGroup()
+        self.buttonGroup.addEntry("all", _("Use All Space"),
+                                  pixmap=gui.readImageFromFile("partscheme-all.png"),
+                                  descr=_("Removes all partitions on the selected "
+                                          "device(s).  This includes partitions "
+                                          "created by other operating systems.\n\n"
+                                          "<b>Tip:</b> This option will remove "
+                                          "data from the selected device(s).  Make "
+                                          "sure you have backups."))
+        self.buttonGroup.addEntry("replace", _("Replace Existing Linux System(s)"),
+                                  pixmap=gui.readImageFromFile("partscheme-replace.png"),
+                                  descr=_("Removes all Linux partitions on the "
+                                          "selected device(s). This does "
+                                          "not remove other partitions you may have "
+                                          "on your storage device(s) (such as VFAT or "
+                                          "FAT32).\n\n"
+                                          "<b>Tip:</b> This option will remove "
+                                          "data from the selected device(s).  Make "
+                                          "sure you have backups."))
+        self.buttonGroup.addEntry("shrink", _("Shrink Current System"),
+                                  pixmap=gui.readImageFromFile("partscheme-shrink.png"),
+                                  descr=_("Shrinks existing partitions to create free "
+                                          "space for the default layout."))
+        self.buttonGroup.addEntry("freespace", _("Use Free Space"),
+                                  pixmap=gui.readImageFromFile("partscheme-freespace.png"),
+                                  descr=_("Retains your current data and partitions and "
+                                          "uses only the unpartitioned space on the "
+                                          "selected device(s), assuming you have enough "
+                                          "free space available."))
+        self.buttonGroup.addEntry("custom", _("Create Custom Layout"),
+                                  pixmap=gui.readImageFromFile("partscheme-custom.png"),
+                                  descr=_("Manually create your own custom layout on "
+                                          "the selected device(s) using our partitioning "
+                                          "tool."))
+
+        self.buttonGroup.setToggleCallback(self.typeChanged)
+
+        widget = self.buttonGroup.render()
+        self.table.attach(widget, 0, 1, 1, 2)
+
+        # if not set in ks, use UI default
+        if self.storage.clearPartType is None or self.storage.clearPartType == CLEARPART_TYPE_LINUX:
+            self.buttonGroup.setCurrent("replace")
+        elif self.storage.clearPartType == CLEARPART_TYPE_NONE:
+            self.buttonGroup.setCurrent("freespace")
+        elif self.storage.clearPartType == CLEARPART_TYPE_ALL:
+            self.buttonGroup.setCurrent("all")
+
+        if self.buttonGroup.getCurrent() == "custom":
+            # make sure reviewButton is active and not sensitive
+            if self.prevrev == None:
+                self.prevrev = self.reviewButton.get_active()
+
+            self.reviewButton.set_active(True)
+            self.reviewButton.set_sensitive(False)
+            self.encryptButton.set_sensitive(False)
+
+        return vbox
diff --git a/pyanaconda/iw/blpasswidget.py b/pyanaconda/iw/blpasswidget.py
new file mode 100644
index 0000000..c6e6881
--- /dev/null
+++ b/pyanaconda/iw/blpasswidget.py
@@ -0,0 +1,164 @@
+#
+# blpasswidget.py - widget for setting of a boot loader password
+#
+# Copyright (C) 2001, 2002  Red Hat, Inc.  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 as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# 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, see <http://www.gnu.org/licenses/>.
+#
+# Author(s): Jeremy Katz <katzj@xxxxxxxxxx>
+#
+
+import gtk
+import gui
+from constants import *
+
+import gettext
+_ = lambda x: gettext.ldgettext("anaconda", x)
+
+class BootloaderPasswordWidget:
+    def __init__(self, anaconda, parent):
+        self.parent = parent
+        self.intf = anaconda.intf
+        
+        if anaconda.bootloader.getPassword():
+            usePass = 1
+            self.password = anaconda.bootloader.getPassword()
+        else:
+            usePass = 0
+            self.password = None
+        
+        vbox = gtk.VBox(False, 6)
+
+        # password widgets + callback
+        self.usePassCb = gtk.CheckButton(_("_Use a boot loader password"))
+        self.usePassCb.set_tooltip_text(_("A boot loader password prevents users from changing kernel options, increasing security."))
+        self.passButton = gtk.Button("No password")
+        if usePass:
+            self.usePassCb.set_active(True)
+            self.passButton.set_sensitive(True)
+        else:
+            self.usePassCb.set_active(False)
+            self.passButton.set_sensitive(False)
+        self.usePassCb.connect("toggled", self.passCallback)
+        self.passButton.connect("clicked", self.passButtonCallback)
+        self.setPassLabel()
+            
+        box = gtk.HBox(False, 12)
+        box.pack_start(self.usePassCb, False)
+        box.pack_start(self.passButton, False)
+        vbox.pack_start(box, False)
+
+        self.widget = vbox
+
+    def getWidget(self):
+        return self.widget
+
+    def getPassword(self):
+        # XXX should we handle the only having a crypted password case?
+        if self.usePassCb.get_active() and self.password:
+            return self.password
+        else:
+            return None
+
+    # set the label on the button for the bootloader password
+    def setPassLabel(self):
+        self.passButton.set_label(_("Change _password"))        
+        if not self.usePassCb.get_active() or not self.password:
+            self.passButton.set_sensitive(False)
+        else:
+            self.passButton.set_sensitive(True)
+
+    # callback for when the password checkbox is clicked
+    def passCallback(self, widget, *args):
+        if not widget.get_active():
+            self.passButton.set_sensitive(False)
+            self.setPassLabel()
+        else:
+            if self.passwordWindow() == 2:
+                widget.set_active(0)
+            self.setPassLabel()
+
+    # callback for when the password button is clicked
+    def passButtonCallback(self, widget, *args):
+        self.passwordWindow()
+        self.setPassLabel()
+
+    # get the bootloader password
+    def passwordWindow(self, *args):
+        dialog = gtk.Dialog(_("Enter Boot Loader Password"), self.parent)
+        dialog.add_button('gtk-cancel', gtk.RESPONSE_CANCEL)
+        dialog.add_button('gtk-ok', 1)
+        dialog.set_position(gtk.WIN_POS_CENTER)
+        gui.addFrame(dialog)
+        
+        label = gui.WrappingLabel(_("Enter a boot loader password and then confirm it.  (Note that your BIOS keymap may be different than the actual keymap you are used to.)"))
+        label.set_alignment(0.0, 0.0)
+        dialog.vbox.pack_start(label)
+
+        table = gtk.Table(2, 2)
+        table.set_row_spacings(5)
+        table.set_col_spacings(5)
+        label = gui.MnemonicLabel(_("_Password:"))
+        table.attach(label, 0, 1, 2, 3, gtk.FILL, 0, 10)
+        pwEntry = gtk.Entry (16)
+        pwEntry.set_visibility (False)
+        label.set_mnemonic_widget(pwEntry)
+        table.attach(pwEntry, 1, 2, 2, 3, gtk.FILL, 0, 10)
+        label = gui.MnemonicLabel(_("Con_firm:"))        
+        table.attach(label, 0, 1, 3, 4, gtk.FILL, 0, 10) 
+        confirmEntry = gtk.Entry (16)
+        confirmEntry.set_visibility (False)
+        label.set_mnemonic_widget(confirmEntry)
+        table.attach(confirmEntry, 1, 2, 3, 4, gtk.FILL, 0, 10)
+        dialog.vbox.pack_start(table)
+
+        # set the default
+        if self.password:
+            pwEntry.set_text(self.password)
+            confirmEntry.set_text(self.password)
+
+        dialog.show_all()
+
+        while 1:
+            rc = dialog.run()
+            if rc in [gtk.RESPONSE_CANCEL, gtk.RESPONSE_DELETE_EVENT]:
+                break
+
+            if pwEntry.get_text() != confirmEntry.get_text():
+                self.intf.messageWindow(_("Passwords don't match"),
+                                        _("Passwords do not match"),
+                                        type='warning')
+                continue
+
+            thePass = pwEntry.get_text()
+            if not thePass:
+                continue
+            if len(thePass) < 6:
+                ret = self.intf.messageWindow(_("Warning"),
+                                    _("Your boot loader password is shorter than "
+                                      "six characters.  We recommend a longer "
+                                      "boot loader password."
+                                      "\n\n"
+                                      "Would you like to continue with this "
+                                      "password?"),
+                                             type = "yesno")
+                if ret == 0:
+                    continue
+
+            self.password = thePass
+            break
+
+        dialog.destroy()
+        return rc
+
diff --git a/pyanaconda/iw/bootloader_main_gui.py b/pyanaconda/iw/bootloader_main_gui.py
new file mode 100644
index 0000000..05588b6
--- /dev/null
+++ b/pyanaconda/iw/bootloader_main_gui.py
@@ -0,0 +1,244 @@
+#
+# bootloader_main_gui.py: gui bootloader configuration dialog
+#
+# Copyright (C) 2001, 2002  Red Hat, Inc.  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 as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# 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, see <http://www.gnu.org/licenses/>.
+#
+# Author(s): Jeremy Katz <katzj@xxxxxxxxxx>
+#
+
+import gtk
+import gobject
+import gui
+from iw_gui import *
+from constants import *
+
+import gettext
+_ = lambda x: gettext.ldgettext("anaconda", x)
+
+from osbootwidget import OSBootWidget
+from blpasswidget import BootloaderPasswordWidget
+
+
+class MainBootloaderWindow(InstallWindow):
+    windowTitle = N_("Boot Loader Configuration")
+
+    def __init__(self, ics):
+        InstallWindow.__init__(self, ics)
+        self.parent = ics.getICW().window
+
+
+    def getPrev(self):
+        pass
+
+
+    def getNext(self):
+        # go ahead and set the device even if we already knew it
+        # since that won't change anything
+        self.bl.setDevice(self.bldev)
+
+        self.bl.drivelist = self.driveorder
+
+        if not self.grubCB.get_active():
+            # if we're not installing a boot loader, don't show the second
+            # screen and don't worry about other options
+            self.dispatch.skipStep("instbootloader", skip = 1)
+
+            # kind of a hack...
+            self.bl.defaultDevice = None
+            return
+        else:
+            self.dispatch.skipStep("instbootloader", skip = 0)
+            self.bl.setUseGrub(1)
+
+        # set the password
+        self.bl.setPassword(self.blpass.getPassword(), isCrypted = 0)
+
+        # set the bootloader images based on what's in our list
+        self.oslist.setBootloaderImages()
+
+    def bootloaderChanged(self, *args):
+        active = self.grubCB.get_active()
+
+        for widget in [ self.oslist.getWidget(), self.blpass.getWidget(), self.deviceButton ]:
+            widget.set_sensitive(active)
+
+
+    def _deviceChange(self, b, anaconda, *args):
+        def __driveChange(combo, dxml, choices):
+            if not choices.has_key("mbr"):
+                return
+
+            iter = combo.get_active_iter()
+            if not iter:
+                return
+
+            first = combo.get_model()[iter][1]
+            desc = choices["mbr"][1]
+            dxml.get_widget("mbrRadio").set_label("%s - /dev/%s" %(_(desc), first))
+            dxml.get_widget("mbrRadio").set_data("bootDevice", first)
+
+        def __genStore(combo, disks, active):
+            model = gtk.TreeStore(gobject.TYPE_STRING, gobject.TYPE_STRING)
+            combo.set_model(model)
+            cell = gtk.CellRendererText()
+            combo.pack_start(cell, True)
+            combo.set_attributes(cell, text = 0)
+
+            for disk in disks:
+                i = model.append(None)
+                model[i] = ("%s %8.0f MB %s" %(disk.name, disk.size,
+                                               disk.description),
+                            "%s" %(disk.name,))
+                if disk.name == active:
+                    combo.set_active_iter(i)
+
+            return model
+
+        (dxml, dialog) = gui.getGladeWidget("blwhere.glade",
+                                            "blwhereDialog")
+        gui.addFrame(dialog)
+        dialog.set_transient_for(self.parent)
+        dialog.show()
+
+        choices = anaconda.platform.bootloaderChoices(self.bl)
+        for t in ("mbr", "boot"):
+            if not choices.has_key(t):
+                continue
+            (device, desc) = choices[t]
+            w = dxml.get_widget("%sRadio" %(t,))
+            w.set_label("%s - /dev/%s" %(_(desc), device))
+            w.show()
+            if self.bldev == device:
+                w.set_active(True)
+            else:
+                w.set_active(False)
+            w.set_data("bootDevice", device)
+
+        for i in range(1, 5):
+            if len(self.driveorder) < i:
+                break
+            combo = dxml.get_widget("bd%dCombo" %(i,))
+            lbl = dxml.get_widget("bd%dLabel" %(i,))
+            combo.show()
+            lbl.show()
+            partitioned = anaconda.storage.partitioned
+            disks = anaconda.storage.disks
+            bl_disks = [d for d in disks if d in partitioned]
+            m = __genStore(combo, bl_disks, self.driveorder[i - 1])
+
+        dxml.get_widget("bd1Combo").connect("changed", __driveChange, dxml, choices)
+        __driveChange(dxml.get_widget("bd1Combo"), dxml, choices)
+
+        while 1:
+            rc = dialog.run()
+            if rc in [gtk.RESPONSE_CANCEL, gtk.RESPONSE_DELETE_EVENT]:
+                break
+
+            # set the boot device based on what they chose
+            if dxml.get_widget("bootRadio").get_active():
+                self.bldev = dxml.get_widget("bootRadio").get_data("bootDevice")
+            elif dxml.get_widget("mbrRadio").get_active():
+                self.bldev = dxml.get_widget("mbrRadio").get_data("bootDevice")
+            else:
+                raise RuntimeError, "No radio button selected!"
+
+            # and adjust the boot order
+            neworder = []
+            for i in range(1, 5):
+                if len(self.driveorder) < i:
+                    break
+
+                combo = dxml.get_widget("bd%dCombo" %(i,))
+                iter = combo.get_active_iter()
+                if not iter:
+                    continue
+
+                act = combo.get_model()[iter][1]
+                if act not in neworder:
+                    neworder.append(act)
+            for d in self.driveorder:
+                if d not in neworder:
+                    neworder.append(d)
+            self.driveorder = neworder
+
+            break
+
+        dialog.destroy()
+        self.grubCB.set_label(_("_Install boot loader on /dev/%s.") %
+                              (self.bldev,))
+        return rc
+
+    def _setBLCBText(self):
+        self.grubCB.set_label(_("_Install boot loader on /dev/%s.") %
+                              (self.bldev,))
+
+
+    def getScreen(self, anaconda):
+        self.dispatch = anaconda.dispatch
+        self.bl = anaconda.bootloader
+        self.intf = anaconda.intf
+
+        self.driveorder = self.bl.drivelist
+        if len(self.driveorder) == 0:
+            partitioned = anaconda.storage.partitioned
+            disks = anaconda.storage.disks
+            self.driveorder = [d.name for d in disks if d in partitioned]
+
+        if self.bl.getPassword():
+            self.usePass = 1
+            self.password = self.bl.getPassword()
+        else:
+            self.usePass = 0
+            self.password = None
+
+        thebox = gtk.VBox (False, 12)
+        thebox.set_border_width(18)
+
+        # make sure we get a valid device to say we're installing to
+        if self.bl.getDevice() is not None:
+            self.bldev = self.bl.getDevice()
+        else:
+            # we don't know what it is yet... if mbr is possible, we want
+            # it, else we want the boot dev
+            choices = anaconda.platform.bootloaderChoices(self.bl)
+            if choices.has_key('mbr'):
+                self.bldev = choices['mbr'][0]
+            else:
+                self.bldev = choices['boot'][0]
+
+        hb = gtk.HBox(False, 12)
+        self.grubCB = gtk.CheckButton(_("_Install boot loader on /dev/%s.") %
+                                      (self.bldev,))
+        self.grubCB.set_active(not self.dispatch.stepInSkipList("instbootloader"))
+        self.grubCB.connect("toggled", self.bootloaderChanged)
+        hb.pack_start(self.grubCB, False)
+
+        self.deviceButton = gtk.Button(_("_Change device"))
+        self.deviceButton.connect("clicked", self._deviceChange, anaconda)
+        hb.pack_start(self.deviceButton, False)
+
+        thebox.pack_start(hb, False)
+
+        # control whether or not there's a boot loader password and what it is
+        self.blpass = BootloaderPasswordWidget(anaconda, self.parent)
+        thebox.pack_start(self.blpass.getWidget(), False)
+
+        # configure the systems available to boot from the boot loader
+        self.oslist = OSBootWidget(anaconda, self.parent)
+        thebox.pack_end(self.oslist.getWidget(), True)
+
+        self.bootloaderChanged()
+        return thebox
diff --git a/pyanaconda/iw/checklist.py b/pyanaconda/iw/checklist.py
new file mode 100644
index 0000000..50026a1
--- /dev/null
+++ b/pyanaconda/iw/checklist.py
@@ -0,0 +1,225 @@
+#
+# checklist.py: A class (derived from GtkTreeView) that provides a list of
+#               checkbox / text string pairs
+#
+# Copyright (C) 2000, 2001  Red Hat, Inc.  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 as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# 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, see <http://www.gnu.org/licenses/>.
+#
+# Author(s): Brent Fox <bfox@xxxxxxxxxx>
+#            Jeremy Katz <katzj@xxxxxxxxxx>
+#
+
+import gtk
+import gobject
+
+class CheckList (gtk.TreeView):
+    """A class (derived from gtk.TreeView) that provides a list of
+    checkbox / text string pairs"""
+
+    # override this to make your own columns if necessary
+    def create_columns(self, columns):
+        # add the string columns to the tree view widget
+        for i in range(1, columns + 1):
+            renderer = gtk.CellRendererText()
+            column = gtk.TreeViewColumn('Text', renderer, text=i,
+                                        **self.sensitivity_args)
+            column.set_clickable(False)
+            self.append_column(column)
+
+    # XXX need to handle the multicolumn case better still....
+    def __init__ (self, columns = 1, custom_store=None, sensitivity=False):
+	if custom_store is None:
+	    self.store = gtk.TreeStore(gobject.TYPE_BOOLEAN,
+				       gobject.TYPE_STRING,
+				       gobject.TYPE_STRING)
+	else:
+	    self.store = custom_store
+	    
+        gtk.TreeView.__init__ (self, self.store)
+        
+        # XXX we only handle two text columns right now
+        if custom_store is None and columns > 2:
+            raise RuntimeError, "CheckList supports a maximum of 2 columns"
+	
+        self.columns = columns
+
+        # sensitivity_col is an optional hidden boolean column that controls
+        # the sensitive property of all of the CellRenderers in its row.
+        #
+        # To enable this functionality the last column in the TreeStore
+        # must be boolean and you must pass a value of True for the
+        # 'sensitivity' keyword argument to this class' constructor.
+        self.sensitivity_col = None
+        self.sensitivity_args = {}
+        last_col = self.store.get_n_columns() - 1
+        if sensitivity and \
+           self.store.get_column_type(last_col) == gobject.TYPE_BOOLEAN:
+            self.sensitivity_col = last_col
+            self.sensitivity_args = {"sensitive": self.sensitivity_col}
+
+        self.checkboxrenderer = gtk.CellRendererToggle()
+        column = gtk.TreeViewColumn('', self.checkboxrenderer, active=0,
+                                    **self.sensitivity_args)
+#        column.set_sizing(gtk.TREE_VIEW_COLUMN_FIXED)
+#        column.set_fixed_width(40)
+        column.set_clickable(True)
+        self.checkboxrenderer.connect ("toggled", self.toggled_item)        
+        self.append_column(column)
+
+	self.create_columns(columns)
+
+        self.set_rules_hint(False)
+        self.set_headers_visible(False)
+        self.columns_autosize()
+        self.set_enable_search(False)
+
+        # keep track of the number of rows we have so we can
+        # iterate over them all
+        self.num_rows = 0
+
+        self.tiptext = {}
+        self.props.has_tooltip = True
+        self.connect("query-tooltip", self._tipQuery)
+
+    def _tipQuery(self, widget, x, y, kbd, tip, *data):
+        (tx, ty) = widget.convert_widget_to_bin_window_coords(x, y)
+        r = widget.get_path_at_pos(tx, ty)
+        if not r:
+            return False
+        path = r[0]
+        if not self.tiptext.has_key(path):
+            return False
+        tip.set_text(self.tiptext[path])
+        return True
+
+    def append_row (self, textList, init_value, tooltipText = None):
+        """Add a row to the list.
+        text: text to display in the row
+        init_value: initial state of the indicator
+        tooltipText: the text that will appear when the mouse is over the row."""
+
+        iter = self.store.append(None)
+        self.store.set_value(iter, 0, init_value)
+        if self.sensitivity_col is not None:
+            self.store.set_value(iter, self.sensitivity_col, True)
+
+        # add the text for the number of columns we have
+        i = 1
+        for text in textList[:self.columns]:
+            self.store.set_value(iter, i, textList[i - 1])
+            i = i + 1
+
+        if tooltipText:
+            self.tiptext[self.store.get_path(iter)] = tooltipText
+
+        self.num_rows = self.num_rows + 1
+
+
+    def toggled_item(self, data, row):
+        """Set a function to be called when the value of a row is toggled.
+        The  function will be called with two arguments, the clicked item
+        in the row and a string for which row was clicked."""
+        
+        iter = self.store.get_iter((int(row),))
+        val = self.store.get_value(iter, 0)
+        self.store.set_value(iter, 0, not val)
+
+
+    def clear (self):
+        "Remove all rows"
+        self.store.clear()
+        self.num_rows = 0
+
+
+    def get_active(self, row):
+        """Return FALSE or TRUE as to whether or not the row is toggled
+        similar to GtkToggleButtons"""
+
+        iter = self.store.get_iter((row,))
+        return self.store.get_value(iter, 0)
+
+
+    def set_active(self, row, is_active):
+        "Set row to be is_active, similar to GtkToggleButton"
+
+        iter = self.store.get_iter((row,))
+        self.store.set_value(iter, 0, is_active)
+
+
+    def get_text(self, row, column):
+        "Get the text from row and column"
+
+        iter = self.store.get_iter((row,))
+        return self.store.get_value(iter, column)
+
+
+    def set_column_title(self, column, title):
+        "Set the title of column to title"
+
+        col = self.get_column(column)
+        if col:
+            col.set_title(title)
+
+
+    def set_column_min_width(self, column, min):
+        "Set the minimum width of column to min"
+
+        col = self.get_column(column)
+        if col:
+            col.set_min_width(min)
+
+
+    def set_column_clickable(self, column, clickable):
+        "Set the column to be clickable"
+
+        col = self.get_column(column)
+        if col:
+            col.set_clickable(clickable)
+            
+
+    def set_column_sizing(self, column, sizing):
+        "Set the column to use the given sizing method"
+
+        col = self.get_column(column)
+        if col:
+            col.set_sizing(sizing)
+
+    def set_column_sort_id(self, column, id):
+        "Set the sort id of column to id"
+
+        col = self.get_column(column)
+        if col:
+            col.set_sort_column_id(id)
+
+def main():
+    win = gtk.Window()
+    cl = CheckList(1)
+    for i in range(1, 10):
+        cl.append_row("%s" %(i,), False, "foo: %d" %(i,))
+
+    sw = gtk.ScrolledWindow()
+    sw.set_policy (gtk.POLICY_NEVER, gtk.POLICY_AUTOMATIC)
+    sw.add (cl)
+    sw.set_shadow_type(gtk.SHADOW_IN)
+    cl.set_headers_visible(True)
+
+    win.add(sw)
+    win.set_size_request(250, 250)
+    win.show_all()
+
+    gtk.main()
+
+if __name__ == "__main__":
+    main()
diff --git a/pyanaconda/iw/cleardisks_gui.py b/pyanaconda/iw/cleardisks_gui.py
new file mode 100644
index 0000000..0fee708
--- /dev/null
+++ b/pyanaconda/iw/cleardisks_gui.py
@@ -0,0 +1,240 @@
+#
+# Select which disks to clear and which ones to just mount.
+#
+# Copyright (C) 2009  Red Hat, Inc.
+# 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 as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# 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, see <http://www.gnu.org/licenses/>.
+#
+
+import gtk, gobject
+import gui
+from DeviceSelector import *
+from constants import *
+import isys
+from iw_gui import *
+from storage.udev import *
+
+import gettext
+_ = lambda x: gettext.ldgettext("anaconda", x)
+
+class ClearDisksWindow (InstallWindow):
+    windowTitle = N_("Clear Disks Selector")
+
+    def getNext (self):
+        # All the rows that are visible in the right hand side should be cleared.
+        cleardisks = []
+        for row in self.store:
+            if row[self.rightVisible]:
+                cleardisks.append(row[OBJECT_COL].name)
+
+        if len(cleardisks) == 0:
+            self.anaconda.intf.messageWindow(_("Error"),
+                                             _("You must select at least one "
+                                               "drive to be used for installation."),
+                                             custom_icon="error")
+            raise gui.StayOnScreen
+
+        # The selected row is the disk to boot from.
+        selected = self.rightDS.getSelected()
+
+        if len(selected) == 0:
+            self.anaconda.intf.messageWindow(_("Error"),
+                                             _("You must select one drive to "
+                                               "boot from."),
+                                             custom_icon="error")
+            raise gui.StayOnScreen
+
+        bootDisk = selected[0][OBJECT_COL].name
+
+        cleardisks.sort(self.anaconda.storage.compareDisks)
+
+        self.anaconda.storage.clearPartDisks = cleardisks
+        self.anaconda.bootloader.updateDriveList([bootDisk])
+
+    def getScreen (self, anaconda):
+        # We can't just use exclusiveDisks here because of kickstart.  First,
+        # the kickstart file could have used ignoredisk --drives= in which case
+        # exclusiveDisks would be empty.  Second, ignoredisk is entirely
+        # optional in which case neither list would be populated.  Luckily,
+        # storage.disks takes isIgnored into account and that handles both these
+        # issues.
+        disks = filter(lambda d: not d.format.hidden, anaconda.storage.disks)
+
+        # Skip this screen as well if there's only one disk to use.
+        if len(disks) == 1:
+            anaconda.storage.clearPartDisks = [disks[0].name]
+            anaconda.bootloader.drivelist = [disks[0].name]
+            return None
+
+        (xml, self.vbox) = gui.getGladeWidget("cleardisks.glade", "vbox")
+        self.leftScroll = xml.get_widget("leftScroll")
+        self.rightScroll = xml.get_widget("rightScroll")
+        self.addButton = xml.get_widget("addButton")
+        self.removeButton = xml.get_widget("removeButton")
+        self.installTargetImage = xml.get_widget("installTargetImage")
+        self.installTargetTip = xml.get_widget("installTargetTip")
+
+        self.anaconda = anaconda
+
+        self.leftVisible = 1
+        self.leftActive = 2
+        self.rightVisible = 4
+        self.rightActive = 5
+
+        # One store for both views.  First the obejct, then a visible/active for
+        # the left hand side, then a visible/active for the right hand side, then
+        # all the other stuff.
+        #
+        # NOTE: the third boolean is a placeholder.  DeviceSelector uses the third
+        # slot in the store to determine whether the row is immutable or not.  We
+        # just need to put False in there for everything.
+        self.store = gtk.TreeStore(gobject.TYPE_PYOBJECT,
+                                   gobject.TYPE_BOOLEAN, gobject.TYPE_BOOLEAN,
+                                   gobject.TYPE_BOOLEAN,
+                                   gobject.TYPE_BOOLEAN, gobject.TYPE_BOOLEAN,
+                                   gobject.TYPE_STRING, gobject.TYPE_STRING,
+                                   gobject.TYPE_STRING, gobject.TYPE_STRING,
+                                   gobject.TYPE_STRING)
+        self.store.set_sort_column_id(6, gtk.SORT_ASCENDING)
+
+        # The left view shows all the drives that will just be mounted, but
+        # can still be moved to the right hand side.
+        self.leftFilteredModel = self.store.filter_new()
+        self.leftSortedModel = gtk.TreeModelSort(self.leftFilteredModel)
+        self.leftTreeView = gtk.TreeView(self.leftSortedModel)
+
+        self.leftFilteredModel.set_visible_func(lambda model, iter, view: model.get_value(iter, self.leftVisible), self.leftTreeView)
+
+        self.leftScroll.add(self.leftTreeView)
+
+        self.leftDS = DeviceSelector(self.store, self.leftSortedModel,
+                                     self.leftTreeView, visible=self.leftVisible,
+                                     active=self.leftActive)
+        self.leftDS.createMenu()
+        self.leftDS.addColumn(_("Model"), 6)
+        self.leftDS.addColumn(_("Capacity"), 7)
+        self.leftDS.addColumn(_("Vendor"), 8)
+        self.leftDS.addColumn(_("Interconnect"), 9, displayed=False)
+        self.leftDS.addColumn(_("Serial Number"), 10, displayed=False)
+
+        # The right view show all the drives that will be wiped during install.
+        self.rightFilteredModel = self.store.filter_new()
+        self.rightSortedModel = gtk.TreeModelSort(self.rightFilteredModel)
+        self.rightTreeView = gtk.TreeView(self.rightSortedModel)
+
+        self.rightFilteredModel.set_visible_func(lambda model, iter, view: model.get_value(iter, self.rightVisible), self.rightTreeView)
+
+        self.rightScroll.add(self.rightTreeView)
+
+        self.rightDS = DeviceSelector(self.store, self.rightSortedModel,
+                                      self.rightTreeView, visible=self.rightVisible,
+                                      active=self.rightActive)
+        self.rightDS.createSelectionCol(title=_("Boot\nLoader"), radioButton=True)
+        self.rightDS.addColumn(_("Model"), 6)
+        self.rightDS.addColumn(_("Capacity"), 7)
+
+        # Store the first disk (according to our detected BIOS order) for
+        # auto boot device selection
+        names = map(lambda d: d.name, disks)
+        self.bootDisk = sorted(names, self.anaconda.storage.compareDisks)[0]
+
+        # The device filtering UI set up exclusiveDisks as a list of the names
+        # of all the disks we should use later on.  Now we need to go get those,
+        # look up some more information in the devicetree, and set up the
+        # selector.
+        for d in disks:
+            rightVisible = d.name in self.anaconda.storage.clearPartDisks
+            rightActive = rightVisible and \
+                          d.name in self.anaconda.bootloader.drivelist[:1]
+            leftVisible = not rightVisible
+            self.store.append(None, (d,
+                                     leftVisible, True, False,
+                                     rightVisible, rightActive,
+                                     d.model,
+                                     str(int(d.size)) + " MB",
+                                     d.vendor, "", d.serial))
+
+        self.addButton.connect("clicked", self._add_clicked)
+        self.removeButton.connect("clicked", self._remove_clicked)
+
+        # Also allow moving devices back and forth with double click, enter, etc.
+        self.leftTreeView.connect("row-activated", self._add_clicked)
+        self.rightTreeView.disconnect(self.rightDS._activated_id)
+        self.rightTreeView.connect("row-activated", self._remove_clicked)
+
+        # And let the user select multiple devices at a time.
+        self.leftTreeView.get_selection().set_mode(gtk.SELECTION_MULTIPLE)
+        self.rightTreeView.get_selection().set_mode(gtk.SELECTION_MULTIPLE)
+
+        if self.anaconda.storage.clearPartType == CLEARPART_TYPE_LINUX:
+            self.installTargetTip.set_markup(_("<b>Tip:</b> All Linux filesystems on the install target devices will be reformatted and wiped of any data.  Make sure you have backups."))
+        elif self.anaconda.storage.clearPartType == CLEARPART_TYPE_ALL:
+            self.installTargetTip.set_markup(_("<b>Tip:</b> The install target devices will be reformatted and wiped of any data.  Make sure you have backups."))
+        else:
+            self.installTargetTip.set_markup(_("<b>Tip:</b> Your filesystems on the install target devices will not be reformatted unless you choose to do so during customization."))
+
+        return self.vbox
+
+    def _autoSelectBootDisk(self):
+        if self.rightDS.getSelected():
+            return
+
+        for row in self.store:
+            if row[OBJECT_COL].name == self.bootDisk and row[self.rightVisible]:
+                row[self.rightActive] = True
+
+    def _add_clicked(self, widget, *args, **kwargs):
+        (sortedModel, pathlist) = self.leftTreeView.get_selection().get_selected_rows()
+
+        if not pathlist:
+            return
+
+        for path in reversed(pathlist):
+            sortedIter = sortedModel.get_iter(path)
+            if not sortedIter:
+                continue
+
+            filteredIter = self.leftSortedModel.convert_iter_to_child_iter(None, sortedIter)
+            iter = self.leftFilteredModel.convert_iter_to_child_iter(filteredIter)
+
+            self.store.set_value(iter, self.leftVisible, False)
+            self.store.set_value(iter, self.rightVisible, True)
+            self.store.set_value(iter, self.rightActive, False)
+
+        self._autoSelectBootDisk()
+        self.leftFilteredModel.refilter()
+        self.rightFilteredModel.refilter()
+
+    def _remove_clicked(self, widget, *args, **kwargs):
+        (sortedModel, pathlist) = self.rightTreeView.get_selection().get_selected_rows()
+
+        if not pathlist:
+            return
+
+        for path in reversed(pathlist):
+            sortedIter = sortedModel.get_iter(path)
+            if not sortedIter:
+                continue
+
+            filteredIter = self.rightSortedModel.convert_iter_to_child_iter(None, sortedIter)
+            iter = self.rightFilteredModel.convert_iter_to_child_iter(filteredIter)
+
+            self.store.set_value(iter, self.leftVisible, True)
+            self.store.set_value(iter, self.rightVisible, False)
+            self.store.set_value(iter, self.rightActive, False)
+
+        self._autoSelectBootDisk()
+        self.leftFilteredModel.refilter()
+        self.rightFilteredModel.refilter()
diff --git a/pyanaconda/iw/congrats_gui.py b/pyanaconda/iw/congrats_gui.py
new file mode 100644
index 0000000..3027568
--- /dev/null
+++ b/pyanaconda/iw/congrats_gui.py
@@ -0,0 +1,103 @@
+#
+# congrats_gui.py: install/upgrade complete screen.
+#
+# Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006  Red Hat, Inc.
+# 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 as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# 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, see <http://www.gnu.org/licenses/>.
+#
+
+import gtk
+import gui
+from iw_gui import *
+from constants import *
+import os
+import platform
+
+import gettext
+_ = lambda x: gettext.ldgettext("anaconda", x)
+
+class CongratulationWindow (InstallWindow):		
+
+    windowTitle = N_("Congratulations")
+
+    def __init__ (self, ics):
+	InstallWindow.__init__(self, ics)
+
+        ics.setPrevEnabled(False)
+
+        # force buttonbar on in case release notes viewer is running
+        ics.cw.mainxml.get_widget("buttonBar").set_sensitive(True)
+
+        self.rebootButton = ics.cw.mainxml.get_widget("rebootButton")
+
+        # this mucks around a bit, but it's the weird case and it's
+        # better than adding a lot of complication to the normal
+	ics.cw.mainxml.get_widget("nextButton").hide()
+        if os.path.exists(os.environ.get("LIVE_BLOCK", "/dev/mapper/live-osimg-min")):
+            ics.cw.mainxml.get_widget("closeButton").show()
+            ics.cw.mainxml.get_widget("closeButton").grab_focus()
+        else:
+            self.rebootButton.show()
+            self.rebootButton.grab_focus()
+            ics.cw.mainxml.get_widget("rebootButton").show()
+            ics.cw.mainxml.get_widget("rebootButton").grab_focus()
+
+    def getNext(self):
+	# XXX - copy any screenshots over
+	gui.copyScreenshots()
+
+    # CongratulationWindow tag=NA
+    def getScreen (self, anaconda):
+        hbox = gtk.HBox (False, 5)
+        
+        pix = gui.readImageFromFile ("done.png")
+        if pix:
+            a = gtk.Alignment ()
+            a.add (pix)
+            a.set (0.5, 0.5, 1.0, 1.0)
+	    a.set_size_request(200, -1)
+            hbox.pack_start (a, False, False, 36)
+
+        if isinstance(anaconda.platform, platform.S390):
+            txt = _("Congratulations, your %s installation is complete.\n\n") % (productName,)
+
+            if not anaconda.canReIPL:
+                self.rebootButton.set_label(_("Shutdown"))
+
+                txt = txt + _("Please shutdown to use the installed system.\n")
+            else:
+                txt = txt + _("Please reboot to use the installed system.\n")
+
+            if not anaconda.reIPLMessage is None:
+                txt = txt + "\n" + anaconda.reIPLMessage + "\n\n"
+
+            txt = txt + _("Note that updates may be available to ensure the proper "
+                          "functioning of your system and installation of these "
+                          "updates is recommended after the reboot.")
+        else:
+            txt = _("Congratulations, your %s installation is complete.\n\n"
+                    "Please reboot to use the installed system.  "
+                    "Note that updates may be available to ensure the proper "
+                    "functioning of your system and installation of these "
+                    "updates is recommended after the reboot.") %(productName,)
+
+	label = gui.WrappingLabel(txt)
+        label.set_size_request(250, -1)
+
+        hbox.pack_start (label, True, True)
+
+        gtk.gdk.beep()
+        return hbox
+
diff --git a/pyanaconda/iw/datacombo.py b/pyanaconda/iw/datacombo.py
new file mode 100644
index 0000000..9b6a092
--- /dev/null
+++ b/pyanaconda/iw/datacombo.py
@@ -0,0 +1,99 @@
+#
+# datacombo.py: A class (derived from GtkComboBox) that provides
+#               the ability to store data and show text in a GtkComboBox easily
+#
+# Copyright (C) 2004  Red Hat, Inc.  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 as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# 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, see <http://www.gnu.org/licenses/>.
+#
+# Author(s): Jeremy Katz <katzj@xxxxxxxxxx>
+#
+
+import gtk
+import gobject
+
+class DataComboBox(gtk.ComboBox):
+    """A class derived from gtk.ComboBox to allow setting a user visible
+    string and (not-visible) data string"""
+
+    def __init__(self, store = None):
+        if store is None:
+            self.store = gtk.TreeStore(gobject.TYPE_STRING, gobject.TYPE_STRING)
+        else:
+            self.store = store
+        gtk.ComboBox.__init__(self, self.store)
+
+        cell = gtk.CellRendererText()
+        self.pack_start(cell, True)
+        self.set_attributes(cell, text = 0)
+
+    def append(self, text, data):
+        iter = self.store.append(None)
+        self.store[iter] = (text, data)
+
+    def get_active_value(self, col = 1):
+        row = self.get_active()
+        return self.get_stored_data(row, col)
+
+    def get_stored_data(self, row, col = 1):
+        if row < 0:
+            return None
+        iter = self.store.get_iter(row)
+        val = self.store.get_value(iter, col)
+        return val
+
+    def get_text(self, row):
+        return self.get_stored_data(row, col = 0)
+
+    def set_active_text(self, t):
+        """set_active_text(string) ->  Sets the active row to whereever t is.
+           returns True if set_active is run, False otherwise.
+        """
+        retval = False
+        n = 0
+        i = self.store.get_iter(n)
+        while i is not None:
+            if self.store.get_value(i, 0) == t:
+                self.set_active(n)
+                retval = True
+                break
+            i = self.store.iter_next(i)
+            n += 1
+
+        return retval
+
+    def clear(self):
+        self.store.clear()
+
+if __name__ == "__main__":
+    def mycb(widget, *args):
+        idx = widget.get_active()
+        print(idx, widget.get_stored_data(idx), widget.get_text(idx))
+        
+    win = gtk.Window()
+
+    cb = DataComboBox()
+    cb.append("/dev/hda5", "hda5")
+    cb.append("/dev/hda6", "hda6")
+    cb.append("/dev/hda7", "hda7")
+    cb.append("/dev/hda8", "hda8")
+    cb.set_active_text("/dev/hda7")
+
+    cb.connect('changed', mycb)
+    
+    win.add(cb)
+    win.show_all()
+
+    gtk.main()
+
diff --git a/pyanaconda/iw/examine_gui.py b/pyanaconda/iw/examine_gui.py
new file mode 100644
index 0000000..e40ebf8
--- /dev/null
+++ b/pyanaconda/iw/examine_gui.py
@@ -0,0 +1,163 @@
+#
+# examine_gui.py: dialog to allow selection of a RHL installation to upgrade
+#
+# Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006  Red Hat, Inc.
+# 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 as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# 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, see <http://www.gnu.org/licenses/>.
+#
+
+import gtk
+import gui
+from iw_gui import *
+from pixmapRadioButtonGroup_gui import pixmapRadioButtonGroup
+from constants import *
+import upgrade
+from flags import flags
+
+import gettext
+_ = lambda x: gettext.ldgettext("anaconda", x)
+
+UPGRADE_STR = "upgrade"
+REINSTALL_STR = "reinstall"
+
+seenExamineScreen = False
+
+class UpgradeExamineWindow (InstallWindow):
+
+    windowTitle = N_("Upgrade Examine")
+
+    def getNext (self):
+        if self.doupgrade:
+            upgrade.setSteps(self.anaconda)
+            self.anaconda.upgrade = True
+
+	    rootfs = self.parts[self.upgradecombo.get_active()]
+            self.anaconda.upgradeRoot = [(rootfs[0], rootfs[1])]
+            self.anaconda.rootParts = self.parts
+
+            self.anaconda.dispatch.skipStep("installtype", skip = 1)
+            self.anaconda.upgrade = True
+        else:
+            self.anaconda.dispatch.skipStep("installtype", skip = 0)
+            self.anaconda.upgrade = False
+	
+        return None
+
+    def createUpgradeOption(self):
+	r = pixmapRadioButtonGroup()
+	r.addEntry(REINSTALL_STR, _("Fresh Installation"),
+		   pixmap=gui.readImageFromFile("install.png"),
+                   descr=_("Choose this option to install a fresh copy of %s "
+                           "on your system.  Existing software and data may "
+                           "be overwritten depending on your configuration "
+                           "choices.") % productName)
+
+	r.addEntry(UPGRADE_STR, _("Upgrade an Existing Installation"),
+		   pixmap=gui.readImageFromFile("upgrade.png"),
+                   descr=_("Choose this option if you would like to upgrade "
+                           "your existing %s system.  This option will "
+                           "preserve the existing data on your storage "
+                           "device(s).") % productName)
+
+	return r
+
+    def upgradeOptionsSetSensitivity(self, state):
+	self.uplabel.set_sensitive(state)
+	self.upgradecombo.set_sensitive(state)
+
+    def optionToggled(self, widget, name):
+	if name == UPGRADE_STR:
+	    self.upgradeOptionsSetSensitivity(widget.get_active())
+	    self.doupgrade = widget.get_active()
+
+    #UpgradeExamineWindow tag = "upgrade"
+    def getScreen (self, anaconda):
+        global seenExamineScreen
+        self.anaconda = anaconda
+
+        if not seenExamineScreen:
+	    # this is the first time we've entered this screen
+	    self.doupgrade = self.anaconda.dispatch.stepInSkipList("installtype")
+            seenExamineScreen = True
+	else:
+	    self.doupgrade = self.anaconda.upgrade
+
+        # we might get here after storage reset that obsoleted
+        # root device objects we had found
+        if not self.anaconda.rootParts:
+            self.anaconda.rootParts = upgrade.findExistingRoots(self.anaconda,
+                                                                flags.cmdline.has_key("upgradeany"))
+            upgrade.setUpgradeRoot(self.anaconda)
+
+        self.parts = self.anaconda.rootParts
+
+        vbox = gtk.VBox (False, 12)
+	vbox.set_border_width (8)
+
+        introLabel = gtk.Label(_("At least one existing installation has been "
+                                 "detected on your system.  What would you "
+                                 "like to do?"))
+        introLabel.set_alignment(0, 0)
+        vbox.pack_start(introLabel, False, False)
+
+	r = self.createUpgradeOption()
+        self.r = r
+
+	b = self.r.render()
+	if self.doupgrade:
+	    self.r.setCurrent(UPGRADE_STR)
+	else:
+	    self.r.setCurrent(REINSTALL_STR)
+
+	self.r.setToggleCallback(self.optionToggled)
+        vbox.pack_start(b, False)
+        self.root = self.parts[0]
+
+	uplabelstr = _("<b>Which %s installation would you like to upgrade?</b>") % productName
+	self.uplabel = gtk.Label(uplabelstr)
+        self.uplabel.set_use_markup(True)
+        self.uplabel.set_alignment(0, 0)
+        model = gtk.ListStore(str)
+	self.upgradecombo = gtk.ComboBox(model)
+
+        cell = gtk.CellRendererText()
+        self.upgradecombo.pack_start(cell, True)
+        self.upgradecombo.set_attributes(cell, markup=0)
+
+	for (dev, desc) in self.parts:
+            iter = model.append()
+	    if (desc is None) or len(desc) < 1:
+		desc = _("Unknown Linux system")
+            model[iter][0] = "<small>%s <i>(installed on %s)</i></small>" %(desc, dev.path)
+
+	# hack hack hackity hack
+        alignment = gtk.Alignment(xalign=0.25)
+        alignmentBox = gtk.VBox(False, 6)
+        alignmentBox.pack_start(self.uplabel, False, False)
+        alignmentBox.pack_start(self.upgradecombo, False, False)
+        alignment.add(alignmentBox)
+        vbox.pack_start(alignment, True, True)
+
+	# set default
+	idx = 0
+	for p in self.parts:
+	    if self.anaconda.upgradeRoot[0][0] == p[0]:
+	        self.upgradecombo.set_active(idx)
+	        break
+	    idx = idx + 1
+
+	self.upgradeOptionsSetSensitivity(self.doupgrade)
+
+        return vbox
diff --git a/pyanaconda/iw/filter_gui.py b/pyanaconda/iw/filter_gui.py
new file mode 100644
index 0000000..a267ce2
--- /dev/null
+++ b/pyanaconda/iw/filter_gui.py
@@ -0,0 +1,764 @@
+#
+# Storage filtering UI
+#
+# Copyright (C) 2009  Red Hat, Inc.
+# 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 as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# 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, see <http://www.gnu.org/licenses/>.
+#
+
+import block
+import collections
+import gtk, gobject
+import gtk.glade
+import gui
+import parted
+import _ped
+from DeviceSelector import *
+from baseudev import *
+from constants import *
+from iw_gui import *
+from storage.devices import devicePathToName
+from storage.udev import *
+from storage.devicelibs.mpath import *
+from flags import flags
+import storage.iscsi
+import storage.fcoe
+import storage.zfcp
+import storage.dasd
+
+import gettext
+_ = lambda x: gettext.ldgettext("anaconda", x)
+
+DEVICE_COL = 4
+MODEL_COL = 5
+CAPACITY_COL = 6
+VENDOR_COL = 7
+INTERCONNECT_COL = 8
+SERIAL_COL = 9
+ID_COL = 10
+PATHS_COL = 11
+PORT_COL = 12
+TARGET_COL = 13
+LUN_COL = 14
+
+# This is kind of a magic class that is used for populating the device store.
+# It mostly acts like a list except for some funny behavior on adding/getting.
+# You must add udev dicts to this list, but when you go to examine the list
+# (by pulling items out, checking membership, etc.) you are comparing based
+# on names.
+#
+# The only reason to have this is to prevent needing two lists in a variety
+# of places throughout FilterWindow.
+class NameCache(collections.MutableSequence):
+    def __init__(self, iterable):
+        self._lst = list(iterable)
+
+    def __contains__(self, item):
+        return item["name"] in iter(self)
+
+    def __delitem__(self, index):
+        return self._lst.__delitem__(index)
+
+    def __getitem__(self, index):
+        return self._lst.__getitem__(index)["name"]
+
+    def __iter__(self):
+        for d in self._lst:
+            yield d["name"]
+
+    def __len__(self):
+        return len(self._lst)
+
+    def __setitem__(self, index, value):
+        return self._lst.__setitem__(index, value)
+
+    def insert(self, index, value):
+        return self._lst.insert(index, value)
+
+# These are global because they need to be accessible across all Callback
+# objects as the same values, and from the AdvancedFilterWindow object to add
+# and remove devices when populating scrolled windows.
+totalDevices = 0
+selectedDevices = 0
+totalSize = 0
+selectedSize = 0
+
+# These are global so they can be accessed from all Callback objects.  The
+# basic callback defines its membership as anything that doesn't pass the
+# is* methods.
+def isCCISS(info):
+    return udev_device_is_cciss(info)
+
+def isRAID(info):
+    if flags.dmraid:
+        return udev_device_is_biosraid(info)
+
+    return False
+
+def isMultipath(info):
+    return udev_device_is_multipath_member(info)
+
+def isOther(info):
+    return udev_device_is_iscsi(info) or udev_device_is_fcoe(info)
+
+class Callbacks(object):
+    def __init__(self, xml):
+        self.model = None
+        self.xml = xml
+
+        self.sizeLabel = self.xml.get_widget("sizeLabel")
+        self.sizeLabel.connect("realize", self.update)
+
+    def addToUI(self, tuple):
+        pass
+
+    def deviceToggled(self, set, device):
+        global selectedDevices, totalDevices
+        global selectedSize, totalSize
+
+        if set:
+            selectedDevices += 1
+            selectedSize += device["XXX_SIZE"]
+        else:
+            selectedDevices -= 1
+            selectedSize -= device["XXX_SIZE"]
+
+        self.update()
+
+    def isMember(self, info):
+        return info and not isRAID(info) and not isCCISS(info) and \
+               not isMultipath(info) and not isOther(info)
+
+    def update(self, *args, **kwargs):
+        global selectedDevices, totalDevices
+        global selectedSize, totalSize
+
+        self.sizeLabel.set_markup(_("Selected devices: %s (%s MB) out of %s (%s MB).") % (selectedDevices, selectedSize, totalDevices, totalSize))
+
+    def visible(self, model, iter, view):
+        # Most basic visibility function - does the model say this row
+        # should be visible?  Subclasses can define their own more specific
+        # visibility function, though they should also take a look at this
+        # one to see what the model says.
+        return self.isMember(model.get_value(iter, OBJECT_COL)) and \
+               model.get_value(iter, VISIBLE_COL)
+
+class RAIDCallbacks(Callbacks):
+    def isMember(self, info):
+        return info and (isRAID(info) or isCCISS(info))
+
+class FilteredCallbacks(Callbacks):
+    def __init__(self, *args, **kwargs):
+        Callbacks.__init__(self, *args, **kwargs)
+
+        # Are we even applying the filtering UI?  This is False when
+        # whateverFilterBy is empty, True the rest of the time.
+        self.filtering = False
+
+    def reset(self):
+        self.notebook.set_current_page(0)
+        self.filtering = False
+
+    def set(self, num):
+        self.notebook.set_current_page(num)
+        self.filtering = True
+
+class MPathCallbacks(FilteredCallbacks):
+    def __init__(self, *args, **kwargs):
+        FilteredCallbacks.__init__(self, *args, **kwargs)
+
+        self._vendors = []
+        self._interconnects = []
+
+        self.filterBy = self.xml.get_widget("mpathFilterBy")
+        self.notebook = self.xml.get_widget("mpathNotebook")
+
+        self.vendorEntry = self.xml.get_widget("mpathVendorEntry")
+        self.interconnectEntry = self.xml.get_widget("mpathInterconnectEntry")
+        self.IDEntry = self.xml.get_widget("mpathIDEntry")
+
+        self.mpathFilterHBox = self.xml.get_widget("mpathFilterHBox")
+        self.mpathFilterHBox.connect("realize", self._populateUI)
+
+        self.vendorEntry.connect("changed", lambda entry: self.model.get_model().refilter())
+        self.interconnectEntry.connect("changed", lambda entry: self.model.get_model().refilter())
+        self.IDEntry.connect("changed", lambda entry: self.model.get_model().refilter())
+
+    def addToUI(self, tuple):
+        if not tuple[VENDOR_COL] in self._vendors:
+            self._vendors.append(tuple[VENDOR_COL])
+
+        if not tuple[INTERCONNECT_COL] in self._interconnects:
+            self._interconnects.append(tuple[INTERCONNECT_COL])
+
+    def isMember(self, info):
+        return info and isMultipath(info)
+
+    def visible(self, model, iter, view):
+        if not FilteredCallbacks.visible(self, model, iter, view):
+            return False
+
+        if self.filtering:
+            if self.notebook.get_current_page() == 0:
+                return self._visible_by_interconnect(model, iter, view)
+            elif self.notebook.get_current_page() == 1:
+                return self._visible_by_vendor(model, iter, view)
+            elif self.notebook.get_current_page() == 2:
+                return self._visible_by_wwid(model, iter, view)
+
+        return True
+
+    def _populateUI(self, widget):
+        cell = gtk.CellRendererText()
+
+        self._vendors.sort()
+        self.vendorEntry.set_model(gtk.ListStore(gobject.TYPE_STRING))
+        self.vendorEntry.pack_start(cell)
+        self.vendorEntry.add_attribute(cell, 'text', 0)
+
+        for v in self._vendors:
+            self.vendorEntry.append_text(v)
+
+        self.vendorEntry.show_all()
+
+        self._interconnects.sort()
+        self.interconnectEntry.set_model(gtk.ListStore(gobject.TYPE_STRING))
+        self.interconnectEntry.pack_start(cell)
+        self.interconnectEntry.add_attribute(cell, 'text', 0)
+
+        for i in self._interconnects:
+            self.interconnectEntry.append_text(i)
+
+        self.interconnectEntry.show_all()
+
+    def _visible_by_vendor(self, model, iter, view):
+        entered = self.vendorEntry.get_child().get_text()
+        return model.get_value(iter, VENDOR_COL).find(entered) != -1
+
+    def _visible_by_interconnect(self, model, iter, view):
+        entered = self.interconnectEntry.get_child().get_text()
+        return model.get_value(iter, INTERCONNECT_COL).find(entered) != -1
+
+    def _visible_by_wwid(self, model, iter, view):
+        # FIXME:  make this support globs, etc.
+        entered = self.IDEntry.get_text()
+
+        return entered != "" and model.get_value(iter, ID_COL).find(entered) != -1
+
+class OtherCallbacks(MPathCallbacks):
+    def __init__(self, *args, **kwargs):
+        FilteredCallbacks.__init__(self, *args, **kwargs)
+
+        self._vendors = []
+        self._interconnects = []
+
+        self.filterBy = self.xml.get_widget("otherFilterBy")
+        self.notebook = self.xml.get_widget("otherNotebook")
+
+        self.vendorEntry = self.xml.get_widget("otherVendorEntry")
+        self.interconnectEntry = self.xml.get_widget("otherInterconnectEntry")
+        self.IDEntry = self.xml.get_widget("otherIDEntry")
+
+        self.otherFilterHBox = self.xml.get_widget("otherFilterHBox")
+        self.otherFilterHBox.connect("realize", self._populateUI)
+
+        self.vendorEntry.connect("changed", lambda entry: self.model.get_model().refilter())
+        self.interconnectEntry.connect("changed", lambda entry: self.model.get_model().refilter())
+        self.IDEntry.connect("changed", lambda entry: self.model.get_model().refilter())
+
+    def isMember(self, info):
+        return info and isOther(info)
+
+class SearchCallbacks(FilteredCallbacks):
+    def __init__(self, *args, **kwargs):
+        FilteredCallbacks.__init__(self, *args, **kwargs)
+
+        self._ports = []
+        self._targets = []
+        self._luns = []
+
+        self.filterBy = self.xml.get_widget("searchFilterBy")
+        self.notebook = self.xml.get_widget("searchNotebook")
+
+        self.portEntry = self.xml.get_widget("searchPortEntry")
+        self.targetEntry = self.xml.get_widget("searchTargetEntry")
+        self.LUNEntry = self.xml.get_widget("searchLUNEntry")
+        self.IDEntry = self.xml.get_widget("searchIDEntry")
+
+        # When these entries are changed, we need to redo the filtering.
+        # If we don't do filter-as-you-type, we'd need a Search/Clear button.
+        self.portEntry.connect("changed", lambda entry: self.model.get_model().refilter())
+        self.targetEntry.connect("changed", lambda entry: self.model.get_model().refilter())
+        self.LUNEntry.connect("changed", lambda entry: self.model.get_model().refilter())
+        self.IDEntry.connect("changed", lambda entry: self.model.get_model().refilter())
+
+    def isMember(self, info):
+        return True
+
+    def visible(self, model, iter, view):
+        if not model.get_value(iter, VISIBLE_COL):
+            return False
+
+        if self.filtering:
+            if self.notebook.get_current_page() == 0:
+                return self._visible_by_ptl(model, iter, view)
+            else:
+                return self._visible_by_wwid(model, iter, view)
+
+        return True
+
+    def _visible_by_ptl(self, model, iter, view):
+        rowPort = model.get_value(iter, PORT_COL)
+        rowTarget = model.get_value(iter, TARGET_COL)
+        rowLUN = model.get_value(iter, LUN_COL)
+
+        enteredPort = self.portEntry.get_text()
+        enteredTarget = self.targetEntry.get_text()
+        enteredLUN = self.LUNEntry.get_text()
+
+        return (not enteredPort or enteredPort and enteredPort == rowPort) and \
+               (not enteredTarget or enteredTarget and enteredTarget == rowTarget) and \
+               (not enteredLUN or enteredLUN and enteredLUN == rowLUN)
+
+    def _visible_by_wwid(self, model, iter, view):
+        # FIXME:  make this support globs, etc.
+        entered = self.IDEntry.get_text()
+
+        return entered != "" and model.get_value(iter, ID_COL).find(entered) != -1
+
+class NotebookPage(object):
+    def __init__(self, store, name, xml, cb):
+        # Every page needs a ScrolledWindow to display the results in.
+        self.scroll = xml.get_widget("%sScroll" % name)
+
+        self.filteredModel = store.filter_new()
+        self.sortedModel = gtk.TreeModelSort(self.filteredModel)
+        self.treeView = gtk.TreeView(self.sortedModel)
+
+        self.scroll.add(self.treeView)
+
+        self.cb = cb
+        self.cb.model = self.sortedModel
+
+        self.ds = DeviceSelector(store, self.sortedModel, self.treeView,
+                                 visible=VISIBLE_COL, active=ACTIVE_COL)
+        self.ds.createMenu()
+        self.ds.createSelectionCol(toggledCB=self.cb.deviceToggled,
+                                   membershipCB=self.cb.isMember)
+
+        self.filteredModel.set_visible_func(self.cb.visible, self.treeView)
+
+        # Not every NotebookPage will have a filter box - just those that do
+        # some sort of filtering (obviously).
+        self.filterBox = xml.get_widget("%sFilterHBox" % name)
+
+        if self.filterBox:
+            self.filterBy = xml.get_widget("%sFilterBy" % name)
+            self.filterBy.connect("changed", self._filter_by_changed)
+
+            # However if the page has a filter box, then it must also have a
+            # notebook with an easily discoverable name.
+            self.notebook = xml.get_widget("%sNotebook" % name)
+
+    def _filter_by_changed(self, combo):
+        active = combo.get_active()
+
+        if active == -1:
+            self.cb.reset()
+        else:
+            self.cb.set(active)
+
+        self.filteredModel.refilter()
+
+    def getNVisible(self):
+        retval = 0
+        iter = self.filteredModel.get_iter_first()
+
+        while iter:
+            if self.cb.visible(self.filteredModel, iter, self.treeView):
+                retval += 1
+
+            iter = self.filteredModel.iter_next(iter)
+
+        return retval
+
+class FilterWindow(InstallWindow):
+    windowTitle = N_("Device Filter")
+
+    def getNext(self):
+        # All pages use the same store, so we only need to use the first one.
+        # However, we do need to make sure all paths from multipath devices
+        # are in the list.
+        selected = set()
+        for dev in self.pages[0].ds.getSelected():
+            selected.add(udev_device_get_name(dev[OBJECT_COL]))
+
+        if len(selected) == 0:
+            self.anaconda.intf.messageWindow(_("Error"),
+                                             _("You must select at least one "
+                                               "drive to be used for installation."),
+                                             custom_icon="error")
+            raise gui.StayOnScreen
+
+        self.anaconda.storage.exclusiveDisks = list(selected)
+
+    def _add_advanced_clicked(self, button):
+        from advanced_storage import addDrive
+
+        if not addDrive(self.anaconda):
+            return
+
+        udev_trigger(subsystem="block", action="change")
+        new_disks = filter(udev_device_is_disk, udev_get_block_devices())
+        (new_singlepaths, new_mpaths, new_partitions) = identifyMultipaths(new_disks)
+        (new_raids, new_nonraids) = self.split_list(lambda d: isRAID(d) and not isCCISS(d),
+                                                    new_singlepaths)
+
+        nonraids = filter(lambda d: d not in self._cachedDevices, new_nonraids)
+        mpaths = filter(lambda d: d not in self._cachedMPaths, new_mpaths)
+        raids = filter(lambda d: d not in self._cachedRaidDevices, new_raids)
+
+        self.populate(nonraids, mpaths, raids, activeByDefault=True)
+
+        # Make sure to update the size label at the bottom.
+        self.pages[0].cb.update()
+
+        self._cachedDevices.extend(nonraids)
+        self._cachedMPaths.extend(mpaths)
+        self._cachedRaidDevices.extend(raids)
+
+    def _makeBasic(self):
+        np = NotebookPage(self.store, "basic", self.xml, Callbacks(self.xml))
+
+        np.ds.addColumn(_("Model"), MODEL_COL)
+        np.ds.addColumn(_("Capacity"), CAPACITY_COL)
+        np.ds.addColumn(_("Vendor"), VENDOR_COL)
+        np.ds.addColumn(_("Interconnect"), INTERCONNECT_COL)
+        np.ds.addColumn(_("Serial Number"), SERIAL_COL)
+        np.ds.addColumn(_("Device"), DEVICE_COL, displayed=False)
+        return np
+
+    def _makeRAID(self):
+        np = NotebookPage(self.store, "raid", self.xml, RAIDCallbacks(self.xml))
+
+        np.ds.addColumn(_("Model"), MODEL_COL)
+        np.ds.addColumn(_("Capacity"), CAPACITY_COL)
+        np.ds.addColumn(_("Device"), DEVICE_COL, displayed=False)
+        return np
+
+    def _makeMPath(self):
+        np = NotebookPage(self.store, "mpath", self.xml, MPathCallbacks(self.xml))
+
+        np.ds.addColumn(_("Identifier"), ID_COL)
+        np.ds.addColumn(_("Capacity"), CAPACITY_COL)
+        np.ds.addColumn(_("Vendor"), VENDOR_COL)
+        np.ds.addColumn(_("Interconnect"), INTERCONNECT_COL)
+        np.ds.addColumn(_("Paths"), PATHS_COL)
+        np.ds.addColumn(_("Device"), DEVICE_COL, displayed=False)
+        return np
+
+    def _makeOther(self):
+        np = NotebookPage(self.store, "other", self.xml, OtherCallbacks(self.xml))
+
+        np.ds.addColumn(_("Identifier"), ID_COL)
+        np.ds.addColumn(_("Capacity"), CAPACITY_COL)
+        np.ds.addColumn(_("Vendor"), VENDOR_COL)
+        np.ds.addColumn(_("Interconnect"), INTERCONNECT_COL)
+        np.ds.addColumn(_("Serial Number"), SERIAL_COL, displayed=False)
+        np.ds.addColumn(_("Device"), DEVICE_COL, displayed=False)
+        return np
+
+    def _makeSearch(self):
+        np = NotebookPage(self.store, "search", self.xml, SearchCallbacks(self.xml))
+
+        np.ds.addColumn(_("Model"), MODEL_COL)
+        np.ds.addColumn(_("Capacity"), CAPACITY_COL, displayed=False)
+        np.ds.addColumn(_("Vendor"), VENDOR_COL)
+        np.ds.addColumn(_("Interconnect"), INTERCONNECT_COL, displayed=False)
+        np.ds.addColumn(_("Serial Number"), SERIAL_COL, displayed=False)
+        np.ds.addColumn(_("Identifier"), ID_COL)
+        np.ds.addColumn(_("Port"), PORT_COL)
+        np.ds.addColumn(_("Target"), TARGET_COL)
+        np.ds.addColumn(_("LUN"), LUN_COL)
+        np.ds.addColumn(_("Device"), DEVICE_COL, displayed=False)
+        return np
+
+    def _page_switched(self, notebook, useless, page_num):
+        # When the page is switched, we need to change what is visible so the
+        # Select All button only selects/deselected things on the current page.
+        # Unfortunately, the only way to do this is iterate over all rows and
+        # check for membership.
+        for line in self.store:
+            line[VISIBLE_COL] = self.pages[page_num].cb.isMember(line[OBJECT_COL])
+
+    def _show_buttons(self, *args, **kwargs):
+        if self.anaconda.simpleFilter:
+            self.buttonBox.hide()
+            self.buttonBox.set_no_show_all(True)
+        else:
+            self.buttonBox.show_all()
+
+    def getScreen(self, anaconda):
+        (self.xml, self.vbox) = gui.getGladeWidget("filter.glade", "vbox")
+        self.buttonBox = self.xml.get_widget("buttonBox")
+        self.notebook = self.xml.get_widget("notebook")
+        self.addAdvanced = self.xml.get_widget("addAdvancedButton")
+
+        self.buttonBox.connect("realize", self._show_buttons)
+        self.notebook.connect("switch-page", self._page_switched)
+        self.addAdvanced.connect("clicked", self._add_advanced_clicked)
+
+        self.pages = []
+
+        self.anaconda = anaconda
+
+        # One common store that all the views on all the notebook tabs share.
+        # Yes, this means a whole lot of columns that are going to be empty or
+        # unused much of the time.  Oh well.
+
+        # Object,
+        # visible, active (checked), immutable,
+        # device, model, capacity, vendor, interconnect, serial number, wwid
+        # paths, port, target, lun
+        self.store = gtk.TreeStore(gobject.TYPE_PYOBJECT,
+                                   gobject.TYPE_BOOLEAN, gobject.TYPE_BOOLEAN,
+                                   gobject.TYPE_BOOLEAN,
+                                   gobject.TYPE_STRING, gobject.TYPE_STRING,
+                                   gobject.TYPE_STRING, gobject.TYPE_STRING,
+                                   gobject.TYPE_STRING, gobject.TYPE_STRING,
+                                   gobject.TYPE_STRING, gobject.TYPE_STRING,
+                                   gobject.TYPE_STRING, gobject.TYPE_STRING,
+                                   gobject.TYPE_STRING)
+        self.store.set_sort_column_id(MODEL_COL, gtk.SORT_ASCENDING)
+
+        udev_trigger(subsystem="block", action="change")
+        # So that drives onlined by these show up in the filter UI
+        storage.iscsi.iscsi().startup(anaconda.intf)
+        storage.fcoe.fcoe().startup(anaconda.intf)
+        storage.zfcp.ZFCP().startup()
+        storage.dasd.DASD().startup(anaconda.intf,
+                                    anaconda.storage.exclusiveDisks,
+                                    anaconda.storage.zeroMbr)
+        disks = filter(udev_device_is_disk, udev_get_block_devices())
+        (singlepaths, mpaths, partitions) = identifyMultipaths(disks)
+
+        # The device list could be really long, so we really only want to
+        # iterate over it the bare minimum of times.  Dividing this list up
+        # now means fewer elements to iterate over later.
+        (raids, nonraids) = self.split_list(lambda d: isRAID(d) and not isCCISS(d),
+                                            singlepaths)
+
+        if anaconda.simpleFilter:
+            # In the typical use case, the user likely only has one drive and
+            # there's no point showing either the filtering UI or the
+            # cleardisks UI.  Unfortunately, that means we need to duplicate
+            # some of the getNext method.
+            if len(singlepaths) == 1:
+                anaconda.storage.exclusiveDisks = [udev_device_get_name(singlepaths[0])]
+                return None
+
+            self.pages = [self._makeBasic()]
+            self.notebook.set_show_border(False)
+            self.notebook.set_show_tabs(False)
+        else:
+            self.pages = [self._makeBasic(), self._makeRAID(),
+                          self._makeMPath(), self._makeOther(),
+                          self._makeSearch()]
+
+        self.populate(nonraids, mpaths, raids)
+
+        # If the "Add Advanced" button is ever clicked, we need to have a list
+        # of what devices previously existed so we know what's new.  Then we
+        # can just add the new devices to the UI.  This is going to be slow,
+        # but the user has to click a button to get to the slow part.
+        self._cachedDevices = NameCache(singlepaths)
+        self._cachedMPaths = NameCache(mpaths)
+        self._cachedRaidDevices = NameCache(raids)
+
+        # Switch to the first notebook page that displays any devices.
+        i = 0
+        for pg in self.pages:
+            if pg.getNVisible():
+                self.notebook.set_current_page(i)
+                break
+
+            i += 1
+
+        return self.vbox
+
+    def populate(self, nonraids, mpaths, raids, activeByDefault=False):
+        def _addTuple(tuple):
+            global totalDevices, totalSize
+            global selectedDevices, selectedSize
+            added = False
+
+            self.store.append(None, tuple)
+
+            for pg in self.pages:
+                if pg.cb.isMember(tuple[0]):
+                    added = True
+                    pg.cb.addToUI(tuple)
+
+            # Only update the size label if this device was added to any pages.
+            # This prevents situations where we're only displaying the basic
+            # filter that has one disk, but there are several advanced disks
+            # in the store that cannot be seen.
+            if added:
+                totalDevices += 1
+                totalSize += tuple[0]["XXX_SIZE"]
+
+                if tuple[ACTIVE_COL]:
+                    selectedDevices += 1
+                    selectedSize += tuple[0]["XXX_SIZE"]
+
+        def _isProtected(info):
+            protectedNames = map(udev_resolve_devspec, self.anaconda.protected)
+
+            sysfs_path = udev_device_get_sysfs_path(info)
+            for protected in protectedNames:
+                _p = "/sys/%s/%s" % (sysfs_path, protected)
+                if os.path.exists(os.path.normpath(_p)):
+                    return True
+
+            return False
+
+        def _active(info):
+            if _isProtected(info) or activeByDefault:
+                return True
+
+            name = udev_device_get_name(info)
+
+            if self.anaconda.storage.exclusiveDisks and \
+               name in self.anaconda.storage.exclusiveDisks:
+                return True
+            elif self.anaconda.storage.ignoredDisks and \
+                name not in self.anaconda.storage.ignoredDisks:
+                return True
+            else:
+                return False
+
+        for d in nonraids:
+            name = udev_device_get_name(d)
+
+            # We aren't guaranteed to be able to get a device.  In
+            # particular, built-in USB flash readers show up as devices but
+            # do not always have any media present, so parted won't be able
+            # to find a device.
+            try:
+                partedDevice = parted.Device(path="/dev/" + name)
+            except (_ped.IOException, _ped.DeviceException):
+                continue
+            d["XXX_SIZE"] = int(partedDevice.getSize())
+            # cciss controllers, without any sets defined, show up as a 0 size
+            # blockdev, ignore these
+            if d["XXX_SIZE"] == 0:
+                continue
+
+            # This isn't so great, but iSCSI and s390 devices have an ID_PATH
+            # that contains a lot of useful identifying info, so that should be
+            # displayed instead of a blank WWID.
+            if udev_device_is_iscsi(d) or udev_device_is_dasd(d) or udev_device_is_zfcp(d):
+                ident = udev_device_get_path(d)
+            else:
+                ident = udev_device_get_wwid(d)
+
+            tuple = (d, True, _active(d), _isProtected(d), name,
+                     partedDevice.model, str(d["XXX_SIZE"]) + " MB",
+                     udev_device_get_vendor(d), udev_device_get_bus(d),
+                     udev_device_get_serial(d), ident, "", "", "", "")
+            _addTuple(tuple)
+
+        if raids and flags.dmraid:
+            used_raidmembers = []
+            for rs in block.getRaidSets():
+                # dmraid does everything in sectors
+                size = (rs.rs.sectors * 512) / (1024.0 * 1024.0)
+                fstype = ""
+
+                # get_members also returns subsets with layered raids, we only
+                # want the devices
+                members = filter(lambda m: isinstance(m, block.device.RaidDev),
+                                 list(rs.get_members()))
+                members = map(lambda m: m.get_devpath(), members)
+                for d in raids:
+                    if udev_device_get_name(d) in members:
+                        fstype = udev_device_get_format(d)
+                        sysfs_path = udev_device_get_sysfs_path(d)
+                        break
+
+                # Skip this set if none of its members are in the raids list
+                if not fstype:
+                    continue
+
+                used_raidmembers.extend(members)
+
+                # biosraid devices don't really get udev data, at least not in a
+                # a way that's useful to the filtering UI.  So we need to fake
+                # that data now so we have something to put into the store.
+                data = {"XXX_SIZE": size, "ID_FS_TYPE": fstype,
+                        "DM_NAME": rs.name, "name": rs.name,
+                        "sysfs_path": sysfs_path}
+
+                model = "BIOS RAID set (%s)" % rs.rs.set_type
+                tuple = (data, True, _active(data), _isProtected(data), rs.name,
+                         model, str(size) + " MB", "", "", "", "", "", "", "", "")
+                _addTuple(tuple)
+
+            unused_raidmembers = []
+            for d in raids:
+                if udev_device_get_name(d) not in used_raidmembers:
+                    unused_raidmembers.append(udev_device_get_name(d))
+
+            self.anaconda.intf.unusedRaidMembersWarning(unused_raidmembers)
+
+        for mpath in mpaths:
+            # We only need to grab information from the first device in the set.
+            name = udev_device_get_name(mpath[0])
+
+            try:
+                partedDevice = parted.Device(path="/dev/" + name)
+            except (_ped.IOException, _ped.DeviceException):
+                continue
+            mpath[0]["XXX_SIZE"] = int(partedDevice.getSize())
+            model = partedDevice.model
+
+            # However, we do need all the paths making up this multipath set.
+            paths = "\n".join(map(udev_device_get_name, mpath))
+
+            # We use a copy here, so as to not modify the original udev info
+            # dict as that would break NameCache matching
+            data = mpath[0].copy()
+            data["name"] = udev_device_get_multipath_name(mpath[0])
+            tuple = (data, True, _active(data), _isProtected(data),
+                     udev_device_get_multipath_name(mpath[0]), model,
+                     str(mpath[0]["XXX_SIZE"]) + " MB",
+                     udev_device_get_vendor(mpath[0]),
+                     udev_device_get_bus(mpath[0]),
+                     udev_device_get_serial(mpath[0]),
+                     udev_device_get_wwid(mpath[0]),
+                     paths, "", "", "")
+            _addTuple(tuple)
+
+    def split_list(self, pred, lst):
+        pos = []
+        neg = []
+
+        for ele in lst:
+            if pred(ele):
+                pos.append(ele)
+            else:
+                neg.append(ele)
+
+        return (pos, neg)
diff --git a/pyanaconda/iw/filter_type.py b/pyanaconda/iw/filter_type.py
new file mode 100644
index 0000000..3c691bd
--- /dev/null
+++ b/pyanaconda/iw/filter_type.py
@@ -0,0 +1,80 @@
+#
+# Copyright (C) 2009  Red Hat, Inc.  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 as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# 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, see <http://www.gnu.org/licenses/>.
+#
+# Author(s): Chris Lumens <clumens@xxxxxxxxxx>
+#
+
+import gtk
+import gobject
+import math
+
+from constants import *
+import gui
+from partition_ui_helpers_gui import *
+from pixmapRadioButtonGroup_gui import pixmapRadioButtonGroup
+
+from iw_gui import *
+from flags import flags
+from storage.deviceaction import *
+
+import gettext
+_ = lambda x: gettext.ldgettext("anaconda", x)
+
+class FilterTypeWindow(InstallWindow):
+    def __init__(self, ics):
+        InstallWindow.__init__(self, ics)
+        ics.setTitle("Filter Type")
+        ics.setNextEnabled(True)
+
+    def getNext(self):
+        if self.buttonGroup.getCurrent() == "simple":
+            self.anaconda.simpleFilter = True
+        else:
+            self.anaconda.simpleFilter = False
+
+        return None
+
+    def getScreen(self, anaconda):
+        self.anaconda = anaconda
+        self.intf = anaconda.intf
+
+        vbox = gtk.VBox()
+        label = gtk.Label(_("What type of devices will your installation "
+                            "involve?"))
+        label.set_alignment(0.0, 0.0)
+        vbox.pack_start(label, expand=False, fill=False)
+
+        self.buttonGroup = pixmapRadioButtonGroup()
+        self.buttonGroup.addEntry("simple", _("Basic Storage Devices"),
+                                  descr=_("Installs or upgrades to typical types "
+                                          "of storage devices.  If you're not sure "
+                                          "which option is right for you, this is "
+                                          "probably it."))
+        self.buttonGroup.addEntry("complex", _("Specialized Storage Devices"),
+                                  descr=_("Installs or upgrades to devices such as "
+                                          "Storage Area Networks (SANs) or mainframe "
+                                          "attached disks (DASD), usually in an "
+                                          "enterprise environment"))
+
+        widget = self.buttonGroup.render()
+        vbox.pack_start(widget, expand=True, fill=True)
+
+        if self.anaconda.simpleFilter == True:
+            self.buttonGroup.setCurrent("simple")
+        else:
+            self.buttonGroup.setCurrent("complex")
+
+        return vbox
diff --git a/pyanaconda/iw/iw_gui.py b/pyanaconda/iw/iw_gui.py
new file mode 100644
index 0000000..997a239
--- /dev/null
+++ b/pyanaconda/iw/iw_gui.py
@@ -0,0 +1,53 @@
+#
+# iw_gui.py: install window base class
+#
+# Copyright (C) 2000, 2001, 2002  Red Hat, Inc.  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 as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# 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, see <http://www.gnu.org/licenses/>.
+#
+
+from constants import *
+import gettext
+_ = lambda x: gettext.ldgettext("anaconda", x)
+
+class InstallWindow:
+
+    windowTitle = None
+
+    def __init__ (self,ics):
+        self.ics = ics
+
+	if self.windowTitle:
+	    ics.setTitle (_(self.windowTitle))
+
+    def getNext (self):
+	return None
+
+    def renderCallback(self):
+	return None
+
+    def getPrev (self):
+	return None
+
+    def getScreen (self):
+        pass
+
+    def getICS (self):
+        return self.ics
+
+    def fixUp (self):
+        pass
+
+    def focus(self):
+        pass
diff --git a/pyanaconda/iw/kbd_gui.py b/pyanaconda/iw/kbd_gui.py
new file mode 100644
index 0000000..95fc106
--- /dev/null
+++ b/pyanaconda/iw/kbd_gui.py
@@ -0,0 +1,39 @@
+#
+# keyboard_gui.py:  Shim around system-config-keyboard
+# Brrrraaaaaiiiinnnns...
+#
+# Copyright (C) 2006, 2007  Red Hat, Inc.  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 as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# 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, see <http://www.gnu.org/licenses/>.
+#
+
+from iw_gui import *
+import sys
+
+sys.path.append("/usr/share/system-config-keyboard")
+
+from keyboard_gui import childWindow as installKeyboardWindow
+
+class KeyboardWindow(InstallWindow, installKeyboardWindow):
+    def __init__(self, ics):
+        InstallWindow.__init__(self, ics)
+        installKeyboardWindow.__init__(self)
+
+    def getNext(self):
+        installKeyboardWindow.getNext(self)
+
+    def getScreen(self, anaconda):
+        default = anaconda.instLanguage.getDefaultKeyboard(anaconda.rootPath)
+        anaconda.keyboard.set(default)
+        return installKeyboardWindow.getScreen(self, default, anaconda.keyboard)
diff --git a/pyanaconda/iw/language_gui.py b/pyanaconda/iw/language_gui.py
new file mode 100644
index 0000000..952f8a8
--- /dev/null
+++ b/pyanaconda/iw/language_gui.py
@@ -0,0 +1,134 @@
+#
+# langauge_gui.py: installtime language selection.
+#
+# Copyright (C) 2000, 2001, 2002  Red Hat, Inc.  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 as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# 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, see <http://www.gnu.org/licenses/>.
+#
+
+import gobject
+import gtk
+import gui
+from iw_gui import *
+from constants import *
+
+import gettext
+_ = lambda x: gettext.ldgettext("anaconda", x)
+
+from gui import setupTreeViewFixupIdleHandler, StayOnScreen
+
+class LanguageWindow (InstallWindow):
+
+    windowTitle = N_("Language Selection")
+
+    def __init__ (self, ics):
+	InstallWindow.__init__ (self, ics)
+
+    def getNext (self):
+        anaconda = self.ics.getICW().anaconda
+
+        (model, iter) = self.listView.get_selection().get_selected()
+        if not iter:
+            raise StayOnScreen
+
+	choice = self.listStore.get_value(iter, 1)
+        self.lang = self.instLang.getLangByName(choice)
+
+        if self.lang in self.instLang.getCurrentLangSearchList():
+            return None
+
+        self.instLang.instLang = self.lang
+        self.instLang.systemLang = self.lang
+        anaconda.timezone.setTimezoneInfo(anaconda.instLanguage.getDefaultTimeZone(anaconda.rootPath))
+	self.ics.getICW().setLanguage()
+
+        return None
+
+    def listScroll(self, widget, *args):
+        # recenter the list
+        (model, iter) = self.listView.get_selection().get_selected()
+        if iter is None:
+            return
+
+        path = self.listStore.get_path(iter)
+        col = self.listView.get_column(0)
+        self.listView.scroll_to_cell(path, col, True, 0.5, 0.5)
+	self.listView.set_cursor(path, col, False)
+
+    # LanguageWindow tag="lang"
+    def getScreen (self, anaconda):
+        self.running = 0
+        mainBox = gtk.VBox (False, 10)
+
+        hbox = gtk.HBox(False, 5)
+        pix = gui.readImageFromFile ("config-language.png")
+        if pix:
+            a = gtk.Alignment ()
+            a.add (pix)
+            hbox.pack_start (a, False)
+
+        label = gtk.Label (_("What language would you like to use during the "
+                         "installation process?"))
+        label.set_line_wrap (True)
+        label.set_size_request(350, -1)
+        hbox.pack_start(label, False)
+
+	self.instLang = anaconda.instLanguage
+
+        self.listStore = gtk.ListStore(gobject.TYPE_STRING,
+                                       gobject.TYPE_STRING,
+                                       gobject.TYPE_STRING)
+
+        for locale in self.instLang.available():
+            iter = self.listStore.append()
+            nick = self.instLang.getLangByName(locale)
+            lang = '%s (<span lang="%s">%s</span>)' % (
+                _(locale), "%s" % (nick.split('.')[0],),
+                self.instLang.getNativeLangName(locale))
+            self.listStore.set_value(iter, 0, lang)
+            self.listStore.set_value(iter, 1, locale)
+            self.listStore.set_value(iter, 2, _(locale))
+
+        self.listStore.set_sort_column_id(2, gtk.SORT_ASCENDING)
+
+        self.listView = gtk.TreeView(self.listStore)
+        col = gtk.TreeViewColumn(None, gtk.CellRendererText(), markup=0)
+        self.listView.append_column(col)
+        self.listView.set_property("headers-visible", False)
+
+        current = self.instLang.getLangName(self.instLang.instLang)
+        iter = self.listStore.get_iter_first()
+        while iter:
+            if self.listStore.get_value(iter, 1) == current:
+                selection = self.listView.get_selection()
+                selection.unselect_all()
+                selection.select_iter(iter)
+                break
+            iter = self.listStore.iter_next(iter)
+        self.listView.connect("size-allocate", self.listScroll)
+
+        sw = gtk.ScrolledWindow ()
+        sw.set_border_width (5)
+        sw.set_shadow_type(gtk.SHADOW_IN)
+        sw.set_policy (gtk.POLICY_NEVER, gtk.POLICY_AUTOMATIC)
+        sw.add (self.listView)
+
+	setupTreeViewFixupIdleHandler(self.listView, self.listStore)
+
+        mainBox.pack_start (hbox, False, False, 10)
+        mainBox.pack_start (sw, True, True)
+
+        self.running = 1
+
+        return mainBox
diff --git a/pyanaconda/iw/lvm_dialog_gui.py b/pyanaconda/iw/lvm_dialog_gui.py
new file mode 100644
index 0000000..2474627
--- /dev/null
+++ b/pyanaconda/iw/lvm_dialog_gui.py
@@ -0,0 +1,1466 @@
+#
+# lvm_dialog_gui.py: dialog for editing a volume group request
+#
+# Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007  Red Hat, Inc.
+# 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 as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# 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, see <http://www.gnu.org/licenses/>.
+#
+# Author(s): Michael Fulbright <msf@xxxxxxxxxx>
+#
+
+import copy
+
+import gobject
+import gtk
+import datacombo
+
+import gui
+from partition_ui_helpers_gui import *
+from constants import *
+from storage.devices import *
+from storage.deviceaction import *
+
+import gettext
+_ = lambda x: gettext.ldgettext("anaconda", x)
+P_ = lambda x, y, z: gettext.ldngettext("anaconda", x, y, z)
+
+import logging
+log = logging.getLogger("anaconda")
+
+class VolumeGroupEditor:
+
+    def getTempVG(self):
+        pvs = [copy.deepcopy(pv) for pv in self.pvs]
+        vg = LVMVolumeGroupDevice('tmp-%s' % self.vg.name,
+                                  parents=pvs, peSize=self.peSize)
+        for lv in self.lvs.values():
+            _l = LVMLogicalVolumeDevice(lv['name'], vg, format=lv['format'],
+                                   size=lv['size'], exists=lv['exists'],
+                                   stripes=lv['stripes'],
+                                   logSize=lv['logSize'],
+                                   snapshotSpace=lv['snapshotSpace'])
+            _l.originalFormat = lv['originalFormat']
+
+        return vg
+
+    def numAvailableLVSlots(self):
+	return max(0, lvm.MAX_LV_SLOTS - len(self.lvs))
+
+    def computeSpaceValues(self):
+        vg = self.getTempVG()
+        vgsize = vg.size
+        vgfree = vg.freeSpace
+        vgused = vgsize - vgfree
+	return (vgsize, vgused, vgfree)
+
+    def getPVWastedRatio(self, newpe):
+        """ given a new pe value, return percentage of smallest PV wasted
+
+        newpe - (int) new value of PE, in KB
+        """
+        pvlist = self.getSelectedPhysicalVolumes()
+
+	waste = 0.0
+	for pv in pvlist:
+	    waste = max(waste, (long(pv.size*1024) % newpe)/(pv.size*1024.0))
+
+	return waste
+
+    def getSmallestPVSize(self):
+        """ finds the smallest PV and returns its size in MB
+        """
+	first = 1
+        pvlist = self.getSelectedPhysicalVolumes()
+	for pv in pvlist:
+            try:
+                pesize = int(self.peCombo.get_active_value()) / 1024.0
+            except:
+                pesize = self.vg.peSize
+
+            # FIXME: move this logic into a property of LVMVolumeGroupDevice
+            pvsize = max(0, lvm.clampSize(pv.size, pesize) - pesize)
+	    if first:
+		minpvsize = pvsize
+		first = 0
+	    else:
+		minpvsize = min(pvsize, minpvsize)
+
+	return minpvsize
+
+
+    def reclampLV(self, newpe):
+        """ given a new pe value, set logical volume sizes accordingly
+
+        newpe - (int) new value of PE, in MB
+        """
+
+        pvlist = self.getSelectedPhysicalVolumes()
+        availSpaceMB = self.computeVGSize(pvlist, newpe)
+
+        # see if total space is enough
+        used = 0
+        resize = False
+        for lv in self.lvs.values():
+            # total space required by an lv may be greater than lv size.
+            vg_space = lv['size'] * lv['stripes'] + lv['logSize'] \
+                        + lv['snapshotSpace']
+            clamped_vg_space = lvm.clampSize(vg_space, newpe, roundup=1)
+            used += clamped_vg_space
+            if lv['size'] != lvm.clampSize(lv['size'], newpe, roundup=1):
+                resize = True
+
+        if used > availSpaceMB:
+            self.intf.messageWindow(_("Not enough space"),
+                                    _("The physical extent size cannot be "
+                                      "changed because otherwise the space "
+                                      "required by the currently defined "
+                                      "logical volumes will be increased "
+                                      "to more than the available space."),
+				    custom_icon="error")
+            return 0
+
+	if resize:
+	    rc = self.intf.messageWindow(_("Confirm Physical Extent Change"),
+					 _("This change in the value of the "
+					   "physical extent will require the "
+					   "sizes of the current logical "
+					   "volume requests to be rounded "
+					   "up in size to an integer multiple "
+					   "of the "
+					   "physical extent.\n\nThis change "
+					   "will take effect immediately."),
+					 type="custom", custom_icon="question",
+					 custom_buttons=["gtk-cancel", _("C_ontinue")])
+	    if not rc:
+		return 0
+
+        for lv in self.lvs.values():
+            lv['size'] = lvm.clampSize(lv['size'], newpe, roundup=1)
+
+        return 1
+            
+    def peChangeCB(self, widget, *args):
+        """ handle changes in the Physical Extent option menu
+
+        widget - menu item which was activated
+        peOption - the Option menu containing the items. The data value for
+                   "lastval" is the previous PE value.
+        """
+
+        curval = int(widget.get_active_value())
+        # this one's in MB so we can stop with all this dividing by 1024
+        curpe = curval / 1024.0
+        lastval = widget.get_data("lastpe")
+	lastidx = widget.get_data("lastidx")
+
+	# see if PE is too large compared to smallest PV
+	maxpvsize = self.getSmallestPVSize()
+	if curpe > maxpvsize:
+            self.intf.messageWindow(_("Not enough space"),
+                                    _("The physical extent size cannot be "
+                                      "changed because the value selected "
+				      "(%(curpe)10.2f MB) is larger than the "
+				      "smallest physical volume "
+				      "(%(maxpvsize)10.2f MB) in the volume "
+				      "group.") % {'curpe': curpe,
+				                   'maxpvsize': maxpvsize},
+                                      custom_icon="error")
+	    widget.set_active(lastidx)
+            return 0
+
+	# see if new PE will make any PV useless due to overhead
+	if lvm.clampSize(maxpvsize, curpe) < curpe:
+            self.intf.messageWindow(_("Not enough space"),
+                                    _("The physical extent size cannot be "
+                                      "changed because the value selected "
+				      "(%(curpe)10.2f MB) is too large "
+				      "compared to the size of the "
+				      "smallest physical volume "
+				      "(%(maxpvsize)10.2f MB) in the "
+				      "volume group.")
+				    % {'curpe': curpe, 'maxpvsize': maxpvsize},
+                                    custom_icon="error")
+	    widget.set_active(lastidx)
+            return 0
+	    
+
+	if self.getPVWastedRatio(curpe) > 0.10:
+	    rc = self.intf.messageWindow(_("Too small"),
+					 _("This change in the value of the "
+					   "physical extent will waste "
+					   "substantial space on one or more "
+					   "of the physical volumes in the "
+					   "volume group."),
+					 type="custom", custom_icon="error",
+					   custom_buttons=["gtk-cancel", _("C_ontinue")])
+	    if not rc:
+		widget.set_active(lastidx)
+		return 0
+
+	# now see if we need to fixup effect PV and LV sizes based on PE
+        if curval > lastval:
+            rc = self.reclampLV(curpe)
+            if not rc:
+		widget.set_active(lastidx)
+		return 0
+            else:
+                self.updateLogVolStore()
+	else:
+	    maxlv = lvm.getMaxLVSize()
+	    for lv in self.lvs.values():
+		if lv['size'] > maxlv:
+		    self.intf.messageWindow(_("Not enough space"),
+					    _("The physical extent size "
+					      "cannot be changed because the "
+					      "resulting maximum logical "
+					      "volume size (%10.2f MB) is "
+					      "smaller "
+					      "than one or more of the "
+					      "currently defined logical "
+					      "volumes.") % (maxlv,),
+					    custom_icon="error")
+		    widget.set_active(lastidx)
+		    return 0
+            
+        widget.set_data("lastpe", curval)
+	widget.set_data("lastidx", widget.get_active())
+
+        # now actually set the VG's extent size
+        self.peSize = curpe
+        self.updateAllowedLvmPartitionsList()
+	self.updateVGSpaceLabels()
+
+    def prettyFormatPESize(self, val):
+        """ Pretty print for PE size in KB """
+        if val < 1024:
+            return "%s KB" % (val,)
+        elif val < 1024*1024:
+            return "%s MB" % (val/1024,)
+        else:
+            return "%s GB" % (val/1024/1024,)
+
+    def createPEOptionMenu(self, default=4096):
+        peCombo = datacombo.DataComboBox()
+
+        actualPE = []
+        for curpe in lvm.getPossiblePhysicalExtents(floor=1024):
+            # don't show PE over 128M, unless it's the default
+            if curpe > 131072 and curpe != default:
+                continue
+
+            actualPE.append(curpe)
+            val = self.prettyFormatPESize(curpe)
+
+            peCombo.append(val, curpe)
+
+        # First try to set the combo's active value to the default we're
+        # passed.  If that doesn't work, just set it to the first one to
+        # prevent TypeErrors everywhere.
+        try:
+            peCombo.set_active(actualPE.index(default))
+        except ValueError:
+            peCombo.set_active(0)
+
+        peCombo.set_data("lastidx", peCombo.get_active())
+        peCombo.connect("changed", self.peChangeCB)
+        peCombo.set_data("lastpe", default)
+
+	return peCombo
+
+    def clickCB(self, row, data):
+	model = self.lvmlist.get_model()
+	pvlist = self.getSelectedPhysicalVolumes()
+
+	# get the selected row
+	iter = model.get_iter((string.atoi(data),))
+
+	# we invert val because we get called before checklist
+	# changes the toggle state
+	val      = not model.get_value(iter, 0)
+	partname = model.get_value(iter, 1)
+        pv = self.storage.devicetree.getDeviceByName(partname)
+        if val:
+            self.pvs.append(pv)
+        else:
+            self.pvs.remove(pv)
+            try:
+                vg = self.getTempVG()
+            except DeviceError as e:
+                self.intf.messageWindow(_("Not enough space"),
+                                    _("You cannot remove this physical "
+                                      "volume because otherwise the "
+                                      "volume group will be too small to "
+                                      "hold the currently defined logical "
+                                      "volumes."), custom_icon="error")
+                self.pvs.append(pv)
+                return False
+
+	self.updateVGSpaceLabels()
+	return True
+
+    def createAllowedLvmPartitionsList(self):
+	store = gtk.TreeStore(gobject.TYPE_BOOLEAN,
+			      gobject.TYPE_STRING,
+			      gobject.TYPE_STRING)
+	partlist = WideCheckList(2, store, self.clickCB)
+
+	sw = gtk.ScrolledWindow()
+	sw.add(partlist)
+	sw.set_policy(gtk.POLICY_NEVER, gtk.POLICY_AUTOMATIC)
+	sw.set_shadow_type(gtk.SHADOW_IN)
+
+        origpvs = self.pvs[:]
+	for device in self.availlvmparts:
+	    # clip size to current PE
+	    pesize = int(self.peCombo.get_active_value()) / 1024.0
+	    size = lvm.clampSize(device.size, pesize)
+	    size_string = "%10.2f MB" % size
+            include = True
+            selected = False
+
+            # now see if the pv is in use either by a vg in the tree or by
+            # the vg we are editing now
+            if device in origpvs:
+                selected = True
+                include = True
+            else:
+                for vg in self.storage.vgs:
+                    if vg.name == self.vg.name:
+                        continue
+
+                    if device in vg.pvs:
+                        include = False
+                        break
+
+                if include and not origpvs:
+                    selected = True
+
+            if include:
+                partlist.append_row((device.name, size_string), selected)
+                if selected and device not in self.pvs:
+                    self.pvs.append(device)
+
+	return (partlist, sw)
+
+    def updateAllowedLvmPartitionsList(self):
+	""" update sizes in pv list """
+	row = 0
+	for part in self.availlvmparts:
+	    size = part.size
+
+	    # clip size to current PE
+	    pesize = int(self.peCombo.get_active_value()) / 1024.0
+	    size = lvm.clampSize(size, pesize)
+	    partsize = "%10.2f MB" % size
+
+	    iter = self.lvmlist.store.get_iter((int(row),))
+	    self.lvmlist.store.set_value(iter, 2, partsize)
+	    row = row + 1
+	
+    def getCurrentLogicalVolume(self):
+	selection = self.logvollist.get_selection()
+	(model, iter) = selection.get_selected()
+	return iter
+
+    def editLogicalVolume(self, lv, isNew = 0):
+        # Mixing logical code and gtk code is confusing to me.  So I am going
+        # to do the logic first and then create all the gtk crap!
+        #
+        # lv -- whatever self.logvolstore.get_value returns
+
+        #newfstypelabel = None # File system type label & combo
+        #newfstypeCombo = None
+        newfslabellabel = None # File system Label label & combo
+        newfslableCombo = None
+        #lvnamelabel = None # Logical Volume name label & entry
+        #lvnameentry = None
+        #lvsizelabel = None # Logical Volume size label & entry
+        #lvsizeentry = None
+        maxsizelabel = None # Maximum size label
+        #mountCombo = None # Mount Point Combo Box
+        #tstr = None # String that appears on top of the window
+        tempvg = self.getTempVG()  # copy of self.vg
+        templv = None
+        cpefsos = None # lambda function that represents
+                       # createPreExistFSOptionSection
+
+        # Define the string
+        if isNew:
+            tstr = _("Make Logical Volume")
+        else:
+            tstr = _("Edit Logical Volume: %s") % lv['name']
+
+        # Create the mountCombo.  This is the box where the mountpoint will
+        # appear.  Note that if the format is swap or Raiddevice, the mount
+        # point is none-sense.
+        templuks = None
+        templv = self.getLVByName(lv['name'], vg=tempvg)
+        usedev = templv
+        if templv.format.type == "luks":
+            templuks = LUKSDevice("luks-%s" % lv['name'],
+                                  parents=[templv],
+                                  format=self.luks[lv['name']],
+                                  exists=templv.format.exists)
+            usedev = templuks
+
+        if lv['format'].type == "luks":
+            format = self.luks[lv['name']]
+        else:
+            format = lv['format']
+
+        if lv['exists']:
+            _origlv = self.getLVByName(lv['name'])
+            originalFormat = _origlv.originalFormat
+            if originalFormat.type == "luks":
+                try:
+                    _origluks = self.storage.devicetree.getChildren(_origlv)[0]
+                except IndexError:
+                    pass
+                else:
+                    originalFormat = _origluks.originalFormat
+
+        mountCombo = createMountPointCombo(usedev, excludeMountPoints=["/boot"])
+
+
+        # Stuff appears differently when the lv exists and when the lv is new.
+        # here we make that difference.  Except for newfslabelCombo,  and
+        # maxsizelabel all vars will have a value != None.
+        if not lv['exists']:
+            # File system type lables & combo
+            newfstypelabel = createAlignedLabel(_("_File System Type:"))
+            newfstypeCombo = createFSTypeMenu(format, fstypechangeCB,mountCombo,
+                    ignorefs = ["mdmember", "lvmpv", "efi", "prepboot", "appleboot"])
+            newfstypelabel.set_mnemonic_widget(newfstypeCombo)
+
+            # Logical Volume name label & entry
+            lvnamelabel = createAlignedLabel(_("_Logical Volume Name:"))
+            lvnameentry = gtk.Entry(32)
+            lvnamelabel.set_mnemonic_widget(lvnameentry)
+            if lv['name']:
+                lvnameentry.set_text(lv['name'])
+            else:
+                lvnameentry.set_text(self.storage.createSuggestedLVName(self.getTempVG()))
+
+            # Logical Volume size label & entry
+            lvsizelabel = createAlignedLabel(_("_Size (MB):"))
+            lvsizeentry = gtk.Entry(16)
+            lvsizelabel.set_mnemonic_widget(lvsizeentry)
+            lvsizeentry.set_text("%Ld" % lv['size'])
+
+            # Maximum size label
+            max_grow = tempvg.freeSpace / lv['stripes']
+            maxsizelabel = createAlignedLabel(_("(Max size is %s MB)") %
+                                              min(lvm.getMaxLVSize(),
+                                                  lv['size'] + max_grow))
+
+            # Encrypt Check Box button.
+            self.lukscb = gtk.CheckButton(_("_Encrypt"))
+            self.lukscb.set_data("formatstate", 1)
+            if lv['format'].type == "luks":
+                self.lukscb.set_active(1)
+            else:
+                self.lukscb.set_active(0)
+
+        else:
+            # File system type lable & combo
+            newfstypelabel = createAlignedLabel(_("Original File System Type:"))
+            newfstypeCombo = gtk.Label(originalFormat.name)
+
+            # File system label label & combo
+            if getattr(originalFormat, "label", None):
+                newfslabellabel = createAlignedLabel(_("Original File System "
+                                                      "Label:"))
+                newfslableCombo = gtk.Label(originalFormat.label)
+
+            # Logical Volume name label & entry
+            lvnamelabel = createAlignedLabel(_("Logical Volume Name:"))
+            lvnameentry = gtk.Label(lv['name'])
+
+            # Logical Volume size label & entry
+            lvsizelabel = createAlignedLabel(_("Size (MB):"))
+            lvsizeentry = gtk.Label(str(lv['size']))
+
+            # Create the File System Format Section
+            self.fsoptionsDict = {}
+            # We are going to lambda the createPreExistFSOptionSection so we can call
+            # it latter with two arguments, row and mainttable.
+            cpefsos = lambda table, row: createPreExistFSOptionSection(templv,
+                    maintable, row, mountCombo, self.storage,
+                    ignorefs = ["software RAID", "physical volume (LVM)", "vfat"],
+                    luksdev=templuks)
+
+
+        # Here is where the gtk crap begins.
+        dialog = gtk.Dialog(tstr, self.parent)
+        gui.addFrame(dialog)
+        dialog.add_button('gtk-cancel', gtk.RESPONSE_CANCEL)
+        dialog.add_button('gtk-ok', 1)
+        dialog.set_position(gtk.WIN_POS_CENTER)
+
+        # Initialize main table
+        maintable = gtk.Table()
+        maintable.set_row_spacings(5)
+        maintable.set_col_spacings(5)
+        row = 0
+
+        # Add the mountCombo that we previously created
+        lbl = createAlignedLabel(_("_Mount Point:"))
+        maintable.attach(lbl, 0, 1, row,row+1)
+        lbl.set_mnemonic_widget(mountCombo)
+        maintable.attach(mountCombo, 1, 2, row, row + 1)
+        row += 1
+
+        # Add the filesystem combo labels.
+        maintable.attach(newfstypelabel, 0, 1, row, row + 1)
+        maintable.attach(newfstypeCombo, 1, 2, row, row + 1)
+        row += 1
+
+        # If there is a File system lable, add it.
+        if newfslabellabel is not None and newfslableCombo is not None:
+            maintable.attach(newfslabellabel, 0, 1, row, row + 1)
+            maintable.attach(newfslableCombo, 1, 2, row, row + 1)
+            row += 1
+
+        # Add the logical volume name
+        maintable.attach(lvnamelabel, 0, 1, row, row + 1)
+        maintable.attach(lvnameentry, 1, 2, row, row + 1)
+        row += 1
+
+        # Add the logical volume size
+        maintable.attach(lvsizelabel, 0, 1, row, row + 1)
+        maintable.attach(lvsizeentry, 1, 2, row, row + 1)
+        row += 1
+
+        # If there is a maxsize, add it.
+        if maxsizelabel is not None:
+            maintable.attach(maxsizelabel, 1, 2, row, row + 1)
+
+        # If we have the createPreExistFSOptionSection lamda function it means
+        # that we have a preexisting lv and we must call the lambda function
+        # to create the Pre exsisting FS option section.
+        if cpefsos is not None:
+            (row, self.fsoptionsDict) = cpefsos(maintable, row)
+
+        # checkbutton for encryption using dm-crypt/LUKS
+        # FIXME: Here we could not decouple the gtk stuff from the logic because
+        #        of the createPreExistFSOptionSection function call.  We must
+        #        decouple that function.
+        if not lv['exists']:
+            maintable.attach(self.lukscb, 0, 2, row, row + 1)
+            row = row + 1
+        else:
+            self.lukscb = self.fsoptionsDict.get("lukscb")
+
+        dialog.vbox.pack_start(maintable)
+        dialog.show_all()
+        # Here ends the gtk crap
+
+        while 1:
+            rc = dialog.run()
+            if rc in [gtk.RESPONSE_CANCEL, gtk.RESPONSE_DELETE_EVENT]:
+                if isNew:
+                    del self.lvs[lv['name']]
+                dialog.destroy()
+                return
+
+            actions = []
+            targetSize = None
+            migrate = None
+            format = None
+            newluks = None
+
+            if templv.format.type == "luks":
+                format = self.luks[lv['name']]
+            else:
+                format = templv.format
+
+            if not templv.exists:
+                fmt_class = newfstypeCombo.get_active_value()
+            else:
+                # existing lv
+                fmt_class = self.fsoptionsDict["fstypeCombo"].get_active_value()
+
+            mountpoint = mountCombo.get_children()[0].get_text().strip()
+            if mountpoint == _("<Not Applicable>"):
+                mountpoint = ""
+
+            # validate logical volume name
+            lvname = lvnameentry.get_text().strip()
+            if not templv.exists:
+                err = sanityCheckLogicalVolumeName(lvname)
+                if err:
+                    self.intf.messageWindow(_("Illegal Logical Volume Name"),
+                                            err, custom_icon="error")
+                    continue
+
+            # check that the name is not already in use
+            used = 0
+            for _lv in self.lvs.values():
+                if _lv == lv:
+                    continue
+
+                if _lv['name'] == lvname:
+                    used = 1
+                    break
+
+            if used:
+                self.intf.messageWindow(_("Illegal logical volume name"),
+                                        _("The logical volume name \"%s\" is "
+                                          "already in use. Please pick "
+                                          "another.") % (lvname,), custom_icon="error")
+                continue
+
+            # test mount point
+            # check in pending logical volume requests
+            # these may not have been put in master list of requests
+            # yet if we have not hit 'OK' for the volume group creation
+            if fmt_class().mountable and mountpoint:
+                used = False
+                curmntpt = getattr(format, "mountpoint", None)
+
+                for _lv in self.lvs.values():
+                    if _lv['format'].type == "luks":
+                        _format = self.luks[_lv['name']]
+                    else:
+                        _format = _lv['format']
+
+                    if not _format.mountable or curmntpt and \
+                       _format.mountpoint == curmntpt:
+                        continue
+
+                    if _format.mountpoint == mountpoint:
+                        used = True
+                        break
+
+                if not used:
+                    # we checked this VG's LVs above; now check the rest of
+                    # the devices in the tree
+                    mountdevs = self.lvs.values()
+                    full_name = "%s-%s" % (self.vg.name, lv['name'])
+                    for (mp,d) in self.storage.mountpoints.iteritems():
+                        if (d.type != "lvmlv" or d.vg.id != self.vg.id) and \
+                           mp == mountpoint and \
+                           not (isinstance(d, LUKSDevice) and
+                                full_name in [dev.name for dev in d.parents]):
+                            used = True
+                            break
+
+                if used:
+                    self.intf.messageWindow(_("Mount point in use"),
+                                            _("The mount point \"%s\" is in "
+                                              "use. Please pick another.") %
+                                            (mountpoint,),
+                                            custom_icon="error")
+                    continue
+
+            # check that size specification is numeric and positive
+            if not templv.exists:
+                badsize = 0
+                try:
+                    size = long(lvsizeentry.get_text())
+                except:
+                    badsize = 1
+
+                if badsize or size <= 0:
+                    self.intf.messageWindow(_("Illegal size"),
+                                            _("The requested size as entered is "
+                                              "not a valid number greater "
+                                              "than 0."), custom_icon="error")
+                    continue
+            else:
+                size = templv.size
+
+            # check that size specification is within limits
+            pesize = int(self.peCombo.get_active_value()) / 1024.0
+            size = lvm.clampSize(size, pesize, roundup=True)
+            maxlv = lvm.getMaxLVSize()
+            if size > maxlv:
+                self.intf.messageWindow(_("Not enough space"),
+                                        _("The current requested size "
+                                          "(%(size)10.2f MB) is larger than "
+                                          "the maximum logical volume size "
+                                          "(%(maxlv)10.2f MB). "
+                                          "To increase this limit you can "
+                                          "create more Physical Volumes from "
+                                          "unpartitioned disk space and "
+                                          "add them to this Volume Group.")
+                                          % {'size': size, 'maxlv': maxlv},
+                                        custom_icon="error")
+                continue
+
+            # Ok -- now we've done all the checks to validate the
+            # user-specified parameters. Time to set up the device...
+            origname = templv.lvname
+            if not templv.exists:
+                templv._name = lvname
+                try:
+                    templv.size = size
+                except ValueError:
+                    self.intf.messageWindow(_("Not enough space"),
+                                            _("The size entered for this "
+                                              "logical volume (%(size)d MB) "
+                                              "combined with the size of the "
+                                              "other logical volume(s) "
+                                              "exceeds the size of the "
+                                              "volume group (%(tempvgsize)d "
+                                              "MB). Please make the volume "
+                                              "group larger or make the "
+                                              "logical volume smaller.")
+                                              % {'size': size,
+                                                 'tempvgsize': tempvg.size},
+                                            custom_icon="error")
+                    continue
+
+                format = fmt_class(mountpoint=mountpoint)
+                if self.lukscb and self.lukscb.get_active():
+                    if templv.format.type != "luks":
+                        newluks = format
+                        format = getFormat("luks",
+                                       passphrase=self.storage.encryptionPassphrase)
+                    else:
+                        newluks = format
+                        format = templv.format
+
+                templv.format = format
+            else:
+                # existing lv
+                if self.fsoptionsDict.has_key("formatcb") and \
+                   self.fsoptionsDict["formatcb"].get_active():
+                    format = fmt_class(mountpoint=mountpoint)
+                    if self.lukscb and self.lukscb.get_active() and \
+                       templv.format.type != "luks":
+                        newluks = format
+                        format = getFormat("luks",
+                                           device=templv.path,
+                                           passphrase=self.storage.encryptionPassphrase)
+                    elif self.lukscb and self.lukscb.get_active():
+                        newluks = format
+                        format = templv.format
+
+                    templv.format = format
+                elif self.fsoptionsDict.has_key("formatcb") and \
+                     not self.fsoptionsDict["formatcb"].get_active():
+                    templv.format = templv.originalFormat
+                    format = templv.format
+
+                if format.mountable:
+                    format.mountpoint = mountpoint
+
+                if self.fsoptionsDict.has_key("migratecb") and \
+                   self.fsoptionsDict["migratecb"].get_active():
+                    format.migrate = True
+
+                if self.fsoptionsDict.has_key("resizecb") and self.fsoptionsDict["resizecb"].get_active():
+                    targetSize = self.fsoptionsDict["resizesb"].get_value_as_int()
+                    templv.targetSize = targetSize
+
+            if format.exists and format.mountable and format.mountpoint:
+                tempdev = StorageDevice('tmp', format=format)
+                if self.storage.formatByDefault(tempdev) and \
+                   not queryNoFormatPreExisting(self.intf):
+                    continue
+
+            # everything ok
+            break
+
+        if templv.format.type == "luks":
+            if newluks:
+                self.luks[templv.lvname] = newluks
+
+            if self.luks.has_key(origname) and origname != templv.lvname:
+                self.luks[templv.lvname] = self.luks[origname]
+                del self.luks[templv.lvname]
+        elif templv.format.type != "luks" and self.luks.has_key(origname):
+            del self.luks[origname]
+
+        self.lvs[templv.lvname] = {'name': templv.lvname,
+                                   'size': templv.size,
+                                   'format': templv.format,
+                                   'originalFormat': templv.originalFormat,
+                                   'stripes': templv.stripes,
+                                   'logSize': templv.logSize,
+                                   'snapshotSpace': templv.snapshotSpace,
+                                   'exists': templv.exists}
+        if self.lvs.has_key(origname) and origname != templv.lvname:
+            del self.lvs[origname]
+
+        self.updateLogVolStore()
+        self.updateVGSpaceLabels()
+        dialog.destroy()
+        return
+
+    def editCurrentLogicalVolume(self):
+	iter = self.getCurrentLogicalVolume()
+
+	if iter is None:
+	    return
+	
+	logvolname = self.logvolstore.get_value(iter, 0)
+	lv = self.lvs[logvolname]
+	self.editLogicalVolume(lv)
+
+    def addLogicalVolumeCB(self, widget):
+        if self.numAvailableLVSlots() < 1:
+            self.intf.messageWindow(_("No free slots"),
+                P_("You cannot create more than %d logical volume "
+                   "per volume group.",
+                   "You cannot create more than %d logical volumes "
+                   "per volume group.", lvm.MAX_LV_SLOTS)
+                % (lvm.MAX_LV_SLOTS,),
+                custom_icon="error")
+            return
+
+        (total, used, free) = self.computeSpaceValues()
+	if free <= 0:
+	    self.intf.messageWindow(_("No free space"),
+				    _("There is no room left in the "
+				      "volume group to create new logical "
+				      "volumes. "
+				      "To add a logical volume you must "
+				      "reduce the size of one or more of "
+				      "the currently existing "
+				      "logical volumes"), custom_icon="error")
+	    return
+
+        tempvg = self.getTempVG()
+        name = self.storage.createSuggestedLVName(tempvg)
+        format = getFormat(self.storage.defaultFSType)
+        self.lvs[name] = {'name': name,
+                          'size': free,
+                          'format': format,
+                          'originalFormat': format,
+                          'stripes': 1,
+                          'logSize': 0,
+                          'snapshotSpace': 0,
+                          'exists': False}
+        self.editLogicalVolume(self.lvs[name], isNew = 1)
+        return
+
+    def editLogicalVolumeCB(self, widget):
+	self.editCurrentLogicalVolume()
+	return
+
+    def delLogicalVolumeCB(self, widget):
+	iter = self.getCurrentLogicalVolume()
+	if iter is None:
+	    return
+	
+	logvolname = self.logvolstore.get_value(iter, 0)
+	if logvolname is None:
+	    return
+
+	rc = self.intf.messageWindow(_("Confirm Delete"),
+				_("Are you sure you want to delete the "
+				"logical volume \"%s\"?") % (logvolname,),
+				type = "custom", custom_buttons=["gtk-cancel", _("_Delete")], custom_icon="warning")
+	if not rc:
+	    return
+
+        del self.lvs[logvolname]
+        self.logvolstore.remove(iter)
+        self.updateVGSpaceLabels()
+        return
+    
+    def logvolActivateCb(self, view, path, col):
+	self.editCurrentLogicalVolume()
+
+    def getSelectedPhysicalVolumes(self):
+        model = self.lvmlist.get_model()
+        pv = []
+        next = model.get_iter_first()
+        currow = 0
+        while next is not None:
+	    iter = next
+	    val      = model.get_value(iter, 0)
+	    partname = model.get_value(iter, 1)
+	    
+	    if val:
+		dev = self.storage.devicetree.getDeviceByName(partname)
+                pv.append(dev)
+
+	    next = model.iter_next(iter)
+	    currow = currow + 1
+
+	return pv
+
+    def computeVGSize(self, pvlist, curpe):
+	availSpaceMB = 0L
+	for pv in pvlist:
+            # have to clamp pvsize to multiple of PE
+            # XXX why the subtraction? fudging metadata?
+	    pvsize = lvm.clampSize(pv.size, curpe) - (curpe/1024)
+
+	    availSpaceMB = availSpaceMB + pvsize
+
+        log.info("computeVGSize: vgsize is %s" % (availSpaceMB,))
+	return availSpaceMB
+
+    def updateLogVolStore(self):
+        self.logvolstore.clear()
+        for lv in self.lvs.values():
+            iter = self.logvolstore.append()
+            if lv['format'].type == "luks":
+                format = self.luks[lv['name']]
+            else:
+                format = lv['format']
+
+            mntpt = getattr(format, "mountpoint", "")
+            if lv['name']:
+                self.logvolstore.set_value(iter, 0, lv['name'])
+                
+            if format.type and format.mountable:
+                self.logvolstore.set_value(iter, 1, mntpt)
+	    else:
+		self.logvolstore.set_value(iter, 1, "N/A")
+
+            self.logvolstore.set_value(iter, 2, "%Ld" % lv['size'])
+
+    def updateVGSpaceLabels(self):
+        (total, used, free) = self.computeSpaceValues()
+
+	self.totalSpaceLabel.set_text("%10.2f MB" % (total,))
+	self.usedSpaceLabel.set_text("%10.2f MB" % (used,))
+
+	if total > 0:
+	    usedpercent = (100.0*used)/total
+	else:
+	    usedpercent = 0.0
+	    
+	self.usedPercentLabel.set_text("(%4.1f %%)" % (usedpercent,))
+
+	self.freeSpaceLabel.set_text("%10.2f MB" % (free,))
+	if total > 0:
+	    freepercent = (100.0*free)/total
+	else:
+	    freepercent = 0.0
+
+	self.freePercentLabel.set_text("(%4.1f %%)" % (freepercent,))
+
+#
+# run the VG editor we created
+#
+    def run(self):
+	if self.dialog is None:
+	    return []
+	
+	while 1:
+	    rc = self.dialog.run()
+
+	    if rc in [gtk.RESPONSE_CANCEL, gtk.RESPONSE_DELETE_EVENT]:
+		self.destroy()
+		return []
+
+	    pvlist = self.getSelectedPhysicalVolumes()
+
+	    # check volume name
+	    volname = self.volnameEntry.get_text().strip()
+	    err = sanityCheckVolumeGroupName(volname)
+	    if err:
+		self.intf.messageWindow(_("Invalid Volume Group Name"), err,
+					custom_icon="error")
+		continue
+
+	    origvname = self.vg.name
+
+	    if origvname != volname:
+                # maybe we should see if _any_ device has this name
+		if volname in [vg.name for vg in self.storage.vgs]:
+		    self.intf.messageWindow(_("Name in use"),
+					    _("The volume group name \"%s\" is "
+					      "already in use. Please pick "
+					      "another." % (volname,)),
+					    custom_icon="error")
+		    continue
+
+	    # get physical extent
+	    pesize = int(self.peCombo.get_active_value()) / 1024.0
+
+	    # everything ok
+	    break
+        return self.convertToActions()
+
+    def convertToActions(self):
+        # here we have to figure out what all was done and convert it to
+        # devices and actions
+        #
+        # set up the vg with the right pvs
+        # set up the lvs
+        #  set up the lvs' formats
+        #
+        log.debug("finished editing vg")
+        log.debug("pvs: %s" % [p.name for p in self.pvs])
+        log.debug("luks: %s" % self.luks.keys())
+        volname = self.volnameEntry.get_text().strip()
+        pesize = int(self.peCombo.get_active_value()) / 1024.0
+        for lv in self.lvs.itervalues():
+            log.debug("lv %s" % lv)
+            _luks = self.luks.get(lv['name'])
+            if _luks:
+                log.debug("  luks: %s" % _luks)
+
+        actions = []
+        origlvs = self.vg.lvs
+        if not self.vg.exists:
+            log.debug("non-existing vg -- setting up lvs, pvs, name, pesize")
+            # remove all of the lvs
+            for lv in self.vg.lvs:
+                self.vg._removeLogVol(lv)
+
+            # set up the pvs
+            for pv in self.vg.pvs:
+                if pv not in self.pvs:
+                    self.vg._removePV(pv)
+            for pv in self.pvs:
+                if pv not in self.vg.pvs:
+                    self.vg._addPV(pv)
+
+            self.vg.name = volname
+            self.vg.peSize = pesize
+
+            if self.isNew:
+                actions = [ActionCreateDevice(self.vg)]
+
+        # Schedule destruction of all non-existing lvs, their formats,
+        # luks devices, &c. Also destroy devices that have been removed.
+        for lv in origlvs:
+            log.debug("old lv %s..." % lv.lvname)
+            if not lv.exists or lv.lvname not in self.lvs or \
+               (not self.lvs[lv.lvname]['exists'] and lv.exists):
+                log.debug("removing lv %s" % lv.lvname)
+                if lv.format.type == "luks":
+                    try:
+                        _luksdev = self.storage.devicetree.getChildren(lv)[0]
+                    except IndexError:
+                        pass
+                    else:
+                        if _luksdev.format.type:
+                            actions.append(ActionDestroyFormat(_luksdev))
+
+                        actions.append(ActionDestroyDevice(_luksdev))
+
+                if lv.format.type:
+                    actions.append(ActionDestroyFormat(lv))
+
+                if lv in self.vg.lvs:
+                    self.vg._removeLogVol(lv)
+
+                actions.append(ActionDestroyDevice(lv))
+
+        # schedule creation of all new lvs, their formats, luks devices, &c
+        tempvg = self.getTempVG()
+        for lv in tempvg.lvs:
+            log.debug("new lv %s" % lv)
+            if not lv.exists:
+                log.debug("creating lv %s" % lv.lvname)
+                # create the device
+                newlv = LVMLogicalVolumeDevice(lv.lvname,
+                                               self.vg,
+                                               size=lv.size)
+                actions.append(ActionCreateDevice(newlv))
+
+                # create the format
+                mountpoint = getattr(lv.format, "mountpoint", None)
+                format = getFormat(lv.format.type,
+                                   mountpoint=mountpoint,
+                                   device=newlv.path)
+                actions.append(ActionCreateFormat(newlv, format))
+
+                if lv.format.type == "luks":
+                    # create the luks device
+                    newluks = LUKSDevice("luks-%s" % newlv.name,
+                                         parents=[newlv])
+                    actions.append(ActionCreateDevice(newluks))
+
+                    # create the luks format
+                    oldfmt = self.luks[lv.lvname]
+                    mountpoint = getattr(oldfmt, "mountpoint", None)
+                    format = getFormat(oldfmt.type,
+                                       mountpoint=mountpoint,
+                                       device=newluks.path)
+                    actions.append(ActionCreateFormat(newluks, format))
+            else:
+                log.debug("lv %s already exists" % lv.lvname)
+                # this lv is preexisting. check for resize and reformat.
+                # first, get the real/original lv
+                origlv = self.getLVByName(lv.lvname)
+                if lv.resizable and lv.targetSize != origlv.size:
+                    actions.append(ActionResizeDevice(origlv, lv.targetSize))
+
+                if lv.format.exists:
+                    log.debug("format already exists")
+                    if lv.format.type == "luks":
+                        # see if the luks device already exists
+                        try:
+                            usedev = self.storage.devicetree.getChildren(origlv)[0]
+                        except IndexError:
+                            # the luks device does not exist, meaning we
+                            # do not have a key for it
+                            continue
+
+                        format = self.luks[lv.lvname]
+                        if not format.exists:
+                            actions.append(ActionCreateFormat(usedev, format))
+                    else:
+                        usedev = origlv
+                        format = lv.format
+
+                    # no formatting action requested, meaning we should
+                    # cancel all format create/destroy actions
+                    if format == usedev.originalFormat:
+                        devicetree = self.storage.devicetree
+                        cancel = []
+                        if origlv.originalFormat.type == "luks":
+                            path = "/dev/mapper/luks-%s" % origlv.originalFormat.uuid
+                            cancel.extend(devicetree.findActions(path=path))
+
+                        cancel.extend(devicetree.findActions(type="create",
+                                                             object="format",
+                                                             devid=origlv.id))
+                        cancel.extend(devicetree.findActions(type="destroy",
+                                                             object="format",
+                                                             devid=origlv.id))
+                        for action in cancel:
+                            devicetree.cancelAction(action)
+
+                        # even though we cancelled a bunch of actions, it's
+                        # pretty much impossible to be sure we cancelled them
+                        # in the correct order. make sure things are back to
+                        # their original state.
+                        if origlv.format.type == "luks":
+                            try:
+                                usedev = devicetree.getChildren(origlv)[0]
+                            except IndexError:
+                                usedev = origlv
+                            else:
+                                usedev.format = usedev.originalFormat
+                        else:
+                            usedev = origlv
+
+                    if hasattr(format, "mountpoint"):
+                        usedev.format.mountpoint = format.mountpoint
+
+                    if format.migratable and format.migrate and \
+                       not usedev.format.migrate:
+                        usedev.format.migrate = format.migrate
+                        actions.append(ActionMigrateFormat(usedev))
+
+                    # check the lv's format also, explicitly, in case it is
+                    # encrypted. in this case we must check them both.
+                    if format.resizable and lv.format.resizable and \
+                            lv.targetSize != format.targetSize and \
+                            usedev.format.exists:
+                        log.debug("resizing format on %s to %d" % (usedev.lvname, lv.targetSize))
+                        actions.append(ActionResizeFormat(usedev, lv.targetSize))
+                elif lv.format.type:
+                    log.debug("new format: %s" % lv.format.type)
+                    # destroy old format and any associated luks devices
+                    if origlv.format.type:
+                        if origlv.format.type == "luks":
+                            # destroy the luks device and its format
+                            try:
+                                _luksdev = self.storage.devicetree.getChildren(origlv)[0]
+                            except IndexError:
+                                pass
+                            else:
+                                if _luksdev.format.type:
+                                    # this is probably unnecessary
+                                    actions.append(ActionDestroyFormat(_luksdev))
+
+                                actions.append(ActionDestroyDevice(_luksdev))
+
+                        actions.append(ActionDestroyFormat(origlv))
+
+                    # create the format
+                    mountpoint = getattr(lv.format, "mountpoint", None)
+                    format = getFormat(lv.format.type,
+                                       mountpoint=mountpoint,
+                                       device=origlv.path)
+                    actions.append(ActionCreateFormat(origlv, format))
+
+                    if lv.format.type == "luks":
+                        # create the luks device
+                        newluks = LUKSDevice("luks-%s" % origlv.name,
+                                             parents=[origlv])
+                        actions.append(ActionCreateDevice(newluks))
+
+                        # create the luks format
+                        tmpfmt = self.luks[lv.lvname]
+                        mountpoint = getattr(tmpfmt, "mountpoint", None)
+                        format = getFormat(tmpfmt.type,
+                                           mountpoint=mountpoint,
+                                           device=newluks.path)
+                        actions.append(ActionCreateFormat(newluks, format))
+                else:
+                    log.debug("no format!?")
+
+	return actions
+
+    def destroy(self):
+	if self.dialog:
+	    self.dialog.destroy()
+	self.dialog = None
+
+    def getLVByName(self, name, vg=None):
+        if vg is None:
+            vg = self.vg
+
+        for lv in vg.lvs:
+            if lv.lvname == name or lv.name == name:
+                return lv
+
+    def __init__(self, anaconda, intf, parent, vg, isNew = 0):
+        self.storage = anaconda.storage
+
+        # the vg instance we were passed
+        self.vg = vg
+        self.peSize = vg.peSize
+        self.pvs = self.vg.pvs[:]
+
+        # a dict of dicts
+        #  keys are lv names
+        #  values are dicts representing the lvs
+        #   name, size, format instance, exists
+        self.lvs = {}
+
+        # a dict of luks devices
+        #  keys are lv names
+        #  values are formats of the mapped devices
+        self.luks = {}
+
+        self.isNew = isNew
+        self.intf = intf
+        self.parent = parent
+        self.actions = []
+
+        for lv in self.vg.lvs:
+            self.lvs[lv.lvname] = {"name": lv.lvname,
+                                   "size": lv.size,
+                                   "format": copy.copy(lv.format),
+                                   "originalFormat": lv.originalFormat,
+                                   "stripes": lv.stripes,
+                                   "logSize": lv.logSize,
+                                   "snapshotSpace": lv.snapshotSpace,
+                                   "exists": lv.exists}
+
+            if lv.format.type == "luks":
+                try:
+                    self.luks[lv.lvname] = self.storage.devicetree.getChildren(lv)[0].format
+                except IndexError:
+                    self.luks[lv.lvname] = lv.format
+
+        self.availlvmparts = self.storage.unusedPVs(vg=vg)
+
+        # if no PV exist, raise an error message and return
+        if len(self.availlvmparts) < 1:
+	    self.intf.messageWindow(_("Not enough physical volumes"),
+			       _("At least one unused physical "
+				 "volume partition is "
+				 "needed to create an LVM Volume Group.\n\n"
+				 "Create a partition or RAID array "
+				 "of type \"physical volume (LVM)\" and then "
+				 "select the \"LVM\" option again."),
+				    custom_icon="error")
+	    self.dialog = None
+            return
+
+	if isNew:
+	    tstr = _("Make LVM Volume Group")
+	else:
+	    try:
+		tstr = _("Edit LVM Volume Group: %s") % (vg.name,)
+	    except AttributeError:
+		tstr = _("Edit LVM Volume Group")
+	    
+        dialog = gtk.Dialog(tstr, self.parent)
+        gui.addFrame(dialog)
+        dialog.add_button('gtk-cancel', gtk.RESPONSE_CANCEL)
+        dialog.add_button('gtk-ok', 1)
+
+        dialog.set_position(gtk.WIN_POS_CENTER)
+
+        maintable = gtk.Table()
+        maintable.set_row_spacings(5)
+        maintable.set_col_spacings(5)
+        row = 0
+
+        # volume group name
+        if not vg.exists:
+            lbl = createAlignedLabel(_("_Volume Group Name:"))
+            self.volnameEntry = gtk.Entry(16)
+            lbl.set_mnemonic_widget(self.volnameEntry)
+            if not self.isNew:
+                self.volnameEntry.set_text(self.vg.name)
+            else:
+                self.volnameEntry.set_text(self.storage.createSuggestedVGName(anaconda.network))
+        else:
+            lbl = createAlignedLabel(_("Volume Group Name:"))
+            self.volnameEntry = gtk.Label(self.vg.name)
+	    
+	maintable.attach(lbl, 0, 1, row, row + 1,
+                         gtk.EXPAND|gtk.FILL, gtk.SHRINK)
+        maintable.attach(self.volnameEntry, 1, 2, row, row + 1, gtk.EXPAND|gtk.FILL, gtk.SHRINK)
+	row = row + 1
+
+        lbl = createAlignedLabel(_("_Physical Extent:"))
+        self.peCombo = self.createPEOptionMenu(self.vg.peSize * 1024)
+        lbl.set_mnemonic_widget(self.peCombo)
+        if vg.exists:
+            self.peCombo.set_sensitive(False)
+
+        maintable.attach(lbl, 0, 1, row, row + 1,
+                         gtk.EXPAND|gtk.FILL, gtk.SHRINK)
+        maintable.attach(self.peCombo, 1, 2, row, row + 1, gtk.EXPAND|gtk.FILL, gtk.SHRINK)
+        row = row + 1
+
+        (self.lvmlist, sw) = self.createAllowedLvmPartitionsList()
+        if vg.exists:
+            self.lvmlist.set_sensitive(False)
+        self.lvmlist.set_size_request(275, 80)
+        lbl = createAlignedLabel(_("Physical Volumes to _Use:"))
+        lbl.set_mnemonic_widget(self.lvmlist)
+        maintable.attach(lbl, 0, 1, row, row + 1)
+        maintable.attach(sw, 1, 2, row, row + 1)
+        row = row + 1
+
+        maintable.attach(createAlignedLabel(_("Used Space:")), 0, 1, row,
+			 row + 1, gtk.EXPAND|gtk.FILL, gtk.SHRINK)
+	lbox = gtk.HBox()
+	self.usedSpaceLabel = gtk.Label("")
+	labelalign = gtk.Alignment()
+	labelalign.set(1.0, 0.5, 0.0, 0.0)
+	labelalign.add(self.usedSpaceLabel)
+	lbox.pack_start(labelalign, False, False)
+	self.usedPercentLabel = gtk.Label("")
+	labelalign = gtk.Alignment()
+	labelalign.set(1.0, 0.5, 0.0, 0.0)
+	labelalign.add(self.usedPercentLabel)
+	lbox.pack_start(labelalign, False, False, padding=10)
+        maintable.attach(lbox, 1, 2, row, row + 1, gtk.EXPAND|gtk.FILL, gtk.SHRINK)
+	maintable.set_row_spacing(row, 0)
+        row = row + 1
+
+        maintable.attach(createAlignedLabel(_("Free Space:")), 0, 1, row,
+			 row + 1, gtk.EXPAND|gtk.FILL, gtk.SHRINK)
+	lbox = gtk.HBox()
+	self.freeSpaceLabel = gtk.Label("")
+	labelalign = gtk.Alignment()
+	labelalign.set(1.0, 0.5, 0.0, 0.0)
+	labelalign.add(self.freeSpaceLabel)
+	lbox.pack_start(labelalign, False, False)
+	self.freePercentLabel = gtk.Label("")
+	labelalign = gtk.Alignment()
+	labelalign.set(1.0, 0.5, 0.0, 0.0)
+	labelalign.add(self.freePercentLabel)
+	lbox.pack_start(labelalign, False, False, padding=10)
+
+        maintable.attach(lbox, 1, 2, row, row + 1, gtk.EXPAND|gtk.FILL, gtk.SHRINK)
+	maintable.set_row_spacing(row, 0)
+        row = row + 1
+
+        maintable.attach(createAlignedLabel(_("Total Space:")), 0, 1, row,
+			 row + 1, gtk.EXPAND|gtk.FILL, gtk.SHRINK)
+	self.totalSpaceLabel = gtk.Label("")
+	labelalign = gtk.Alignment()
+	labelalign.set(0.0, 0.5, 0.0, 0.0)
+	labelalign.add(self.totalSpaceLabel)
+        maintable.attach(labelalign, 1, 2, row, row + 1, gtk.EXPAND|gtk.FILL, gtk.SHRINK)
+	maintable.set_row_spacing(row, 5)
+        row = row + 1
+
+	# populate list of logical volumes
+        lvtable = gtk.Table()
+        lvtable.set_row_spacings(5)
+        lvtable.set_col_spacings(5)
+	self.logvolstore = gtk.ListStore(gobject.TYPE_STRING,
+				      gobject.TYPE_STRING,
+				      gobject.TYPE_STRING)
+	
+	if self.vg.lvs:
+	    for lv in self.vg.lvs:
+		iter = self.logvolstore.append()
+		self.logvolstore.set_value(iter, 0, lv.lvname)
+                if lv.format.type == "luks":
+                    try:
+                        format = self.storage.devicetree.getChildren(lv)[0].format
+                    except IndexError:
+                        format = lv.format
+                else:
+                    format = lv.format
+
+                if getattr(format, "mountpoint", None):
+		    self.logvolstore.set_value(iter, 1,
+                                               format.mountpoint)
+		else:
+		    self.logvolstore.set_value(iter, 1, "")
+		self.logvolstore.set_value(iter, 2, "%Ld" % lv.size)
+
+	self.logvollist = gtk.TreeView(self.logvolstore)
+        col = gtk.TreeViewColumn(_("Logical Volume Name"),
+				 gtk.CellRendererText(), text=0)
+        self.logvollist.append_column(col)
+        col = gtk.TreeViewColumn(_("Mount Point"),
+				 gtk.CellRendererText(), text=1)
+        self.logvollist.append_column(col)
+        col = gtk.TreeViewColumn(_("Size (MB)"),
+				 gtk.CellRendererText(), text=2)
+        self.logvollist.append_column(col)
+        self.logvollist.connect('row-activated', self.logvolActivateCb)
+
+        sw = gtk.ScrolledWindow()
+        sw.add(self.logvollist)
+        sw.set_size_request(100, 100)
+        sw.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
+	sw.set_shadow_type(gtk.SHADOW_IN)
+        lvtable.attach(sw, 0, 1, 0, 1)
+
+	# button box of options
+	lvbbox = gtk.VBox()
+        add = gtk.Button(_("_Add"))
+        add.connect("clicked", self.addLogicalVolumeCB)
+	lvbbox.pack_start(add)
+        edit = gtk.Button(_("_Edit"))
+        edit.connect("clicked", self.editLogicalVolumeCB)
+	lvbbox.pack_start(edit)
+        delete = gtk.Button(_("_Delete"))
+        delete.connect("clicked", self.delLogicalVolumeCB)
+	lvbbox.pack_start(delete)
+
+	lvalign = gtk.Alignment()
+	lvalign.set(0.5, 0.0, 0.0, 0.0)
+	lvalign.add(lvbbox)
+        lvtable.attach(lvalign, 1, 2, 0, 1, gtk.SHRINK, gtk.SHRINK)
+
+	# pack all logical volumne stuff in a frame
+	lvtable.set_border_width(12)
+        l = gtk.Label()
+        l.set_markup_with_mnemonic("<b>%s</b>" %(_("_Logical Volumes"),))
+        l.set_mnemonic_widget(self.logvollist)
+	frame = gtk.Frame()
+        frame.set_label_widget(l)
+	frame.add(lvtable)
+        frame.set_shadow_type(gtk.SHADOW_NONE)
+
+#	dialog.vbox.pack_start(frame)
+	maintable.attach(frame, 0, 2, row, row+1)
+	row = row + 1
+	
+        dialog.vbox.pack_start(maintable)
+	dialog.set_size_request(550, 450)
+        dialog.show_all()
+
+	# set space labels to correct values
+	self.updateVGSpaceLabels()
+
+	self.dialog = dialog
diff --git a/pyanaconda/iw/netconfig_dialog.py b/pyanaconda/iw/netconfig_dialog.py
new file mode 100644
index 0000000..336cf0e
--- /dev/null
+++ b/pyanaconda/iw/netconfig_dialog.py
@@ -0,0 +1,329 @@
+#
+# netconfig_dialog.py: Configure a network interface now.
+#
+# Copyright (C) 2006  Red Hat, Inc.  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 as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# 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, see <http://www.gnu.org/licenses/>.
+#
+# Author(s): Jeremy Katz <katzj@xxxxxxxxxx>
+#
+
+import gtk
+import gobject
+import gui
+
+from constants import *
+import gettext
+_ = lambda x: gettext.ldgettext("anaconda", x)
+
+import network
+import isys
+
+class NetworkConfigurator:
+    def __init__(self, network):
+        (xml, w) = gui.getGladeWidget("netconfig.glade", "NetworkConfigWindow")
+
+        self.window = w
+        self.network = network
+        self.xml = xml
+        self.rc = gtk.RESPONSE_CANCEL
+
+        self._setSizeGroup()
+        self._connectSignals()
+        self._populateNetdevs()
+
+        self.xml.get_widget("ipv4Checkbutton").set_active(True)
+        self.xml.get_widget("ipv6Checkbutton").set_active(False)
+
+    def _connectSignals(self):
+        sigs = { "on_ipv4Checkbutton_toggled": self._ipv4Toggled,
+                 "on_ipv6Checkbutton_toggled": self._ipv6Toggled,
+                 "on_dhcpCheckbutton_toggled": self._dhcpToggled,
+                 "on_interfaceCombo_changed": self._netdevChanged,
+                 "on_cancelButton_clicked": self._cancel,
+                 "on_okButton_clicked": self._ok }
+        self.xml.signal_autoconnect(sigs)
+
+    def _setSizeGroup(self): # too bad we can't do this in the glade file
+        sg = gtk.SizeGroup(gtk.SIZE_GROUP_HORIZONTAL)
+        for w in ("nameserverLabel", "gatewayLabel", "ipv6Label",
+                  "ipv4Label", "interfaceLabel"):
+            sg.add_widget(self.xml.get_widget(w))
+
+    def _netdevChanged(self, combo):
+        active = combo.get_active_iter()
+        val = combo.get_model().get_value(active, 1)
+        netdev = self.network.available()[val]
+
+        bootproto = netdev.get("BOOTPROTO")
+        if not bootproto or bootproto == "dhcp" or bootproto == "ibft":
+            self.xml.get_widget("dhcpCheckbutton").set_active(True)
+        else:
+            self.xml.get_widget("dhcpCheckbutton").set_active(False)
+
+            # FIXME: need to set ipv6 here too once we have that
+            try:
+                if netdev.get('IPADDR'):
+                    self.xml.get_widget("ipv4Address").set_text(netdev.get('IPADDR'))
+            except:
+                pass
+
+            try:
+                if netdev.get('NETMASK'):
+                    self.xml.get_widget("ipv4Netmask").set_text(netdev.get('NETMASK'))
+            except:
+                pass
+
+            try:
+                if self.network.gateway:
+                    self.xml.get_widget("gatewayEntry").set_text(self.network.gateway)
+            except:
+                pass
+
+            try:
+                if self.network.primaryNS:
+                    self.xml.get_widget("nameserverEntry").set_text(self.network.primaryNS)
+            except:
+                pass
+
+    def _ipv4Toggled(self, cb):
+        if self.xml.get_widget("dhcpCheckbutton").get_active():
+            return
+        if cb.get_active():
+            self.xml.get_widget("ipv4Box").set_sensitive(True)
+        else:
+            self.xml.get_widget("ipv4Box").set_sensitive(False)
+
+    def _ipv6Toggled(self, cb):
+        if self.xml.get_widget("dhcpCheckbutton").get_active():
+            return
+        if cb.get_active():
+            self.xml.get_widget("ipv6Box").set_sensitive(True)
+        else:
+            self.xml.get_widget("ipv6Box").set_sensitive(False)
+
+    def _dhcpToggled(self, cb):
+        boxes = ("ipv4Box", "ipv6Box", "nameserverBox", "gatewayBox")
+        if not cb.get_active():
+            map(lambda x: self.xml.get_widget(x).set_sensitive(True), boxes)
+            self.xml.get_widget("ipv4Box").set_sensitive(self.xml.get_widget("ipv4Checkbutton").get_active())
+            self.xml.get_widget("ipv6Box").set_sensitive(self.xml.get_widget("ipv6Checkbutton").get_active())
+        else:
+            map(lambda x: self.xml.get_widget(x).set_sensitive(False), boxes)
+
+    def _populateNetdevs(self):
+        combo = self.xml.get_widget("interfaceCombo")
+
+        cell = gtk.CellRendererText()
+        combo.pack_start(cell, True)
+        combo.set_attributes(cell, text = 0)
+        cell.set_property("wrap-width", 525)
+        combo.set_size_request(480, -1)
+
+        store = gtk.TreeStore(gobject.TYPE_STRING, gobject.TYPE_STRING)
+        combo.set_model(store)
+
+        netdevs = self.network.available()
+        devs = netdevs.keys()
+        devs.sort()
+        ksdevice = self.network.getKSDevice()
+        if ksdevice:
+            ksdevice = ksdevice.get('DEVICE')
+        selected_interface = None
+
+        for dev in devs:
+            i = store.append(None)
+            hwaddr = netdevs[dev].get("HWADDR")
+
+            if hwaddr:
+                desc = "%s - %s" %(dev, hwaddr,)
+            else:
+                desc = "%s" %(dev,)
+
+            if selected_interface is None:
+                selected_interface = i
+
+            if ksdevice and ksdevice == dev:
+                selected_interface = i
+
+            store[i] = (desc, dev)
+
+        if selected_interface:
+            combo.set_active_iter(selected_interface)
+        else:
+            combo.set_active(0)
+
+    def run(self):
+        gui.addFrame(self.window)
+        busycursor = gui.getBusyCursorStatus()
+        gui.setCursorToNormal()
+
+        self.window.show()
+        while True:
+            rc = self.window.run()
+            if rc in [gtk.RESPONSE_CANCEL, gtk.RESPONSE_DELETE_EVENT]:
+                self._cancel()
+                break
+            if self._ok():
+                break
+
+        # restore busy cursor
+        if busycursor:
+            gui.setCursorToBusy()
+        return self.rc
+
+    def destroy(self):
+        self.window.destroy()
+
+    def _handleIPError(self, field, errmsg):
+        d = gtk.MessageDialog(None, 0, gtk.MESSAGE_ERROR,
+                              gtk.BUTTONS_OK,
+                                _("An error occurred converting the value "
+                                  "entered for \"%(field)s\":\n%(errmsg)s")
+                                % {'field': field, 'errmsg': errmsg})
+        d.set_title(_("Error With Data"))
+        d.set_position(gtk.WIN_POS_CENTER)
+        gui.addFrame(d)
+        d.run()
+        d.destroy()
+
+    def _handleIPMissing(self, field):
+        d = gtk.MessageDialog(None, 0, gtk.MESSAGE_ERROR, gtk.BUTTONS_OK,
+                         _("A value is required for the field %s.") % (field,))
+        d.set_title(_("Error With Data"))
+        d.set_position(gtk.WIN_POS_CENTER)
+        gui.addFrame(d)
+        d.run()
+        d.destroy()
+
+    def _handleNetworkError(self, field):
+        d = gtk.MessageDialog(None, 0, gtk.MESSAGE_ERROR,
+                              gtk.BUTTONS_OK,
+                              _("An error occurred trying to bring up the "
+                                "%s network interface.") % (field,))
+        d.set_title(_("Error Configuring Network"))
+        d.set_position(gtk.WIN_POS_CENTER)
+        gui.addFrame(d)
+        d.run()
+        d.destroy()
+
+    def _cancel(self, *args):
+        self.rc = gtk.RESPONSE_CANCEL
+
+    def _ok(self, *args):
+        self.rc = gtk.RESPONSE_OK
+        haveNet = False
+        combo = self.xml.get_widget("interfaceCombo")
+        active = combo.get_active_iter()
+        val = combo.get_model().get_value(active, 1)
+        for v, dev in self.network.available().items():
+            if v == val:
+                dev.set(('ONBOOT', 'yes'))
+                netdev = dev
+            else:
+                dev.set(('ONBOOT', 'no'))
+
+        # FIXME: need to do input validation
+        if self.xml.get_widget("dhcpCheckbutton").get_active():
+            netdev.set(('BOOTPROTO', 'dhcp'))
+            self.window.hide()
+            w = gui.WaitWindow(_("Dynamic IP Address"),
+                               _("Sending request for IP address information "
+                                 "for %s") % (netdev.get('DEVICE'),))
+            haveNet = self.network.bringUp(devices=[netdev])
+            w.pop()
+        else:
+            netdev.set(('BOOTPROTO', 'static'))
+            ipv4addr = self.xml.get_widget("ipv4Address").get_text()
+            ipv4nm = self.xml.get_widget("ipv4Netmask").get_text()
+            gateway = self.xml.get_widget("gatewayEntry").get_text()
+            ns = self.xml.get_widget("nameserverEntry").get_text()
+
+            try:
+                network.sanityCheckIPString(ipv4addr)
+                netdev.set(('IPADDR', ipv4addr))
+            except network.IPMissing, msg:
+                self._handleIPMissing(_("IP Address"))
+                return False
+            except network.IPError, msg:
+                self._handleIPError(_("IP Address"), msg)
+                return False
+
+            if ipv4nm.find('.') == -1:
+                # user provided a CIDR prefix
+                try:
+                    if int(ipv4nm) > 32 or int(ipv4nm) < 0:
+                        msg = _("IPv4 CIDR prefix must be between 0 and 32.")
+                        self._handleIPError(_("IPv4 Network Mask"), msg)
+                        return False
+                    else:
+                        ipv4nm = isys.prefix2netmask(int(ipv4nm))
+                        netdev.set(('NETMASK', ipv4nm))
+                except:
+                    self._handleIPMissing(_("IPv4 Network Mask"))
+                    return False
+            else:
+                # user provided a dotted-quad netmask
+                try:
+                    network.sanityCheckIPString(ipv4nm)
+                    netdev.set(('NETMASK', ipv4nm))
+                except network.IPMissing, msg:
+                    self._handleIPMissing(_("IPv4 Network Mask"))
+                    return False
+                except network.IPError, msg:
+                    self._handleIPError(_("IPv4 Network Mask"), msg)
+                    return False
+
+            try:
+                if gateway:
+                    network.sanityCheckIPString(gateway)
+                    netdev.set(('GATEWAY', gateway))
+            except network.IPMissing, msg:
+                pass
+            except network.IPError, msg:
+                self._handleIPError(_("Gateway"), msg)
+                return False
+
+            try:
+                if ns:
+                    network.sanityCheckIPString(ns)
+                    netdev.set(('DNS1', ns))
+            except network.IPMissing, msg:
+                pass
+            except network.IPError, msg:
+                self._handleIPError(_("Nameserver"), msg)
+                return False
+
+            try:
+                haveNet = self.network.bringUp(devices=[netdev])
+            except Exception, e:
+                import logging
+                log = logging.getLogger("anaconda")
+                log.error("Error configuring network device: %s" %(e,))
+                self._handleIPError(_("Error configuring network device:"), e)
+                return False
+
+        if not haveNet:
+            self._handleNetworkError(netdev.get('DEVICE'))
+            return False
+
+        return True
+
+def main():
+    net = network.Network()
+    d = NetworkConfigurator(net)
+    ret = d.run()
+
+if __name__ == "__main__":
+    main()
diff --git a/pyanaconda/iw/network_gui.py b/pyanaconda/iw/network_gui.py
new file mode 100644
index 0000000..4d8e5da
--- /dev/null
+++ b/pyanaconda/iw/network_gui.py
@@ -0,0 +1,106 @@
+#
+# network_gui.py: Network configuration dialog
+#
+# Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006,  Red Hat, Inc.
+#               2007, 2008, 2009
+#
+# 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; either version 2 of the License, or
+# (at your option) any later version.
+#
+# 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, see <http://www.gnu.org/licenses/>.
+#
+# Author(s): Michael Fulbright <msf@xxxxxxxxxx>
+#            David Cantrell <dcantrell@xxxxxxxxxx>
+#
+
+import string
+from iw_gui import *
+import gui
+import network
+import iutil
+import gobject
+import subprocess
+
+from constants import *
+import gettext
+_ = lambda x: gettext.ldgettext("anaconda", x)
+
+class NetworkWindow(InstallWindow):
+    def getScreen(self, anaconda):
+        self.intf = anaconda.intf
+        self.anaconda = anaconda
+        self.hostname = network.getDefaultHostname(anaconda)
+
+        # load the UI
+        (self.xml, self.align) = gui.getGladeWidget("network.glade",
+                                                    "network_align")
+        self.icon = self.xml.get_widget("icon")
+        self.hostnameEntry = self.xml.get_widget("hostnameEntry")
+        self.hostnameEntry.set_text(self.hostname)
+
+        self.xml.get_widget("netconfButton").connect("clicked", self._NMConfig)
+
+        # pressing Enter in confirm == clicking Next
+        self.hostnameEntry.connect("activate",
+                                   lambda w: self.ics.setGrabNext(1))
+
+        # load the icon
+        gui.readImageFromFile("network.png", image=self.icon)
+
+        return self.align
+
+    def focus(self):
+        self.hostnameEntry.grab_focus()
+
+    def hostnameError(self):
+        self.hostnameEntry.grab_focus()
+        raise gui.StayOnScreen
+
+    def getNext(self):
+        hostname = string.strip(self.hostnameEntry.get_text())
+        herrors = network.sanityCheckHostname(hostname)
+
+        if not hostname:
+            self.intf.messageWindow(_("Error with Hostname"),
+                                    _("You must enter a valid hostname for this "
+                                      "computer."), custom_icon="error")
+            self.hostnameError()
+
+        if herrors is not None:
+            self.intf.messageWindow(_("Error with Hostname"),
+                                    _("The hostname \"%(hostname)s\" is not "
+                                      "valid for the following reason:\n\n"
+                                      "%(herrors)s")
+                                    % {'hostname': hostname,
+                                       'herrors': herrors},
+                                    custom_icon="error")
+            self.hostnameError()
+
+        self.anaconda.network.hostname = hostname
+        return None
+
+    def _NMExited(self, pid, condition, data):
+        self.intf.icw.window.set_sensitive(True)
+
+    def _NMConfig(self, *args):
+
+        self.intf.icw.window.set_sensitive(False)
+        cmd = ["/usr/bin/nm-connection-editor"]
+        out = open("/dev/tty5", "w")
+        try:
+            proc = subprocess.Popen(cmd, stdout=out, stderr=out)
+        except Exception as e:
+            self.intf.icw.window.set_sensitive(True)
+            import logging
+            log = logging.getLogger("anaconda")
+            log.error("Could not start nm-connection-editor: %s" % e)
+        else:
+            gobject.child_watch_add(proc.pid, self._NMExited, data=None, priority=gobject.PRIORITY_DEFAULT)
diff --git a/pyanaconda/iw/osbootwidget.py b/pyanaconda/iw/osbootwidget.py
new file mode 100644
index 0000000..8c89d43
--- /dev/null
+++ b/pyanaconda/iw/osbootwidget.py
@@ -0,0 +1,397 @@
+#
+# osbootwidget.py: gui bootloader list of operating systems to boot
+#
+# Copyright (C) 2001, 2002  Red Hat, Inc.  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 as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# 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, see <http://www.gnu.org/licenses/>.
+#
+# Author(s): Jeremy Katz <katzj@xxxxxxxxxx>
+#
+
+import gtk
+import gobject
+import iutil
+import parted
+import gui
+import datacombo
+from constants import *
+from storage.devices import devicePathToName
+
+import gettext
+_ = lambda x: gettext.ldgettext("anaconda", x)
+
+class OSBootWidget:
+    """Widget to display OSes to boot and allow adding new ones."""
+    
+    def __init__(self, anaconda, parent, blname = None):
+        self.bl = anaconda.bootloader
+        self.storage = anaconda.storage
+        self.parent = parent
+        self.intf = anaconda.intf
+        if blname is not None:
+            self.blname = blname
+        else:
+            self.blname = "GRUB"
+
+        self.setIllegalChars()
+        
+        self.vbox = gtk.VBox(False, 5)
+        label = gtk.Label("<b>" + _("Boot loader operating system list") + "</b>")
+	label.set_alignment(0.0, 0.0)
+        label.set_property("use-markup", True)
+        self.vbox.pack_start(label, False)
+
+        box = gtk.HBox (False, 5)
+        sw = gtk.ScrolledWindow()
+        sw.set_shadow_type(gtk.SHADOW_ETCHED_IN)
+        sw.set_policy(gtk.POLICY_NEVER, gtk.POLICY_AUTOMATIC)
+        sw.set_size_request(300, 100)
+        box.pack_start(sw, True)
+
+
+        self.osStore = gtk.ListStore(gobject.TYPE_BOOLEAN, gobject.TYPE_STRING,
+                                     gobject.TYPE_STRING, gobject.TYPE_BOOLEAN)
+        self.osTreeView = gtk.TreeView(self.osStore)
+        theColumns = [ _("Default"), _("Label"), _("Device") ]
+
+        self.checkboxrenderer = gtk.CellRendererToggle()
+        column = gtk.TreeViewColumn(theColumns[0], self.checkboxrenderer,
+                                    active = 0)
+        column.set_sizing(gtk.TREE_VIEW_COLUMN_AUTOSIZE)
+        self.checkboxrenderer.connect("toggled", self.toggledDefault)
+        self.checkboxrenderer.set_radio(True)
+        self.osTreeView.append_column(column)
+
+        for columnTitle in theColumns[1:]:
+            renderer = gtk.CellRendererText()
+            column = gtk.TreeViewColumn(columnTitle, renderer,
+                                        text = theColumns.index(columnTitle))
+            column.set_clickable(False)
+            self.osTreeView.append_column(column)
+
+        self.osTreeView.set_headers_visible(True)
+        self.osTreeView.columns_autosize()
+        self.osTreeView.set_size_request(100, 100)
+        sw.add(self.osTreeView)
+        self.osTreeView.connect('row-activated', self.osTreeActivateCb)
+
+        self.imagelist = self.bl.images.getImages()
+        self.defaultDev = self.bl.images.getDefault()
+        self.fillOSList()
+
+        buttonbar = gtk.VButtonBox()
+        buttonbar.set_layout(gtk.BUTTONBOX_START)
+        buttonbar.set_border_width(5)
+        add = gtk.Button(_("_Add"))
+        buttonbar.pack_start(add, False)
+        add.connect("clicked", self.addEntry)
+
+        edit = gtk.Button(_("_Edit"))
+        buttonbar.pack_start(edit, False)
+        edit.connect("clicked", self.editEntry)
+
+        delete = gtk.Button(_("_Delete"))
+        buttonbar.pack_start(delete, False)
+        delete.connect("clicked", self.deleteEntry)
+        box.pack_start(buttonbar, False)
+
+        self.vbox.pack_start(box, False)
+
+        self.widget = self.vbox
+
+    def setIllegalChars(self):
+        # illegal characters for boot loader labels
+        if self.blname == "GRUB":
+            self.illegalChars = [ "$", "=" ]
+        else:
+            self.illegalChars = [ "$", "=", " " ]
+
+    def changeBootLoader(self, blname):
+        if blname is not None:
+            self.blname = blname
+        else:
+            self.blname = "GRUB"
+        self.setIllegalChars()
+        self.fillOSList()
+
+    # adds/edits a new "other" os to the boot loader config
+    def editOther(self, oldDevice, oldLabel, isDefault, isRoot = 0):
+        dialog = gtk.Dialog(_("Image"), self.parent)
+        dialog.add_button('gtk-cancel', gtk.RESPONSE_CANCEL)
+        dialog.add_button('gtk-ok', 1)
+        dialog.set_position(gtk.WIN_POS_CENTER)
+        gui.addFrame(dialog)
+
+        dialog.vbox.pack_start(gui.WrappingLabel(
+            _("Enter a label for the boot loader menu to display. The "
+	      "device (or hard drive and partition number) is the device "
+	      "from which it boots.")))
+
+        table = gtk.Table(2, 5)
+        table.set_row_spacings(5)
+        table.set_col_spacings(5)
+
+        label = gui.MnemonicLabel(_("_Label"))
+        table.attach(label, 0, 1, 1, 2, gtk.FILL, 0, 10)
+        labelEntry = gtk.Entry(32)
+        label.set_mnemonic_widget(labelEntry)
+        table.attach(labelEntry, 1, 2, 1, 2, gtk.FILL, 0, 10)
+        if oldLabel:
+            labelEntry.set_text(oldLabel)
+
+        label = gui.MnemonicLabel(_("_Device"))
+        table.attach(label, 0, 1, 2, 3, gtk.FILL, 0, 10)
+        if not isRoot:
+            parts = []
+
+            for part in self.storage.partitions:
+                if part.partedPartition.getFlag(parted.PARTITION_LVM) or \
+                   part.partedPartition.getFlag(parted.PARTITION_RAID) or \
+                   not part.partedPartition.active:
+                    continue
+
+                parts.append(part)
+
+            deviceCombo = datacombo.DataComboBox()
+            defindex = 0
+            i = 0
+            for part in parts:
+                deviceCombo.append(part.path, part.name)
+                if oldDevice and oldDevice == part.name:
+                    defindex = i
+                i = i + 1
+
+
+            deviceCombo.set_active(defindex)
+            
+            table.attach(deviceCombo, 1, 2, 2, 3, gtk.FILL, 0, 10)
+            label.set_mnemonic_widget(deviceCombo)
+        else:
+            table.attach(gtk.Label(oldDevice), 1, 2, 2, 3, gtk.FILL, 0, 10)
+
+        default = gtk.CheckButton(_("Default Boot _Target"))
+        table.attach(default, 0, 2, 3, 4, gtk.FILL, 0, 10)
+        if isDefault != 0:
+            default.set_active(True)
+
+        if self.numentries == 1 and oldDevice != None:
+            default.set_sensitive(False)
+        else:
+            default.set_sensitive(True)
+        
+        dialog.vbox.pack_start(table)
+        dialog.show_all()
+
+        while 1:
+            rc = dialog.run()
+
+            # cancel
+            if rc in [gtk.RESPONSE_CANCEL, gtk.RESPONSE_DELETE_EVENT]:
+                break
+
+            label = labelEntry.get_text()
+
+            if not isRoot:
+                dev = deviceCombo.get_active_value()
+            else:
+                dev = oldDevice
+
+            if not label:
+                self.intf.messageWindow(_("Error"),
+                                        _("You must specify a label for the "
+                                          "entry"),
+                                        type="warning")
+                continue
+
+            foundBad = 0
+            for char in self.illegalChars:
+                if char in label:
+                    self.intf.messageWindow(_("Error"),
+                                            _("Boot label contains illegal "
+                                              "characters"),
+                                            type="warning")
+                    foundBad = 1
+                    break
+            if foundBad:
+                continue
+
+            # verify that the label hasn't been used
+            foundBad = 0
+            for key in self.imagelist.keys():
+                if dev == key:
+                    continue
+                if self.blname == "GRUB":
+                    thisLabel = self.imagelist[key][1]
+                else:
+                    thisLabel = self.imagelist[key][0]
+
+                # if the label is the same as it used to be, they must
+                # have changed the device which is fine
+                if thisLabel == oldLabel:
+                    continue
+
+                if thisLabel == label:
+                    self.intf.messageWindow(_("Duplicate Label"),
+                                            _("This label is already in "
+                                              "use for another boot entry."),
+                                            type="warning")
+                    foundBad = 1
+                    break
+            if foundBad:
+                continue
+
+            # XXX need to do some sort of validation of the device?
+
+            # they could be duplicating a device, which we don't handle
+            if dev in self.imagelist.keys() and (not oldDevice or
+                                                 dev != oldDevice):
+                self.intf.messageWindow(_("Duplicate Device"),
+                                        _("This device is already being "
+                                          "used for another boot entry."),
+                                        type="warning")
+                continue
+
+            # if we're editing a previous, get what the old info was for
+            # labels.  otherwise, make it something safe for grub and the
+            # device name for lilo for lack of any better ideas
+            if oldDevice:
+                (oldshort, oldlong, oldisroot) = self.imagelist[oldDevice]
+            else:
+                (oldshort, oldlong, oldisroot) = (dev, label, None)
+                
+            # if we're editing and the device has changed, delete the old
+            if oldDevice and dev != oldDevice:
+                del self.imagelist[oldDevice]
+                
+            # go ahead and add it
+            if self.blname == "GRUB":
+                self.imagelist[dev] = (oldshort, label, isRoot)
+            else:
+                self.imagelist[dev] = (label, oldlong, isRoot)
+
+            if default.get_active():
+                self.defaultDev = dev
+
+            # refill the os list store
+            self.fillOSList()
+            break
+        
+        dialog.destroy()
+
+    def getSelected(self):
+        selection = self.osTreeView.get_selection()
+        (model, iter) = selection.get_selected()
+        if not iter:
+            return None
+
+        dev = devicePathToName(model.get_value(iter, 2))
+        label = model.get_value(iter, 1)
+        isRoot = model.get_value(iter, 3)
+        isDefault = model.get_value(iter, 0)
+        return (dev, label, isDefault, isRoot)
+
+
+    def addEntry(self, widget, *args):
+        self.editOther(None, None, 0)
+
+    def deleteEntry(self, widget, *args):
+        rc = self.getSelected()
+        if not rc:
+            return
+        (dev, label, isDefault, isRoot) = rc
+        if not isRoot:
+            del self.imagelist[dev]
+            if isDefault:
+                keys = self.imagelist.keys()
+                keys.sort()
+                self.defaultDev = keys[0]
+                
+            self.fillOSList()
+        else:
+            self.intf.messageWindow(_("Cannot Delete"),
+                                    _("This boot target cannot be deleted "
+				      "because it is for the %s "
+				      "system you are about to install.")
+                                    %(productName,),
+                                      type="warning")
+
+    def editEntry(self, widget, *args):
+        rc = self.getSelected()
+        if not rc:
+            return
+        (dev, label, isDefault, isRoot) = rc
+        self.editOther(dev, label, isDefault, isRoot)
+
+    # the default os was changed in the treeview
+    def toggledDefault(self, data, row):
+        iter = self.osStore.get_iter((int(row),))
+        dev = self.osStore.get_value(iter, 2)
+        self.defaultDev = devicePathToName(dev)
+        self.fillOSList()
+
+    # fill in the os list tree view
+    def fillOSList(self):
+        self.osStore.clear()
+        
+        keys = self.imagelist.keys()
+        keys.sort()
+
+        for dev in keys:
+            (label, longlabel, fstype) = self.imagelist[dev]
+            device = self.storage.devicetree.getDeviceByName(dev)
+            if self.blname == "GRUB":
+                theLabel = longlabel
+            else:
+                theLabel = label
+
+            # if the label is empty, remove from the image list and don't
+            # worry about it
+            if not theLabel:
+                del self.imagelist[dev]
+                continue
+
+	    isRoot = 0
+            rootDev = self.storage.rootDevice
+            if rootDev and rootDev.name == dev:
+		isRoot = 1
+
+            devPath = getattr(device, "path", "/dev/%s" % dev)
+            iter = self.osStore.append()
+            self.osStore.set_value(iter, 1, theLabel)
+            self.osStore.set_value(iter, 2, devPath)
+            self.osStore.set_value(iter, 3, isRoot)
+            if self.defaultDev == dev:
+                self.osStore.set_value(iter, 0, True)
+            else:
+                self.osStore.set_value(iter, 0, False)
+
+        self.numentries = len(keys)
+
+    def osTreeActivateCb(self, view, path, col):
+        self.editEntry(view)
+        
+        
+    def getWidget(self):
+        return self.widget
+
+    # FIXME: I really shouldn't have such intimate knowledge of
+    # the bootloader object
+    def setBootloaderImages(self):
+        "Apply the changes from our list into the self.bl object"
+        # make a copy of our image list to shove into the bl struct
+        self.bl.images.images = {}
+        for key in self.imagelist.keys():
+            self.bl.images.images[key] = self.imagelist[key]
+        self.bl.images.setDefault(self.defaultDev)
+        
diff --git a/pyanaconda/iw/package_gui.py b/pyanaconda/iw/package_gui.py
new file mode 100644
index 0000000..4e6bfbe
--- /dev/null
+++ b/pyanaconda/iw/package_gui.py
@@ -0,0 +1,39 @@
+#
+# package_gui.py: package group selection screen
+#
+# Copyright (C) 2005  Red Hat, Inc.  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 as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# 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, see <http://www.gnu.org/licenses/>.
+#
+# Author(s): Jeremy Katz <katzj@xxxxxxxxxx>
+#
+
+# FIXME: group selection isn't currently backend independent
+from GroupSelector import GroupSelector
+
+import gui
+from iw_gui import *
+
+from constants import *
+import gettext
+_ = lambda x: gettext.ldgettext("anaconda", x)
+
+class GroupSelectionWindow (InstallWindow):
+    def getScreen(self, anaconda):
+        self.backend = anaconda.backend
+        self.intf = anaconda.intf
+        self.grpsel = GroupSelector(self.backend.ayum, gui.findGladeFile,
+                                    gui.addFrame)
+        self.grpsel.doRefresh()
+        return self.grpsel.vbox
diff --git a/pyanaconda/iw/partition_dialog_gui.py b/pyanaconda/iw/partition_dialog_gui.py
new file mode 100644
index 0000000..9279636
--- /dev/null
+++ b/pyanaconda/iw/partition_dialog_gui.py
@@ -0,0 +1,534 @@
+#
+# partition_dialog_gui.py: dialog for editting a partition request
+#
+# Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007  Red Hat, Inc.
+# 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 as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# 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, see <http://www.gnu.org/licenses/>.
+#
+# Author(s): Michael Fulbright <msf@xxxxxxxxxx>
+#
+
+import copy
+
+import gobject
+import gtk
+
+import gui
+from storage.devices import PartitionDevice, LUKSDevice
+from storage.deviceaction import *
+from partition_ui_helpers_gui import *
+from constants import *
+
+import gettext
+_ = lambda x: gettext.ldgettext("anaconda", x)
+
+class PartitionEditor:
+    def sizespinchangedCB(self, widget, fillmaxszsb):
+	size = widget.get_value_as_int()
+	maxsize = fillmaxszsb.get_value_as_int()
+        if size < 1:
+            widget.set_value(1)
+            size = 1
+	if size > maxsize:
+	    fillmaxszsb.set_value(size)
+
+	# ugly got to be better way
+	adj = fillmaxszsb.get_adjustment()
+	adj.clamp_page(size, adj.upper)
+	fillmaxszsb.set_adjustment(adj)
+
+    def fillmaxszCB(self, widget, spin):
+	spin.set_sensitive(widget.get_active())
+
+    # pass in CB defined above because of two scope limitation of python!
+    def createSizeOptionsFrame(self, request, fillmaxszCB):
+	frame = gtk.Frame(_("Additional Size Options"))
+	sizeoptiontable = gtk.Table()
+	sizeoptiontable.set_row_spacings(5)
+	sizeoptiontable.set_border_width(4)
+
+	fixedrb     = gtk.RadioButton(label=_("_Fixed size"))
+	fillmaxszrb = gtk.RadioButton(group=fixedrb,
+				      label=_("Fill all space _up "
+					      "to (MB):"))
+	maxsizeAdj = gtk.Adjustment(value = 1, lower = 1,
+				    upper = MAX_PART_SIZE, step_incr = 1)
+	fillmaxszsb = gtk.SpinButton(maxsizeAdj, digits = 0)
+	fillmaxszsb.set_property('numeric', True)
+	fillunlimrb = gtk.RadioButton(group=fixedrb,
+				     label=_("Fill to maximum _allowable "
+					     "size"))
+
+	fillmaxszrb.connect("toggled", fillmaxszCB, fillmaxszsb)
+
+	# default to fixed, turn off max size spinbutton
+	fillmaxszsb.set_sensitive(0)
+	if request.req_grow:
+	    if request.req_max_size:
+		fillmaxszrb.set_active(1)
+		fillmaxszsb.set_sensitive(1)
+		fillmaxszsb.set_value(request.req_max_size)
+	    else:
+		fillunlimrb.set_active(1)
+	else:
+	    fixedrb.set_active(1)
+
+	sizeoptiontable.attach(fixedrb, 0, 1, 0, 1)
+	sizeoptiontable.attach(fillmaxszrb, 0, 1, 1, 2)
+	sizeoptiontable.attach(fillmaxszsb, 1, 2, 1, 2)
+	sizeoptiontable.attach(fillunlimrb, 0, 1, 2, 3)
+
+	frame.add(sizeoptiontable)
+
+	return (frame, fixedrb, fillmaxszrb, fillmaxszsb)
+
+
+    def run(self):
+	if self.dialog is None:
+	    return []
+
+        while 1:
+            rc = self.dialog.run()
+            actions = []
+            luksdev = None
+	    
+            # user hit cancel, do nothing
+            if rc in [gtk.RESPONSE_CANCEL, gtk.RESPONSE_DELETE_EVENT]:
+                self.destroy()
+                return []
+
+            mountpoint = self.mountCombo.get_children()[0].get_text()
+            if mountpoint == _("<Not Applicable>"):
+                mountpoint = ""
+
+            if mountpoint:
+                used = False
+                for (mp, dev) in self.storage.mountpoints.iteritems():
+                    if mp == mountpoint and \
+                       dev.id != self.origrequest.id and \
+                       not (self.origrequest.format.type == "luks" and
+                            self.origrequest in dev.parents):
+                        used = True
+                        break
+
+                if used:
+                    self.intf.messageWindow(_("Mount point in use"),
+                                            _("The mount point \"%s\" is in "
+                                              "use. Please pick another.") %
+                                            (mountpoint,),
+                                            custom_icon="error")
+                    continue
+
+            if not self.origrequest.exists:
+                # read out UI into a partition specification
+                fmt_class = self.newfstypeCombo.get_active_value()
+                # there's nothing about origrequest we care about
+                #request = copy.copy(self.origrequest)
+
+                if self.primonlycheckbutton.get_active():
+                    primary = True
+                else:
+                    primary = None
+
+                if self.fixedrb.get_active():
+                    grow = None
+                else:
+                    grow = True
+
+                self.sizespin.update()
+
+                if self.fillmaxszrb.get_active():
+                    self.fillmaxszsb.update()
+                    maxsize = self.fillmaxszsb.get_value_as_int()
+                else:
+                    maxsize = 0
+
+                allowdrives = []
+                model = self.driveview.get_model()
+                iter = model.get_iter_first()
+                while iter:
+                    val   = model.get_value(iter, 0)
+                    drive = model.get_value(iter, 1)
+
+                    if val:
+                        allowdrives.append(drive)
+
+                    iter = model.iter_next(iter)
+
+                if len(allowdrives) == len(self.storage.partitioned):
+                    allowdrives = None
+
+                size = self.sizespin.get_value_as_int()
+                disks = []
+                if allowdrives:
+                    for drive in allowdrives:
+                        for disk in self.storage.partitioned:
+                            if disk.name == drive:
+                                disks.append(disk)
+
+                format = fmt_class(mountpoint=mountpoint)
+                weight = self.anaconda.platform.weight(mountpoint=mountpoint,
+                                                       fstype=format.type)
+                if self.isNew:
+                    request = self.storage.newPartition(size=size,
+                                                        grow=grow,
+                                                        maxsize=maxsize,
+                                                        primary=primary,
+                                                        format=format,
+                                                        parents=disks,
+                                                        weight=weight)
+                else:
+                    request = self.origrequest
+                    request.weight = weight
+
+                if self.lukscb and self.lukscb.get_active() and \
+                   request.format.type != "luks":
+                    luksformat = format
+                    format = getFormat("luks",
+                                       passphrase=self.storage.encryptionPassphrase)
+                    luksdev = LUKSDevice("luks%d" % self.storage.nextID,
+                                         format=luksformat,
+                                         parents=request)
+                elif self.lukscb and not self.lukscb.get_active() and \
+                     self.origrequest.format.type == "luks":
+                    # destroy the luks format and the mapped device
+                    try:
+                        luksdev = self.storage.devicetree.getChildren(self.origrequest)[0]
+                    except IndexError:
+                        pass
+                    else:
+                        actions.append(ActionDestroyFormat(luksdev))
+                        actions.append(ActionDestroyDevice(luksdev))
+                        luksdev = None
+
+                    actions.append(ActionDestroyFormat(request))
+
+                if self.isNew:
+                    # we're all set, so create the actions
+                    actions.append(ActionCreateDevice(request))
+                else:
+                    request.req_size = size
+                    request.req_base_size = size
+                    request.req_grow = grow
+                    request.req_max_size = maxsize
+                    request.req_primary = primary
+                    request.req_disks = disks
+
+                actions.append(ActionCreateFormat(request, format))
+                if luksdev:
+                    actions.append(ActionCreateDevice(luksdev))
+                    actions.append(ActionCreateFormat(luksdev))
+            else:
+                # preexisting partition
+                request = self.origrequest
+                if request.format.type == "luks":
+                    try:
+                        usedev = self.storage.devicetree.getChildren(request)[0]
+                    except IndexError:
+                        usedev = request
+                else:
+                    usedev = request
+
+                origformat = usedev.format
+                devicetree = self.anaconda.storage.devicetree
+
+                if self.fsoptionsDict.has_key("formatcb"):
+                    if self.fsoptionsDict["formatcb"].get_active():
+                        fmt_class = self.fsoptionsDict["fstypeCombo"].get_active_value()
+
+                        # carry over exists, migrate, size, and device
+                        # necessary for partition editor UI
+                        format = fmt_class(mountpoint=mountpoint,
+                                           device=usedev.path)
+
+                        luksdev = None
+                        if self.fsoptionsDict.has_key("lukscb") and \
+                           self.fsoptionsDict["lukscb"].get_active() and \
+                           (request.format.type != "luks" or
+                            (request.format.exists and
+                             not request.format.hasKey)):
+                            luksdev = LUKSDevice("luks%d" % self.storage.nextID,
+                                                 format=format,
+                                                 parents=request)
+                            format = getFormat("luks",
+                                               device=self.origrequest.path,
+                                               passphrase=self.storage.encryptionPassphrase)
+                        elif self.fsoptionsDict.has_key("lukscb") and \
+                             not self.fsoptionsDict["lukscb"].get_active() and \
+                             request.format.type == "luks":
+                            # user elected to format the device w/o encryption
+                            try:
+                                luksdev = self.storage.devicetree.getChildren(request)[0]
+                            except IndexError:
+                                pass
+                            else:
+                                actions.append(ActionDestroyFormat(luksdev))
+                                actions.append(ActionDestroyDevice(luksdev))
+                                luksdev = None
+
+                            actions.append(ActionDestroyFormat(request))
+                            # we set the new format's device while under the
+                            # impression that the device was going to be
+                            # encrypted, so we need to remedy that now
+                            format.device = request.path
+                            usedev = request
+
+                        actions.append(ActionCreateFormat(usedev, format))
+                        if luksdev:
+                            actions.append(ActionCreateDevice(luksdev))
+                            actions.append(ActionCreateFormat(luksdev))
+                    elif not self.fsoptionsDict["formatcb"].get_active():
+                        # if the format checkbutton is inactive, cancel all
+                        # actions on this device that create or destroy
+                        # formats
+                        cancel = []
+                        if request.originalFormat.type == "luks":
+                            path = "/dev/mapper/luks-%s" % request.originalFormat.uuid
+                            cancel.extend(devicetree.findActions(path=path))
+
+                        cancel.extend(devicetree.findActions(type="destroy",
+                                                             object="format",
+                                                             devid=request.id))
+                        cancel.extend(devicetree.findActions(type="create",
+                                                             object="format",
+                                                             devid=request.id))
+                        cancel.reverse()
+                        for action in cancel:
+                            devicetree.cancelAction(action)
+
+                        # even though we cancelled a bunch of actions, it's
+                        # pretty much impossible to be sure we cancelled them
+                        # in the correct order. make sure things are back to
+                        # their original state.
+                        request.format = request.originalFormat
+                        if request.format.type == "luks":
+                            try:
+                                usedev = devicetree.getChildren(request)[0]
+                            except IndexError:
+                                usedev = request
+                            else:
+                                usedev.format = usedev.originalFormat
+                        else:
+                            usedev = request
+
+                        if usedev.format.mountable:
+                            usedev.format.mountpoint = mountpoint
+                elif self.origrequest.protected and usedev.format.mountable:
+                    # users can set a mountpoint for protected partitions
+                    usedev.format.mountpoint = mountpoint
+
+                request.weight = self.anaconda.platform.weight(mountpoint=mountpoint,
+                                                               fstype=request.format.type)
+
+                if self.fsoptionsDict.has_key("migratecb") and \
+                   self.fsoptionsDict["migratecb"].get_active():
+                    actions.append(ActionMigrateFormat(usedev))
+
+                if self.fsoptionsDict.has_key("resizecb") and \
+                   self.fsoptionsDict["resizecb"].get_active():
+                    size = self.fsoptionsDict["resizesb"].get_value_as_int()
+
+                    try:
+                        actions.append(ActionResizeDevice(request, size))
+                        if request.format.type and request.format.exists:
+                            actions.append(ActionResizeFormat(request, size))
+                    except ValueError:
+                        pass
+
+                if request.format.exists and \
+                   getattr(request, "mountpoint", None) and \
+                   self.storage.formatByDefault(request):
+                    if not queryNoFormatPreExisting(self.intf):
+                        continue
+
+            # everything ok, fall out of loop
+	    break
+
+	return actions
+
+    def destroy(self):
+	if self.dialog:
+	    self.dialog.destroy()
+	self.dialog = None
+
+
+    def __init__(self, anaconda, parent, origrequest, isNew = 0,
+                 restrictfs = None):
+        self.anaconda = anaconda
+	self.storage = self.anaconda.storage
+	self.intf = self.anaconda.intf
+	self.origrequest = origrequest
+	self.isNew = isNew
+	self.parent = parent
+
+	if isNew:
+	    tstr = _("Add Partition")
+	else:
+	    tstr = _("Edit Partition: %s") % (origrequest.path,)
+	    
+        self.dialog = gtk.Dialog(tstr, self.parent)
+        gui.addFrame(self.dialog)
+        self.dialog.add_button('gtk-cancel', gtk.RESPONSE_CANCEL)
+        self.dialog.add_button('gtk-ok', 1)
+        self.dialog.set_position(gtk.WIN_POS_CENTER)
+        
+        maintable = gtk.Table()
+        maintable.set_row_spacings(5)
+        maintable.set_col_spacings(5)
+        row = 0
+
+        # if this is a luks device we need to grab info from two devices
+        # to make it seem like one device. wee!
+        if self.origrequest.format.type == "luks":
+            try:
+                luksdev = self.storage.devicetree.getChildren(self.origrequest)[0]
+            except IndexError:
+                usereq = self.origrequest
+                luksdev = None
+            else:
+                usereq = luksdev
+        else:
+            luksdev = None
+            usereq = self.origrequest
+
+        # Mount Point entry
+	lbl = createAlignedLabel(_("_Mount Point:"))
+        maintable.attach(lbl, 0, 1, row, row + 1)
+        self.mountCombo = createMountPointCombo(usereq)
+	lbl.set_mnemonic_widget(self.mountCombo)
+        maintable.attach(self.mountCombo, 1, 2, row, row + 1)
+        row = row + 1
+
+        # Partition Type
+        if not self.origrequest.exists:
+	    lbl = createAlignedLabel(_("File System _Type:"))
+            maintable.attach(lbl, 0, 1, row, row + 1)
+
+            self.newfstypeCombo = createFSTypeMenu(usereq.format,
+                                                   fstypechangeCB,
+                                                   self.mountCombo,
+                                                   availablefstypes = restrictfs)
+	    lbl.set_mnemonic_widget(self.newfstypeCombo)
+            maintable.attach(self.newfstypeCombo, 1, 2, row, row + 1)
+        else:
+            self.newfstypeCombo = None
+            
+        row = row + 1
+
+        # allowable drives
+        if not self.origrequest.exists:
+            lbl = createAlignedLabel(_("Allowable _Drives:"))
+            maintable.attach(lbl, 0, 1, row, row + 1)
+
+            req_disk_names = [d.name for d in self.origrequest.req_disks]
+            self.driveview = createAllowedDrivesList(self.storage.partitioned,
+                                                     req_disk_names,
+                                                     disallowDrives=[self.anaconda.updateSrc])
+            lbl.set_mnemonic_widget(self.driveview)
+            sw = gtk.ScrolledWindow()
+            sw.add(self.driveview)
+            sw.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
+            sw.set_shadow_type(gtk.SHADOW_IN)
+            maintable.attach(sw, 1, 2, row, row + 1)
+            self.driveview.set_size_request(375, 80)
+
+            row = row + 1
+
+        # original fs type and label
+        if self.origrequest.exists:
+            maintable.attach(createAlignedLabel(_("Original File System Type:")),
+                             0, 1, row, row + 1)
+            self.fstypeCombo = gtk.Label(usereq.originalFormat.name)
+
+            maintable.attach(self.fstypeCombo, 1, 2, row, row + 1)
+            row += 1
+
+            if getattr(usereq.originalFormat, "label", None):
+                maintable.attach(createAlignedLabel(_("Original File System "
+                                                      "Label:")),
+                                 0, 1, row, row + 1)
+                fslabel = gtk.Label(usereq.originalFormat.label)
+                maintable.attach(fslabel, 1, 2, row, row + 1)
+                row = row + 1
+
+        # size
+        if not self.origrequest.exists:
+            # Size specification
+            lbl = createAlignedLabel(_("_Size (MB):"))
+            maintable.attach(lbl, 0, 1, row, row + 1)
+            sizeAdj = gtk.Adjustment(value = 1, lower = 1,
+                                     upper = MAX_PART_SIZE, step_incr = 1)
+            self.sizespin = gtk.SpinButton(sizeAdj, digits = 0)
+            self.sizespin.set_property('numeric', True)
+
+            if self.origrequest.req_size:
+                self.sizespin.set_value(self.origrequest.req_size)
+
+            lbl.set_mnemonic_widget(self.sizespin)
+            maintable.attach(self.sizespin, 1, 2, row, row + 1)
+        else:
+            self.sizespin = None
+            
+        row = row + 1
+
+        # format/migrate options for pre-existing partitions, as long as they
+        # aren't protected (we'd still like to be able to mount them, though)
+	self.fsoptionsDict = {}
+        if self.origrequest.exists and \
+           not self.origrequest.protected:
+	    (row, self.fsoptionsDict) = createPreExistFSOptionSection(self.origrequest, maintable, row, self.mountCombo, self.storage, luksdev=luksdev)
+
+        # size options
+        if not self.origrequest.exists:
+            (sizeframe, self.fixedrb, self.fillmaxszrb,
+             self.fillmaxszsb) = self.createSizeOptionsFrame(self.origrequest,
+                                                        self.fillmaxszCB)
+            self.sizespin.connect("value-changed", self.sizespinchangedCB,
+                                  self.fillmaxszsb)
+
+            maintable.attach(sizeframe, 0, 2, row, row + 1)
+            row = row + 1
+        else:
+            self.sizeoptiontable = None
+
+        # create only as primary
+        if not self.origrequest.exists:
+            self.primonlycheckbutton = gtk.CheckButton(_("Force to be a _primary "
+                                                    "partition"))
+            self.primonlycheckbutton.set_active(0)
+            if self.origrequest.req_primary:
+                self.primonlycheckbutton.set_active(1)
+
+            # only show if we have something other than primary
+            if self.storage.extendedPartitionsSupported():
+                maintable.attach(self.primonlycheckbutton, 0, 2, row, row+1)
+                row = row + 1
+
+        # checkbutton for encryption using dm-crypt/LUKS
+        if not self.origrequest.exists:
+            self.lukscb = gtk.CheckButton(_("_Encrypt"))
+            self.lukscb.set_data("formatstate", 1)
+
+            if self.origrequest.format.type == "luks":
+                self.lukscb.set_active(1)
+            else:
+                self.lukscb.set_active(0)
+            maintable.attach(self.lukscb, 0, 2, row, row + 1)
+            row = row + 1
+
+        # put main table into dialog
+        self.dialog.vbox.pack_start(maintable)
+        self.dialog.show_all()
+
diff --git a/pyanaconda/iw/partition_gui.py b/pyanaconda/iw/partition_gui.py
new file mode 100644
index 0000000..9496e4e
--- /dev/null
+++ b/pyanaconda/iw/partition_gui.py
@@ -0,0 +1,1835 @@
+#
+# partition_gui.py: allows the user to choose how to partition their disks
+#
+# Copyright (C) 2001, 2002  Red Hat, Inc.  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 as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# 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, see <http://www.gnu.org/licenses/>.
+#
+# Author(s): Matt Wilson <msw@xxxxxxxxxx>
+#            Michael Fulbright <msf@xxxxxxxxxx>
+#
+
+import gobject
+import gtk
+import gtk.glade
+try:
+    import gnomecanvas
+except ImportError:
+    import gnome.canvas as gnomecanvas
+import pango
+import gui
+import parted
+import string
+import types
+import copy
+
+import storage
+from iw_gui import *
+from flags import flags
+
+import datacombo
+import lvm_dialog_gui as l_d_g
+import raid_dialog_gui as r_d_g
+import partition_dialog_gui as p_d_g
+
+from partIntfHelpers import *
+from constants import *
+from partition_ui_helpers_gui import *
+from storage.partitioning import doPartitioning
+from storage.partitioning import hasFreeDiskSpace
+from storage.devicelibs import lvm
+from storage.devices import devicePathToName, PartitionDevice
+
+import gettext
+_ = lambda x: gettext.ldgettext("anaconda", x)
+P_ = lambda x, y, z: gettext.ldngettext("anaconda", x, y, z)
+
+import logging
+log = logging.getLogger("anaconda")
+
+STRIPE_HEIGHT = 35.0
+LOGICAL_INSET = 3.0
+TREE_SPACING = 2
+
+# XXX hack but will work for now
+if gtk.gdk.screen_width() > 640:
+    CANVAS_WIDTH = 490
+else:
+    CANVAS_WIDTH = 390
+CANVAS_HEIGHT = 200
+
+MODE_ADD = 1
+MODE_EDIT = 2
+
+class Slice:
+    """Class representing a slice of a stripe.
+
+    parent -- the stripe that the slice belongs too.
+    text -- what will appear in the slice
+    type -- either SLICE or SUBSLICE
+    xoffset -- start percentage
+    xlength -- a length percentage
+    dcCB -- function that is called on a double click.
+    cCB -- function that is called when one click (selected)
+    sel_col -- color when selected
+    unsel_col -- color when unselected
+    obj -- some python object that is related to this slice.
+    selected -- initial state of slice.
+    """
+    SLICE = 0
+    SUBSLICE = 1
+    CONTAINERSLICE = 2
+
+    def __init__(self, parent, text, type, xoffset, xlength, dcCB=lambda: None,
+            cCB=lambda x: None, sel_col="cornsilk1", unsel_col="white",
+            obj = None, selected = False):
+        self.text = text
+        self.type = type
+        self.xoffset = xoffset
+        self.xlength = xlength
+        self.parent = parent
+        self.dcCB = dcCB
+        self.cCB = cCB
+        self.sel_col = sel_col
+        self.unsel_col = unsel_col
+        self.obj = obj
+        self.selected = selected
+
+    def eventHandler(self, widget, event):
+        if event.type == gtk.gdk.BUTTON_PRESS:
+            if event.button == 1:
+                self.select()
+                self.cCB(self.obj)
+        elif event.type == gtk.gdk._2BUTTON_PRESS:
+            #self.select()
+            self.dcCB()
+
+        return True
+
+    def putOnCanvas(self):
+        pgroup = self.parent.getGroup()
+        self.group = pgroup.add(gnomecanvas.CanvasGroup)
+        self.box = self.group.add(gnomecanvas.CanvasRect)
+        self.group.connect("event", self.eventHandler)
+        canvas_text = self.group.add(gnomecanvas.CanvasText,
+                                    font="sans", size_points=8)
+
+        xoffset = self.xoffset * CANVAS_WIDTH
+        xlength = self.xlength * CANVAS_WIDTH
+
+        if self.type == Slice.SUBSLICE:
+            yoffset = 0.0 + LOGICAL_INSET
+            yheight = STRIPE_HEIGHT - (LOGICAL_INSET * 2)
+            texty = 0.0
+        else:
+            yoffset = 0.0
+            yheight = STRIPE_HEIGHT
+            texty = LOGICAL_INSET
+
+        if self.selected:
+            fill_color = self.sel_col
+        else:
+            fill_color = self.unsel_col
+
+        self.group.set(x=xoffset, y=yoffset)
+        self.box.set(x1=0.0, y1=0.0, x2=xlength,
+                     y2=yheight, fill_color=fill_color,
+                     outline_color='black', width_units=1.0)
+        canvas_text.set(x=2.0, y=texty + 2.0, text=self.text,
+                            fill_color='black',
+                            anchor=gtk.ANCHOR_NW, clip=True,
+                            clip_width=xlength-1, clip_height=yheight-1)
+
+    def shutDown(self):
+        self.parent = None
+        if self.group:
+            self.group.destroy()
+            self.group = None
+
+    def select(self):
+        for slice in self.parent.slices:
+            slice.deselect()
+        self.selected = True
+
+        if self.group and self.box:
+            if self.type != Slice.CONTAINERSLICE:
+                self.group.raise_to_top()
+            self.box.set(outline_color="red")
+            self.box.set(fill_color=self.sel_col)
+
+    def deselect(self):
+        self.selected = False
+        if self.box:
+            self.box.set(outline_color="black", fill_color=self.unsel_col)
+
+class Stripe(object):
+    """
+    canvas -- the canvas where everything goes
+    text -- the text that will appear on top of the stripe
+    yoff -- its the position in the y axis where this stripe should be drawn
+    dcCB -- function that should be called on a double click
+    obj -- some python object that is related to this stripe
+
+    """
+    def __init__(self, canvas, text, dcCB, obj = None):
+        self.canvas_text = None
+        self.canvas = canvas
+        self.text = text
+        self.group = None
+        self._slices = []
+        self.dcCB = dcCB
+        self.selected = None
+        self.obj = obj
+
+    def putOnCanvas(self, yoff):
+        """
+        returns the yposition after drawhing this stripe.
+
+        """
+        # We set the text for the stripe.
+        self.canvas_text = self.canvas.root().add(gnomecanvas.CanvasText,
+                x=0.0, y=yoff, font="sans", size_points=9)
+        self.canvas_text.set(text=self.text, fill_color='black',
+                anchor=gtk.ANCHOR_NW, weight=pango.WEIGHT_BOLD)
+
+        (xxx1, yyy1, xxx2, yyy2) =  self.canvas_text.get_bounds()
+        textheight = yyy2 - yyy1 + 2
+        self.group = self.canvas.root().add(gnomecanvas.CanvasGroup,
+                                       x=0, y=yoff+textheight)
+
+        self.group.add(gnomecanvas.CanvasRect, x1=0.0, y1=0.0, x2=CANVAS_WIDTH,
+                  y2=STRIPE_HEIGHT, fill_color='green',
+                  outline_color='grey71', width_units=1.0)
+        self.group.lower_to_bottom()
+
+        # We paint all the container slices first.  So the contained slices
+        # actually show up.
+        for slice in [s for s in self.slices if s.type == Slice.CONTAINERSLICE]:
+            slice.putOnCanvas()
+        # After painting the containers we paint the rest.
+        for slice in [s for s in self.slices if s.type != Slice.CONTAINERSLICE]:
+            slice.putOnCanvas()
+
+        # 10 is a separator space.
+        return yoff + STRIPE_HEIGHT+textheight+10
+
+    def shutDown(self):
+        for slice in self.slices:
+            slice.shutDown()
+        self._slices = []
+
+        if self.canvas_text:
+            self.canvas_text.destroy()
+
+        if self.group:
+            self.group.destroy()
+            self.group = None
+
+    def getGroup(self):
+        return self.group
+
+    @property
+    def slices(self):
+        return self._slices
+
+    def addSlice(self, new_slice):
+        # check to see if they overlap.
+        for slice in self.slices:
+            # Container slices and subslices can overlap.
+            if new_slice.type+slice.type == Slice.CONTAINERSLICE+Slice.SUBSLICE:
+                continue
+
+            if new_slice.xoffset > slice.xoffset \
+                    and new_slice.xoffset < slice.xoffset + slice.xlength:
+                # there is a colission, we cannot add.
+                return
+
+        self._slices.append(new_slice)
+
+    def getSelectedSlice(self):
+        for slice in self.slices:
+            if slice.selected:
+                return slice
+        return None
+
+class StripeGraph:
+    """ This class will only handle one stripe."""
+
+    __canvas = None
+    def __init__(self):
+        self.stripe = None
+        self.next_ypos = 0.0
+
+    def __del__(self):
+        self.shutDown()
+
+    def shutDown(self):
+        if self.stripe:
+            self.stripe.shutDown()
+            self.stripe = None
+
+        self.next_ypos = 0.0
+
+    @classmethod
+    def getCanvas(cls):
+        if not StripeGraph.__canvas:
+            StripeGraph.__canvas = gnomecanvas.Canvas()
+        return StripeGraph.__canvas
+
+    def setDisplayed(self, obj):
+        # Check to see if we already have the correct obj displayed.
+        if self.getDisplayed() and self.getDisplayed().obj == obj:
+            return
+
+        if self.stripe:
+            self.stripe.shutDown()
+
+        self.stripe = self._createStripe(obj)
+        self.stripe.putOnCanvas(0)
+
+        # Trying to center the picture.
+        apply(self.getCanvas().set_scroll_region, self.getCanvas().root().get_bounds())
+
+    def getDisplayed(self):
+        return self.stripe
+
+    def selectSliceFromObj(self, obj):
+        """Search for obj in the slices """
+        stripe = self.getDisplayed()
+        if not stripe:
+            return
+
+        for slice in stripe.slices:
+            # There is a part object in each slice.
+            if not slice.obj:
+                continue
+
+            if obj == slice.obj and not slice.selected:
+                slice.select()
+                break
+
+    def _createStripe(self, obj):
+        #This method needs to be overridden
+        pass
+
+    def getSelectedSlice(self):
+        return self.stripe.getSelectedSlice()
+
+
+class DiskStripeGraph(StripeGraph):
+    """Handles the creation of a bar view for the 'normal' devies.
+
+    storage -- the storage object
+
+    cCB -- call back function used when the user clicks on a slice. This function
+           is passed a device object when its executed.
+    dcCB -- call back function used when the user double clicks on a slice.
+    drive -- drive to display
+    """
+    def __init__(self, storage, drive=None, cCB=lambda x:None, dcCB=lambda:None):
+        StripeGraph.__init__(self)
+        self.storage = storage
+        self.cCB = cCB
+        self.dcCB = dcCB
+       # Define the default colors per partition type.
+        self.part_type_colors = \
+                {"sel_logical": "cornsilk1", "unsel_logical": "white",
+                 "sel_extended": "cornsilk1", "unsel_extended": "white",
+                 "sel_normal": "cornsilk1", "unsel_normal": "white",
+                 "sel_freespace": "grey88", "unsel_freespace": "grey88"}
+        if drive:
+            self.setDisplayed(drive)
+
+    def _createStripe(self, drive):
+        # Create the stripe
+        drivetext = _("Drive %(drive)s (%(size)-0.f MB) (Model: %(model)s)") \
+                    % {'drive': drive.path,
+                       'size': drive.size,
+                       'model': drive.model}
+        stripe = Stripe(self.getCanvas(), drivetext, self.dcCB, obj = drive)
+
+        # Free Extended Calculation
+        # Free slice/partition in the extended partition "free space".  If there
+        # is space between the last logical partition and the ending of the
+        # extended partition we create a "free space" in the extended part.
+        # Create the slices.
+
+        # These offsets are where the partition/slices end. 0<offset<1
+        last_logical_offset = None
+        last_extended_offset = None
+
+        for part in drive.format.partedDisk.getFreeSpacePartitions() \
+                + [d for d in drive.format.partitions]:
+            if part.getSize(unit="MB") <= 1.0:
+                continue
+
+            # Create the start and length for the slice.
+            xoffset = (float(part.geometry.start)
+                        / float(drive.partedDevice.length))
+            xlength = (float(part.geometry.length)
+                        / float(drive.partedDevice.length))
+
+            if part.type == parted.PARTITION_LOGICAL:
+                partstr = "%s\n%.0f MB" % (part.path, float(part.getSize()))
+                stype = Slice.SUBSLICE
+                unsel_col = self.part_type_colors["unsel_logical"]
+                sel_col = self.part_type_colors["sel_logical"]
+
+                # Free Extended Calculation
+                if last_logical_offset == None:
+                    last_logical_offset = xoffset + xlength
+                elif last_logical_offset < xoffset + xlength:
+                    last_logical_offset = xoffset + xlength
+
+            elif part.type == parted.PARTITION_FREESPACE:
+                partstr = "%s\n%.0f MB" % (_("Free"), float(part.getSize()))
+                stype = Slice.SLICE
+                unsel_col = self.part_type_colors["unsel_freespace"]
+                sel_col = self.part_type_colors["sel_freespace"]
+
+            elif part.type == parted.PARTITION_EXTENDED:
+                partstr = ""
+                stype = Slice.CONTAINERSLICE
+                unsel_col = self.part_type_colors["unsel_extended"]
+                sel_col = self.part_type_colors["sel_extended"]
+
+                # Free Extended Calculation
+                last_extended_offset = xoffset + xlength
+
+            elif part.type == parted.PARTITION_NORMAL:
+                partstr = "%s\n%.0f MB" % (part.path, float(part.getSize()))
+                stype = Slice.SLICE
+                unsel_col = self.part_type_colors["unsel_normal"]
+                sel_col = self.part_type_colors["sel_normal"]
+
+            else:
+                # We don't really want to draw anything in this case.
+                continue
+
+            # We need to use the self.storage objects not the partedDisk ones.
+            # The free space has not storage object.
+            if part.type != parted.PARTITION_FREESPACE:
+                partName = devicePathToName(part.getDeviceNodeName())
+                o_part = self.storage.devicetree.getDeviceByName(partName)
+            else:
+                o_part = None
+
+            slice = Slice(stripe, partstr, stype, xoffset, xlength,
+                    dcCB = self.dcCB, cCB = self.cCB, sel_col = sel_col,
+                    unsel_col = unsel_col, obj = o_part)
+            stripe.addSlice(slice)
+
+        # Free Extended Calculation
+        if (last_logical_offset != None and last_extended_offset != None) \
+                and last_logical_offset < last_extended_offset:
+            # We must create a "free extended" slice
+            stype = Slice.SUBSLICE
+            unsel_col = self.part_type_colors["unsel_freespace"]
+            sel_col = self.part_type_colors["sel_freespace"]
+            xoffset = last_logical_offset
+            xlength = last_extended_offset - last_logical_offset
+            slcstr = "%s\n%.0f MB" % (_("Free"), float(drive.size * xlength))
+
+            slice = Slice(stripe, slcstr, stype, xoffset, xlength,
+                    dcCB = self.dcCB, cCB = self.cCB, sel_col=sel_col,
+                    unsel_col=unsel_col)
+            stripe.addSlice(slice)
+
+        return stripe
+
+class LVMStripeGraph(StripeGraph):
+    """
+    storage -- the storage object
+
+    cCB -- call back function used when the user clicks on a slice. This function
+           is passed a device object when its executed.
+    dcCB -- call back function used when the user double clicks on a slice.
+    vg -- volume group to display
+    """
+    def __init__(self, storage, vg=None, cCB=lambda x:None, dcCB=lambda:None):
+        StripeGraph.__init__(self)
+        self.storage = storage
+        self.cCB = cCB
+        self.dcCB = dcCB
+       # Define the default colors per partition type.
+        self.part_type_colors = \
+                {"sel_lv": "cornsilk1", "unsel_lv": "white",
+                 "sel_freespace": "grey88", "unsel_freespace": "grey88"}
+        if vg:
+            self.setDisplayed(vg)
+
+    def _createStripe(self, vg):
+        # Create the stripe
+        vgtext = _("LVM Volume Group %s (%-0.f MB)") % (vg.name, vg.size)
+        stripe = Stripe(self.getCanvas(), vgtext, self.dcCB, obj = vg)
+
+        # Create the slices.
+        # Since se don't have a start and length like in the partitions, we
+        # put all the LVs next to each other and put the free space at the end.
+        curr_offset = float(0)
+        for lv in vg.lvs:
+            lvstr = "%s\n%.0f MB" % (lv.name, float(lv.size))
+            stype = Slice.SLICE
+            sel_col = self.part_type_colors["sel_lv"]
+            unsel_col = self.part_type_colors["unsel_lv"]
+
+            #xoffset = float(curr_offset) / float(vg.size)
+            xoffset = curr_offset
+            xlength = float(lv.size) / float(vg.size)
+
+            slice = Slice(stripe, lvstr, stype, xoffset, xlength,
+                    dcCB = self.dcCB, cCB = self.cCB, sel_col = sel_col,
+                    unsel_col = unsel_col, obj = lv)
+            stripe.addSlice(slice)
+
+            curr_offset += xlength
+
+        # We add the free space if there is any space left.
+        if curr_offset < 1:
+            #freestr = _("Free")
+            stype = Slice.SLICE
+            sel_col = self.part_type_colors["sel_freespace"]
+            unsel_col = self.part_type_colors["unsel_freespace"]
+
+            xoffset = curr_offset
+            xlength = float(1 - curr_offset)
+
+            # with the xlength we give an approximate size
+            freestr = "%s\n%.0f MB" % (_("Free"), float(vg.size*xlength))
+
+            # We append no object.
+            slice = Slice(stripe, freestr, stype, xoffset, xlength,
+                    dcCB = self.dcCB, cCB = self.cCB, sel_col = sel_col,
+                    unsel_col = unsel_col)
+
+            stripe.addSlice(slice)
+
+        return stripe
+
+class MDRaidArrayStripeGraph(StripeGraph):
+    """
+    storage -- the storage object
+
+    cCB -- call back function used when the user clicks on a slice. This function
+           is passed a device object when its executed.
+    dcCB -- call back function used when the user double clicks on a slice.
+    md -- RAID device to display.
+    """
+    def __init__(self, storage, md=None, cCB=lambda x:None, dcCB=lambda:None):
+        StripeGraph.__init__(self)
+        self.storage = storage
+        self.cCB = cCB
+        self.dcCB = dcCB
+        self.part_type_colors = \
+                {"sel_md": "cornsilk1", "unsel_md": "white"}
+        if md:
+            self.setDisplayed(md)
+
+    def _createStripe(self, md):
+        mdtext = _("MD RAID ARRAY %s (%-0.f MB)") % (md.path, md.size)
+        stripe = Stripe(self.getCanvas(), mdtext, self.dcCB, obj = md)
+
+        # Since we can't really create subslices with md devices we will only
+        # show the md device size in the bar.
+        mdstr = "%s\n%.0f MB" % (md.path, float(md.size))
+        stype = Slice.SLICE
+        sel_col = self.part_type_colors["sel_md"]
+        unsel_col = self.part_type_colors["unsel_md"]
+        xoffset = 0
+        xlength = 1
+
+        slice = Slice(stripe, mdstr, stype, xoffset, xlength,
+                dcCB = self.dcCB, cCB = self.cCB, sel_col = sel_col,
+                unsel_col = unsel_col, obj = md)
+        stripe.addSlice(slice)
+
+        return stripe
+
+class MessageGraph:
+    def __init__(self, canvas, message):
+        self.canvas = canvas
+        self.message = message
+        self.canvas_text = None
+
+    def display(self):
+        if self.canvas_text != None:
+            # This means that its already displayed.
+            return
+
+        self.canvas_text = self.canvas.root().add(gnomecanvas.CanvasText,
+                x=0.0, y=20, font="sans", size_points=16)
+        self.canvas_text.set(text=self.message, fill_color='black',
+                anchor=gtk.ANCHOR_CENTER, weight=pango.WEIGHT_BOLD)
+
+        # Trying to center the picture.
+        apply(self.canvas.set_scroll_region, self.canvas.root().get_bounds())
+
+    def destroy(self):
+        if self.canvas_text:
+            self.canvas_text.destroy()
+            self.canvas_text = None
+
+class DiskTreeModelHelper:
+    def __init__(self, model, columns, iter):
+        self.model = model
+        self.iter = iter
+        self.columns = columns
+
+    def __getitem__(self, key):
+        if type(key) == types.StringType:
+            key = self.columns[key]
+        try:
+            return self.model.get_value(self.iter, key)
+        except:
+            return None
+
+    def __setitem__(self, key, value):
+        if type(key) == types.StringType:
+            key = self.columns[key]
+        self.model.set_value(self.iter, key, value)
+
+class DiskTreeModel(gtk.TreeStore):
+    isLeaf = -3
+    isFormattable = -2
+    
+    # format: column header, type, x alignment, hide?, visibleKey
+    titles = ((N_("Device"), gobject.TYPE_STRING, 0.0, 0, 0),
+              (N_("Label"), gobject.TYPE_STRING, 0.0, 1, 0),
+              (N_("Size (MB)"), gobject.TYPE_STRING, 1.0, 0, 0),
+              (N_("Mount Point"), gobject.TYPE_STRING, 0.0, 0, isLeaf),
+              (N_("Type"), gobject.TYPE_STRING, 0.0, 0, 0),
+              (N_("Format"), gobject.TYPE_OBJECT, 0.5, 0, isFormattable),
+              ("", gobject.TYPE_STRING, 0.0, 0, 0),
+              # the following must be the last two
+              ("IsLeaf", gobject.TYPE_BOOLEAN, 0.0, 1, 0),
+              ("IsFormattable", gobject.TYPE_BOOLEAN, 0.0, 1, 0),
+              ("PyObject", gobject.TYPE_PYOBJECT, 0.0, 1, 0))
+    
+    def __init__(self):
+	self.hiddenPartitions = []
+        self.titleSlot = {}
+        i = 0
+        types = [self]
+        self.columns = []
+        for title, kind, alignment, hide, key in self.titles:
+            self.titleSlot[title] = i
+            types.append(kind)
+            if hide:
+                i += 1
+                continue
+            elif kind == gobject.TYPE_OBJECT:
+                renderer = gtk.CellRendererPixbuf()
+                propertyMapping = {'pixbuf': i}
+            elif kind == gobject.TYPE_BOOLEAN:
+                renderer = gtk.CellRendererToggle()
+                propertyMapping = {'active': i}
+            elif (kind == gobject.TYPE_STRING or
+                  kind == gobject.TYPE_INT):
+                renderer = gtk.CellRendererText()
+                propertyMapping = {'markup': i}
+
+            # wire in the cells that we want only visible on leaf nodes to
+            # the special leaf node column.
+            if key < 0:
+                propertyMapping['visible'] = len(self.titles) + key
+                
+            renderer.set_property('xalign', alignment)
+	    if title == "Mount Point":
+		title = _("Mount Point/\nRAID/Volume")
+	    elif title == "Size (MB)":
+		title = _("Size\n(MB)")
+            elif title != "":
+                title = _(title)
+            col = apply(gtk.TreeViewColumn, (title, renderer),
+                        propertyMapping)
+	    col.set_alignment(0.5)
+	    if kind == gobject.TYPE_STRING or kind == gobject.TYPE_INT:
+		col.set_property('sizing', gtk.TREE_VIEW_COLUMN_AUTOSIZE)
+            self.columns.append(col)
+            i += 1
+
+        apply(gtk.TreeStore.__init__, types)
+
+        self.view = gtk.TreeView(self)
+        # append all of the columns
+        map(self.view.append_column, self.columns)
+
+    def getTreeView(self):
+        return self.view
+
+    def selectRowFromObj(self, obj, iter=None):
+        """Find the row in the tree containing obj and select it.
+
+        obj -- the object that we are searching
+        iter -- an iter from the tree. If None, get the first one.
+
+        Returns the iter where obj was found.  None otherwise.
+        """
+        retval = None
+        r_obj = None
+        #FIXME: watch out for hidden rows.
+
+        if not iter:
+            iter = self.get_iter_first()
+
+        while iter:
+            # r_obj -> (row object)
+            r_obj = self[iter]["PyObject"]
+
+            if obj and r_obj == obj:
+                # We have fond our object, select this row and break.
+                selection = self.view.get_selection()
+                if selection is not None:
+                    selection.unselect_all()
+                    selection.select_iter(iter)
+
+                # Make sure the tree view shows what we have selected.
+                path = self.get_path(iter)
+                col = self.view.get_column(0)
+                self.view.set_cursor(path, col, False)
+                self.view.scroll_to_cell(path, col, True, 0.5, 0.5)
+                retval = iter
+                break
+
+            if self.iter_has_child(iter):
+                # Call recursively if row has children.
+                rv = self.selectRowFromObj(obj, iter=self.iter_children(iter))
+                if rv != None:
+                    retval = rv
+                    break
+
+            iter = self.iter_next(iter)
+
+        return iter
+
+    def getCurrentDevice(self):
+        """ Return the device representing the current selection,
+            None otherwise.
+        """
+        selection = self.view.get_selection()
+        model, iter = selection.get_selected()
+        if not iter:
+            return None
+
+        return model[iter]['PyObject']
+
+    def getCurrentDeviceParent(self):
+        """ Return the parent of the selected row.  Returns an iter.
+            None if there is no parent.
+        """
+        selection = self.view.get_selection()
+        model, iter = selection.get_selected()
+        if not iter:
+            return None
+
+        return model.iter_parent(iter)
+
+    def resetSelection(self):
+        pass
+
+    def clear(self):
+        selection = self.view.get_selection()
+        if selection is not None:
+            selection.unselect_all()
+        gtk.TreeStore.clear(self)
+
+    def __getitem__(self, iter):
+        if type(iter) == gtk.TreeIter:
+            return DiskTreeModelHelper(self, self.titleSlot, iter)
+        raise KeyError, iter
+
+
+class PartitionWindow(InstallWindow):
+    def __init__(self, ics):
+	InstallWindow.__init__(self, ics)
+        ics.setTitle(_("Partitioning"))
+        ics.setNextEnabled(True)
+        self.parent = ics.getICW().window
+
+    def quit(self):
+        pass
+
+    def presentPartitioningComments(self,title, labelstr1, labelstr2, comments,
+				    type="ok", custom_buttons=None):
+
+        if flags.autostep:
+            return 1
+
+        win = gtk.Dialog(title)
+        gui.addFrame(win)
+        
+        if type == "ok":
+            win.add_button('gtk-ok', 1)
+	    defaultchoice = 0
+        elif type == "yesno":
+            win.add_button('gtk-no', 2)
+            win.add_button('gtk-yes', 1)
+	    defaultchoice = 1
+	elif type == "continue":
+            win.add_button('gtk-cancel', 0)
+            win.add_button(_("Continue"), 1)
+	    defaultchoice = 1
+	elif type == "custom":
+	    rid=0
+
+	    for button in custom_buttons:
+		widget = win.add_button(button, rid)
+		rid = rid + 1
+
+            defaultchoice = rid - 1
+	    
+        image = gtk.Image()
+        image.set_from_stock('gtk-dialog-warning', gtk.ICON_SIZE_DIALOG)
+        hbox = gtk.HBox(False, 9)
+	al=gtk.Alignment(0.0, 0.0)
+	al.add(image)
+        hbox.pack_start(al, False)
+
+        buffer = gtk.TextBuffer(None)
+        buffer.set_text(comments)
+        text = gtk.TextView()
+        text.set_buffer(buffer)
+        text.set_property("editable", False)
+        text.set_property("cursor_visible", False)
+        text.set_wrap_mode(gtk.WRAP_WORD)
+        
+        sw = gtk.ScrolledWindow()
+        sw.add(text)
+	sw.set_size_request(400, 200)
+        sw.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
+        sw.set_shadow_type(gtk.SHADOW_IN)
+        
+        info1 = gtk.Label(labelstr1)
+        info1.set_line_wrap(True)
+        info1.set_size_request(400, -1)
+
+        info2 = gtk.Label(labelstr2)
+        info2.set_line_wrap(True)
+        info2.set_size_request(400, -1)
+        
+        vbox = gtk.VBox(False, 9)
+
+	al=gtk.Alignment(0.0, 0.0)
+	al.add(info1)
+        vbox.pack_start(al, False)
+	
+        vbox.pack_start(sw, True, True)
+
+	al=gtk.Alignment(0.0, 0.0)
+	al.add(info2)
+        vbox.pack_start(al, True)
+	
+        hbox.pack_start(vbox, True, True)
+
+        win.vbox.pack_start(hbox)
+        win.set_position(gtk.WIN_POS_CENTER)
+        win.set_default_response(defaultchoice)
+        win.show_all()
+        rc = win.run()
+        win.destroy()
+        return rc
+        
+    def getNext(self):
+        (errors, warnings) = self.storage.sanityCheck()
+        if errors:
+            labelstr1 =  _("The partitioning scheme you requested "
+                           "caused the following critical errors.")
+            labelstr2 = _("You must correct these errors before "
+                          "you continue your installation of "
+                          "%s.") % (productName,)
+
+            commentstr = string.join(errors, "\n\n")
+            
+            self.presentPartitioningComments(_("Partitioning Errors"),
+                                             labelstr1, labelstr2,
+                                             commentstr, type="ok")
+            raise gui.StayOnScreen
+        
+        if warnings:
+            # "storage configuration"
+            labelstr1 = _("The partitioning scheme you requested "
+                          "generated the following warnings.")
+            labelstr2 = _("Would you like to continue with "
+                         "your requested partitioning "
+                         "scheme?")
+            
+            commentstr = string.join(warnings, "\n\n")
+            rc = self.presentPartitioningComments(_("Partitioning Warnings"),
+                                                  labelstr1, labelstr2,
+                                                  commentstr,
+						  type="yesno")
+            if rc != 1:
+                raise gui.StayOnScreen
+
+        formatWarnings = getPreExistFormatWarnings(self.storage)
+        if formatWarnings:
+            labelstr1 = _("The following pre-existing devices have been "
+                          "selected to be formatted, destroying all data.")
+
+#            labelstr2 = _("Select 'Yes' to continue and format these "
+#                          "partitions, or 'No' to go back and change these "
+#                          "settings.")
+            labelstr2 = ""
+            commentstr = ""
+            for (dev, type, mntpt) in formatWarnings:
+                commentstr = commentstr + \
+                        "%s         %s         %s\n" % (dev,type,mntpt)
+
+            rc = self.presentPartitioningComments(_("Format Warnings"),
+                                                  labelstr1, labelstr2,
+                                                  commentstr,
+						  type="custom",
+						  custom_buttons=["gtk-cancel",
+								  _("_Format")])
+            if rc != 1:
+                raise gui.StayOnScreen
+
+        self.stripeGraph.shutDown()
+        self.tree.clear()
+        del self.parent
+        return None
+
+    def getPrev(self):
+        self.stripeGraph.shutDown()
+        # temporarily unset storage.clearPartType so that all devices will be
+        # found during storage reset
+        clearPartType = self.storage.clearPartType
+        self.storage.clearPartType = None
+        self.storage.reset()
+        self.storage.clearPartType = clearPartType
+        self.tree.clear()
+        del self.parent
+        return None
+
+    def addDevice(self, device, treeiter):
+        if device.format.hidden:
+            return
+
+        if device.format.type == "luks":
+            # we'll want to grab format info from the mapped
+            # device, not the encrypted one
+            try:
+                dm_dev = self.storage.devicetree.getChildren(device)[0]
+            except IndexError:
+                format = device.format
+            else:
+                format = dm_dev.format
+        else:
+            format = device.format
+
+        # icon for the format column
+        if device.format.type == "luks" and not device.format.exists:
+            # we're creating the LUKS header
+            format_icon = self.lock_pixbuf
+        elif not format.exists:
+            # we're creating a format on the device
+            format_icon = self.checkmark_pixbuf
+        else:
+            format_icon = None
+
+        # mount point string
+        if format.type == "lvmpv":
+            vg = None
+            for _vg in self.storage.vgs:
+                if _vg.dependsOn(device):
+                    vg = _vg
+                    break
+
+            mnt_str = getattr(vg, "name", "")
+        elif format.type == "mdmember":
+            array = None
+            for _array in self.storage.mdarrays:
+                if _array.dependsOn(device):
+                    array = _array
+                    break
+
+            mnt_str = getattr(array, "name", "")
+        else:
+            mnt_str = getattr(format, "mountpoint", "")
+            if mnt_str is None:
+                mnt_str = ""
+
+        # device name
+        name_str = getattr(device, "lvname", device.name)
+
+        # label
+        label_str = getattr(format, "label", "")
+        if label_str is None:
+            label_str = ""
+
+        self.tree[treeiter]['Device'] = name_str
+        self.tree[treeiter]['Size (MB)'] = "%Ld" % device.size
+        self.tree[treeiter]['PyObject'] = device
+        self.tree[treeiter]['IsFormattable'] = format.formattable
+        self.tree[treeiter]['Format'] = format_icon
+        self.tree[treeiter]['Mount Point'] = mnt_str
+        self.tree[treeiter]['IsLeaf'] = True
+        self.tree[treeiter]['Type'] = format.name
+        self.tree[treeiter]['Label'] = label_str
+
+    def populate(self, initial = 0):
+        self.tree.resetSelection()
+
+        # first do LVM
+        vgs = self.storage.vgs
+        if vgs:
+	    lvmparent = self.tree.append(None)
+	    self.tree[lvmparent]['Device'] = _("LVM Volume Groups")
+            for vg in vgs:
+                vgparent = self.tree.append(lvmparent)
+                self.addDevice(vg, vgparent)
+                self.tree[vgparent]['Type'] = ""
+                for lv in vg.lvs:
+                    iter = self.tree.append(vgparent)
+                    self.addDevice(lv, iter)
+
+                # We add a row for the VG free space.
+                if vg.freeSpace > 0:
+                    iter = self.tree.append(vgparent)
+                    self.tree[iter]['Device'] = _("Free")
+                    self.tree[iter]['Size (MB)'] = vg.freeSpace
+                    self.tree[iter]['PyObject'] = None
+                    self.tree[iter]['Mount Point'] = ""
+                    self.tree[iter]['IsLeaf'] = True
+
+        # handle RAID next
+        mdarrays = self.storage.mdarrays
+        if mdarrays:
+	    raidparent = self.tree.append(None)
+	    self.tree[raidparent]['Device'] = _("RAID Devices")
+            for array in mdarrays:
+                iter = self.tree.append(raidparent)
+                self.addDevice(array, iter)
+                name = "%s <span size=\"small\" color=\"gray\">(%s)</span>" % \
+                            (array.name, array.path)
+                self.tree[iter]['Device'] = name
+
+        # now normal partitions
+        disks = self.storage.partitioned
+        drvparent = self.tree.append(None)
+        self.tree[drvparent]['Device'] = _("Hard Drives")
+        for disk in disks:
+            # add a parent node to the tree
+            parent = self.tree.append(drvparent)
+
+            self.tree[parent]['PyObject'] = disk
+            if disk.partitioned:
+                part = disk.format.firstPartition
+                extendedParent = None
+                while part:
+                    if part.type & parted.PARTITION_METADATA:
+                        part = part.nextPartition()
+                        continue
+
+                    partName = devicePathToName(part.getDeviceNodeName())
+                    device = self.storage.devicetree.getDeviceByName(partName)
+                    if not device and not part.type & parted.PARTITION_FREESPACE:
+                        log.debug("can't find partition %s in device"
+                                           " tree" % partName)
+
+                    # ignore the tiny < 1 MB free space partitions (#119479)
+                    if part.getSize(unit="MB") <= 1.0 and \
+                       part.type & parted.PARTITION_FREESPACE:
+                        if not part.active or not device.bootable:
+                            part = part.nextPartition()
+                            continue
+
+                    if device and device.isExtended:
+                        if extendedParent:
+                            raise RuntimeError, ("can't handle more than "
+                                                 "one extended partition per disk")
+                        extendedParent = self.tree.append(parent)
+                        iter = extendedParent
+                    elif device and device.isLogical:
+                        if not extendedParent:
+                            raise RuntimeError, ("crossed logical partition "
+                                                 "before extended")
+                        iter = self.tree.append(extendedParent)
+                    else:
+                        iter = self.tree.append(parent)
+
+                    if device and not device.isExtended:
+                        self.addDevice(device, iter)
+                    else:
+                        # either extended or freespace
+                        if part.type & parted.PARTITION_FREESPACE:
+                            devstring = _("Free")
+                            ptype = ""
+                        else:
+                            devstring = device.name
+                            ptype = _("Extended")
+
+                        self.tree[iter]['Device'] = devstring
+                        self.tree[iter]['Type'] = ptype
+                        size = part.getSize(unit="MB")
+                        if size < 1.0:
+                            sizestr = "< 1"
+                        else:
+                            sizestr = "%Ld" % (size)
+                        self.tree[iter]['Size (MB)'] = sizestr
+                        self.tree[iter]['PyObject'] = device
+
+                    part = part.nextPartition()
+            else:
+                # whole-disk formatting
+                self.addDevice(disk, parent)
+
+            # Insert a '\n' when device string is too long.  Usually when it
+            # contains '/dev/mapper'.  First column should be around 20 chars.
+            if len(disk.name) + len(disk.path) > 20:
+                separator = "\n"
+            else:
+                separator= " "
+            self.tree[parent]['Device'] = \
+                    "%s%s<span size=\"small\" color=\"gray\">(%s)</span>" \
+                    % (disk.name, separator, disk.path)
+
+        self.treeView.expand_all()
+        self.messageGraph.display()
+
+    def barviewActivateCB(self):
+        """ Should be called when we double click on a slice"""
+        # This is a bit of a hack to make the double click on free space work.
+        # This function is useful when the selected slice is a free space,
+        # in any other case it calls self.treeActiveCB.
+
+        # We first see if the double click was from a free space or from another
+        # slice.
+        sel_slice = self.stripeGraph.getSelectedSlice()
+
+        if sel_slice == None:
+            # This really should not happen. Do nothing.
+            return
+
+        # The selected slice is a free slice if the object contained in it is
+        # None.
+        if sel_slice.obj != None:
+            # This is not a free slice, we should call treeActivateCB
+            return self.treeActivateCB()
+        else:
+            # Display a create window according to the stripe object.
+            # Get the device from the stripe.obj
+            disp_stripe = self.stripeGraph.getDisplayed()
+            if disp_stripe == None:
+                # this should not happen
+                return
+
+            # Display a create dialog.
+            stripe_dev = disp_stripe.obj
+            if stripe_dev.partitioned:
+                tempformat = self.storage.defaultFSType
+                device = self.storage.newPartition(fmt_type=tempformat)
+                self.editPartition(device, isNew = True)
+
+            elif isinstance(stripe_dev, storage.LVMVolumeGroupDevice):
+                self.editLVMLogicalVolume(vg = stripe_dev)
+                return
+
+    def treeActivateCB(self, *args):
+        curr_dev = self.tree.getCurrentDevice()
+        if isinstance(curr_dev, storage.PartitionDevice) \
+                or isinstance(curr_dev, storage.LVMLogicalVolumeDevice) \
+                or isinstance(curr_dev, storage.LVMVolumeGroupDevice) \
+                or isinstance(curr_dev, storage.MDRaidArrayDevice):
+            self.editCB()
+
+        elif curr_dev == None:
+            # Its probably a free space
+            iparent = self.tree.getCurrentDeviceParent()
+            if iparent == None:
+                # it was not free space, it is a root row.
+                return
+
+            # We execute a create function given the type of parent that was
+            # found.
+            # FIXME: This code might repeat itself.  might be a good idea to
+            # put it in a function.
+            curr_parent = self.tree[iparent]["PyObject"]
+            if curr_parent.partitioned:
+                tempformat = self.storage.defaultFSType
+                device = self.storage.newPartition(fmt_type=tempformat)
+                self.editPartition(device, isNew = True)
+
+            elif isinstance(curr_parent, storage.LVMVolumeGroupDevice):
+                self.editLVMLogicalVolume(vg = curr_parent)
+                return
+
+    def treeSelectCB(self, selection, *args):
+        # The edit and create buttons will be enabled if the user has chosen
+        # something editable and/or deletable.
+        self.deleteButton.set_sensitive(False)
+        self.editButton.set_sensitive(False)
+
+        # I have no idea why this iter might be None.  Its best to return
+        # without any action.
+        model, iter = selection.get_selected()
+        if not iter:
+            return
+
+        # If we return because there is no parent, make sure we show the user
+        # the infoGraph and no stripeGraph.  The 'create' and 'delete' buttons
+        # will be deactivated.
+        iparent = model.iter_parent(iter)
+        if not iparent:
+            self.stripeGraph.shutDown()
+            self.messageGraph.display()
+            return # This is a root row.
+
+        # We destroy the message first.  We will make sure to repaint it later
+        # if no stipe is displayed.  Can't destroy it at the end of this func
+        # because it uncenters the created stripe, if any.
+        self.messageGraph.destroy()
+
+        device = model[iter]['PyObject']
+
+        # See if we need to change what is in the canvas. In all possibilities
+        # we must make sure we have the correct StripeGraph class.
+        if not device:
+            # This is free space.
+            parent = self.tree[iparent]["PyObject"]
+            if parent.partitioned:
+                if not isinstance(self.stripeGraph, DiskStripeGraph):
+                    self.stripeGraph.shutDown()
+                    self.stripeGraph = DiskStripeGraph(self.storage,
+                            drive = parent, cCB = self.tree.selectRowFromObj,
+                            dcCB = self.barviewActivateCB)
+                self.stripeGraph.setDisplayed(parent)
+
+            elif isinstance(parent, storage.LVMVolumeGroupDevice):
+                if not isinstance(self.stripeGraph, LVMStripeGraph):
+                    self.stripeGraph.shutDown()
+                    self.stripeGraph = LVMStripeGraph(self.storage,
+                            vg = parent, cCB = self.tree.selectRowFromObj,
+                            dcCB = self.barviewActivateCB)
+                self.stripeGraph.setDisplayed(parent)
+
+        elif device.partitioned:
+            if not isinstance(self.stripeGraph, DiskStripeGraph):
+                self.stripeGraph.shutDown()
+                self.stripeGraph = DiskStripeGraph(self.storage,
+                        drive = device,
+                        cCB = self.tree.selectRowFromObj,
+                        dcCB = self.barviewActivateCB)
+            self.stripeGraph.setDisplayed(device)
+            # this is deletable but not editable.
+            self.deleteButton.set_sensitive(True)
+
+        elif isinstance(device, storage.PartitionDevice):
+            if not isinstance(self.stripeGraph, DiskStripeGraph):
+                self.stripeGraph.shutDown()
+                self.stripeGraph = DiskStripeGraph(self.storage,
+                        drive = device.parents[0],
+                        cCB = self.tree.selectRowFromObj,
+                        dcCB = self.barviewActivateCB)
+            self.stripeGraph.setDisplayed(device.parents[0])
+            self.stripeGraph.selectSliceFromObj(device)
+            self.deleteButton.set_sensitive(True)
+            self.editButton.set_sensitive(True)
+
+        elif isinstance(device, storage.LVMVolumeGroupDevice):
+            if not isinstance(self.stripeGraph, LVMStripeGraph):
+                self.stripeGraph.shutDown()
+                self.stripeGraph = LVMStripeGraph(self.storage, vg = device,
+                        cCB = self.tree.selectRowFromObj,
+                        dcCB = self.barviewActivateCB)
+            self.stripeGraph.setDisplayed(device)
+            self.deleteButton.set_sensitive(True)
+            self.editButton.set_sensitive(True)
+
+        elif isinstance(device, storage.LVMLogicalVolumeDevice):
+            if not isinstance(self.stripeGraph, LVMStripeGraph):
+                self.stripeGraph.shutDown()
+                self.stripeGraph = LVMStripeGraph(self.storage, vg = device.vg,
+                        cCB = self.tree.selectRowFromObj,
+                        dcCB = self.barviewActivateCB)
+            self.stripeGraph.setDisplayed(device.vg)
+            self.stripeGraph.selectSliceFromObj(device)
+            self.deleteButton.set_sensitive(True)
+            self.editButton.set_sensitive(True)
+
+        elif isinstance(device, storage.MDRaidArrayDevice):
+            if not isinstance(self.stripeGraph, MDRaidArrayStripeGraph):
+                self.stripeGraph.shutDown()
+                self.stripeGraph = MDRaidArrayStripeGraph(self.storage,
+                        md = device,
+                        cCB = self.tree.selectRowFromObj,
+                        dcCB = self.barviewActivateCB)
+            self.stripeGraph.setDisplayed(device)
+            self.deleteButton.set_sensitive(True)
+            self.editButton.set_sensitive(True)
+
+        else:
+            # This means that the user selected something that is not showable
+            # in the bar view.  Just show the information message.
+            self.stripeGraph.shutDown()
+            self.messageGraph.display()
+            self.deleteButton.set_sensitive(False)
+            self.editButton.set_sensitive(False)
+
+    def deleteCB(self, widget):
+        """ Right now we can say that if the device is partitioned we
+            want to delete all of the devices it contains. At some point
+            we will want to support creation and removal of partitionable
+            devices. This will need some work when that time comes.
+        """
+        device = self.tree.getCurrentDevice()
+        if device.partitioned:
+            if doClearPartitionedDevice(self.intf,
+                                        self.storage,
+                                        device):
+                self.refresh()
+        elif doDeleteDevice(self.intf,
+                            self.storage,
+                            device):
+            if isinstance(device, storage.devices.PartitionDevice):
+                justRedraw = False
+            else:
+                justRedraw = True
+                if device.type == "lvmlv" and device in device.vg.lvs:
+                    device.vg._removeLogVol(device)
+
+            self.refresh(justRedraw=justRedraw)
+
+    def createCB(self, *args):
+        # First we must decide what parts of the create_storage_dialog
+        # we will activate.
+
+        # For the Partition checkboxes.
+        # If we see that there is free space in the "Hard Drive" list, then we
+        # must activate all the partition radio buttons (RAID partition,
+        # LVM partition and Standard partition).  We will have only one var to
+        # control all three activations (Since they all depend on the same
+        # thing)
+        activate_create_partition = False
+        free_part_available = hasFreeDiskSpace(self.storage)
+        if free_part_available:
+            activate_create_partition = True
+
+        # We activate the create Volume Group radio button if there is a free
+        # partition with a Physical Volume format.
+        activate_create_vg = False
+        availpvs = len(self.storage.unusedPVs())
+        if (lvm.has_lvm()
+                and getFormat("lvmpv").supported
+                and availpvs > 0):
+            activate_create_vg = True
+
+        # We activate the create RAID dev if there are partitions that have
+        # raid format and are not related to any raid dev.
+        activate_create_raid_dev = False
+        availraidparts = len(self.storage.unusedMDMembers())
+        availminors = self.storage.unusedMDMinors
+        if (len(availminors) > 0
+                and getFormat("software RAID").supported
+                and availraidparts > 1):
+            activate_create_raid_dev = True
+
+        # Must check if all the possibilities are False.  In this case tell the
+        # user that he can't create anything and the reasons.
+        if (not activate_create_partition
+                and not activate_create_vg
+                and not activate_create_raid_dev):
+            self.intf.messageWindow(_("Cannot perform any creation action"),
+                        _("Note that the creation action requires one of the "
+                        "following:\n\n"
+                        "* Free space in one of the Hard Drives.\n"
+                        "* At least two free Software RAID partitions.\n"
+                        "* At least one free physical volume (LVM) partition.\n"
+                        "* At least one Volume Group with free space."),
+                        custom_icon="warning")
+            return
+
+        # We will activate the create lv button when we have a VG to put the
+        # LVs on.
+        activate_create_lv = False
+        vgs_with_free_space = []
+        for vg in self.storage.vgs:
+            if vg.freeSpace > 0:
+                vgs_with_free_space.append(vg)
+        if len(vgs_with_free_space) > 0:
+            activate_create_lv = True
+
+        # GTK crap starts here.
+        create_storage_xml = gtk.glade.XML(
+                gui.findGladeFile("create-storage.glade"), domain="anaconda")
+        self.dialog = create_storage_xml.get_widget("create_storage_dialog")
+
+        # Activate the partition radio buttons if needed.
+        # sp_rb -> standard partition
+        sp_rb = create_storage_xml.get_widget("create_storage_rb_standard_part")
+        # lp_rb -> lvm partition (physical volume)
+        lp_rb = create_storage_xml.get_widget("create_storage_rb_lvm_part")
+        # rp_rb -> RAID partition
+        rp_rb = create_storage_xml.get_widget("create_storage_rb_raid_part")
+        if activate_create_partition:
+            sp_rb.set_sensitive(True)
+            lp_rb.set_sensitive(True)
+            rp_rb.set_sensitive(True)
+
+        # Activate the Volume Group radio buttons if needed.
+        # vg_rb -> Volume Group
+        vg_rb = create_storage_xml.get_widget("create_storage_rb_lvm_vg")
+        if activate_create_vg:
+            vg_rb.set_sensitive(True)
+
+        # Activate the Logical Volume radio button if needed.
+        # We must also take care to control the combo box.
+        lv_rb = create_storage_xml.get_widget("create_storage_rb_lvm_lv")
+        if activate_create_lv:
+            # The combobox will be visible if the radio button is active.
+            # The combobox will be sensitive when the radio button is active.
+            def toggle_vg_cb_CB(button, vg_cb, selected_dev):
+                if button.get_active():
+                    vg_cb.set_sensitive(True)
+
+                    # We set the VG to whatever the user has chosen in the tree
+                    # view. We will fall back on the first item on the list if
+                    # there is no chosen VG.
+                    if selected_dev and selected_dev.name \
+                            and vg_cb.set_active_text(selected_dev.name):
+                        # if set_active is True, we don't need to do anything else
+                        pass
+                    else:
+                        vg_cb.set_active_text(vgs_with_free_space[0].name)
+
+                else:
+                    vg_cb.set_sensitive(False)
+
+            vg_cb_st = gtk.TreeStore(gobject.TYPE_STRING, gobject.TYPE_PYOBJECT)
+            vg_cb = datacombo.DataComboBox(store = vg_cb_st)
+            vg_cb.set_sensitive(False)
+
+            for vg in vgs_with_free_space:
+                # FIXME: the name length might be a problem.
+                vg_cb.append(vg.name, vg)
+            lv_hb = create_storage_xml.get_widget("create_storage_hb_lvm_lv")
+            lv_hb.pack_start(vg_cb)
+
+            lv_rb.set_sensitive(True)
+            selected_dev = self.tree.getCurrentDevice()
+            lv_rb.connect("toggled", toggle_vg_cb_CB, vg_cb, selected_dev)
+
+        # Activate the RAID dev if needed.
+        # rd_rb -> RAID device
+        rd_rb = create_storage_xml.get_widget("create_storage_rb_raid_dev")
+        if activate_create_raid_dev:
+            rd_rb.set_sensitive(True)
+
+        # Before drawing lets select the first radio button that is sensitive:
+        # How can I get sensitivity from gtk.radiobutton?
+        if activate_create_partition:
+            sp_rb.set_active(True)
+            sp_rb.grab_focus()
+        elif activate_create_vg:
+            vg_rb.set_active(True)
+            vg_rb.grab_focus()
+        elif activate_create_raid_dev:
+            rd_rb.set_active(True)
+            rd_rb.grab_focus()
+
+        gui.addFrame(self.dialog)
+        self.dialog.show_all()
+
+        # Lets work the information messages with CB
+        # The RAID info message
+        rinfo_button = create_storage_xml.get_widget("create_storage_info_raid")
+        whatis_r = _("Software RAID allows you to combine several disks into "
+                    "a larger RAID device.  A RAID device can be configured "
+                    "to provide additional speed and reliability compared "
+                    "to using an individual drive.  For more information on "
+                    "using RAID devices please consult the %s "
+                    "documentation.\n") % (productName,)
+        whatneed_r = _("To use RAID you must first create at least two "
+                "partitions of type 'software RAID'.  Then you can create a "
+                "RAID device that can be formatted and mounted.\n\n")
+        whathave_r = P_(
+                "You currently have %d software RAID partition free to use.",
+                "You currently have %d software RAID partitions free to use.",
+                availraidparts) % (availraidparts,)
+        rinfo_message = "%s\n%s%s" % (whatis_r, whatneed_r, whathave_r)
+        rinfo_cb = lambda x : self.intf.messageWindow(_("About RAID"),
+                                rinfo_message, custom_icon="information")
+        rinfo_button.connect("clicked", rinfo_cb)
+
+        # The LVM info message
+        lvminfo_button = create_storage_xml.get_widget("create_storage_info_lvm")
+        whatis_lvm = _("Logical Volume Manager (LVM) is a 3 level construct. "
+                "The first level is made up of disks or partitions formatted with "
+                "LVM metadata called Physical Volumes (PV).  A Volume Group "
+                "(VG) sits on top of one or more PVs. The VG, in turn, is the "
+                "base to create one or more Logical Volumes (LV).  Note that a "
+                "VG can be an aggregate of PVs from multiple physical disks.  For "
+                "more information on using LVM please consult the %s "
+                "documentation\n") % (productName, )
+        whatneed_lvm = _("To create a PV you need a partition with "
+                "free space.  To create a VG you need a PV that is not "
+                "part of any existing VG.  To create an LV you need a VG with "
+                "free space.\n\n")
+        whathave_lvm = P_("You currently have %d available PV free to use.\n",
+                            "You currently have %d available PVs free to use.\n",
+                            availpvs) % (availpvs, )
+        if free_part_available:
+            whathave_lvm = whathave_lvm + _("You currently have free space to "
+                    "create PVs.")
+        lvminfo_message = "%s\n%s%s" % (whatis_lvm, whatneed_lvm, whathave_lvm)
+        lvminfo_cb = lambda x : self.intf.messageWindow(_("About LVM"),
+                                    lvminfo_message, custom_icon="information")
+        lvminfo_button.connect("clicked", lvminfo_cb)
+
+        dialog_rc = self.dialog.run()
+
+        # If Cancel was pressed
+        if dialog_rc == 0:
+            self.dialog.destroy()
+            return
+
+        # If Create was pressed  Make sure we do a dialog.destroy before
+        # calling any other screen.  We don't want the create dialog to show
+        # in the back when we pop up other screens.
+        if dialog_rc != 1:
+            log.error("I received a dialog_rc != 1 (%d) witch should not "
+                    "happen" % dialog_rc)
+            self.dialog.destroy()
+            return
+
+        self.dialog.destroy()
+        if rp_rb.get_active():
+            member = self.storage.newPartition(fmt_type="mdmember")
+            self.editPartition(member, isNew = True, restrictfs=["mdmember"])
+            return
+
+        elif rd_rb.get_active():
+            array = self.storage.newMDArray(fmt_type=self.storage.defaultFSType)
+            self.editRaidArray(array, isNew = True)
+            return
+
+        elif lp_rb.get_active():
+            member = self.storage.newPartition(fmt_type="lvmpv")
+            self.editPartition(member, isNew = True, restrictfs=["lvmpv"])
+            return
+
+        elif vg_rb.get_active():
+            tempvg = self.storage.newVG()
+            self.editLVMVolumeGroup(tempvg, isNew = True)
+            return
+
+        elif lv_rb.get_active():
+            selected_vg = vg_cb.get_active_value()
+            self.editLVMLogicalVolume(vg = selected_vg)
+            return
+
+        elif sp_rb.get_active():
+            tempformat = self.storage.defaultFSType
+            device = self.storage.newPartition(fmt_type=tempformat)
+            self.editPartition(device, isNew = True)
+            return
+
+    def resetCB(self, *args):
+        if not confirmResetPartitionState(self.intf):
+            return
+
+        self.stripeGraph.shutDown()
+        self.storage.reset()
+        self.tree.clear()
+        self.populate()
+
+    def refresh(self, justRedraw=None):
+        log.debug("refresh: justRedraw=%s" % justRedraw)
+        self.stripeGraph.shutDown()
+        self.tree.clear()
+
+        if justRedraw:
+            rc = 0
+        else:
+            try:
+                doPartitioning(self.storage)
+                rc = 0
+            except PartitioningError, msg:
+                self.intf.messageWindow(_("Error Partitioning"),
+                       _("Could not allocate requested partitions: %s.") % (msg),
+                                        custom_icon="error")
+                rc = -1
+            except PartitioningWarning, msg:
+                # XXX somebody other than me should make this look better
+                # XXX this doesn't handle the 'delete /boot partition spec' case
+                #     (it says 'add anyway')
+                dialog = gtk.MessageDialog(self.parent, 0, gtk.MESSAGE_WARNING,
+                                           gtk.BUTTONS_NONE,
+                                           _("Warning: %s.") % (msg))
+                gui.addFrame(dialog)
+                button = gtk.Button(_("_Modify Partition"))
+                dialog.add_action_widget(button, 1)
+                button = gtk.Button(_("_Continue"))
+                dialog.add_action_widget(button, 2)
+                dialog.set_position(gtk.WIN_POS_CENTER)
+
+                dialog.show_all()
+                rc = dialog.run()
+                dialog.destroy()
+                
+                if rc == 1:
+                    rc = -1
+                else:
+                    rc = 0
+                    all_devices = self.storage.devicetree.devices
+                    bootDevs = [d for d in all_devices if d.bootable]
+                    #if reqs:
+                    #    for req in reqs:
+                    #        req.ignoreBootConstraints = 1
+
+	if not rc == -1:
+	    self.populate()
+
+        return rc
+
+    def editCB(self, *args):
+        device = self.tree.getCurrentDevice()
+        reason = self.storage.deviceImmutable(device, ignoreProtected=True)
+        if reason:
+            self.intf.messageWindow(_("Unable To Edit"),
+                                    _("You cannot edit this device:\n\n%s")
+                                    % reason,
+                                    custom_icon="error")
+            return
+
+        if device.type == "mdarray":
+            self.editRaidArray(device)
+        elif device.type == "lvmvg":
+            self.editLVMVolumeGroup(device)
+        elif device.type == "lvmlv":
+            self.editLVMLogicalVolume(lv = device)
+        elif isinstance(device, storage.devices.PartitionDevice):
+            self.editPartition(device)
+
+    # isNew implies that this request has never been successfully used before
+    def editRaidArray(self, raiddev, isNew = False):
+        # r_d_g -> raid_dialog_gui
+        raideditor = r_d_g.RaidEditor(self.storage, self.intf, self.parent,
+                raiddev, isNew)
+
+        while True:
+            actions = raideditor.run()
+
+            for action in actions:
+                # FIXME: this needs to handle exceptions
+                self.storage.devicetree.registerAction(action)
+
+	    if self.refresh(justRedraw=True):
+                actions.reverse()
+                for action in actions:
+                    self.storage.devicetree.cancelAction(action)
+                    if self.refresh():
+                        raise RuntimeError, ("Returning partitions to state "
+                                             "prior to RAID edit failed")
+                continue
+	    else:
+		break
+
+	raideditor.destroy()		
+
+
+    def editPartition(self, device, isNew = False, restrictfs = None):
+        # p_d_g -> partition_dialog_gui
+        parteditor = p_d_g.PartitionEditor(self.anaconda, self.parent, device,
+                isNew = isNew, restrictfs = restrictfs)
+
+        while True:
+            orig_device = copy.copy(device)
+            actions = parteditor.run()
+
+            for action in actions:
+                # XXX we should handle exceptions here
+                self.anaconda.storage.devicetree.registerAction(action)
+
+            if self.refresh(justRedraw=not actions):
+                # autopart failed -- cancel the actions and try to get
+                # back to previous state
+                actions.reverse()
+                for action in actions:
+                    self.anaconda.storage.devicetree.cancelAction(action)
+
+                # FIXME: proper action/device management would be better
+                if not isNew:
+                    device.req_size = orig_device.req_size
+                    device.req_base_size = orig_device.req_base_size
+                    device.req_grow = orig_device.req_grow
+                    device.req_max_size = orig_device.req_max_size
+                    device.req_primary = orig_device.req_primary
+                    device.req_disks = orig_device.req_disks
+
+                if self.refresh():
+                    # this worked before and doesn't now...
+                    raise RuntimeError, ("Returning partitions to state "
+                                         "prior to edit failed")
+            else:
+		break
+
+	parteditor.destroy()
+	return 1
+
+    def editLVMVolumeGroup(self, device, isNew = False):
+        # l_d_g -> lvm_dialog_gui
+        vgeditor = l_d_g.VolumeGroupEditor(self.anaconda, self.intf, self.parent,
+                device, isNew)
+
+        while True:
+            actions = vgeditor.run()
+
+            for action in actions:
+                # FIXME: handle exceptions
+                self.storage.devicetree.registerAction(action)
+
+	    if self.refresh(justRedraw=True):
+                actions.reverse()
+                for action in actions:
+                    self.storage.devicetree.cancelAction(action)
+
+                if self.refresh():
+                    raise RuntimeError, ("Returning partitions to state "
+                                         "prior to edit failed")
+		continue
+	    else:
+		break
+
+	vgeditor.destroy()
+
+    def editLVMLogicalVolume (self, lv = None, vg = None):
+        """Will be consistent with the state of things and use this funciton
+        for creating and editing LVs.
+
+        lv -- the logical volume to edit.  If this is set there is no need
+              for the other two arguments.
+        vg -- the volume group where the new lv is going to be created. This
+              will only be relevant when we are createing an LV.
+        """
+
+        if lv != None:
+            # l_d_g -> lvm_dialog_gui
+            vgeditor = l_d_g.VolumeGroupEditor(self.anaconda, self.intf, self.parent,
+                    lv.vg, isNew = False)
+            lv = vgeditor.lvs[lv.lvname]
+            isNew = False
+
+        elif vg != None:
+            # l_d_g -> lvm_dialog_gui
+            vgeditor = l_d_g.VolumeGroupEditor(self.anaconda, self.intf, self.parent,
+                    vg, isNew = False)
+            tempvg = vgeditor.getTempVG()
+            name = self.storage.createSuggestedLVName(tempvg)
+            format = getFormat(self.storage.defaultFSType)
+            vgeditor.lvs[name] = {'name': name,
+                              'size': vg.freeSpace,
+                              'format': format,
+                              'originalFormat': format,
+                              'stripes': 1,
+                              'logSize': 0,
+                              'snapshotSpace': 0,
+                              'exists': False}
+            lv = vgeditor.lvs[name]
+            isNew = True
+
+        else:
+            # This is non-sense.
+            return
+
+
+        while True:
+            vgeditor.editLogicalVolume(lv, isNew = isNew)
+            actions = vgeditor.convertToActions()
+
+            for action in actions:
+                # FIXME: handle exceptions
+                self.storage.devicetree.registerAction(action)
+
+            if self.refresh(justRedraw=True):
+                actions.reverse()
+                for action in actions:
+                    self.storage.devicetree.cancelAction(action)
+
+                if self.refresh():
+                    raise RuntimeError, ("Returning partitions to state "
+                                         "prior to edit failed")
+                continue
+            else:
+                break
+
+        vgeditor.destroy()
+
+    def getScreen(self, anaconda):
+        self.anaconda = anaconda
+        self.storage = anaconda.storage
+        self.intf = anaconda.intf
+        self.checkmark_pixbuf = gui.getPixbuf("checkMark.png")
+        self.lock_pixbuf = gui.getPixbuf("gnome-lock.png")
+
+        checkForSwapNoMatch(anaconda)
+
+        # Beginning of the GTK stuff.
+        # create the operational buttons
+        buttonBox = gtk.HButtonBox()
+        buttonBox.set_spacing(6)
+        buttonBox.set_layout(gtk.BUTTONBOX_END)
+
+        ops = ((_("_Create"), self.createCB),
+               (_("_Edit"), self.editCB),
+               (_("_Delete"), self.deleteCB),
+               (_("Re_set"), self.resetCB))
+
+        for label, cb in ops:
+            button = gtk.Button(label)
+            buttonBox.add (button)
+            button.connect ("clicked", cb)
+
+            # We need these to control their sensitivity.
+            if label == _("_Edit"):
+                self.editButton = button
+                self.editButton.set_sensitive(False)
+            elif label == _("_Delete"):
+                self.deleteButton = button
+                self.deleteButton.set_sensitive(False)
+
+        # Create the disk tree (Fills the tree and the Bar View)
+        self.tree = DiskTreeModel()
+        self.treeView = self.tree.getTreeView()
+        self.treeView.connect('row-activated', self.treeActivateCB)
+        self.treeViewSelection = self.treeView.get_selection()
+        self.treeViewSelection.connect("changed", self.treeSelectCB)
+        self.stripeGraph = StripeGraph()
+        self.messageGraph = MessageGraph(self.stripeGraph.getCanvas(),
+                _("Please Select A Device"))
+        self.populate(initial = 1)
+
+        # Create the top scroll window
+        # We don't actually need a *scroll* window but nuthing else worked.
+        hadj = gtk.Adjustment(step_incr = 5.0)
+        vadj = gtk.Adjustment(step_incr = 5.0)
+        swt = gtk.ScrolledWindow(hadjustment = hadj, vadjustment = vadj)
+        swt.add(self.stripeGraph.getCanvas())
+        swt.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
+        swt.set_shadow_type(gtk.SHADOW_IN)
+
+        # Create the bottom scroll window
+        swb = gtk.ScrolledWindow()
+        swb.add(self.treeView)
+        swb.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
+        swb.set_shadow_type(gtk.SHADOW_IN)
+
+        # Create main vertical box and add everything.
+        MVbox = gtk.VBox(False, 5)
+        MVbox.pack_start(swt, False, False)
+        MVbox.pack_start(swb, True)
+        MVbox.pack_start(buttonBox, False, False)
+        MVbox.pack_start(gtk.HSeparator(), False)
+
+        return MVbox
diff --git a/pyanaconda/iw/partition_ui_helpers_gui.py b/pyanaconda/iw/partition_ui_helpers_gui.py
new file mode 100644
index 0000000..f38adea
--- /dev/null
+++ b/pyanaconda/iw/partition_ui_helpers_gui.py
@@ -0,0 +1,445 @@
+#
+# partition_ui_helpers_gui.py: convenience functions for partition_gui.py
+#                              and friends.
+#
+# Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007  Red Hat, Inc.
+# 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 as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# 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, see <http://www.gnu.org/licenses/>.
+#
+# Author(s): Michael Fulbright <msf@xxxxxxxxxx>
+#
+
+import gobject
+import gtk
+import checklist
+import datacombo
+import iutil
+
+from constants import *
+from partIntfHelpers import *
+from storage.formats import *
+
+import gettext
+_ = lambda x: gettext.ldgettext("anaconda", x)
+
+FLAG_FORMAT = 1
+FLAG_MIGRATE = 2
+
+class WideCheckList(checklist.CheckList):
+    def toggled_item(self, data, row):
+
+	rc = True
+	if self.clickCB:
+	    rc = self.clickCB(data, row)
+
+	if rc:
+	    checklist.CheckList.toggled_item(self, data, row)
+
+    
+    def __init__(self, columns, store, clickCB=None, sensitivity=False):
+        checklist.CheckList.__init__(self, columns=columns,
+                                     custom_store=store,
+                                     sensitivity=sensitivity)
+
+        # make checkbox column wider
+        column = self.get_column(columns)
+        self.set_expander_column(column)
+        column = self.get_column(0)
+        column.set_sizing(gtk.TREE_VIEW_COLUMN_FIXED)
+        column.set_fixed_width(25)
+
+	self.clickCB = clickCB
+
+def createAlignedLabel(text):
+    label = gtk.Label(text)
+    label.set_alignment(0.0, 0.5)
+    label.set_property("use-underline", True)
+
+    return label
+
+defaultMountPoints = ['/', '/boot', '/home', '/tmp', '/usr',
+                      '/var', '/usr/local', '/opt']
+
+if iutil.isS390():
+    # Many s390 have 2G DASDs, we recomment putting /usr/share on its own DASD
+    defaultMountPoints.insert(5, '/usr/share')
+
+if iutil.isEfi():
+    defaultMountPoints.insert(2, '/boot/efi')
+
+def createMountPointCombo(request, excludeMountPoints=[]):
+    mountCombo = gtk.combo_box_entry_new_text()
+
+    mntptlist = []
+    label = getattr(request.format, "label", None)
+    if request.exists and label and label.startswith("/"):
+        mntptlist.append(label)
+        idx = 0
+
+    for p in defaultMountPoints:
+        if p in excludeMountPoints:
+            continue
+
+        if not p in mntptlist and (p[0] == "/"):
+            mntptlist.append(p)
+
+    map(mountCombo.append_text, mntptlist)
+
+    if (request.format.type or request.format.migrate) and \
+       request.format.mountable:
+        mountpoint = request.format.mountpoint
+        mountCombo.set_sensitive(1)
+        if mountpoint:
+            mountCombo.get_children()[0].set_text(mountpoint)
+        else:
+            mountCombo.get_children()[0].set_text("")
+    else:
+        mountCombo.get_children()[0].set_text(_("<Not Applicable>"))
+        mountCombo.set_sensitive(0)
+
+    mountCombo.set_data("saved_mntpt", None)
+
+    return mountCombo
+
+def setMntPtComboStateFromType(fmt_class, mountCombo):
+    prevmountable = mountCombo.get_data("prevmountable")
+    mountpoint = mountCombo.get_data("saved_mntpt")
+
+    format = fmt_class()
+    if prevmountable and format.mountable:
+        return
+
+    if format.mountable:
+        mountCombo.set_sensitive(1)
+        if mountpoint != None:
+            mountCombo.get_children()[0].set_text(mountpoint)
+        else:
+            mountCombo.get_children()[0].set_text("")
+    else:
+        if mountCombo.get_children()[0].get_text() != _("<Not Applicable>"):
+            mountCombo.set_data("saved_mntpt", mountCombo.get_children()[0].get_text())
+        mountCombo.get_children()[0].set_text(_("<Not Applicable>"))
+        mountCombo.set_sensitive(0)
+
+    mountCombo.set_data("prevmountable", format.mountable)
+
+def fstypechangeCB(widget, mountCombo):
+    fstype = widget.get_active_value()
+    setMntPtComboStateFromType(fstype, mountCombo)
+
+def createAllowedDrivesStore(disks, reqdrives, drivelist, selectDrives=True,
+                             disallowDrives=[]):
+    drivelist.clear()
+    for disk in disks:
+        selected = 0
+
+        if selectDrives:
+            if reqdrives:
+                if disk.name in reqdrives:
+                    selected = 1
+            else:
+                if disk.name not in disallowDrives:
+                    selected = 1
+
+        sizestr = "%8.0f MB" % disk.size
+        drivelist.append_row((disk.name,
+                              sizestr,
+                              disk.description),
+                             selected)
+
+    if len(disks) < 2:
+        drivelist.set_sensitive(False)
+    else:
+        drivelist.set_sensitive(True)
+
+def createAllowedDrivesList(disks, reqdrives, selectDrives=True, disallowDrives=[]):
+    store = gtk.TreeStore(gobject.TYPE_BOOLEAN,
+                          gobject.TYPE_STRING,
+                          gobject.TYPE_STRING,
+                          gobject.TYPE_STRING,
+                          gobject.TYPE_BOOLEAN)
+    drivelist = WideCheckList(3, store, sensitivity=True)
+    createAllowedDrivesStore(disks, reqdrives, drivelist, selectDrives=selectDrives,
+                             disallowDrives=disallowDrives)
+
+    return drivelist
+    
+    
+
+# pass in callback for when fs changes because of python scope issues
+def createFSTypeMenu(format, fstypechangeCB, mountCombo,
+                     availablefstypes = None, ignorefs = None):
+    store = gtk.TreeStore(gobject.TYPE_STRING, gobject.TYPE_PYOBJECT)
+    fstypecombo = datacombo.DataComboBox(store)
+    
+    if availablefstypes:
+        names = availablefstypes
+    else:
+        names = device_formats.keys()
+    if format and format.supported and format.formattable:
+        default = format.type
+    else:
+        default = get_default_filesystem_type()
+        
+    names.sort()
+    defindex = 0
+    i = 0
+    for name in names:
+        # we could avoid instantiating them all if we made a static class
+        # method that does what the supported property does
+        format = device_formats[name]()
+        if not format.supported:
+            continue
+
+        if ignorefs and name in ignorefs:
+            continue
+        
+        if format.formattable:
+            fstypecombo.append(format.name, device_formats[name])
+            if default == name:
+                defindex = i
+                defismountable = format.mountable
+            i = i + 1
+
+    fstypecombo.set_active(defindex)
+
+    if fstypechangeCB and mountCombo:
+        fstypecombo.connect("changed", fstypechangeCB, mountCombo)
+
+    if mountCombo:
+        mountCombo.set_data("prevmountable",
+                            fstypecombo.get_active_value()().mountable)
+        mountCombo.connect("changed", mountptchangeCB, fstypecombo)
+
+    return fstypecombo
+
+def mountptchangeCB(widget, fstypecombo):
+    if iutil.isEfi() and widget.get_children()[0].get_text() == "/boot/efi":
+        fstypecombo.set_active_text(getFormat("efi").name)
+    if widget.get_children()[0].get_text() == "/boot":
+        fstypecombo.set_active_text(get_default_filesystem_type(boot=True))
+
+def resizeOptionCB(widget, data):
+    (formatcb, resizesb) = data
+    formatcb.set_sensitive(not widget.get_active())
+    resizesb.set_sensitive(widget.get_active())
+
+def formatOptionResizeCB(widget, data):
+    (resizecb, resizesb, fmt) = data
+
+    if widget.get_active():
+        lower = 1
+    else:
+        lower = resizesb.get_data("reqlower")
+
+    adj = resizesb.get_adjustment()
+    adj.lower = lower
+    resizesb.set_adjustment(adj)
+
+    if resizesb.get_value_as_int() < lower:
+        resizesb.set_value(adj.lower)
+
+    resizecb.set_sensitive(not widget.get_active())
+    resizesb.set_sensitive(resizecb.get_active())
+
+def formatMigrateOptionCB(widget, data):
+    (sensitive,) = widget.get_properties('sensitive')
+    if not sensitive:
+        return
+
+    (combowidget, mntptcombo, fs, lukscb, othercombo, othercb, flag) = data
+    combowidget.set_sensitive(widget.get_active())
+
+    if othercb is not None:
+        othercb.set_sensitive(not widget.get_active())
+        othercb.set_active(False)
+
+        if othercombo is not None:
+            othercombo.set_sensitive(othercb.get_active())
+
+    if lukscb is not None:
+        lukscb.set_data("formatstate", widget.get_active())
+        if not widget.get_active():
+            # set "Encrypt" checkbutton to match partition's initial state
+            lukscb.set_active(lukscb.get_data("encrypted"))
+            lukscb.set_sensitive(False)
+        else:
+            lukscb.set_sensitive(True)
+
+    # inject event for fstype menu
+    if widget.get_active():
+        fstype = combowidget.get_active_value()
+        setMntPtComboStateFromType(fstype, mntptcombo)
+        combowidget.grab_focus()
+    else:
+        if isinstance(fs, type(fs)):
+            fs = type(fs)
+
+        setMntPtComboStateFromType(fs, mntptcombo)
+
+
+def createPreExistFSOptionSection(origrequest, maintable, row, mountCombo,
+                                  partitions, ignorefs=[], luksdev=None):
+    """ createPreExistFSOptionSection: given inputs for a preexisting partition,
+        create a section that will provide format and migrate options
+
+        Returns the value of row after packing into the maintable,
+        and a dictionary consistenting of:
+           formatcb      - checkbutton for 'format as new fs'
+           fstype        - part of format fstype menu
+           fstypeMenu    - part of format fstype menu
+           migratecb     - checkbutton for migrate fs
+           migfstypeMenu - menu for migrate fs types
+           lukscb        - checkbutton for 'encrypt using LUKS/dm-crypt'
+           resizecb      - checkbutton for 'resize fs'
+           resizesb      - spinbutton with resize target
+    """
+    rc = {}
+
+    if luksdev:
+        origfs = luksdev.format
+    else:
+        origfs = origrequest.format
+
+    if origfs.formattable or not origfs.type:
+        formatcb = gtk.CheckButton(label=_("_Format as:"))
+        maintable.attach(formatcb, 0, 1, row, row + 1)
+        formatcb.set_active(origfs.formattable and not origfs.exists)
+        rc["formatcb"] = formatcb
+
+        fstypeCombo = createFSTypeMenu(origfs, fstypechangeCB,
+                                       mountCombo, ignorefs=ignorefs)
+        fstypeCombo.set_sensitive(formatcb.get_active())
+        maintable.attach(fstypeCombo, 1, 2, row, row + 1)
+        row += 1
+        rc["fstypeCombo"] = fstypeCombo
+    else:
+        formatcb = None
+        fstypeCombo = None
+
+    if formatcb and not formatcb.get_active() and not origfs.migrate:
+        mountCombo.set_data("prevmountable", origfs.mountable)
+
+    # this gets added to the table a bit later on
+    lukscb = gtk.CheckButton(_("_Encrypt"))
+
+    if origfs.migratable and origfs.exists:
+        migratecb = gtk.CheckButton(label=_("Mi_grate filesystem to:"))
+        if formatcb is not None:
+            migratecb.set_active(origfs.migrate and (not formatcb.get_active()))
+        else:
+            migratecb.set_active(origfs.migrate)
+
+        migtypes = [origfs.migrationTarget]
+
+        maintable.attach(migratecb, 0, 1, row, row + 1)
+        migfstypeCombo = createFSTypeMenu(origfs,
+                                          None, None,
+                                          availablefstypes = migtypes)
+        migfstypeCombo.set_sensitive(migratecb.get_active())
+        maintable.attach(migfstypeCombo, 1, 2, row, row + 1)
+        row = row + 1
+        rc["migratecb"] = migratecb
+        rc["migfstypeCombo"] = migfstypeCombo
+        migratecb.connect("toggled", formatMigrateOptionCB,
+                          (migfstypeCombo, mountCombo, origfs, None,
+                           fstypeCombo, formatcb, FLAG_MIGRATE))
+    else:
+        migratecb = None
+        migfstypeCombo = None
+
+    if formatcb:
+        formatcb.connect("toggled", formatMigrateOptionCB,
+                         (fstypeCombo, mountCombo, origfs, lukscb,
+                          migfstypeCombo, migratecb, FLAG_FORMAT))
+
+    if origrequest.resizable and origfs.exists:
+        resizecb = gtk.CheckButton(label=_("_Resize"))
+        resizecb.set_active(origfs.resizable and \
+                            (origfs.currentSize != origfs.targetSize) and \
+                            (origfs.currentSize != 0))
+        rc["resizecb"] = resizecb
+        maintable.attach(resizecb, 0, 1, row, row + 1)
+
+        if origrequest.targetSize is not None:
+            value = origrequest.targetSize
+        else:
+            value = origrequest.size
+
+        reqlower = 1
+        requpper = origrequest.maxSize
+
+        if origfs.exists:
+            reqlower = origrequest.minSize
+
+            if origrequest.type == "partition":
+                geomsize = origrequest.partedPartition.geometry.getSize(unit="MB")
+                if (geomsize != 0) and (requpper > geomsize):
+                    requpper = geomsize
+
+        adj = gtk.Adjustment(value = value, lower = reqlower,
+                             upper = requpper, step_incr = 1)
+        resizesb = gtk.SpinButton(adj, digits = 0)
+        resizesb.set_property('numeric', True)
+        resizesb.set_data("requpper", requpper)
+        resizesb.set_data("reqlower", reqlower)
+        rc["resizesb"] = resizesb
+        maintable.attach(resizesb, 1, 2, row, row + 1)
+        resizecb.connect('toggled', resizeOptionCB, (formatcb, resizesb))
+        resizeOptionCB(resizecb, (formatcb, resizesb))
+        row = row + 1
+
+        if formatcb:
+            formatcb.connect("toggled", formatOptionResizeCB,
+                             (resizecb, resizesb, origfs))
+
+    if luksdev:
+        lukscb.set_active(1)
+
+    if origrequest.originalFormat.type == "luks":
+        lukscb.set_data("encrypted", 1)
+    else:
+        lukscb.set_data("encrypted", 0)
+
+    if formatcb:
+        lukscb.set_sensitive(formatcb.get_active())
+        lukscb.set_data("formatstate", formatcb.get_active())
+    else:
+        lukscb.set_sensitive(0)
+        lukscb.set_data("formatstate", 0)
+
+    rc["lukscb"] = lukscb
+    maintable.attach(lukscb, 0, 2, row, row + 1)
+    row = row + 1
+
+    return (row, rc)
+
+# do tests we just want in UI for now, not kickstart
+def doUIRAIDLVMChecks(request, storage):
+    fstype = request.format.name
+    numdrives = len(storage.partitioned)
+    
+##     if fstype and fstype.getName() == "physical volume (LVM)":
+## 	if request.grow:
+## 	    return (_("Partitions of type '%s' must be of fixed size, and "
+## 		     "cannot be marked to fill to use available space.")) % (fstype.getName(),)
+
+    if fstype in ["physical volume (LVM)", "software RAID"]:
+	if numdrives > 1 and (not request.req_disks or len(request.req_disks) > 1):
+	    return (_("Partitions of type '%s' must be constrained to "
+		      "a single drive.  To do this, select the "
+		      "drive in the 'Allowable Drives' checklist.")) % (fstype.getName(),)
+    
+    return None
diff --git a/pyanaconda/iw/pixmapRadioButtonGroup_gui.py b/pyanaconda/iw/pixmapRadioButtonGroup_gui.py
new file mode 100644
index 0000000..0ded4e2
--- /dev/null
+++ b/pyanaconda/iw/pixmapRadioButtonGroup_gui.py
@@ -0,0 +1,248 @@
+#
+# pixmapRadioButtonGroup_gui.py: general purpose radio button group with pixmaps
+#                                and descriptions
+#
+# Copyright (C) 2000, 2001, 2002  Red Hat, Inc.  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 as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# 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, see <http://www.gnu.org/licenses/>.
+#
+
+import gtk
+from constants import *
+
+class pixmapRadioButtonGroup:
+
+    def toggled (self, widget):
+	if self.togglecb is not None:
+
+	    name = None
+	    for b in self.buttonToEntry.keys():
+		if b == widget:
+		    name = self.buttonToEntry[b]
+	    
+	    self.togglecb(widget, name)
+	    
+#        if not widget.get_active ():
+#	    return
+
+    #
+    # expects a gtk pixmap for pixmap
+    #
+    def pixRadioButton (self, group, labelstr, pixmap, description=None):
+        pix = pixmap
+
+	hbox = gtk.HBox (False, 18)
+	if pix != None:
+	    hbox.pack_start (pix, True, True, 0)
+
+	label = gtk.Label("")
+	label.set_line_wrap(True)
+	label.set_markup("<b>"+labelstr+"</b>")
+	label.set_alignment (0.0, 0.5)
+	if description is not None:
+	    label.set_markup ("<b>%s</b>\n<small>%s</small>" %(labelstr,
+                                                               description))
+	    label.set_line_wrap(True)
+	    if  gtk.gdk.screen_width() > 640:
+		wraplen = 600
+	    else:
+		wraplen = 250
+		
+	    label.set_size_request(wraplen, -1)
+	label.set_use_markup (True)
+	label.set_use_underline(True)
+	    
+	hbox.pack_start (label, True, True, 0)
+	button = gtk.RadioButton (group)
+	button.add (hbox)
+	label.set_mnemonic_widget(button)
+        return button
+
+    # add a entry to end of list
+    # (label and descr should already be passed through _())
+    def addEntry(self, name, label, pixmap=None, descr=None, userdata=None):
+	node = {}
+	node["name"] = name
+	node["label"] = label
+	node["descr"] = descr
+	node["pixmap"] = pixmap
+	node["userdata"] = userdata
+	self.entries.append(node)
+
+    #
+    # finds entry matching name and makes it current
+    #
+    # MUST call AFTER calling render, since widgets are not created yet otherwise
+    #
+    def setCurrent(self, name):
+	for b in self.buttonToEntry.keys():
+	    if self.buttonToEntry[b] == name:
+		b.set_active(1)
+
+	
+
+    #
+    # returns name of current selection
+    #
+    # MUST call AFTER calling render, since widgets are not created yet otherwise
+    #
+    def getCurrent(self):
+	for b in self.buttonToEntry.keys():
+	    if b.get_active():
+		return self.buttonToEntry[b]
+
+
+    #
+    # MUST call AFTER calling render, since widgets are not created yet otherwise
+    #
+    def packWidgetInEntry(self, name, widget):
+	# find button for name
+	for b in self.buttonToEntry.keys():
+	    if self.buttonToEntry[b] == name:
+		# now find box for button
+		for (button, box, buttons) in self.topLevelButtonList:
+		    if button == b:
+			box.pack_end(widget)
+			return
+
+    def setToggleCallback(self, cb):
+	self.togglecb = cb
+	    
+    # render resulting list, returns a box you can pack
+    #
+    # call this after adding all parents and nodes
+    def render(self):
+
+	radioGroup = None
+	buttons = []
+	for item in self.entries:
+	    box = gtk.VBox (False, 6)
+	    name = item["name"]
+	    label = item["label"]
+	    pixmap = item["pixmap"]
+	    descr = item["descr"]
+	    radioGroup = self.pixRadioButton(radioGroup, label, pixmap,
+					     description=descr)
+	    buttons.append(radioGroup)
+	    self.buttonToEntry[radioGroup] = name
+
+	    self.topLevelButtonList.append((radioGroup, box, buttons))
+	    radioGroup.connect("toggled", self.toggled)
+
+	finalVBox = gtk.VBox(False, 6)
+	finalVBox.set_border_width (5)
+
+	for (button, box, buttons) in self.topLevelButtonList:
+	    vbox = gtk.VBox (False, 6)
+	    finalVBox.pack_start(vbox, False, False)
+	    vbox.pack_start (button, False, False)
+	    
+	    if box:
+		tmphbox = gtk.HBox(False)
+
+		crackhbox = gtk.HBox(False)
+		crackhbox.set_size_request(50, -1)
+
+		tmphbox.pack_start(crackhbox, False, False)
+		tmphbox.pack_start(box, True, True)
+		vbox.pack_start(tmphbox, False, False)
+		
+        return finalVBox
+    
+    
+    # InstallPathWindow tag="instpath"
+    def __init__(self):
+	self.entries = []
+	self.topLevelButtonList = []
+	self.buttonToEntry = {}
+	self.togglecb = None
+
+
+if __name__ == "__main__":
+    def readPixmap(fn):
+	pixbuf = gtk.gdk.pixbuf_new_from_file(fn)
+
+	source = gtk.IconSource()
+	source.set_pixbuf(pixbuf)
+	source.set_size(gtk.ICON_SIZE_DIALOG)
+	source.set_size_wildcarded(False)
+	iconset = gtk.IconSet()
+	iconset.add_source(source)
+	p = gtk.image_new_from_icon_set(iconset, gtk.ICON_SIZE_DIALOG)
+
+	return p
+
+    def nowquit(widget):
+	global r
+
+	print("selection -> %s" % (r.getCurrent(),))
+
+	gtk.mainquit()
+	
+    win = gtk.Window()
+    win.connect('destroy', nowquit)
+
+
+    if 0:
+	opts = ['8.0 - /dev/hda1', '7.1 - /dev/hda5']
+    else:
+	opts = ['8.0 - /dev/hda1']
+
+    label = "The following installed system will be upgraded:"
+    upgradeoption = gtk.OptionMenu()
+    upgradeoptionmenu = gtk.Menu()
+    for lev in opts:
+	item = gtk.MenuItem(lev)
+	item.show()        
+	upgradeoptionmenu.add(item)
+
+    upboxtmp = gtk.VBox(False, 5)
+    l = gtk.Label(label)
+    l.set_alignment(0.0, 0.0)
+    upboxtmp.pack_start(l)
+    upboxtmp.pack_start(upgradeoption)
+    upgradeoption.set_menu(upgradeoptionmenu)
+
+    upgradeoption.set_sensitive(0)
+    
+    # hack indent it
+    upbox = gtk.HBox(False)
+
+    crackhbox = gtk.HBox(False)
+    crackhbox.set_size_request(80, -1)
+
+    upbox.pack_start(crackhbox, False, False)
+    upbox.pack_start(upboxtmp, True, True)
+
+    r = pixmapRadioButtonGroup()
+    r.addEntry("upgrade", "_Upgrade Existing Installation", pixmap=readPixmap("/usr/share/anaconda/pixmaps/upgrade.png"),  descr="Choose this option if you would like to upgrade your existing %s system.  This option will preserve the data on your drive" % (productName,), userdata="data")
+
+    r.addEntry("install", "_Reinstall %s" %(productName,), pixmap=readPixmap("../pixmaps/install.png"),
+	       descr="Choose this option to reinstall your system.  Depending on how you partition your system, your previous data may be lost.", userdata="data2")
+    b = r.render()
+    r.setCurrent("Don't Upgrade")
+
+    r.packWidgetInEntry("Upgrade Existing Installation", upbox)
+
+    vbox = gtk.VBox()
+    vbox.pack_start(b, False, False)
+    
+    button = gtk.Button("Quit")
+    button.connect("pressed", nowquit)
+    vbox.pack_start(button, False, False)
+    
+    win.add(vbox)
+    win.show_all()
+
+    gtk.main()
diff --git a/pyanaconda/iw/progress_gui.py b/pyanaconda/iw/progress_gui.py
new file mode 100644
index 0000000..a72b526
--- /dev/null
+++ b/pyanaconda/iw/progress_gui.py
@@ -0,0 +1,150 @@
+#
+# progress_gui.py: install/upgrade progress window setup.
+#
+# Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007  Red Hat, Inc.
+# 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 as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# 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, see <http://www.gnu.org/licenses/>.
+#
+
+import os
+import glob
+
+import gtk
+import pango
+
+import gui
+from flags import flags
+from iw_gui import *
+from constants import *
+import language
+
+import logging
+log = logging.getLogger("anaconda")
+
+class InstallProgressWindow (InstallWindow):
+    windowTitle = N_("Installing Packages")
+
+    def __init__ (self, ics):
+	InstallWindow.__init__ (self, ics)
+        ics.setPrevEnabled (False)
+        ics.setNextEnabled (False)
+
+        self._updateChange = 0.01
+        self._showPercentage = False
+
+    def processEvents(self):
+        gui.processEvents()
+
+    def get_fraction(self):
+        return self.progress.get_fraction()
+    def set_fraction(self, pct):
+        cur = self.get_fraction()
+        if pct - cur > self._updateChange:
+            self.progress.set_fraction(pct)
+            if self._showPercentage:
+                self.progress.set_text("%d %%" %(pct * 100,))
+            self.processEvents()
+
+    def set_label(self, txt):
+        # handle txt strings that contain '&' and '&amp;'
+        # we convert everything to '&' first, then take them all to '&amp;'
+        # so we avoid things like &amp;&amp;
+        # we have to use '&amp;' for the set_markup() method
+        txt = txt.replace('&amp;', '&')
+        txt = txt.replace('&', '&amp;')
+        self.infolabel.set_markup(txt)
+        self.infolabel.set_ellipsize(pango.ELLIPSIZE_END)
+        self.processEvents()
+
+    def set_text(self, txt):
+        if self._showPercentage:
+            log.debug("Setting progress text with showPercentage set")
+            return
+        self.progress.set_text(txt)
+        self.processEvents()
+
+    def renderCallback(self):
+        self.intf.icw.nextClicked()
+
+    def setShowPercentage(self, val):
+        if val not in (True, False):
+            raise ValueError, "Invalid value passed to setShowPercentage"
+        self._showPercentage = val
+
+    def _getRnotes(self):
+        langs = []
+        pixmaps = []
+        if (os.environ.has_key('LANG')):
+            langs = language.expandLangs(os.environ['LANG'])
+        langs.append('')
+
+        pixmaps = []
+        paths = ("/tmp/product/pixmaps/rnotes/%s/*.png",
+                 "/usr/share/anaconda/pixmaps/rnotes/%s/*.png")
+        for p in paths:
+            for lang in langs:
+                path = p % lang
+                pixmaps = glob.glob(path)
+                if len(pixmaps) > 0:
+                    break
+
+        if len(pixmaps) > 0:
+            files = pixmaps
+        else:
+            files = ["progress_first.png"]
+
+        return files
+        
+
+    def getScreen (self, anaconda):
+	self.intf = anaconda.intf
+	if anaconda.dir == DISPATCH_BACK:
+	    self.intf.icw.prevClicked()
+	    return
+
+        self.pixmaps = self._getRnotes()
+
+	# Create vbox to contain components of UI
+        vbox = gtk.VBox (False, 12)
+
+        # Create rnote area
+        self.adpix = None
+        self.adbox = None
+        pix = gui.readImageFromFile ("progress_first.png")
+        if pix:
+            frame = gtk.Frame()
+            frame.set_shadow_type(gtk.SHADOW_NONE)
+            box = gtk.EventBox()
+            self.adpix = pix
+            box.add(self.adpix)
+            self.adbox = box
+            frame.add(box)
+            vbox.pack_start(frame, False)
+
+
+	self.progress = gtk.ProgressBar()
+        vbox.pack_start(self.progress, False)
+
+        self.infolabel = gui.WrappingLabel("")
+        self.infolabel.set_alignment(0,0)
+        vbox.pack_start(self.infolabel)
+
+	# All done with creating components of UI
+	self.intf.setPackageProgressWindow(self)
+	self.intf.setInstallProgressClass(self)
+
+	vbox.set_border_width(6)
+
+	return vbox
diff --git a/pyanaconda/iw/raid_dialog_gui.py b/pyanaconda/iw/raid_dialog_gui.py
new file mode 100644
index 0000000..2255815
--- /dev/null
+++ b/pyanaconda/iw/raid_dialog_gui.py
@@ -0,0 +1,615 @@
+#
+# raid_dialog_gui.py: dialog for editting a raid request
+#
+# Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007  Red Hat, Inc.
+# 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 as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# 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, see <http://www.gnu.org/licenses/>.
+#
+# Author(s): Michael Fulbright <msf@xxxxxxxxxx>
+#            Jeremy Katz <katzj@xxxxxxxxxx>
+#
+
+import copy
+
+import gobject
+import gtk
+import datacombo
+
+import gui
+import storage.devicelibs.mdraid as mdraidlib
+from storage.devices import *
+from storage.deviceaction import *
+from partition_ui_helpers_gui import *
+from constants import *
+
+import gettext
+_ = lambda x: gettext.ldgettext("anaconda", x)
+
+class RaidEditor:
+
+    def createAllowedRaidPartitionsList(self, allraidparts, reqraidpart,
+                                        preexist):
+
+	store = gtk.TreeStore(gobject.TYPE_BOOLEAN,
+			      gobject.TYPE_STRING,
+			      gobject.TYPE_STRING)
+	partlist = WideCheckList(2, store, 
+                                 clickCB=self.raidlist_toggle_callback)
+
+	sw = gtk.ScrolledWindow()
+	sw.add(partlist)
+	sw.set_policy(gtk.POLICY_NEVER, gtk.POLICY_AUTOMATIC)
+	sw.set_shadow_type(gtk.SHADOW_IN)
+
+        tempDevList = []
+        if not self.isNew:
+            # We need this list if we are editing.
+            for dev in reqraidpart:
+                tempDevList.append(dev)
+
+	partrow = 0
+	for part in allraidparts:
+	    partname = "%s" % part.name
+	    partsize = "%8.0f MB" % part.size
+
+            if part in tempDevList:
+                #list the partition and put it as selected
+                partlist.append_row((partname, partsize), True)
+            else:
+                if not self.origrequest.exists:
+                    partlist.append_row((partname, partsize), False)
+
+
+	return (partlist, sw)
+
+    def createRaidLevelMenu(self, levels, reqlevel):
+        levelcombo = gtk.combo_box_new_text()
+	defindex = 0
+        if mdraidlib.RAID1 in levels:
+            defindex = levels.index(mdraidlib.RAID1)
+	i = 0
+	for lev in levels:
+            levelcombo.append_text("RAID%d" % lev)
+
+	    if reqlevel is not None and lev == reqlevel:
+		defindex = i
+	    i = i + 1
+
+        levelcombo.set_active(defindex)
+
+	if reqlevel is not None and reqlevel == mdraidlib.RAID0:
+	    self.sparesb.set_sensitive(0)
+
+        if self.sparesb:
+            levelcombo.connect("changed", self.raidlevelchangeCB, self.sparesb)
+            
+	return levelcombo
+
+    def createRaidMinorMenu(self, minors, reqminor):
+        minorcombo = datacombo.DataComboBox()
+	defindex = 0
+	i = 0
+	for minor in minors:
+            minorcombo.append("md%d" %(minor,), minor)
+	    if reqminor and minor == reqminor:
+		defindex = i
+	    i = i + 1
+
+        minorcombo.set_active(defindex)
+
+	return minorcombo
+
+
+    def raidlevelchangeCB(self, widget, sparesb):
+	raidlevel = widget.get_model()[widget.get_active()][0]
+	numparts = sparesb.get_data("numparts")
+	maxspares = mdraidlib.get_raid_max_spares(raidlevel, numparts)
+
+	if maxspares > 0 and not mdraidlib.isRaid(mdraidlib.RAID0, raidlevel):
+	    adj = sparesb.get_adjustment() 
+	    value = adj.value 
+	    if adj.value > maxspares: 
+		value = maxspares 
+
+	    sparesb.set_sensitive(1)
+	    spareAdj = gtk.Adjustment(value = value, lower = 0,
+				      upper = maxspares, step_incr = 1)
+	    spareAdj.clamp_page(0, maxspares)
+	    sparesb.set_adjustment(spareAdj)
+	    sparesb.set_value(value)
+	else:
+	    sparesb.set_value(0)
+	    sparesb.set_sensitive(0)
+
+    def run(self):
+	if self.dialog is None:
+	    return []
+	
+	while 1:
+	    self.allow_ok_button()
+	    rc = self.dialog.run()
+
+	    # user hit cancel, do nothing
+	    if rc in [gtk.RESPONSE_CANCEL, gtk.RESPONSE_DELETE_EVENT]:
+		self.destroy()
+		return []
+
+            actions = []
+            luksdev = None
+	    raidmembers = []
+            migrate = None
+	    model = self.raidlist.get_model()
+	    iter = model.get_iter_first()
+            format = None
+	    while iter:
+		val   = model.get_value(iter, 0)
+		part = model.get_value(iter, 1)
+
+		if val:
+		    dev = self.storage.devicetree.getDeviceByName(part)
+		    raidmembers.append(dev)
+
+                iter = model.iter_next(iter)
+
+            # The user has to select some devices to be part of the array.
+            if not raidmembers:
+                continue
+
+            mountpoint = self.mountCombo.get_children()[0].get_text()
+            if mountpoint == _("<Not Applicable>"):
+                mountpoint = ""
+
+            if mountpoint:
+                used = False
+                for (mp, dev) in self.storage.mountpoints.iteritems():
+                    if mp == mountpoint and \
+                       dev.id != self.origrequest.id and \
+                       not (self.origrequest.format.type == "luks" and
+                            self.origrequest in dev.parents):
+                        used = True
+                        break
+
+                if used:
+                    self.intf.messageWindow(_("Mount point in use"),
+                                            _("The mount point \"%s\" is in "
+                                              "use. Please pick another.") %
+                                            (mountpoint,),
+                                            custom_icon="error")
+                    continue
+
+            if not self.origrequest.exists:
+                # new device
+                fmt_class = self.fstypeCombo.get_active_value()
+                raidminor = int(self.minorCombo.get_active_value())
+
+                model = self.levelcombo.get_model()
+                raidlevel = model[self.levelcombo.get_active()][0]
+
+                if not mdraidlib.isRaid(mdraidlib.RAID0, raidlevel):
+                    self.sparesb.update()
+                    spares = self.sparesb.get_value_as_int()
+                else:
+                    spares = 0
+
+                format = fmt_class(mountpoint=mountpoint)
+                members = len(raidmembers) - spares
+
+                try:
+                    request = self.storage.newMDArray(minor=raidminor,
+                                                  level=raidlevel,
+                                                  format=format,
+                                                  parents=raidmembers,
+                                                  totalDevices=len(raidmembers),
+                                                  memberDevices=members)
+                except ValueError, e:
+                    self.intf.messageWindow(_("Error"), str(e),
+                                            custom_icon="error")
+                    continue
+
+                # we must destroy luks leaf before original raid request
+                if self.origrequest.format.type == "luks":
+                    # => not self.isNew
+                    # destroy luks format and mapped device
+                    # XXX remove catching, it should always succeed
+                    try:
+                        luksdev = self.storage.devicetree.getChildren(self.origrequest)[0]
+                    except IndexError:
+                        pass
+                    else:
+                        actions.append(ActionDestroyFormat(luksdev))
+                        actions.append(ActionDestroyDevice(luksdev))
+                        luksdev = None
+
+                if self.lukscb and self.lukscb.get_active():
+                    luksdev = LUKSDevice("luks-%s" % request.name,
+                                         format=format,
+                                         parents=request)
+                    format = getFormat("luks",
+                                       passphrase=self.storage.encryptionPassphrase)
+                    request.format = format
+                elif self.lukscb and not self.lukscb.get_active() and \
+                    self.origrequest.format.type == "luks":
+
+                    # XXXRV not needed as we destroy origrequest ?
+                    actions.append(ActionDestroyFormat(self.origrequest))
+
+                if not self.isNew:
+                    # This may be handled in devicetree.registerAction,
+                    # but not in case when we change minor and thus
+                    # device name/path (at least with current md)
+                    actions.append(ActionDestroyDevice(self.origrequest))
+                actions.append(ActionCreateDevice(request))
+                actions.append(ActionCreateFormat(request))
+            
+	    else:
+                # existing device
+                fmt_class = self.fsoptionsDict["fstypeCombo"].get_active_value()
+		if self.fsoptionsDict.has_key("formatcb") and \
+                   self.fsoptionsDict["formatcb"].get_active():
+                    format = fmt_class(mountpoint=mountpoint)
+                    if self.fsoptionsDict.has_key("lukscb") and \
+                       self.fsoptionsDict["lukscb"].get_active() and \
+                       (self.origrequest.format.type != "luks" or
+                        (self.origrequest.format.exists and
+                         not self.origrequest.format.hasKey)):
+                        luksdev = LUKSDevice("luks-%s" % self.origrequest.name,
+                                             format=format,
+                                             parents=self.origrequest)
+                        format = getFormat("luks",
+                                           device=self.origrequest.path,
+                                           passphrase=self.storage.encryptionPassphrase)
+                    elif self.fsoptionsDict.has_key("lukscb") and \
+                         not self.fsoptionsDict["lukscb"].get_active() and \
+                         self.origrequest.format.type == "luks":
+                        # destroy luks format and mapped device
+                        try:
+                            luksdev = self.storage.devicetree.getChildren(self.origrequest)[0]
+                        except IndexError:
+                            pass
+                        else:
+                            actions.append(ActionDestroyFormat(luksdev))
+                            actions.append(ActionDestroyDevice(luksdev))
+                            luksdev = None
+
+                        actions.append(ActionDestroyFormat(self.origrequest))
+                elif self.fsoptionsDict.has_key("formatcb") and \
+                     not self.fsoptionsDict["formatcb"].get_active():
+                    # if the format checkbutton is inactive, cancel all
+                    # actions on this device that create or destroy formats
+                    devicetree = self.storage.devicetree
+                    request = self.origrequest
+                    cancel = []
+                    if request.originalFormat.type == "luks":
+                        path = "/dev/mapper/luks-%s" % request.originalFormat.uuid
+                        cancel.extend(devicetree.findActions(path=path))
+
+                    cancel.extend(devicetree.findActions(type="destroy",
+                                                         object="format",
+                                                         devid=request.id))
+                    cancel.extend(devicetree.findActions(type="create",
+                                                         object="format",
+                                                         devid=request.id))
+                    for action in cancel:
+                        devicetree.cancelAction(action)
+
+                    # even though we cancelled a bunch of actions, it's
+                    # pretty much impossible to be sure we cancelled them
+                    # in the correct order. make sure things are back to
+                    # their original state.
+                    request.format = request.originalFormat
+                    if request.format.type == "luks":
+                        try:
+                            usedev = devicetree.getChildren(request)[0]
+                        except IndexError:
+                            usedev = request
+                        else:
+                            usedev.format = usedev.originalFormat
+                    else:
+                        usedev = request
+
+                    if usedev.format.mountable:
+                        usedev.format.mountpoint = mountpoint
+
+                if self.origrequest.format.mountable:
+                    self.origrequest.format.mountpoint = mountpoint
+
+		if self.fsoptionsDict.has_key("migratecb") and \
+		   self.fsoptionsDict["migratecb"].get_active():
+                    if self.origrequest.format.type == "luks":
+                        try:
+                            usedev = self.storage.devicetree.getChildren(self.origrequest)[0]
+                        except IndexError:
+                            usedev = self.origrequest
+                    else:
+                        usedev = self.origrequest
+                    migrate = True
+
+                if self.origrequest.format.exists and not format and \
+                   self.storage.formatByDefault(self.origrequest):
+                    if not queryNoFormatPreExisting(self.intf):
+		        continue
+
+                if format:
+                    actions.append(ActionCreateFormat(self.origrequest, format))
+
+	    # everything ok, break out
+	    break
+
+
+        if luksdev:
+            actions.append(ActionCreateDevice(luksdev))
+            actions.append(ActionCreateFormat(luksdev))
+
+        if migrate:
+            actions.append(ActionMigrateFormat(usedev))
+
+	return actions
+
+    def destroy(self):
+	if self.dialog:
+	    self.dialog.destroy()
+
+	self.dialog = None
+	
+    def __init__(self, storage, intf, parent, origrequest, isNew = 0):
+	self.storage = storage
+	self.origrequest = origrequest
+	self.isNew = isNew
+	self.intf = intf
+	self.parent = parent
+
+	self.dialog = None
+
+	#
+	# start of editRaidRequest
+	#
+        availraidparts = self.storage.unusedMDMembers(array=self.origrequest)
+
+	# if no raid partitions exist, raise an error message and return
+	if len(availraidparts) < 2:
+	    dlg = gtk.MessageDialog(self.parent, 0, gtk.MESSAGE_ERROR,
+				    gtk.BUTTONS_OK,
+				    _("At least two unused software RAID "
+				      "partitions are needed to create "
+				      "a RAID device.\n\n"
+				      "First create at least two partitions "
+				      "of type \"software RAID\", and then "
+				      "select the \"RAID\" option again."))
+	    gui.addFrame(dlg)
+	    dlg.show_all()
+	    dlg.set_position(gtk.WIN_POS_CENTER)
+	    dlg.run()
+	    dlg.destroy()
+	    return
+
+	if isNew:
+	    tstr = _("Make RAID Device")
+	else:
+	    if origrequest.minor is not None:
+		tstr = _("Edit RAID Device: %s") % (origrequest.path,)
+	    else:
+		tstr = _("Edit RAID Device")
+		
+	dialog = gtk.Dialog(tstr, self.parent)
+	gui.addFrame(dialog)
+	dialog.add_button('gtk-cancel', gtk.RESPONSE_CANCEL)
+	self.ok_button = dialog.add_button('gtk-ok', 1)
+	dialog.set_position(gtk.WIN_POS_CENTER)
+
+	maintable = gtk.Table()
+	maintable.set_row_spacings(5)
+	maintable.set_col_spacings(5)
+	row = 0
+
+        # we'll maybe add this further down
+        self.lukscb = gtk.CheckButton(_("_Encrypt"))
+        self.lukscb.set_data("formatstate", 1)
+
+        if origrequest.format.type == "luks":
+            try:
+                luksdev = self.storage.devicetree.getChildren(origrequest)[0]
+            except IndexError:
+                luksdev = None
+                usedev = origrequest
+                format = origrequest.format
+            else:
+                usedev = luksdev
+                format = usedev.format
+        else:
+            luksdev = None
+            usedev = origrequest
+            format = origrequest.format
+
+	# Mount Point entry
+	lbl = createAlignedLabel(_("_Mount Point:"))
+	maintable.attach(lbl, 0, 1, row, row + 1)
+	self.mountCombo = createMountPointCombo(usedev)
+	lbl.set_mnemonic_widget(self.mountCombo)
+	maintable.attach(self.mountCombo, 1, 2, row, row + 1)
+	row = row + 1
+
+	# Filesystem Type
+        if not origrequest.exists:
+            lbl = createAlignedLabel(_("_File System Type:"))
+            maintable.attach(lbl, 0, 1, row, row + 1)
+            self.fstypeCombo = createFSTypeMenu(format,
+                                                fstypechangeCB,
+                                                self.mountCombo,
+                                                ignorefs = ["mdmember", "efi", "prepboot", "appleboot"])
+	    lbl.set_mnemonic_widget(self.fstypeCombo)
+            maintable.attach(self.fstypeCombo, 1, 2, row, row + 1)
+            row += 1
+        else:
+            maintable.attach(createAlignedLabel(_("Original File System Type:")),
+                             0, 1, row, row + 1)
+            self.fstypeCombo = gtk.Label(usedev.originalFormat.name)
+            maintable.attach(self.fstypeCombo, 1, 2, row, row + 1)
+            row += 1
+
+            if getattr(usedev.originalFormat, "label", None):
+                maintable.attach(createAlignedLabel(_("Original File System "
+                                                      "Label:")),
+                                 0, 1, row, row + 1)
+                maintable.attach(gtk.Label(usedev.originalFormat.label),
+                                 1, 2, row, row + 1)
+                row += 1
+
+	# raid minors
+	lbl = createAlignedLabel(_("RAID _Device:"))	
+	maintable.attach(lbl, 0, 1, row, row + 1)
+
+        if not origrequest.exists:
+            availminors = self.storage.unusedMDMinors[:16]
+            reqminor = origrequest.minor
+            if reqminor is not None and reqminor not in availminors:
+                availminors.append(reqminor)
+
+            availminors.sort()
+            self.minorCombo = self.createRaidMinorMenu(availminors, reqminor)
+	    lbl.set_mnemonic_widget(self.minorCombo)
+        else:
+            self.minorCombo = gtk.Label("%s" %(origrequest.name,))
+	maintable.attach(self.minorCombo, 1, 2, row, row + 1)
+	row = row + 1
+
+	# raid level
+	lbl = createAlignedLabel(_("RAID _Level:"))
+	maintable.attach(lbl, 0, 1, row, row + 1)
+
+        if not origrequest.exists:
+            # Create here, pack below
+            numparts =  len(availraidparts)
+            if origrequest.spares:
+                nspares = origrequest.spares
+            else:
+                nspares = 0
+
+            if origrequest.level:
+                maxspares = mdraidlib.get_raid_max_spares(origrequest.level,
+                                                          numparts)
+            else:
+                maxspares = 0
+
+            spareAdj = gtk.Adjustment(value = nspares, lower = 0,
+                                      upper = maxspares, step_incr = 1)
+            self.sparesb = gtk.SpinButton(spareAdj, digits = 0)
+            self.sparesb.set_data("numparts", numparts)
+
+            if maxspares > 0:
+                self.sparesb.set_sensitive(1)
+            else:
+                self.sparesb.set_value(0)
+                self.sparesb.set_sensitive(0)
+        else:
+            self.sparesb = gtk.Label(str(origrequest.spares))
+
+
+        if not origrequest.exists:
+            self.levelcombo = self.createRaidLevelMenu(mdraidlib.raid_levels,
+                                                       origrequest.level)
+	    lbl.set_mnemonic_widget(self.levelcombo)
+        else:
+            self.levelcombo = gtk.Label(origrequest.level)
+
+	maintable.attach(self.levelcombo, 1, 2, row, row + 1)
+	row = row + 1
+
+	# raid members
+	lbl=createAlignedLabel(_("_RAID Members:"))
+	maintable.attach(lbl, 0, 1, row, row + 1)
+
+	# XXX need to pass in currently used partitions for this device
+	(self.raidlist, sw) = self.createAllowedRaidPartitionsList(availraidparts,
+                                                                   origrequest.devices,
+                                                                   origrequest.exists)
+
+	lbl.set_mnemonic_widget(self.raidlist)
+	self.raidlist.set_size_request(275, 80)
+	maintable.attach(sw, 1, 2, row, row + 1)
+	row = row + 1
+
+        if origrequest.exists:
+            self.raidlist.set_sensitive(False)
+
+	# number of spares - created widget above
+	lbl = createAlignedLabel(_("Number of _spares:"))
+	maintable.attach(lbl, 0, 1, row, row + 1)
+	maintable.attach(self.sparesb, 1, 2, row, row + 1)
+	lbl.set_mnemonic_widget(self.sparesb)
+	row = row + 1
+
+	# format or not?
+	self.formatButton = None
+	self.fsoptionsDict = {}
+	if not format.exists and not origrequest.exists:
+	    self.formatButton = gtk.CheckButton(_("_Format partition?"))
+	    if not format.type:
+		self.formatButton.set_active(1)
+	    else:
+		self.formatButton.set_active(0)
+            # it only makes sense to show this for preexisting RAID
+            if origrequest.exists:
+                maintable.attach(self.formatButton, 0, 2, row, row + 1)
+                row = row + 1
+
+            # checkbutton for encryption using dm-crypt/LUKS
+            if origrequest.format.type == "luks":
+                self.lukscb.set_active(1)
+            else:
+                self.lukscb.set_active(0)
+            maintable.attach(self.lukscb, 0, 2, row, row + 1)
+            row = row + 1
+	else:
+	    (row, self.fsoptionsDict) = createPreExistFSOptionSection(origrequest, maintable, row, self.mountCombo, self.storage, luksdev=luksdev)
+
+	# put main table into dialog
+	dialog.vbox.pack_start(maintable)
+
+	dialog.show_all()
+	self.dialog = dialog
+	return
+
+    def allow_ok_button(self, path=None):
+        """
+        Determine if the OK button should be enabled.
+        
+        If path is given it points to the row where the toggle state is about to
+        change.
+        """
+        model = self.raidlist.get_model()
+        allow = False
+        iter = model.get_iter_first()
+        toggled_iter = None
+        if path:
+            toggled_iter = model.get_iter(path)
+        while iter:
+            val = model.get_value(iter, 0)
+            if toggled_iter and \
+                    model.get_value(toggled_iter, 1) == \
+                    model.get_value(iter, 1):
+                # this is being toggled, negate the value:
+                if not val:
+                    allow = True
+            else:
+                if val:
+                    allow = True
+            iter = model.iter_next(iter)
+
+        self.ok_button.set_sensitive(allow)
+
+    def raidlist_toggle_callback(self, data, path):
+        self.allow_ok_button(path)
+        return 1
+
diff --git a/pyanaconda/iw/task_gui.py b/pyanaconda/iw/task_gui.py
new file mode 100644
index 0000000..5716309
--- /dev/null
+++ b/pyanaconda/iw/task_gui.py
@@ -0,0 +1,705 @@
+#
+# task_gui.py: Choose tasks for installation
+#
+# Copyright (C) 2006, 2007, 2008 Red Hat, Inc.  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 as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# 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, see <http://www.gnu.org/licenses/>.
+#
+
+import gtk
+import gtk.glade
+import gobject
+import gui
+import gzip
+from iw_gui import *
+from image import *
+from constants import *
+import isys
+import shutil
+
+import gettext
+_ = lambda x: gettext.ldgettext("anaconda", x)
+
+import network
+import iutil
+
+from yuminstall import AnacondaYumRepo
+import urlgrabber.grabber
+import yum.Errors
+
+import logging
+log = logging.getLogger("anaconda")
+
+def setupRepo(anaconda, repo):
+    if repo.needsNetwork() and not network.hasActiveNetDev():
+        if not anaconda.intf.enableNetwork():
+            return False
+        urlgrabber.grabber.reset_curl_obj()
+    try:
+        anaconda.backend.doRepoSetup(anaconda, thisrepo=repo.id, fatalerrors=False)
+        anaconda.backend.doSackSetup(anaconda, thisrepo=repo.id, fatalerrors=False)
+        log.info("added (UI) repository %s with source URL %s, id:%s" % (repo.name, repo.mirrorlist or repo.baseurl, repo.id))
+    except (IOError, yum.Errors.RepoError) as e:
+        anaconda.intf.messageWindow(_("Error"),
+              _("Unable to read package metadata from repository.  "
+                "This may be due to a missing repodata directory.  "
+                "Please ensure that your repository has been "
+                "correctly generated.\n\n%s" % str(e)),
+                                type="ok", custom_icon="error")
+        repo.disable()
+        repo.close()
+        anaconda.backend.ayum.repos.delete(repo.id)
+        return False
+
+    return True
+
+class RepoEditor:
+    # Window-level callbacks
+    def on_addRepoDialog_destroy(self, widget, *args):
+        pass
+
+    def on_cancelButton_clicked(self, widget, *args):
+        pass
+
+    def on_okButton_clicked(self, widget, *args):
+        pass
+
+    def on_typeComboBox_changed(self, widget, *args):
+        if widget.get_active() == -1:
+            return
+
+        # When the combo box's value is changed, set the notebook's current
+        # page to match.  This requires that the combo box and notebook have
+        # the same method types at the same indices (so, HTTP must be the
+        # same position on both, etc.).
+        self.notebook.set_current_page(widget.get_active())
+
+        if widget.get_active() == 1:
+            if self.repo:
+                self.proxyCheckbox.set_active(self.repo.proxy is True)
+                self.proxyTable.set_sensitive(self.repo.proxy is True)
+            else:
+                self.proxyCheckbox.set_active(False)
+                self.proxyTable.set_sensitive(False)
+
+    # URL-specific callbacks
+    def on_proxyCheckbox_toggled(self, widget, *args):
+        table = self.dxml.get_widget("proxyTable")
+        table.set_sensitive(widget.get_active())
+
+    def on_mirrorlistCheckbox_toggled(self, widget, *args):
+        pass
+
+    def __init__(self, anaconda, repoObj):
+        self.anaconda = anaconda
+        self.backend = self.anaconda.backend
+        self.intf = self.anaconda.intf
+        self.repo = repoObj
+
+        (self.dxml, self.dialog) = gui.getGladeWidget("addrepo.glade", "addRepoDialog")
+        self.dxml.signal_autoconnect(self)
+
+        self.notebook = self.dxml.get_widget("typeNotebook")
+        self.nameEntry = self.dxml.get_widget("nameEntry")
+        self.typeComboBox = self.dxml.get_widget("typeComboBox")
+
+        self.baseurlEntry = self.dxml.get_widget("baseurlEntry")
+        self.mirrorlistCheckbox = self.dxml.get_widget("mirrorlistCheckbox")
+        self.proxyCheckbox = self.dxml.get_widget("proxyCheckbox")
+        self.proxyEntry = self.dxml.get_widget("proxyEntry")
+        self.proxyTable = self.dxml.get_widget("proxyTable")
+        self.usernameEntry = self.dxml.get_widget("usernameEntry")
+        self.passwordEntry = self.dxml.get_widget("passwordEntry")
+
+        self.nfsServerEntry = self.dxml.get_widget("nfsServerEntry")
+        self.nfsPathEntry = self.dxml.get_widget("nfsPathEntry")
+        self.nfsOptionsEntry = self.dxml.get_widget("nfsOptionsEntry")
+
+        self.partitionComboBox = self.dxml.get_widget("partitionComboBox")
+        self.directoryChooser = self.dxml.get_widget("directoryChooserButton")
+
+        self.dialog.set_title(_("Edit Repository"))
+
+        # Remove these until they are actually implemented
+        self.typeComboBox.remove_text(3)
+
+    # Given a method string, return the index of the typeComboBox that should
+    # be made active in order to match.
+    def _methodToIndex(self, method):
+        mapping = {"http": 0, "ftp": 0, "https": 0,
+                   "cdrom": 1,
+                   "nfs": 2}
+#                   "nfs": 2, "nfsiso": 2,
+#                   "hd": 3}
+
+        try:
+            return mapping[method.split(':')[0].lower()]
+        except:
+            return 0
+
+    def _addAndEnableRepo(self, repo):
+        try:
+            self.backend.ayum.repos.add(repo)
+        except yum.Errors.DuplicateRepoError, e:
+            self.intf.messageWindow(_("Error"),
+                  _("The repository %s has already been added.  Please "
+                    "choose a different repository name and "
+                    "URL.") % self.repo.name, type="ok", custom_icon="error")
+            return False
+
+        repo.enable()
+        return True
+
+    def _validURL(self, url):
+        return len(url) > 0 and (url.startswith("http://";) or
+                                 url.startswith("https://";) or
+                                 url.startswith("ftp://";))
+
+    def createDialog(self):
+
+        if self.repo:
+            self.nameEntry.set_text(self.repo.name)
+            if self.repo.anacondaBaseURLs:
+                url = self.repo.anacondaBaseURLs[0]
+            else:
+                url = ''
+            self.typeComboBox.set_active(self._methodToIndex(url))
+
+            if not url or url.startswith("http") or url.startswith("ftp"):
+                if self.repo.mirrorlist:
+                    self.baseurlEntry.set_text(self.repo.mirrorlist)
+                    self.mirrorlistCheckbox.set_active(True)
+                else:
+                    self.baseurlEntry.set_text(url)
+
+                    self.mirrorlistCheckbox.set_active(False)
+
+                if self.repo.proxy:
+                    self.proxyCheckbox.set_active(True)
+                    self.proxyTable.set_sensitive(True)
+                    self.proxyEntry.set_text(self.repo.proxy)
+                    self.usernameEntry.set_text(self.repo.proxy_username or '')
+                    self.passwordEntry.set_text(self.repo.proxy_password or '')
+                else:
+                    self.proxyCheckbox.set_active(False)
+                    self.proxyTable.set_sensitive(False)
+            elif url.startswith("nfs"):
+                (opts, server, path) = iutil.parseNfsUrl(url)
+                self.nfsServerEntry.set_text(server)
+                self.nfsPathEntry.set_text(path)
+                self.nfsOptionsEntry.set_text(opts)
+            elif url.startswith("cdrom:"):
+                pass
+            elif url.startswith("hd:"):
+                m = url[3:]
+                if m.count(":") == 1:
+                    (device, path) = m.split(":")
+                    fstype = "auto"
+                else:
+                    (device, fstype, path) = m.split(":")
+
+                # find device in self.partitionComboBox and select it
+                self.directoryChooser.set_current_folder("%s%s" % (self.anaconda.backend.ayum.isodir, path))
+            else:
+                self.baseurlEntry.set_text(url)
+
+        else:
+            self.typeComboBox.set_active(0)
+            self.proxyCheckbox.set_active(False)
+            self.proxyTable.set_sensitive(False)
+
+        gui.addFrame(self.dialog)
+
+        lbl = self.dxml.get_widget("descLabel")
+        txt = lbl.get_text()
+        lbl.set_text(txt)
+
+        self.dialog.show_all()
+
+    def _applyURL(self, repo):
+        if self.proxyCheckbox.get_active():
+            proxy = self.proxyEntry.get_text()
+            proxy.strip()
+
+            if not self._validURL(proxy):
+                self.intf.messageWindow(_("Invalid Proxy URL"),
+                                        _("You must provide an HTTP, HTTPS, "
+                                          "or FTP URL to a proxy."))
+                return False
+
+            repo.proxy = proxy
+            # with empty string yum would create invalid proxy string
+            repo.proxy_username = self.usernameEntry.get_text() or None
+            repo.proxy_password = self.passwordEntry.get_text() or None
+
+        repourl = self.baseurlEntry.get_text()
+        repourl.strip()
+        if not self._validURL(repourl):
+            self.intf.messageWindow(_("Invalid Repository URL"),
+                                    _("You must provide an HTTP, HTTPS, "
+                                      "or FTP URL to a repository."))
+            return False
+
+        if self.mirrorlistCheckbox.get_active():
+            repo.baseurl = []
+            repo.mirrorlist = repourl
+        else:
+            repo.baseurl = [repourl]
+            repo.mirrorlist = None
+        repo.anacondaBaseURLs = repo.baseurl
+
+        repo.name = self.nameEntry.get_text()
+
+        return True
+
+    def _applyMedia(self, repo):
+        # FIXME works only if storage has detected format of cdrom drive
+        ayum = self.anaconda.backend.ayum
+        cdr = scanForMedia(ayum.tree, self.anaconda.storage)
+        if not cdr:
+            self.intf.messageWindow(_("No Media Found"),
+                                    _("No installation media was found. "
+                                      "Please insert a disc into your drive "
+                                      "and try again."))
+            return False
+
+        log.info("found installation media on %s" % cdr)
+        repo.name = self.nameEntry.get_text()
+        repo.anacondaBaseURLs = ["cdrom://%s:%s" % (cdr, self.anaconda.backend.ayum.tree)]
+        repo.baseurl = "file://%s" % ayum.tree
+        ayum.mediagrabber = ayum.mediaHandler
+        self.anaconda.mediaDevice = cdr
+        ayum.currentMedia = 1
+        repo.mediaid = getMediaId(ayum.tree)
+        log.info("set mediaid of repo %s to: %s" % (repo.name, repo.mediaid))
+
+        return True
+
+    def _applyNfs(self, repo):
+        server = self.nfsServerEntry.get_text()
+        server.strip()
+
+        path = self.nfsPathEntry.get_text()
+        path.strip()
+
+        options = self.nfsOptionsEntry.get_text()
+        options.strip()
+
+        repo.name = self.nameEntry.get_text()
+
+        if not server or not path:
+            self.intf.messageWindow(_("Error"),
+                                    _("Please enter an NFS server and path."))
+            return False
+
+        if not network.hasActiveNetDev():
+            if not self.anaconda.intf.enableNetwork():
+                self.intf.messageWindow(_("No Network Available"),
+                    _("Some of your software repositories require "
+                      "networking, but there was an error enabling the "
+                      "network on your system."))
+                return False
+            urlgrabber.grabber.reset_curl_obj()
+
+        import tempfile
+        dest = tempfile.mkdtemp("", repo.name.replace(" ", ""), "/mnt")
+
+        try:
+            isys.mount("%s:%s" % (server, path), dest, "nfs", options=options)
+        except Exception as e:
+            self.intf.messageWindow(_("Error Setting Up Repository"),
+                _("The following error occurred while setting up the "
+                  "repository:\n\n%s") % e)
+            return False
+
+        repo.baseurl = "file://%s" % dest
+        repo.anacondaBaseURLs = ["nfs:%s:%s:%s" % (options,server,path)]
+        return True
+
+    def _applyHd(self, repo):
+        return True
+
+    def run(self):
+        applyFuncs = [ self._applyURL, self._applyMedia, self._applyNfs,
+                       self._applyHd ]
+
+        while True:
+            rc = self.dialog.run()
+            if rc in [gtk.RESPONSE_CANCEL, gtk.RESPONSE_DELETE_EVENT]:
+                break
+
+            reponame = self.nameEntry.get_text()
+            reponame.strip()
+            if len(reponame) == 0:
+                self.intf.messageWindow(_("Invalid Repository Name"),
+                                        _("You must provide a repository name."))
+                continue
+
+            # Always create a new repo object here instead of attempting to
+            # somehow expire the metadata and refetch.  We'll just have to make
+            # sure that if we're just editing the repo, we grab all the
+            # attributes from the old one before deleting it.
+            if self.repo:
+                # use temporary id so that we don't get Duplicate Repo error
+                # when adding
+                newRepoObj = AnacondaYumRepo("UIedited_%s" %
+                                             self.anaconda.backend.ayum.repoIDcounter.next())
+                newRepoObj.cost = self.repo.cost
+                removeOld = True
+            else:
+                newRepoObj = AnacondaYumRepo(reponame.replace(" ", ""))
+                removeOld = False
+
+            # corresponds to self.repos.setCacheDir in AnacondaYum.doConfigSetup
+            newRepoObj.basecachedir = self.anaconda.backend.ayum.conf.cachedir
+
+            type = self.typeComboBox.get_active()
+            if not applyFuncs[type](newRepoObj) or not self._addAndEnableRepo(newRepoObj) or not \
+                   setupRepo(self.anaconda, newRepoObj):
+                continue
+
+            if removeOld:
+                try:
+                    os.unlink("%s/cachecookie" % self.repo.cachedir)
+                    os.unlink("%s/repomd.xml" % self.repo.cachedir)
+                except:
+                    pass
+
+                self.repo.disable()
+                self.repo.close()
+                self.anaconda.backend.ayum.repos.delete(self.repo.id)
+                log.info("deleted (UI) repository %s with source URL %s, id:%s"
+                         % (self.repo.name, self.repo.mirrorlist or self.repo.baseurl, self.repo.id))
+                try:
+                    shutil.rmtree(self.repo.cachedir)
+                except Exception as e:
+                    log.warning("error removing cachedir for %s: %s" %(self.repo, e))
+                    pass
+
+            if (newRepoObj.enablegroups or 
+                (removeOld and self.repo.enablegroups)):
+                # update groups information
+                try:
+                    self.anaconda.backend.ayum.doGroupSetup()
+                except Exception as e:
+                    log.debug("unable to reset group information after UI repo edit: %s"
+                              % e)
+                else:
+                    log.info("group information reset after UI repo edit")
+
+            self.repo = newRepoObj
+            break
+
+        self.dialog.hide()
+        return rc
+
+class RepoMethodstrEditor(RepoEditor):
+    def __init__(self, anaconda, methodstr):
+        # Create temporary repo to store methodstr needed for
+        # createDialog parent method.
+        temprepo = AnacondaYumRepo("UITmpMethodstrRepo")
+        temprepo.name = "Installation Repo"
+        temprepo.anacondaBaseURLs = [methodstr]
+        RepoEditor.__init__(self, anaconda, temprepo)
+
+    def createDialog(self):
+        RepoEditor.createDialog(self)
+
+        # Hide a bunch of stuff that doesn't apply when we're just prompting
+        # for enough information to form a methodstr.
+        self.nameEntry.set_sensitive(False)
+        self.mirrorlistCheckbox.hide()
+        self.proxyCheckbox.hide()
+        self.proxyTable.hide()
+
+    def _applyURL(self):
+        repourl = self.baseurlEntry.get_text()
+        repourl.strip()
+        if not self._validURL(repourl):
+            self.intf.messageWindow(_("Invalid Repository URL"),
+                                    _("You must provide an HTTP, HTTPS, "
+                                      "or FTP URL to a repository."))
+            return False
+
+        return repourl
+
+    def _applyMedia(self):
+        cdr = scanForMedia(self.anaconda.backend.ayum.tree, self.anaconda.storage)
+        if not cdr:
+            self.intf.messageWindow(_("No Media Found"),
+                                    _("No installation media was found. "
+                                      "Please insert a disc into your drive "
+                                      "and try again."))
+            return False
+
+        self.anaconda.backend.ayum.mediagrabber = self.anaconda.backend.ayum.mediaHandler
+        self.anaconda.backend.ayum.anaconda.mediaDevice = cdr
+        self.anaconda.backend.ayum.currentMedia = 1
+        log.info("found installation media on %s" % cdr)
+        return "cdrom://%s:%s" % (cdr, self.anaconda.backend.ayum.tree)
+
+    def _applyNfs(self):
+        server = self.nfsServerEntry.get_text()
+        server.strip()
+
+        path = self.nfsPathEntry.get_text()
+        path.strip()
+
+        options = self.nfsOptionsEntry.get_text()
+        options.strip()
+
+        if not server or not path:
+            self.intf.messageWindow(_("Error"),
+                                    _("Please enter an NFS server and path."))
+            return False
+
+        return "nfs:%s:%s:%s" % (options, server, path)
+
+    def _applyHd(self):
+        return None
+
+    def run(self):
+        applyFuncs = [ self._applyURL, self._applyMedia, self._applyNfs,
+                       self._applyHd ]
+
+        while True:
+            rc = self.dialog.run()
+            if rc in [gtk.RESPONSE_CANCEL, gtk.RESPONSE_DELETE_EVENT]:
+                rc = None
+                break
+
+            type = self.typeComboBox.get_active()
+            retval = applyFuncs[type]()
+            if not retval:
+                continue
+
+            rc = retval
+            break
+
+        self.dialog.hide()
+        return rc
+
+class RepoCreator(RepoEditor):
+    def __init__(self, anaconda):
+        RepoEditor.__init__(self, anaconda, None)
+        self.dialog.set_title(_("Add Repository"))
+
+class TaskWindow(InstallWindow):
+    def getNext(self):
+        if not self._anyRepoEnabled():
+            self.anaconda.intf.messageWindow(_("No Software Repos Enabled"),
+                _("You must have at least one software repository enabled to "
+                  "continue installation."))
+            raise gui.StayOnScreen
+
+        if self.xml.get_widget("customRadio").get_active():
+            self.dispatch.skipStep("group-selection", skip = 0)
+        else:
+            self.dispatch.skipStep("group-selection", skip = 1)
+
+        tasks = self.xml.get_widget("taskList").get_model()
+        for (cb, task, grps) in filter(lambda x: not x[0], tasks):
+            map(lambda g: setattr(self.backend.ayum.comps.return_group(g),
+                                  "default", False), grps)
+        for (cb, task, grps) in filter(lambda x: x[0], tasks):
+            map(lambda g: setattr(self.backend.ayum.comps.return_group(g),
+                                  "default", True), grps)
+
+    def _editRepo(self, *args):
+        repo = None
+
+        # If we were passed an extra argument, it's the repo store and we
+        # are editing an existing repo as opposed to adding a new one.
+        if len(args) > 1:
+            (model, iter) = args[1].get_selection().get_selected()
+            if iter:
+                repo = model.get_value(iter, 2)
+            else:
+                return
+        else:
+            return
+
+        if repo.needsNetwork() and not network.hasActiveNetDev():
+            if not self.anaconda.intf.enableNetwork():
+                return gtk.RESPONSE_CANCEL
+
+            urlgrabber.grabber.reset_curl_obj()
+
+        dialog = RepoEditor(self.anaconda, repo)
+        dialog.createDialog()
+        dialog.run()
+
+        model.set_value(iter, 0, dialog.repo.isEnabled())
+        model.set_value(iter, 1, dialog.repo.name)
+        model.set_value(iter, 2, dialog.repo)
+
+    def _addRepo(self, *args):
+        dialog = RepoCreator(self.anaconda)
+        dialog.createDialog()
+        if dialog.run() in [gtk.RESPONSE_CANCEL, gtk.RESPONSE_DELETE_EVENT]:
+            return gtk.RESPONSE_CANCEL
+
+        s = self.xml.get_widget("repoList").get_model()
+        s.append([dialog.repo.isEnabled(), dialog.repo.name, dialog.repo])
+
+    def _taskToggled(self, button, path, store):
+        # First, untoggle everything in the store.
+        for row in store:
+            row[0] = False
+
+        # Then, enable the one that was clicked.
+        store[path][0] = True
+
+    def _anyRepoEnabled(self):
+        model = self.rs.get_model()
+        iter = model.get_iter_first()
+
+        while True:
+            if model.get_value(iter, 0):
+                return True
+
+            iter = model.iter_next(iter)
+            if not iter:
+                return False
+
+        return False
+
+    def _repoToggled(self, button, row, store):
+        i = store.get_iter(int(row))
+        wasChecked = store.get_value(i, 0)
+        repo = store.get_value(i, 2)
+
+        if not wasChecked:
+            if repo.needsNetwork() and not network.hasActiveNetDev():
+                if not self.anaconda.intf.enableNetwork():
+                    return
+
+                urlgrabber.grabber.reset_curl_obj()
+
+            repo.enable()
+            if not setupRepo(self.anaconda, repo):
+                return
+        else:
+            repo.disable()
+            repo.close()
+
+        store.set_value(i, 0, not wasChecked)
+
+    def _createTaskStore(self):
+        store = gtk.ListStore(gobject.TYPE_BOOLEAN,
+                              gobject.TYPE_STRING,
+                              gobject.TYPE_PYOBJECT)
+        tl = self.xml.get_widget("taskList")
+        tl.set_model(store)
+
+        cbr = gtk.CellRendererToggle()
+        cbr.set_radio(True)
+        cbr.connect("toggled", self._taskToggled, store)
+
+        col = gtk.TreeViewColumn('', cbr, active = 0)
+        tl.append_column(col)
+
+        col = gtk.TreeViewColumn('Text', gtk.CellRendererText(), text = 1)
+        col.set_clickable(False)
+        tl.append_column(col)
+
+        anyEnabled = False
+
+        for (txt, grps) in self.tasks:
+            if not self.backend.groupListExists(grps):
+                continue
+
+            enabled = self.backend.groupListDefault(grps)
+            store.append([not anyEnabled and enabled, _(txt), grps])
+
+            if enabled:
+                anyEnabled = True
+
+        return tl
+
+    def __sortRepos(self, store, aIter, bIter):
+        aStr = store.get_value(aIter, 1)
+        bStr = store.get_value(bIter, 1)
+
+        if aStr == "Installation Repo":
+            return -1
+        elif bStr == "Installation Repo":
+            return 1
+        elif aStr < bStr or bStr is None:
+            return -1
+        elif aStr > bStr or aStr is None:
+            return 1
+        else:
+            return aStr == bStr
+
+    def _createRepoStore(self):
+        store = gtk.ListStore(gobject.TYPE_BOOLEAN,
+                              gobject.TYPE_STRING,
+                              gobject.TYPE_PYOBJECT)
+
+        tl = self.xml.get_widget("repoList")
+        tl.set_model(store)
+
+        cbr = gtk.CellRendererToggle()
+        col = gtk.TreeViewColumn('', cbr, active = 0)
+        cbr.connect("toggled", self._repoToggled, store)
+        tl.append_column(col)
+
+        col = gtk.TreeViewColumn('Text', gtk.CellRendererText(), text = 1)
+        col.set_clickable(False)
+        tl.append_column(col)
+
+        for (reponame, repo) in self.repos.repos.items():
+            store.append([repo.isEnabled(), repo.name, repo])
+
+        store.set_sort_column_id(1, gtk.SORT_ASCENDING)
+        store.set_sort_func(1, self.__sortRepos)
+
+        return tl
+
+    def getScreen (self, anaconda):
+        self.intf = anaconda.intf
+        self.dispatch = anaconda.dispatch
+        self.backend = anaconda.backend
+        self.anaconda = anaconda
+
+        self.tasks = anaconda.instClass.tasks
+        self.repos = anaconda.backend.ayum.repos
+
+        (self.xml, vbox) = gui.getGladeWidget("tasksel.glade", "taskBox")
+
+        lbl = self.xml.get_widget("mainLabel")
+        if anaconda.instClass.description:
+            lbl.set_text(_(anaconda.instClass.description))
+        else:
+            txt = lbl.get_text()
+            lbl.set_text(txt %(productName,))
+
+        custom = not self.dispatch.stepInSkipList("group-selection")
+        if custom:
+            self.xml.get_widget("customRadio").set_active(True)
+        else:
+            self.xml.get_widget("customRadio").set_active(False)
+
+        self.ts = self._createTaskStore()
+        self.rs = self._createRepoStore()
+
+        if len(self.ts.get_model()) == 0:
+            self.xml.get_widget("cbVBox").hide()
+            self.xml.get_widget("mainLabel").hide()
+
+        self.xml.get_widget("addRepoButton").connect("clicked", self._addRepo)
+        self.xml.get_widget("editRepoButton").connect("clicked", self._editRepo, self.rs)
+
+        return vbox
diff --git a/pyanaconda/iw/timezone_gui.py b/pyanaconda/iw/timezone_gui.py
new file mode 100644
index 0000000..c5ecd88
--- /dev/null
+++ b/pyanaconda/iw/timezone_gui.py
@@ -0,0 +1,181 @@
+#
+# timezone_gui.py: gui timezone selection.
+#
+# Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006  Red Hat, Inc.
+# 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 as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# 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, see <http://www.gnu.org/licenses/>.
+#
+
+import string
+import gtk
+import gtk.glade
+import gtk.gdk
+import gobject
+from scdate.core import zonetab
+import pango
+import sys
+
+from timezone_map_gui import TimezoneMap, Enum
+from iw_gui import *
+from booty.bootloaderInfo import dosFilesystems
+from bootloader import hasWindows
+
+from constants import *
+import gettext
+_ = lambda x: gettext.ldgettext("anaconda", x)
+
+try:
+    import gnomecanvas
+except ImportError:
+    import gnome.canvas as gnomecanvas
+
+class TimezoneWindow(InstallWindow):
+    def __init__(self, ics):
+        InstallWindow.__init__(self, ics)
+
+        # Need to set the custom handler before loading the glade file or
+        # this won't work.
+        gtk.glade.set_custom_handler(self.custom_widget_handler)
+
+        # Set the default now.  We'll fix it for real in getScreen.
+        self.default = "America/New York"
+
+        self.zonetab = zonetab.ZoneTab()
+
+        # Pull in a bunch of widgets.
+        self.xml = gtk.glade.XML("/usr/share/system-config-date/system-config-date.glade", domain="system-config-date")
+        self.vbox = self.xml.get_widget("tz_vbox")
+        self.utcCheckbox = self.xml.get_widget("utc_check")
+        self.notebook = self.xml.get_widget("notebook")
+
+        ics.setTitle(_("Time Zone Selection"))
+        ics.setNextEnabled(1)
+
+    def custom_widget_handler(self, xml, function_name, widget_name, str1, str2,
+                              int1, int2):
+        if hasattr(self, function_name):
+            handler = getattr(self, function_name)
+            return handler(str1, str2, int1, int2)
+        else:
+            # Lame.
+            return gtk.Label()
+
+    def timezone_widget_create (self, str1, str2, int1, int2):
+        mappath = "/usr/share/system-config-date/pixmaps/map1440.png"
+
+        self.tz = AnacondaTZMap(self.zonetab, self.default, map=mappath,
+                                viewportWidth=480)
+        self.tz.show_all()
+        return self.tz
+
+    def getNext(self):
+        newzone = self.tz.getCurrent().tz
+        self.timezone.setTimezoneInfo(newzone.replace(" ", "_"), self.utcCheckbox.get_active())
+        return None
+
+    # TimezoneWindow tag="timezone"
+    def getScreen(self, anaconda):
+	self.intf = anaconda.intf        
+        self.timezone = anaconda.timezone
+        (self.default, asUTC) = self.timezone.getTimezoneInfo()
+
+        if not self.default:
+            self.default = anaconda.instLanguage.getDefaultTimeZone(anaconda.rootPath)
+            asUTC = 0
+
+        if (string.find(self.default, "UTC") != -1):
+            self.default = "America/New_York"
+
+        self.default = self.default.replace("_", " ")
+
+        # Now fix the default we set when we made the timezone map widget.
+        self.tz.setCurrent(self.zonetab.findEntryByTZ(self.default))
+        self.utcCheckbox.set_active(asUTC)
+
+        if not anaconda.ksdata:
+            self.utcCheckbox.set_active(not hasWindows(anaconda.bootloader))
+
+        self.notebook.remove(self.vbox)
+        return self.vbox
+
+class AnacondaTZMap(TimezoneMap):
+    def __init__(self, zonetab, default, map="", viewportWidth=480):
+        TimezoneMap.__init__(self, zonetab, default, map=map, viewportWidth=viewportWidth)
+        self.columns = Enum("TRANSLATED", "TZ", "ENTRY")
+
+    def status_bar_init(self):
+        self.status = None
+
+    def load_entries (self, root):
+        iter = self.tzStore.get_iter_first()
+
+        for entry in self.zonetab.getEntries():
+            if entry.lat is not None and entry.long is not None:
+                x, y = self.map2canvas(entry.lat, entry.long)
+                marker = root.add(gnomecanvas.CanvasText, x=x, y=y,
+                                  text=u'\u00B7', fill_color='yellow',
+                                  anchor=gtk.ANCHOR_CENTER,
+                                  weight=pango.WEIGHT_BOLD)
+                self.markers[entry.tz] = marker
+
+                if entry.tz == "America/New York":
+                    # In case the /etc/sysconfig/clock is messed up, use New
+                    # York as the default.
+                    self.fallbackEntry = entry
+
+            iter = self.tzStore.insert_after(iter, [gettext.ldgettext("system-config-date", entry.tz), entry.tz, entry])
+
+    def timezone_list_init (self, default):
+        self.hbox = gtk.HBox()
+        self.tzStore = gtk.ListStore(gobject.TYPE_STRING, gobject.TYPE_STRING,
+                                     gobject.TYPE_PYOBJECT)
+
+        root = self.canvas.root()
+
+        self.load_entries(root)
+
+        # Add the ListStore to the sorted model after the list has been
+        # populated, since otherwise we end up resorting on every addition.
+        self.tzSorted = gtk.TreeModelSort(self.tzStore)
+        self.tzSorted.set_sort_column_id(0, gtk.SORT_ASCENDING)
+        self.tzCombo = gtk.ComboBox(model=self.tzSorted)
+        cell = gtk.CellRendererText()
+        self.tzCombo.pack_start(cell, True)
+        self.tzCombo.add_attribute(cell, 'text', 0)
+        self.tzCombo.connect("changed", self.selectionChanged)
+        self.hbox.pack_start(self.tzCombo, False, False)
+
+        self.pack_start(self.hbox, False, False)
+
+    def selectionChanged(self, widget, *args):
+        iter = widget.get_active_iter()
+        if iter is None:
+            return
+        entry = widget.get_model().get_value(iter, self.columns.ENTRY)
+        if entry:
+            self.setCurrent (entry, skipList=1)
+            if entry.long != None and entry.lat != None:
+                self.move_to (entry.long, entry.lat)
+
+    def updateTimezoneList(self):
+        # Find the currently selected item in the combo box and update both
+        # the combo and the comment label.
+        iter = self.tzCombo.get_model().get_iter_first()
+        while iter:
+            if self.tzCombo.get_model().get_value(iter, 1) == self.currentEntry.tz:
+                self.tzCombo.set_active_iter(iter)
+                break
+
+            iter = self.tzCombo.get_model().iter_next(iter)
diff --git a/pyanaconda/iw/upgrade_bootloader_gui.py b/pyanaconda/iw/upgrade_bootloader_gui.py
new file mode 100644
index 0000000..caaf2f3
--- /dev/null
+++ b/pyanaconda/iw/upgrade_bootloader_gui.py
@@ -0,0 +1,209 @@
+#
+# upgrade_bootloader_gui.py: gui bootloader dialog for upgrades
+#
+# Copyright (C) 2002, 2007  Red Hat, Inc.  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 as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# 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, see <http://www.gnu.org/licenses/>.
+#
+# Author(s): Jeremy Katz <katzj@xxxxxxxxxx>
+#
+
+# must replace with explcit form so update disks will work
+from iw_gui import *
+
+import gtk
+from booty import checkbootloader
+from storage.devices import devicePathToName
+
+from constants import *
+import gettext
+_ = lambda x: gettext.ldgettext("anaconda", x)
+
+import logging
+log = logging.getLogger("anaconda")
+
+class UpgradeBootloaderWindow (InstallWindow):
+    windowTitle = N_("Upgrade Boot Loader Configuration")
+
+    def getPrev(self):
+        pass
+
+    def getNext(self):
+        if self.nobl_radio.get_active():
+            self.dispatch.skipStep("bootloadersetup", skip = 1)
+            self.dispatch.skipStep("bootloader", skip = 1)
+            self.dispatch.skipStep("bootloaderadvanced", skip = 1)
+            self.dispatch.skipStep("instbootloader", skip = 1)
+        elif self.newbl_radio.get_active():
+            self.dispatch.skipStep("bootloadersetup", skip = 0)
+            self.dispatch.skipStep("bootloader", skip = 0)
+            self.dispatch.skipStep("bootloaderadvanced", skip = 0)
+            self.dispatch.skipStep("instbootloader", skip = 0)
+            self.bl.doUpgradeOnly = 0
+        else:
+            self.dispatch.skipStep("bootloadersetup", skip = 0)
+            self.dispatch.skipStep("bootloader", skip = 1)
+            self.dispatch.skipStep("bootloaderadvanced", skip = 1)
+            self.dispatch.skipStep("instbootloader", skip = 0)
+            self.bl.doUpgradeOnly = 1
+
+            if self.type == "GRUB":
+                self.bl.useGrubVal = 1
+            else:
+                self.bl.useGrubVal = 0
+            self.bl.setDevice(devicePathToName(self.bootDev))
+
+    def _newToLibata(self, rootPath):
+        # NOTE: any changes here need to be done in upgrade_bootloader_text too
+        try:
+            f = open("/proc/modules", "r")
+            buf = f.read()
+            if buf.find("libata") == -1:
+                return False
+        except:
+            log.debug("error reading /proc/modules")
+            pass
+
+        try:
+            f = open(rootPath + "/etc/modprobe.conf")
+        except:
+            log.debug("error reading /etc/modprobe.conf")
+            return False
+
+        modlines = f.readlines()
+        f.close()
+
+        try:
+            f = open("/tmp/scsidisks")
+        except:
+            log.debug("error reading /tmp/scsidisks")
+            return False
+        mods = []
+        for l in f.readlines():
+            (disk, mod) = l.split()
+            if mod.strip() not in mods:
+                mods.append(mod.strip())
+        f.close()
+
+        for l in modlines:
+            stripped = l.strip()
+
+            if stripped == "" or stripped[0] == "#":
+                continue
+
+            if stripped.find("scsi_hostadapter") != -1:
+                mod = stripped.split()[-1]
+                if mod in mods:
+                    mods.remove(mod)
+
+        if len(mods) > 0:
+            return True
+        return False
+
+    def getScreen(self, anaconda):
+        self.dispatch = anaconda.dispatch
+        self.bl = anaconda.bootloader
+
+        newToLibata = self._newToLibata(anaconda.rootPath)
+
+        (self.type, self.bootDev) = \
+                    checkbootloader.getBootloaderTypeAndBoot(anaconda.rootPath, storage=anaconda.storage)
+
+        self.update_radio = gtk.RadioButton(None, _("_Update boot loader configuration"))
+        updatestr = _("This will update your current boot loader.")
+
+        if newToLibata or (self.type is None or self.bootDev is None):
+            if newToLibata:
+                current = _("Due to system changes, your boot loader "
+                            "configuration can not be automatically updated.")
+            else:
+                current = _("The installer is unable to detect the boot loader "
+                            "currently in use on your system.")
+            self.update_label = gtk.Label("%s" % (updatestr,))
+            self.update_radio.set_sensitive(False)
+            self.update_label.set_sensitive(False)
+            update = 0
+        else:
+            current = _("The installer has detected the %(type)s boot loader "
+                        "currently installed on %(bootDev)s.") \
+                      % {'type': self.type, 'bootDev': self.bootDev}
+            self.update_label = gtk.Label("%s  %s" % (updatestr,
+                                         _("This is the recommended option.")))
+            self.update_radio.set_active(False)
+            update = 1
+
+        self.newbl_radio = gtk.RadioButton(self.update_radio,
+                                          _("_Create new boot loader "
+                                            "configuration"))
+        self.newbl_label = gtk.Label(_("This option creates a "
+                                      "new boot loader configuration.  If "
+                                      "you wish to switch boot loaders, you "
+                                      "should choose this."))
+
+        self.newbl_radio.set_active(False)
+        self.nobl_radio = gtk.RadioButton(self.update_radio,
+                                         _("_Skip boot loader updating"))
+        self.nobl_label = gtk.Label(_("This option makes no changes to boot "
+                                     "loader configuration.  If you are "
+                                     "using a third party boot loader, you "
+                                     "should choose this."))
+        self.nobl_radio.set_active(False)
+
+        for label in [self.update_label, self.nobl_label, self.newbl_label]:
+            label.set_alignment(0.8, 0)
+            label.set_size_request(275, -1)
+            label.set_line_wrap(True)
+
+        str = _("What would you like to do?")
+        # if they have one, the default is to update, otherwise the
+        # default is to not touch anything
+        if update == 1:
+            default = self.update_radio
+        elif newToLibata:
+            default = self.newbl_radio
+        else:
+            default = self.nobl_radio
+
+        if not self.dispatch.stepInSkipList("bootloader"):
+            self.newbl_radio.set_active(True)
+        elif self.dispatch.stepInSkipList("instbootloader"):
+            self.nobl_radio.set_active(True)
+        else:
+            default.set_active(True)
+
+        box = gtk.VBox(False, 5)
+
+        label = gtk.Label(current)
+        label.set_line_wrap(True)
+        label.set_alignment(0.5, 0.0)
+        label.set_size_request(300, -1)
+        label2 = gtk.Label(str)
+        label2.set_line_wrap(True)
+        label2.set_alignment(0.5, 0.0)
+        label2.set_size_request(300, -1)
+
+        box.pack_start(label, False)
+        box.pack_start(label2, False, padding = 10)
+
+        box.pack_start(self.update_radio, False)
+        box.pack_start(self.update_label, False)
+        box.pack_start(self.nobl_radio, False)
+        box.pack_start(self.nobl_label, False)
+        box.pack_start(self.newbl_radio, False)
+        box.pack_start(self.newbl_label, False)
+
+        a = gtk.Alignment(0.2, 0.1)
+        a.add(box)
+
+        return a
diff --git a/pyanaconda/iw/upgrade_migratefs_gui.py b/pyanaconda/iw/upgrade_migratefs_gui.py
new file mode 100644
index 0000000..dd3de5c
--- /dev/null
+++ b/pyanaconda/iw/upgrade_migratefs_gui.py
@@ -0,0 +1,118 @@
+#
+# upgrade_migratefs_gui.py: dialog for migrating filesystems on upgrades
+#
+# Copyright (C) 2001, 2002  Red Hat, Inc.  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 as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# 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, see <http://www.gnu.org/licenses/>.
+#
+# Author(s): Mike Fulbright <msf@xxxxxxxxxx>
+#
+
+from iw_gui import *
+from constants import *
+from storage.formats import getFormat
+from storage.deviceaction import ActionMigrateFormat
+import string
+import isys 
+import iutil
+import gtk
+
+import gettext
+_ = lambda x: gettext.ldgettext("anaconda", x)
+
+import logging
+log = logging.getLogger("anaconda")
+
+class UpgradeMigrateFSWindow (InstallWindow):		
+    windowTitle = N_("Migrate File Systems")
+
+    def getNext (self):
+        # I don't like this but I also don't see a better way right now
+        for (cb, entry) in self.cbs:
+            action = self.devicetree.findActions(device=entry,
+                                                 type="migrate")
+            if cb.get_active():
+                if action:
+                    # the migrate action has already been scheduled
+                    continue
+
+                newfs = getFormat(entry.format.migrationTarget)
+                if not newfs:
+                    log.warning("failed to get new filesystem type (%s)"
+                                % entry.format.migrationTarget)
+                    continue
+                action = ActionMigrateFormat(entry)
+                self.devicetree.registerAction(action)
+            elif action:
+                self.devicetree.cancelAction(action)
+
+        return None
+
+    def getScreen (self, anaconda):
+        self.devicetree = anaconda.storage.devicetree
+        self.migent = anaconda.storage.migratableDevices
+        
+        box = gtk.VBox (False, 5)
+        box.set_border_width (5)
+
+	text = (_("This release of %(productName)s supports "
+                 "an updated file system, which has several "
+                 "benefits over the file system traditionally shipped "
+                 "in %(productName)s.  This installation program can migrate "
+                 "formatted partitions without data loss.\n\n"
+                 "Which of these partitions would you like to migrate?") %
+                  {'productName': productName})
+        
+	label = gtk.Label (text)
+        label.set_alignment (0.5, 0.0)
+        label.set_size_request(400, -1)
+        label.set_line_wrap (True)
+        box.pack_start(label, False)
+
+        cbox = gtk.VBox(False, 5)
+        self.cbs = []
+        for entry in self.migent:
+            # don't allow the user to migrate /boot to ext4 (#439944)
+            if (getattr(entry.format, "mountpoint", None) == "/boot" and
+                not entry.format.migrate and entry.format.type == "ext3"):
+                continue
+            
+            cb = gtk.CheckButton("%s - %s - %s" % (entry.path,
+                                                   entry.format.name,
+                                                   getattr(entry.format,
+                                                           "mountpoint",
+                                                           None)))
+            cb.set_active(entry.format.migrate)
+            cbox.pack_start(cb, False)
+
+            self.cbs.append((cb, entry))
+
+        sw = gtk.ScrolledWindow()
+        sw.set_policy(gtk.POLICY_NEVER, gtk.POLICY_AUTOMATIC)
+        sw.add_with_viewport(cbox)
+        sw.set_size_request(-1, 175)
+        
+        viewport = sw.get_children()[0]
+        viewport.set_shadow_type(gtk.SHADOW_IN)
+        
+        a = gtk.Alignment(0.25, 0.5)
+        a.add(sw)
+
+        box.pack_start(a, True)
+        
+        a = gtk.Alignment(0.5, 0.5)
+        a.add(box)
+        return a
+    
+                       
diff --git a/pyanaconda/iw/upgrade_swap_gui.py b/pyanaconda/iw/upgrade_swap_gui.py
new file mode 100644
index 0000000..0edba09
--- /dev/null
+++ b/pyanaconda/iw/upgrade_swap_gui.py
@@ -0,0 +1,209 @@
+#
+# upgrade_swap_gui.py: dialog for adding swap files for 2.4
+#
+# Copyright (C) 2001, 2002  Red Hat, Inc.  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 as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# 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, see <http://www.gnu.org/licenses/>.
+#
+# Author(s): Mike Fulbright <msf@xxxxxxxxxx>
+#
+
+import iutil
+import upgrade
+import gui
+import gobject
+import gtk
+from iw_gui import *
+from flags import flags
+
+from constants import *
+import gettext
+_ = lambda x: gettext.ldgettext("anaconda", x)
+
+class UpgradeSwapWindow (InstallWindow):		
+    windowTitle = N_("Upgrade Swap Partition")
+
+    def getNext (self):
+        #-If the user doesn't need to add swap, we don't do anything
+        if not self.neededSwap:
+            return None
+
+        if self.option2.get_active():
+            rc = self.warning()
+
+            if rc == 0:
+                raise gui.StayOnScreen
+            else:
+                return None
+
+	selection = self.view.get_selection()
+	(model, iter) = selection.get_selected()
+	if iter:
+	    dev = model.get_value(iter, 0)
+	    size = model.get_value(iter, 1)
+            val = int(self.entry.get_text())
+	else:
+	    raise RuntimeError, "unknown value for upgrade swap location"
+
+        if val > 2000 or val < 1:
+            rc = self.swapWrongSize()
+            raise gui.StayOnScreen
+
+        elif (val+16) > size:
+            rc = self.swapTooBig()
+            raise gui.StayOnScreen            
+
+        else:
+            self.storage.createSwapFile(dev, val)
+            self.dispatch.skipStep("addswap", 1)
+                
+        return None
+
+    def toggle (self, data):
+        self.swapbox.set_sensitive(self.option1.get_active())
+
+    def clist_cb(self, clist, row, col, data):
+        self.row = row
+    
+    def getScreen (self, anaconda):
+        self.neededSwap = 0
+        self.storage = anaconda.storage
+        self.intf = anaconda.intf
+        self.dispatch = anaconda.dispatch
+        
+        rc = anaconda.upgradeSwapInfo
+
+        self.neededSwap = 1
+        self.row = 0
+        box = gtk.VBox (False, 5)
+        box.set_border_width (5)
+
+	label = gtk.Label (_("Recent kernels (2.4 or newer) need significantly more "
+                            "swap than older kernels, up to twice "
+                            "the amount of RAM on the system.  "
+                            "You currently have %dMB of swap configured, but "
+                            "you may create additional swap space on one of "
+                            "your file systems now.")
+                          % (iutil.swapAmount() / 1024) +
+                          _("\n\nThe installer has detected %s MB of RAM.\n") %
+                          (iutil.memInstalled()/1024))
+
+        label.set_alignment (0.5, 0.0)
+#        label.set_size_request(400, 200)
+        label.set_line_wrap (True)
+        box.pack_start(label, False)
+
+        hs = gtk.HSeparator()
+        box.pack_start(hs, False)
+
+        self.option1 = gtk.RadioButton(None,
+                                      (_("I _want to create a swap file")))
+        box.pack_start(self.option1, False)
+
+        (fsList, suggSize, suggMntPoint) = rc
+
+        self.swapbox = gtk.VBox(False, 5)
+        box.pack_start(self.swapbox, False)
+        
+
+        label = gui.MnemonicLabel (_("Select the _partition to put the swap file on:"))
+        a = gtk.Alignment(0.2, 0.5)
+        a.add(label)
+        self.swapbox.pack_start(a, False)
+
+	self.store = gtk.ListStore(gobject.TYPE_STRING,
+				   gobject.TYPE_STRING,
+				   gobject.TYPE_STRING)
+
+        for (dev, size) in fsList:
+	    iter = self.store.append()
+	    self.store.set_value(iter, 0, dev)
+	    self.store.set_value(iter, 1, str(size))
+
+	self.view=gtk.TreeView(self.store)
+        label.set_mnemonic_widget(self.view)
+
+	i = 0
+	for title in [(_("Mount Point")), (_("Partition")), (_("Free Space (MB)"))]:
+	    col = gtk.TreeViewColumn(title, gtk.CellRendererText(), text=i)
+	    self.view.append_column(col)
+	    i = i + 1
+
+	sw = gtk.ScrolledWindow()
+	sw.add(self.view)
+	sw.set_shadow_type(gtk.SHADOW_IN)
+	sw.set_policy(gtk.POLICY_NEVER, gtk.POLICY_AUTOMATIC)
+	sw.set_size_request(300, 90)
+	a = gtk.Alignment(0.5, 0.5)
+        a.add(sw)
+        self.swapbox.pack_start(a, False, True, 10)
+
+	rootiter = self.store.get_iter_first()
+	sel = self.view.get_selection()
+	sel.select_iter(rootiter)
+
+        label = gtk.Label (_("A minimum swap file size of "
+                            "%d MB is recommended.  Please enter a size for the swap "
+                            "file:") % suggSize)
+        label.set_size_request(400, 40)
+        label.set_line_wrap (True)
+        a = gtk.Alignment(0.5, 0.5)
+        a.add(label)
+        self.swapbox.pack_start(a, False, True, 10)
+
+
+        hbox = gtk.HBox(False, 5)
+        a = gtk.Alignment(0.4, 0.5)
+        a.add(hbox)
+        self.swapbox.pack_start(a, False)
+
+        label = gui.MnemonicLabel (_("Swap file _size (MB):"))
+        hbox.pack_start(label, False)
+
+        self.entry = gtk.Entry(4)
+        label.set_mnemonic_widget(self.entry)
+        self.entry.set_size_request(40, 25)
+        self.entry.set_text(str(suggSize))
+        hbox.pack_start(self.entry, False, True, 10)
+
+        self.option2 = gtk.RadioButton(self.option1,
+                                      (_("I _don't want to create a swap "
+                                         "file")))
+        box.pack_start(self.option2, False, True, 20)
+
+        self.option1.connect("toggled", self.toggle)
+        return box
+
+
+    def warning(self):
+        rc = self.intf.messageWindow(_("Warning"), 
+                    _("A swap file is strongly recommended. "
+                      "Failure to create one could cause the installer "
+                      "to abort abnormally.  Are you sure you wish "
+                      "to continue?"), type = "yesno")
+        return rc
+
+    def swapWrongSize(self):
+        rc = self.intf.messageWindow(_("Warning"), 
+                    _("The swap file must be between 1 and 2000 MB in size."),
+                       type = "okcancel")
+        return rc
+
+    def swapTooBig(self):
+        
+        rc = self.intf.messageWindow(_("Warning"), 
+                    _("There is not enough space on the device you "
+			  "selected for the swap partition."),
+                       type = "okcancel")
+        return rc
diff --git a/pyanaconda/iw/welcome_gui.py b/pyanaconda/iw/welcome_gui.py
new file mode 100644
index 0000000..d2e6fc5
--- /dev/null
+++ b/pyanaconda/iw/welcome_gui.py
@@ -0,0 +1,68 @@
+#
+# welcome_gui.py: gui welcome screen.
+#
+# Copyright (C) 2000, 2001, 2002  Red Hat, Inc.  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 as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# 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, see <http://www.gnu.org/licenses/>.
+#
+
+import gtk
+import gui
+import sys
+from iw_gui import *
+
+from constants import *
+import gettext
+_ = lambda x: gettext.ldgettext("anaconda", x)
+
+class WelcomeWindow (InstallWindow):
+
+    windowTitle = "" #N_("Welcome")
+
+    def __init__ (self, ics):
+        InstallWindow.__init__ (self, ics)
+        ics.setGrabNext (1)
+        self.anaconda = None
+
+    # WelcomeWindow tag="wel"
+    def getScreen (self, anaconda):
+        self.anaconda = anaconda
+        # this is a bit ugly... but scale the image if we're not at 800x600
+        (w, h) = self.ics.cw.window.get_size_request()
+        if w >= 800:
+            height = None
+            width = None
+        else:
+            width = 500
+            height = 258
+        pix = gui.readImageFromFile("splash.png", width, height, dither=False)
+        box = gtk.EventBox ()
+        box.add (pix)
+        return box
+
+    def getNext (self):
+        if self.anaconda.requiresNetworkInstall():
+            self.anaconda.intf.messageWindow(_("Network Install Required"),
+                                             _("Your installation source is set to "
+                                               "a network location, but no netork "
+                                               "devices were found on your "
+                                               "system.  To avoid a network "
+                                               "installation, boot with the full "
+                                               "DVD, full CD set, or do not pass "
+                                               "a repo= parameter that specifies "
+                                               "a network source."),
+                                             type="custom",
+                                             custom_icon="error",
+                                             custom_buttons=[_("E_xit Installer")])
+            sys.exit(0)
diff --git a/pyanaconda/iw/zipl_gui.py b/pyanaconda/iw/zipl_gui.py
new file mode 100644
index 0000000..9f2bdc2
--- /dev/null
+++ b/pyanaconda/iw/zipl_gui.py
@@ -0,0 +1,132 @@
+#
+# zipl_gui.py
+#
+# Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006  Red Hat, Inc.
+# 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 as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# 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, see <http://www.gnu.org/licenses/>.
+#
+
+# must replace with explcit form so update disks will work
+import gtk
+import string
+from iw_gui import *
+from constants import *
+from storage.dasd import getDasdPorts
+import gettext
+_ = lambda x: gettext.ldgettext("anaconda", x)
+
+class ZiplWindow (InstallWindow):
+    checkMark = None
+    checkMark_Off = None
+
+    def __init__ (self, ics):
+        InstallWindow.__init__ (self, ics)
+        self.ics.setTitle ("z/IPL")
+        self.ics.windowTitle = N_("z/IPL Boot Loader Configuration")
+
+    def getPrev (self):
+        # avoid coming back in here if the user backs past and then tries
+        # to skip this screen
+	pass
+
+    def getNext (self):
+        self.bl.args.set(self.kernelEntry.get_text())
+
+
+    # ZiplWindow tag="zipl"
+    def getScreen(self, anaconda):
+	self.dispatch = anaconda.dispatch
+	self.bl = anaconda.bootloader
+        self.intf = anaconda.intf
+
+	imageList = self.bl.images.getImages()
+	defaultDevice = self.bl.images.getDefault()
+        self.ignoreSignals = 0
+
+        box  = gtk.VBox(False, 5)
+        box.set_border_width(5)
+
+        label = gtk.Label(_("The z/IPL boot loader will be installed on your "
+                            "system."))
+        label = gtk.Label(_("The z/IPL Boot Loader will now be installed "
+                           "on your system."
+                           "\n"
+                           "\n"
+                           "The root partition will be the one you "
+                           "selected previously in the partition setup."
+                           "\n"
+                           "\n"
+                           "The kernel used to start the machine will be "
+                           "the one to be installed by default."
+                           "\n"
+                           "\n"
+                           "If you wish to make changes later after "
+                           "the installation feel free to change the "
+                           "/etc/zipl.conf configuration file."
+                           "\n"
+                           "\n"
+                           "You can now enter any additional kernel parameters "
+                           "which your machine or your setup may require."))
+        label.set_size_request(500, -1)
+        label.set_line_wrap(True)
+        label.set_alignment(0.0, 0.0)
+        label.set_padding(50,50)
+        box.pack_start(label, False)
+
+        box.pack_start (gtk.HSeparator (), False)
+
+        label = gtk.Label(_("Kernel Parameters") + ":")
+        label.set_alignment(0.0, 0.5)
+        self.kernelEntry = gtk.Entry()
+        clabel1 = gtk.Label(_("Chandev Parameters") + ":")
+        clabel1.set_alignment(0.0, 0.5)
+        self.chandeventry1 = gtk.Entry()
+        clabel2 = gtk.Label(_("Chandev Parameters") + ":")
+        clabel2.set_alignment(0.0, 0.5)
+        self.chandeventry2 = gtk.Entry()
+
+        if self.bl.args and self.bl.args.get():
+            kernelparms = self.bl.args.get()
+        else:
+            kernelparms = ""
+        if getDasdPorts() and (kernelparms.find("dasd=") == -1):
+            if len(kernelparms) > 0:
+                kernelparms = "%s dasd=%s" %(kernelparms, getDasdPorts())
+            else:
+                kernelparms = "dasd=%s" %(getDasdPorts(),)
+        self.kernelEntry.set_text(kernelparms)
+        
+        if self.bl.args and self.bl.args.chandevget():
+            cdevs = self.bl.args.chandevget()
+            self.chandeventry1.set_text('')
+            self.chandeventry2.set_text('')
+            if len(cdevs) > 0:
+                self.chandeventry1.set_text(cdevs[0])
+            if len(cdevs) > 1:
+                self.chandeventry2.set_text(string.join(cdevs[1:],';'))
+        hbox = gtk.HBox(False, 5)
+        hbox.pack_start(label, False)
+        hbox.pack_start(self.kernelEntry)
+        box.pack_start(hbox, False)
+        hbox1 = gtk.HBox(False, 5)
+        hbox1.pack_start(clabel1, False)
+        hbox1.pack_start(self.chandeventry1)
+        box.pack_start(hbox1, False)
+        hbox2 = gtk.HBox(False, 5)
+        hbox2.pack_start(clabel2, False)
+        hbox2.pack_start(self.chandeventry2)
+        box.pack_start(hbox2, False)
+
+        return box
diff --git a/pyanaconda/kickstart.py b/pyanaconda/kickstart.py
new file mode 100644
index 0000000..8e3368d
--- /dev/null
+++ b/pyanaconda/kickstart.py
@@ -0,0 +1,1499 @@
+#
+# kickstart.py: kickstart install support
+#
+# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007
+# Red Hat, Inc.  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 as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# 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, see <http://www.gnu.org/licenses/>.
+#
+
+from storage.deviceaction import *
+from storage.devices import LUKSDevice
+from storage.devicelibs.lvm import getPossiblePhysicalExtents
+from storage.formats import getFormat
+from storage.partitioning import clearPartitions
+from storage.partitioning import shouldClear
+import storage.iscsi
+import storage.fcoe
+import storage.zfcp
+
+from errors import *
+import iutil
+import isys
+import os
+import os.path
+import tempfile
+from flags import flags
+from constants import *
+import sys
+import string
+import urlgrabber
+import warnings
+import network
+import upgrade
+import pykickstart.commands as commands
+from storage.devices import *
+from scdate.core import zonetab
+from pykickstart.base import KickstartCommand, BaseData
+from pykickstart.constants import *
+from pykickstart.errors import *
+from pykickstart.parser import *
+from pykickstart.version import *
+
+import gettext
+_ = lambda x: gettext.ldgettext("anaconda", x)
+
+import logging
+log = logging.getLogger("anaconda")
+stderrLog = logging.getLogger("anaconda.stderr")
+from anaconda_log import logger, logLevelMap, setHandlersLevel,\
+    DEFAULT_TTY_LEVEL
+
+class AnacondaKSScript(Script):
+    def run(self, chroot, serial, intf = None):
+        if self.inChroot:
+            scriptRoot = chroot
+        else:
+            scriptRoot = "/"
+
+        (fd, path) = tempfile.mkstemp("", "ks-script-", scriptRoot + "/tmp")
+
+        os.write(fd, self.script)
+        os.close(fd)
+        os.chmod(path, 0700)
+
+        # Always log stdout/stderr from scripts.  Using --logfile just lets you
+        # pick where it goes.  The script will also be logged to program.log
+        # because of execWithRedirect, and to anaconda.log if the script fails.
+        if self.logfile:
+            if self.inChroot:
+                messages = "%s/%s" % (scriptRoot, self.logfile)
+            else:
+                messages = self.logfile
+
+            d = os.path.basename(messages)
+            if not os.path.exists(d):
+                os.makedirs(d)
+        else:
+            messages = "%s.log" % path
+
+        if intf:
+            intf.suspend()
+        rc = iutil.execWithRedirect(self.interp, ["/tmp/%s" % os.path.basename(path)],
+                                    stdin = messages, stdout = messages, stderr = messages,
+                                    root = scriptRoot)
+        if intf:
+            intf.resume()
+
+        # Always log an error.  Only fail if we have a handle on the
+        # windowing system and the kickstart file included --erroronfail.
+        if rc != 0:
+            log.error("Error code %s running the kickstart script at line %s" % (rc, self.lineno))
+
+            try:
+                f = open(messages, "r")
+                err = f.readlines()
+                f.close()
+                for l in err:
+                    log.error("\t%s" % l)
+            except:
+                err = None
+
+            if self.errorOnFail:
+                if intf != None:
+                    msg = _("There was an error running the kickstart "
+                            "script at line %(lineno)s.  You may examine the "
+                            "output in %(msgs)s.  This is a fatal error and "
+                            "installation will be aborted.  Press the "
+                            "OK button to exit the installer.") \
+                          % {'lineno': self.lineno, 'msgs': messages}
+
+                    if err:
+                        intf.detailedMessageWindow(_("Scriptlet Failure"), msg, err)
+                    else:
+                        intf.messageWindow(_("Scriptlet Failure"), msg)
+
+                sys.exit(0)
+
+        if serial or self.logfile is not None:
+            os.chmod("%s" % messages, 0600)
+
+class AnacondaKSPackages(Packages):
+    def __init__(self):
+        Packages.__init__(self)
+
+        # Has the %packages section been seen at all?
+        self.seen = False
+
+
+def getEscrowCertificate(anaconda, url):
+    if not url:
+        return None
+
+    if url in anaconda.storage.escrowCertificates:
+        return anaconda.storage.escrowCertificates[url]
+
+    needs_net = not url.startswith("/") and not url.startswith("file:")
+    if needs_net and not network.hasActiveNetDev():
+        if not anaconda.intf.enableNetwork(anaconda):
+            anaconda.intf.messageWindow(_("No Network Available"),
+                                        _("Encryption key escrow requires "
+                                          "networking, but there was an error "
+                                          "enabling the network on your "
+                                          "system."), type="custom",
+                                        custom_icon="error",
+                                        custom_buttons=[_("_Exit installer")])
+            sys.exit(1)
+
+    log.info("escrow: downloading %s" % (url,))
+
+    try:
+        f = urlgrabber.urlopen(url)
+    except urlgrabber.grabber.URLGrabError as e:
+        msg = _("The following error was encountered while downloading the escrow certificate:\n\n%s" % e)
+        if anaconda.intf:
+            anaconda.intf.kickstartErrorWindow(msg)
+            sys.exit(1)
+        else:
+            stderrLog.critical(msg)
+            sys.exit(1)
+
+    try:
+        anaconda.storage.escrowCertificates[url] = f.read()
+    finally:
+        f.close()
+
+    return anaconda.storage.escrowCertificates[url]
+
+def deviceMatches(spec):
+    if not spec.startswith("/dev/"):
+        spec = os.path.normpath("/dev/" + spec)
+
+    matches = udev_resolve_glob(spec)
+    dev = udev_resolve_devspec(spec)
+
+    # udev_resolve_devspec returns None if there's no match, but we don't
+    # want that ending up in the list.
+    if dev and dev not in matches:
+        matches.append(dev)
+
+    return matches
+
+# Remove any existing formatting on a device, but do not remove the partition
+# itself.  This sets up an existing device to be used in a --onpart option.
+def removeExistingFormat(device, storage):
+    deps = storage.deviceDeps(device)
+    while deps:
+        leaves = [d for d in deps if d.isleaf]
+        for leaf in leaves:
+            storage.destroyDevice(leaf)
+            deps.remove(leaf)
+
+    storage.devicetree.registerAction(ActionDestroyFormat(device))
+
+###
+### SUBCLASSES OF PYKICKSTART COMMAND HANDLERS
+###
+
+class Authconfig(commands.authconfig.FC3_Authconfig):
+    def execute(self, anaconda):
+        anaconda.security.auth = self.authconfig
+
+class AutoPart(commands.autopart.F12_AutoPart):
+    def execute(self, anaconda):
+        # sets up default autopartitioning.  use clearpart separately
+        # if you want it
+        anaconda.instClass.setDefaultPartitioning(anaconda.storage, anaconda.platform)
+        anaconda.storage.doAutoPart = True
+
+        if self.encrypted:
+            anaconda.storage.encryptedAutoPart = True
+            anaconda.storage.encryptionPassphrase = self.passphrase
+            anaconda.storage.autoPartEscrowCert = \
+                getEscrowCertificate(anaconda, self.escrowcert)
+            anaconda.storage.autoPartAddBackupPassphrase = \
+                self.backuppassphrase
+
+        anaconda.ksdata.skipSteps.extend(["partition", "zfcpconfig", "parttype"])
+
+class AutoStep(commands.autostep.FC3_AutoStep):
+    def execute(self, anaconda):
+        flags.autostep = 1
+        flags.autoscreenshot = self.autoscreenshot
+
+class Bootloader(commands.bootloader.F12_Bootloader):
+    def execute(self, anaconda):
+        if self.location == "none":
+            location = None
+        elif self.location == "partition":
+            location = "boot"
+        else:
+            location = self.location
+
+        if self.upgrade and not anaconda.upgrade:
+            raise KickstartValueError, formatErrorMsg(self.lineno, msg="Selected upgrade mode for bootloader but not doing an upgrade")
+
+        if self.upgrade:
+            anaconda.bootloader.kickstart = 1
+            anaconda.bootloader.doUpgradeOnly = 1
+
+        if location is None:
+            anaconda.ksdata.permanentSkipSteps.extend(["bootloadersetup", "instbootloader"])
+        else:
+            anaconda.ksdata.showSteps.append("bootloader")
+
+            if self.appendLine:
+                anaconda.bootloader.args.append(self.appendLine)
+
+            if self.password:
+                anaconda.bootloader.setPassword(self.password, isCrypted = 0)
+
+            if self.md5pass:
+                anaconda.bootloader.setPassword(self.md5pass)
+
+            if location != None:
+                anaconda.bootloader.defaultDevice = location
+            else:
+                anaconda.bootloader.defaultDevice = -1
+
+            if self.timeout:
+                anaconda.bootloader.timeout = self.timeout
+
+            # add unpartitioned devices that will get partitioned into
+            # bootloader.drivelist
+            disks = anaconda.storage.disks
+            partitioned = anaconda.storage.partitioned
+            for disk in [d for d in disks if not d.partitioned]:
+                if shouldClear(disk, anaconda.storage.clearPartType,
+                               anaconda.storage.clearPartDisks):
+                    # add newly partitioned disks to the drivelist
+                    anaconda.bootloader.drivelist.append(disk.name)
+                elif disk.name in anaconda.bootloader.drivelist:
+                    # remove unpartitioned disks from the drivelist
+                    anaconda.bootloader.drivelist.remove(disk.name)
+            anaconda.bootloader.drivelist.sort(
+                cmp=anaconda.storage.compareDisks)
+
+            # Throw out drives specified that don't exist.
+            if self.driveorder and len(self.driveorder) > 0:
+                new = []
+                for drive in self.driveorder:
+                    if drive in anaconda.bootloader.drivelist:
+                        new.append(drive)
+                    else:
+                        log.warning("requested drive %s in boot drive order "
+                                    "doesn't exist" %(drive,))
+
+                anaconda.bootloader.updateDriveList(new)
+
+        anaconda.ksdata.permanentSkipSteps.extend(["upgbootloader", "bootloader"])
+
+class ClearPart(commands.clearpart.FC3_ClearPart):
+    def parse(self, args):
+        retval = commands.clearpart.FC3_ClearPart.parse(self, args)
+
+        if self.type is None:
+            self.type = CLEARPART_TYPE_NONE
+
+        # Do any glob expansion now, since we need to have the real list of
+        # disks available before the execute methods run.
+        drives = []
+        for spec in self.drives:
+            matched = deviceMatches(spec)
+            if matched:
+                drives.extend(matched)
+            else:
+                raise KickstartValueError, formatErrorMsg(self.lineno, msg="Specified nonexistent disk %s in clearpart command" % spec)
+
+        self.drives = drives
+
+        return retval
+
+    def execute(self, anaconda):
+        anaconda.storage.clearPartType = self.type
+        anaconda.storage.clearPartDisks = self.drives
+        if self.initAll:
+            anaconda.storage.reinitializeDisks = self.initAll
+
+        clearPartitions(anaconda.storage)
+        anaconda.ksdata.skipSteps.append("cleardiskssel")
+
+class Fcoe(commands.fcoe.F13_Fcoe):
+    def parse(self, args):
+        fc = commands.fcoe.F13_Fcoe.parse(self, args)
+
+        if fc.nic not in isys.getDeviceProperties():
+            raise KickstartValueError, formatErrorMsg(self.lineno, msg="Specified nonexistent nic %s in fcoe command" % fc.nic)
+
+        storage.fcoe.fcoe().addSan(nic=fc.nic, dcb=fc.dcb)
+
+        return fc
+
+class Firewall(commands.firewall.F10_Firewall):
+    def execute(self, anaconda):
+        anaconda.firewall.enabled = self.enabled
+        anaconda.firewall.trustdevs = self.trusts
+
+        for port in self.ports:
+            anaconda.firewall.portlist.append (port)
+
+        for svc in self.services:
+            anaconda.firewall.servicelist.append (svc)
+
+class IgnoreDisk(commands.ignoredisk.F8_IgnoreDisk):
+    def parse(self, args):
+        retval = commands.ignoredisk.F8_IgnoreDisk.parse(self, args)
+
+        # See comment in ClearPart.parse
+        drives = []
+        for spec in self.ignoredisk:
+            matched = deviceMatches(spec)
+            if matched:
+                drives.extend(matched)
+            else:
+                raise KickstartValueError, formatErrorMsg(self.lineno, msg="Specified nonexistent disk %s in ignoredisk command" % spec)
+
+        self.ignoredisk = drives
+
+        drives = []
+        for spec in self.onlyuse:
+            matched = deviceMatches(spec)
+            if matched:
+                drives.extend(matched)
+            else:
+                raise KickstartValueError, formatErrorMsg(self.lineno, msg="Specified nonexistent disk %s in ignoredisk command" % spec)
+
+        self.onlyuse = drives
+
+        return retval
+
+    def execute(self, anaconda):
+        anaconda.storage.ignoredDisks = self.ignoredisk
+        anaconda.storage.exclusiveDisks = self.onlyuse
+        anaconda.ksdata.skipSteps.extend(["filter", "filtertype"])
+
+class Iscsi(commands.iscsi.F10_Iscsi):
+    def parse(self, args):
+        tg = commands.iscsi.F10_Iscsi.parse(self, args)
+
+        try:
+            storage.iscsi.iscsi().addTarget(tg.ipaddr, tg.port,
+                tg.user, tg.password, tg.user_in, tg.password_in)
+            log.info("added iscsi target: %s" %(tg.ipaddr,))
+        except (IOError, ValueError), e:
+            raise KickstartValueError, formatErrorMsg(self.lineno,
+                                                      msg=str(e))
+        return tg
+
+class IscsiName(commands.iscsiname.FC6_IscsiName):
+    def parse(self, args):
+        retval = commands.iscsiname.FC6_IscsiName.parse(self, args)
+
+        storage.iscsi.iscsi().initiator = self.iscsiname
+        return retval
+
+class Keyboard(commands.keyboard.FC3_Keyboard):
+    def execute(self, anaconda):
+        anaconda.keyboard.set(self.keyboard)
+        anaconda.keyboard.beenset = 1
+        anaconda.ksdata.skipSteps.append("keyboard")
+
+class Lang(commands.lang.FC3_Lang):
+    def execute(self, anaconda):
+        anaconda.instLanguage.instLang = self.lang
+        anaconda.instLanguage.systemLang = self.lang
+        anaconda.ksdata.skipSteps.append("language")
+
+class LogVolData(commands.logvol.F12_LogVolData):
+    def execute(self, anaconda):
+        storage = anaconda.storage
+        devicetree = storage.devicetree
+
+        storage.doAutoPart = False
+
+        if self.mountpoint == "swap":
+            type = "swap"
+            self.mountpoint = ""
+            if self.recommended:
+                (self.size, self.maxSizeMB) = iutil.swapSuggestion()
+                self.grow = True
+        else:
+            if self.fstype != "":
+                type = self.fstype
+            else:
+                type = storage.defaultFSType
+
+        # Sanity check mountpoint
+        if self.mountpoint != "" and self.mountpoint[0] != '/':
+            raise KickstartValueError, formatErrorMsg(self.lineno, msg="The mount point \"%s\" is not valid." % (self.mountpoint,))
+
+        # Check that the VG this LV is a member of has already been specified.
+        vg = devicetree.getDeviceByName(self.vgname)
+        if not vg:
+            raise KickstartValueError, formatErrorMsg(self.lineno, msg="No volume group exists with the name \"%s\".  Specify volume groups before logical volumes." % self.vgname)
+
+        # If this specifies an existing request that we should not format,
+        # quit here after setting up enough information to mount it later.
+        if not self.format:
+            if not self.name:
+                raise KickstartValueError, formatErrorMsg(self.lineno, msg="--noformat used without --name")
+
+            dev = devicetree.getDeviceByName("%s-%s" % (vg.name, self.name))
+            if not dev:
+                raise KickstartValueError, formatErrorMsg(self.lineno, msg="No preexisting logical volume with the name \"%s\" was found." % self.name)
+
+            dev.format.mountpoint = self.mountpoint
+            dev.format.mountopts = self.fsopts
+            anaconda.ksdata.skipSteps.extend(["partition", "zfcpconfig", "parttype"])
+            return
+
+        # Make sure this LV name is not already used in the requested VG.
+        if not self.preexist:
+            tmp = devicetree.getDeviceByName("%s-%s" % (vg.name, self.name))
+            if tmp:
+                raise KickstartValueError, formatErrorMsg(self.lineno, msg="Logical volume name already used in volume group %s" % vg.name)
+
+            # Size specification checks
+            if not self.percent:
+                if not self.size:
+                    raise KickstartValueError, formatErrorMsg(self.lineno, msg="Size required")
+                elif not self.grow and self.size*1024 < vg.peSize:
+                    raise KickstartValueError, formatErrorMsg(self.lineno, msg="Logical volume size must be larger than the volume group physical extent size.")
+            elif self.percent <= 0 or self.percent > 100:
+                raise KickstartValueError, formatErrorMsg(self.lineno, msg="Percentage must be between 0 and 100")
+
+        # Now get a format to hold a lot of these extra values.
+        format = getFormat(type,
+                           mountpoint=self.mountpoint,
+                           mountopts=self.fsopts)
+        if not format:
+            raise KickstartValueError, formatErrorMsg(self.lineno, msg="The \"%s\" filesystem type is not supported." % type)
+
+        # If we were given a pre-existing LV to create a filesystem on, we need
+        # to verify it and its VG exists and then schedule a new format action
+        # to take place there.  Also, we only support a subset of all the
+        # options on pre-existing LVs.
+        if self.preexist:
+            device = devicetree.getDeviceByName("%s-%s" % (vg.name, self.name))
+            if not device:
+                raise KickstartValueError, formatErrorMsg(self.lineno, msg="Specified nonexistent LV %s in logvol command" % self.name)
+
+            removeExistingFormat(device, storage)
+            devicetree.registerAction(ActionCreateFormat(device, format))
+        else:
+            # If a previous device has claimed this mount point, delete the
+            # old one.
+            try:
+                if self.mountpoint:
+                    device = storage.mountpoints[self.mountpoint]
+                    storage.destroyDevice(device)
+            except KeyError:
+                pass
+
+            request = storage.newLV(format=format,
+                                    name=self.name,
+                                    vg=vg,
+                                    size=self.size,
+                                    grow=self.grow,
+                                    maxsize=self.maxSizeMB,
+                                    percent=self.percent)
+
+            if self.fsprofile and hasattr(request.format, "fsprofile"):
+                request.format.fsprofile = self.fsprofile
+
+            storage.createDevice(request)
+
+        if self.encrypted:
+            if self.passphrase and not storage.encryptionPassphrase:
+                storage.encryptionPassphrase = self.passphrase
+
+            cert = getEscrowCertificate(anaconda, self.escrowcert)
+            if self.preexist:
+                luksformat = format
+                device.format = getFormat("luks", passphrase=self.passphrase, device=device.path,
+                                          escrow_cert=cert,
+                                          add_backup_passphrase=self.backuppassphrase)
+                luksdev = LUKSDevice("luks%d" % storage.nextID,
+                                     format=luksformat,
+                                     parents=device)
+            else:
+                luksformat = request.format
+                request.format = getFormat("luks", passphrase=self.passphrase,
+                                           escrow_cert=cert,
+                                           add_backup_passphrase=self.backuppassphrase)
+                luksdev = LUKSDevice("luks%d" % storage.nextID,
+                                     format=luksformat,
+                                     parents=request)
+            storage.createDevice(luksdev)
+
+        anaconda.ksdata.skipSteps.extend(["partition", "zfcpconfig", "parttype"])
+
+class Logging(commands.logging.FC6_Logging):
+    def execute(self, anaconda):
+        if logger.tty_loglevel == DEFAULT_TTY_LEVEL:
+            # not set from the command line
+            level = logLevelMap[self.level]
+            logger.tty_loglevel = level
+            storage_log = logging.getLogger("storage")
+            setHandlersLevel(log, level)
+            setHandlersLevel(storage_log, level)
+
+        if logger.remote_syslog == None and len(self.host) > 0:
+            # not set from the command line, ok to use kickstart
+            remote_server = self.host
+            if self.port:
+                remote_server = "%s:%s" %(self.host, self.port)
+            logger.updateRemote(remote_server)
+    
+class NetworkData(commands.network.F8_NetworkData):
+    def execute(self, anaconda):
+        if self.bootProto:
+            devices = anaconda.network.netdevices
+            if (devices and self.bootProto):
+                if not self.device:
+                    list = devices.keys ()
+                    list.sort()
+                    device = list[0]
+                else:
+                    device = self.device
+
+                try:
+                    dev = devices[device]
+                except KeyError:
+                    raise KickstartValueError, formatErrorMsg(self.lineno, msg="The provided network interface %s does not exist" % device)
+
+                dev.set (("bootproto", self.bootProto))
+                dev.set (("dhcpclass", self.dhcpclass))
+
+                if self.onboot:
+                    dev.set (("onboot", "yes"))
+                else:
+                    dev.set (("onboot", "no"))
+
+                if self.bootProto == "static":
+                    if (self.ip):
+                        dev.set (("ipaddr", self.ip))
+                    if (self.netmask):
+                        dev.set (("netmask", self.netmask))
+
+                if self.ethtool:
+                    dev.set (("ethtool_opts", self.ethtool))
+
+                if isys.isWireless(device):
+                    if self.essid:
+                        dev.set(("essid", self.essid))
+                    if self.wepkey:
+                        dev.set(("wepkey", self.wepkey))
+
+        if self.hostname != "":
+            anaconda.network.setHostname(self.hostname)
+            anaconda.network.overrideDHCPhostname = True
+
+        if self.nameserver != "":
+            anaconda.network.setDNS(self.nameserver, device)
+
+        if self.gateway != "":
+            anaconda.network.setGateway(self.gateway, device)
+
+        needs_net = (anaconda.methodstr and
+                     (anaconda.methodstr.startswith("http:") or
+                      anaconda.methodstr.startswith("ftp:") or
+                      anaconda.methodstr.startswith("nfs:")))
+        if needs_net and not network.hasActiveNetDev():
+            log.info("Bringing up network in stage2 kickstart ...")
+            rc = anaconda.network.bringUp()
+            log.info("Network setup %s" % (rc and 'succeeded' or 'failed',))
+
+class MultiPath(commands.multipath.FC6_MultiPath):
+    def parse(self, args):
+        raise NotImplementedError("The multipath kickstart command is not currently supported")
+
+class DmRaid(commands.dmraid.FC6_DmRaid):
+    def parse(self, args):
+        raise NotImplementedError("The dmraid kickstart command is not currently supported")
+
+class PartitionData(commands.partition.F12_PartData):
+    def execute(self, anaconda):
+        storage = anaconda.storage
+        devicetree = storage.devicetree
+        kwargs = {}
+
+        storage.doAutoPart = False
+
+        if self.onbiosdisk != "":
+            for (disk, biosdisk) in storage.eddDict.iteritems():
+                if str(biosdisk) == self.onbiosdisk:
+                    self.disk = disk
+                    break
+
+            if self.disk == "":
+                raise KickstartValueError, formatErrorMsg(self.lineno, msg="Specified BIOS disk %s cannot be determined" % self.onbiosdisk)
+
+        if self.mountpoint == "swap":
+            type = "swap"
+            self.mountpoint = ""
+            if self.recommended:
+                (self.size, self.maxSizeMB) = iutil.swapSuggestion()
+                self.grow = True
+        # if people want to specify no mountpoint for some reason, let them
+        # this is really needed for pSeries boot partitions :(
+        elif self.mountpoint == "None":
+            self.mountpoint = ""
+            if self.fstype:
+                type = self.fstype
+            else:
+                type = storage.defaultFSType
+        elif self.mountpoint == 'appleboot':
+            type = "Apple Bootstrap"
+            self.mountpoint = ""
+            kwargs["weight"] = anaconda.platform.weight(fstype="appleboot")
+        elif self.mountpoint == 'prepboot':
+            type = "PPC PReP Boot"
+            self.mountpoint = ""
+            kwargs["weight"] = anaconda.platform.weight(fstype="prepboot")
+        elif self.mountpoint.startswith("raid."):
+            type = "mdmember"
+            kwargs["name"] = self.mountpoint
+
+            if devicetree.getDeviceByName(kwargs["name"]):
+                raise KickstartValueError, formatErrorMsg(self.lineno, msg="RAID partition defined multiple times")
+
+            # store "raid." alias for other ks partitioning commands
+            if self.onPart:
+                anaconda.ksdata.onPart[kwargs["name"]] = self.onPart
+            self.mountpoint = ""
+        elif self.mountpoint.startswith("pv."):
+            type = "lvmpv"
+            kwargs["name"] = self.mountpoint
+
+            if devicetree.getDeviceByName(kwargs["name"]):
+                raise KickstartValueError, formatErrorMsg(self.lineno, msg="PV partition defined multiple times")
+
+            # store "pv." alias for other ks partitioning commands
+            if self.onPart:
+                anaconda.ksdata.onPart[kwargs["name"]] = self.onPart
+            self.mountpoint = ""
+        elif self.mountpoint == "/boot/efi":
+            type = "EFI System Partition"
+            self.fsopts = "defaults,uid=0,gid=0,umask=0077,shortname=winnt"
+            kwargs["weight"] = anaconda.platform.weight(fstype="efi")
+        else:
+            if self.fstype != "":
+                type = self.fstype
+            elif self.mountpoint == "/boot":
+                type = anaconda.platform.defaultBootFSType
+            else:
+                type = storage.defaultFSType
+
+        # If this specified an existing request that we should not format,
+        # quit here after setting up enough information to mount it later.
+        if not self.format:
+            if not self.onPart:
+                raise KickstartValueError, formatErrorMsg(self.lineno, msg="--noformat used without --onpart")
+
+            dev = devicetree.getDeviceByName(udev_resolve_devspec(self.onPart))
+            if not dev:
+                raise KickstartValueError, formatErrorMsg(self.lineno, msg="No preexisting partition with the name \"%s\" was found." % self.onPart)
+
+            dev.format.mountpoint = self.mountpoint
+            dev.format.mountopts = self.fsopts
+            anaconda.ksdata.skipSteps.extend(["partition", "zfcpconfig", "parttype"])
+            return
+
+        # Size specification checks.
+        if not self.size and not self.onPart:
+            raise KickstartValueError, formatErrorMsg(self.lineno, msg="Partition requires a size specification")
+
+        # Now get a format to hold a lot of these extra values.
+        kwargs["format"] = getFormat(type,
+                                     mountpoint=self.mountpoint,
+                                     label=self.label,
+                                     mountopts=self.fsopts)
+        if not kwargs["format"]:
+            raise KickstartValueError, formatErrorMsg(self.lineno, msg="The \"%s\" filesystem type is not supported." % type)
+
+        # If we were given a specific disk to create the partition on, verify
+        # that it exists first.  If it doesn't exist, see if it exists with
+        # mapper/ on the front.  If that doesn't exist either, it's an error.
+        if self.disk:
+            names = [self.disk, "mapper/" + self.disk]
+            for n in names:
+                disk = devicetree.getDeviceByName(udev_resolve_devspec(n))
+                if not disk:
+                    raise KickstartValueError, formatErrorMsg(self.lineno, msg="Specified nonexistent disk %s in partition command" % n)
+
+                should_clear = shouldClear(disk,
+                                           storage.clearPartType,
+                                           storage.clearPartDisks)
+                if disk and (disk.partitioned or should_clear):
+                    kwargs["disks"] = [disk]
+                    break
+                elif disk:
+                    raise KickstartValueError, formatErrorMsg(self.lineno, msg="Specified unpartitioned disk %s in partition command" % self.disk)
+
+            if not kwargs["disks"]:
+                raise KickstartValueError, formatErrorMsg(self.lineno, msg="Specified nonexistent disk %s in partition command" % self.disk)
+
+        kwargs["grow"] = self.grow
+        kwargs["size"] = self.size
+        kwargs["maxsize"] = self.maxSizeMB
+        kwargs["primary"] = self.primOnly
+
+        # If we were given a pre-existing partition to create a filesystem on,
+        # we need to verify it exists and then schedule a new format action to
+        # take place there.  Also, we only support a subset of all the options
+        # on pre-existing partitions.
+        if self.onPart:
+            device = devicetree.getDeviceByName(udev_resolve_devspec(self.onPart))
+            if not device:
+                raise KickstartValueError, formatErrorMsg(self.lineno, msg="Specified nonexistent partition %s in partition command" % self.onPart)
+
+            removeExistingFormat(device, storage)
+            devicetree.registerAction(ActionCreateFormat(device, kwargs["format"]))
+        else:
+            # If a previous device has claimed this mount point, delete the
+            # old one.
+            try:
+                if self.mountpoint:
+                    device = storage.mountpoints[self.mountpoint]
+                    storage.destroyDevice(device)
+            except KeyError:
+                pass
+
+            request = storage.newPartition(**kwargs)
+
+            if self.fsprofile and hasattr(request.format, "fsprofile"):
+                request.format.fsprofile = self.fsprofile
+
+            storage.createDevice(request)
+
+        if self.encrypted:
+            if self.passphrase and not storage.encryptionPassphrase:
+               storage.encryptionPassphrase = self.passphrase
+
+            cert = getEscrowCertificate(anaconda, self.escrowcert)
+            if self.onPart:
+                luksformat = format
+                device.format = getFormat("luks", passphrase=self.passphrase, device=device.path,
+                                          escrow_cert=cert,
+                                          add_backup_passphrase=self.backuppassphrase)
+                luksdev = LUKSDevice("luks%d" % storage.nextID,
+                                     format=luksformat,
+                                     parents=device)
+            else:
+                luksformat = request.format
+                request.format = getFormat("luks", passphrase=self.passphrase,
+                                           escrow_cert=cert,
+                                           add_backup_passphrase=self.backuppassphrase)
+                luksdev = LUKSDevice("luks%d" % storage.nextID,
+                                     format=luksformat,
+                                     parents=request)
+            storage.createDevice(luksdev)
+
+        anaconda.ksdata.skipSteps.extend(["partition", "zfcpconfig", "parttype"])
+
+class Reboot(commands.reboot.FC6_Reboot):
+    def execute(self, anaconda):
+        anaconda.ksdata.skipSteps.append("complete")
+
+class RaidData(commands.raid.F12_RaidData):
+    def execute(self, anaconda):
+        raidmems = []
+        devicename = "md%d" % self.device
+
+        storage = anaconda.storage
+        devicetree = storage.devicetree
+        kwargs = {}
+
+        storage.doAutoPart = False
+
+        if self.mountpoint == "swap":
+            type = "swap"
+            self.mountpoint = ""
+        elif self.mountpoint.startswith("pv."):
+            type = "lvmpv"
+            kwargs["name"] = self.mountpoint
+            anaconda.ksdata.onPart[kwargs["name"]] = devicename
+
+            if devicetree.getDeviceByName(kwargs["name"]):
+                raise KickstartValueError, formatErrorMsg(self.lineno, msg="PV partition defined multiple times")
+
+            self.mountpoint = ""
+        else:
+            if self.fstype != "":
+                type = self.fstype
+            elif self.mountpoint == "/boot" and anaconda.platform.supportsMdRaidBoot:
+                type = anaconda.platform.defaultBootFSType
+            else:
+                type = storage.defaultFSType
+
+        # Sanity check mountpoint
+        if self.mountpoint != "" and self.mountpoint[0] != '/':
+            raise KickstartValueError, formatErrorMsg(self.lineno, msg="The mount point is not valid.")
+
+        # If this specifies an existing request that we should not format,
+        # quit here after setting up enough information to mount it later.
+        if not self.format:
+            if not devicename:
+                raise KickstartValueError, formatErrorMsg(self.lineno, msg="--noformat used without --device")
+
+            dev = devicetree.getDeviceByName(devicename)
+            if not dev:
+                raise KickstartValueError, formatErrorMsg(self.lineno, msg="No preexisting RAID device with the name \"%s\" was found." % devicename)
+
+            dev.format.mountpoint = self.mountpoint
+            dev.format.mountopts = self.fsopts
+            anaconda.ksdata.skipSteps.extend(["partition", "zfcpconfig", "parttype"])
+            return
+
+        # Get a list of all the RAID members.
+        for member in self.members:
+            # if member is using --onpart, use original device
+            member = anaconda.ksdata.onPart.get(member, member)
+            dev = devicetree.getDeviceByName(member)
+            if dev and dev.format.type == "luks":
+                try:
+                    dev = devicetree.getChildren(dev)[0]
+                except IndexError:
+                    dev = None
+            if not dev:
+                raise KickstartValueError, formatErrorMsg(self.lineno, msg="Tried to use undefined partition %s in RAID specification" % member)
+
+            raidmems.append(dev)
+
+        if not self.preexist:
+            if len(raidmems) == 0:
+                raise KickstartValueError, formatErrorMsg(self.lineno, msg="RAID Partition defined without any RAID members")
+
+            if self.level == "":
+                raise KickstartValueError, formatErrorMsg(self.lineno, msg="RAID Partition defined without RAID level")
+
+        # Now get a format to hold a lot of these extra values.
+        kwargs["format"] = getFormat(type,
+                                     mountpoint=self.mountpoint,
+                                     mountopts=self.fsopts)
+        if not kwargs["format"]:
+            raise KickstartValueError, formatErrorMsg(self.lineno, msg="The \"%s\" filesystem type is not supported." % type)
+
+        kwargs["name"] = devicename
+        kwargs["level"] = self.level
+        kwargs["parents"] = raidmems
+        kwargs["memberDevices"] = len(raidmems)
+        kwargs["totalDevices"] = kwargs["memberDevices"]+self.spares
+
+        # If we were given a pre-existing RAID to create a filesystem on,
+        # we need to verify it exists and then schedule a new format action
+        # to take place there.  Also, we only support a subset of all the
+        # options on pre-existing RAIDs.
+        if self.preexist:
+            device = devicetree.getDeviceByName(devicename)
+            if not device:
+                raise KickstartValueError, formatErrorMsg(self.lineno, msg="Specifeid nonexistent RAID %s in raid command" % devicename)
+
+            removeExistingFormat(device, storage)
+            devicetree.registerAction(ActionCreateFormat(device, kwargs["format"]))
+        else:
+            # If a previous device has claimed this mount point, delete the
+            # old one.
+            try:
+                if self.mountpoint:
+                    device = storage.mountpoints[self.mountpoint]
+                    storage.destroyDevice(device)
+            except KeyError:
+                pass
+
+            try:
+                request = storage.newMDArray(**kwargs)
+            except ValueError, e:
+                raise KickstartValueError, formatErrorMsg(self.lineno, msg=str(e))
+
+            if self.fsprofile and hasattr(request.format, "fsprofile"):
+                request.format.fsprofile = self.fsprofile
+
+            storage.createDevice(request)
+
+        if self.encrypted:
+            if self.passphrase and not storage.encryptionPassphrase:
+               storage.encryptionPassphrase = self.passphrase
+
+            cert = getEscrowCertificate(anaconda, self.escrowcert)
+            if self.preexist:
+                luksformat = format
+                device.format = getFormat("luks", passphrase=self.passphrase, device=device.path,
+                                          escrow_cert=cert,
+                                          add_backup_passphrase=self.backuppassphrase)
+                luksdev = LUKSDevice("luks%d" % storage.nextID,
+                                     format=luksformat,
+                                     parents=device)
+            else:
+                luksformat = request.format
+                request.format = getFormat("luks", passphrase=self.passphrase,
+                                           escrow_cert=cert,
+                                           add_backup_passphrase=self.backuppassphrase)
+                luksdev = LUKSDevice("luks%d" % storage.nextID,
+                                     format=luksformat,
+                                     parents=request)
+            storage.createDevice(luksdev)
+
+        anaconda.ksdata.skipSteps.extend(["partition", "zfcpconfig", "parttype"])
+
+class RootPw(commands.rootpw.F8_RootPw):
+    def execute(self, anaconda):
+        anaconda.users.rootPassword["password"] = self.password
+        anaconda.users.rootPassword["isCrypted"] = self.isCrypted
+        anaconda.users.rootPassword["lock"] = self.lock
+        anaconda.ksdata.skipSteps.append("accounts")
+
+class SELinux(commands.selinux.FC3_SELinux):
+    def execute(self, anaconda):
+        anaconda.security.setSELinux(self.selinux)
+
+class SkipX(commands.skipx.FC3_SkipX):
+    def execute(self, anaconda):
+        anaconda.ksdata.skipSteps.extend(["setsanex", "videocard", "xcustom"])
+
+        if anaconda.desktop is not None:
+            anaconda.desktop.setDefaultRunLevel(3)
+
+class Timezone(commands.timezone.FC6_Timezone):
+    def execute(self, anaconda):
+        # check validity
+        tab = zonetab.ZoneTab()
+        if self.timezone not in (entry.tz.replace(' ','_') for entry in
+                                 tab.getEntries()):
+            log.warning("Timezone %s set in kickstart is not valid." % (self.timezone,))
+
+        anaconda.timezone.setTimezoneInfo(self.timezone, self.isUtc)
+        anaconda.ksdata.skipSteps.append("timezone")
+
+class Upgrade(commands.upgrade.F11_Upgrade):
+    def execute(self, anaconda):
+        anaconda.upgrade = self.upgrade
+
+class VolGroupData(commands.volgroup.FC3_VolGroupData):
+    def execute(self, anaconda):
+        pvs = []
+
+        storage = anaconda.storage
+        devicetree = storage.devicetree
+
+        storage.doAutoPart = False
+
+        # Get a list of all the physical volume devices that make up this VG.
+        for pv in self.physvols:
+            # if pv is using --onpart, use original device
+            pv = anaconda.ksdata.onPart.get(pv, pv)
+            dev = devicetree.getDeviceByName(pv)
+            if dev and dev.format.type == "luks":
+                try:
+                    dev = devicetree.getChildren(dev)[0]
+                except IndexError:
+                    dev = None
+            if not dev:
+                raise KickstartValueError, formatErrorMsg(self.lineno, msg="Tried to use undefined partition %s in Volume Group specification" % pv)
+
+            pvs.append(dev)
+
+        if len(pvs) == 0 and not self.preexist:
+            raise KickstartValueError, formatErrorMsg(self.lineno, msg="Volume group defined without any physical volumes.  Either specify physical volumes or use --useexisting.")
+
+        if self.pesize not in getPossiblePhysicalExtents(floor=1024):
+            raise KickstartValueError, formatErrorMsg(self.lineno, msg="Volume group specified invalid pesize")
+
+        # If --noformat or --useexisting was given, there's really nothing to do.
+        if not self.format or self.preexist:
+            if not self.vgname:
+                raise KickstartValueError, formatErrorMsg(self.lineno, msg="--noformat or --useexisting used without giving a name")
+
+            dev = devicetree.getDeviceByName(self.vgname)
+            if not dev:
+                raise KickstartValueError, formatErrorMsg(self.lineno, msg="No preexisting VG with the name \"%s\" was found." % self.vgname)
+        else:
+            request = storage.newVG(pvs=pvs,
+                                    name=self.vgname,
+                                    peSize=self.pesize/1024.0)
+
+            storage.createDevice(request)
+
+class XConfig(commands.xconfig.F10_XConfig):
+    def execute(self, anaconda):
+        if self.startX:
+            anaconda.desktop.setDefaultRunLevel(5)
+
+        if self.defaultdesktop:
+            anaconda.desktop.setDefaultDesktop(self.defaultdesktop)
+
+class ZeroMbr(commands.zerombr.F9_ZeroMbr):
+    def execute(self, anaconda):
+        anaconda.storage.zeroMbr = 1
+
+class ZFCP(commands.zfcp.F12_ZFCP):
+    def parse(self, args):
+        fcp = commands.zfcp.F12_ZFCP.parse(self, args)
+        try:
+            storage.zfcp.ZFCP().addFCP(fcp.devnum, fcp.wwpn, fcp.fcplun)
+        except ValueError, e:
+            log.warning(str(e))
+
+        return fcp
+
+###
+### HANDLERS
+###
+
+# This is just the latest entry from pykickstart.handlers.control with all the
+# classes we're overriding in place of the defaults.
+commandMap = {
+        "auth": Authconfig,
+        "authconfig": Authconfig,
+        "autopart": AutoPart,
+        "autostep": AutoStep,
+        "bootloader": Bootloader,
+        "clearpart": ClearPart,
+        "dmraid": DmRaid,
+        "fcoe": Fcoe,
+        "firewall": Firewall,
+        "halt": Reboot,
+        "ignoredisk": IgnoreDisk,
+        "install": Upgrade,
+        "iscsi": Iscsi,
+        "iscsiname": IscsiName,
+        "keyboard": Keyboard,
+        "lang": Lang,
+        "logging": Logging,
+        "multipath": MultiPath,
+        "poweroff": Reboot,
+        "reboot": Reboot,
+        "rootpw": RootPw,
+        "selinux": SELinux,
+        "shutdown": Reboot,
+        "skipx": SkipX,
+        "timezone": Timezone,
+        "upgrade": Upgrade,
+        "xconfig": XConfig,
+        "zerombr": ZeroMbr,
+        "zfcp": ZFCP,
+}
+
+dataMap = {
+        "LogVolData": LogVolData,
+        "NetworkData": NetworkData,
+        "PartData": PartitionData,
+        "RaidData": RaidData,
+        "VolGroupData": VolGroupData,
+}
+
+superclass = returnClassForVersion()
+
+class AnacondaKSHandler(superclass):
+    def __init__ (self, anaconda):
+        superclass.__init__(self, commandUpdates=commandMap, dataUpdates=dataMap)
+        self.packages = AnacondaKSPackages()
+
+        self.permanentSkipSteps = []
+        self.skipSteps = []
+        self.showSteps = []
+        self.anaconda = anaconda
+        self.id = self.anaconda.id
+        self.onPart = {}
+
+        # All the KickstartCommand and KickstartData objects that
+        # handleCommand returns, so we can later iterate over them and run
+        # the execute methods.  These really should be stored in the order
+        # they're seen in the kickstart file.
+        self._dataObjs = []
+
+    def add(self, obj):
+        if isinstance(obj, KickstartCommand):
+            # Commands can only be run once, and the latest one seen takes
+            # precedence over any earlier ones.
+            i = 0
+            while i < len(self._dataObjs):
+                if self._dataObjs[i].__class__ == obj.__class__:
+                    self._dataObjs.pop(i)
+                    break
+
+                i += 1
+
+            self._dataObjs.append(obj)
+        else:
+            # Data objects can be seen over and over again.
+            self._dataObjs.append(obj)
+
+    def execute(self):
+        for obj in filter(lambda o: hasattr(o, "execute"), self._dataObjs):
+            obj.execute(self.anaconda)
+
+class AnacondaPreParser(KickstartParser):
+    # A subclass of KickstartParser that only looks for %pre scripts and
+    # sets them up to be run.  All other scripts and commands are ignored.
+    def __init__ (self, handler, followIncludes=True, errorsAreFatal=True,
+                  missingIncludeIsFatal=True):
+        KickstartParser.__init__(self, handler, missingIncludeIsFatal=False)
+
+    def addScript (self):
+        if self._script["type"] != KS_SCRIPT_PRE:
+            return
+
+        s = AnacondaKSScript (self._script["body"], type=self._script["type"],
+                              interp=self._script["interp"],
+                              lineno=self._script["lineno"],
+                              inChroot=self._script["chroot"],
+                              logfile=self._script["log"],
+                              errorOnFail=self._script["errorOnFail"])
+        self.handler.scripts.append(s)
+
+    def addPackages (self, line):
+        pass
+
+    def handleCommand (self, lineno, args):
+        pass
+
+    def handlePackageHdr (self, lineno, args):
+        pass
+
+    def handleScriptHdr (self, lineno, args):
+        if not args[0] == "%pre":
+            return
+
+        KickstartParser.handleScriptHdr(self, lineno, args)
+
+class AnacondaKSParser(KickstartParser):
+    def __init__ (self, handler, followIncludes=True, errorsAreFatal=True,
+                  missingIncludeIsFatal=True):
+        KickstartParser.__init__(self, handler)
+
+    def addScript (self):
+        if string.join(self._script["body"]).strip() == "":
+            return
+
+        s = AnacondaKSScript (self._script["body"], type=self._script["type"],
+                              interp=self._script["interp"],
+                              lineno=self._script["lineno"],
+                              inChroot=self._script["chroot"],
+                              logfile=self._script["log"],
+                              errorOnFail=self._script["errorOnFail"])
+        self.handler.scripts.append(s)
+
+    def handlePackageHdr (self, lineno, args):
+        KickstartParser.handlePackageHdr (self, lineno, args)
+        self.handler.packages.seen = True
+
+    def handleCommand (self, lineno, args):
+        if not self.handler:
+            return
+
+        retval = KickstartParser.handleCommand(self, lineno, args)
+        self.handler.add(retval)
+        return retval
+
+def preScriptPass(anaconda, file):
+    # The first pass through kickstart file processing - look for %pre scripts
+    # and run them.  This must come in a separate pass in case a script
+    # generates an included file that has commands for later.
+    ksparser = AnacondaPreParser(AnacondaKSHandler(anaconda))
+
+    try:
+        ksparser.readKickstart(file)
+    except IOError, e:
+        if anaconda.intf:
+            anaconda.intf.kickstartErrorWindow("Could not open kickstart file or included file named %s" % e.filename)
+            sys.exit(1)
+        else:
+            stderrLog.critical(_("The following error was found while parsing the kickstart "
+                              "configuration file:\n\n%s") % e)
+            sys.exit(1)
+    except KickstartError, e:
+       if anaconda.intf:
+           anaconda.intf.kickstartErrorWindow(e.__str__())
+           sys.exit(1)
+       else:
+            stderrLog.critical(_("The following error was found while parsing the kickstart "
+                              "configuration file:\n\n%s") % e)
+            sys.exit(1)
+
+    # run %pre scripts
+    runPreScripts(anaconda, ksparser.handler.scripts)
+
+def parseKickstart(anaconda, file):
+    try:
+        file = preprocessKickstart(file)
+    except KickstartError, msg:
+        stderrLog.critical(_("Error processing %%ksappend lines: %s") % msg)
+        sys.exit(1)
+    except Exception, e:
+        stderrLog.critical(_("Unknown error processing %%ksappend lines: %s") % e)
+        sys.exit(1)
+
+    handler = AnacondaKSHandler(anaconda)
+    ksparser = AnacondaKSParser(handler)
+
+    # We need this so all the /dev/disk/* stuff is set up before parsing.
+    udev_trigger(subsystem="block", action="change")
+    # So that drives onlined by these can be used in the ks file
+    storage.iscsi.iscsi().startup()
+    storage.fcoe.fcoe().startup()
+    storage.zfcp.ZFCP().startup()
+    # Note we do NOT call dasd.startup() here, that does not online drives, but
+    # only checks if they need formatting, which requires zerombr to be known
+
+    try:
+        ksparser.readKickstart(file)
+    except IOError, e:
+        # We may not have an intf now, but we can do better than just raising
+        # the exception.
+        if anaconda.intf:
+            anaconda.intf.kickstartErrorWindow("Could not open kickstart file or included file named %s" % e.filename)
+            sys.exit(1)
+        else:
+            stderrLog.critical(_("The following error was found while parsing the kickstart "
+                              "configuration file:\n\n%s") % e)
+            sys.exit(1)
+    except KickstartError, e:
+        if anaconda.intf:
+            anaconda.intf.kickstartErrorWindow(e.__str__())
+            sys.exit(1)
+        else:
+            stderrLog.critical(_("The following error was found while parsing the kickstart "
+                              "configuration file:\n\n%s") % e)
+            sys.exit(1)
+
+    return handler
+
+def runPostScripts(anaconda):
+    if not anaconda.ksdata:
+        return
+
+    postScripts = filter (lambda s: s.type == KS_SCRIPT_POST,
+                          anaconda.ksdata.scripts)
+
+    if len(postScripts) == 0:
+        return
+
+    # Remove environment variables that cause problems for %post scripts.
+    for var in ["LIBUSER_CONF"]:
+        if os.environ.has_key(var):
+            del(os.environ[var])
+
+    log.info("Running kickstart %%post script(s)")
+    if anaconda.intf is not None:
+        w = anaconda.intf.waitWindow(_("Post-Installation"),
+                            _("Running post-installation scripts"))
+        
+    map (lambda s: s.run(anaconda.rootPath, flags.serial, anaconda.intf), postScripts)
+
+    log.info("All kickstart %%post script(s) have been run")
+    if anaconda.intf is not None:
+        w.pop()
+
+def runPreScripts(anaconda, scripts):
+    preScripts = filter (lambda s: s.type == KS_SCRIPT_PRE, scripts)
+
+    if len(preScripts) == 0:
+        return
+
+    log.info("Running kickstart %%pre script(s)")
+    if anaconda.intf is not None:
+        w = anaconda.intf.waitWindow(_("Pre-Installation"),
+                            _("Running pre-installation scripts"))
+    
+    map (lambda s: s.run("/", flags.serial, anaconda.intf), preScripts)
+
+    log.info("All kickstart %%pre script(s) have been run")
+    if anaconda.intf is not None:
+        w.pop()
+
+def runTracebackScripts(anaconda):
+    log.info("Running kickstart %%traceback script(s)")
+    for script in filter (lambda s: s.type == KS_SCRIPT_TRACEBACK,
+                          anaconda.ksdata.scripts):
+        script.run("/", flags.serial)
+    log.info("All kickstart %%traceback script(s) have been run")
+
+def selectPackages(anaconda):
+    ksdata = anaconda.ksdata
+    ignoreAll = False
+
+    # If no %packages header was seen, use the installclass's default group
+    # selections.  This can also be explicitly specified with %packages
+    # --default.  Otherwise, select whatever was given (even if it's nothing).
+    if not ksdata.packages.seen or ksdata.packages.default:
+        anaconda.instClass.setGroupSelection(anaconda)
+        return
+
+    for pkg in ksdata.packages.packageList:
+        num = anaconda.backend.selectPackage(pkg)
+        if ksdata.packages.handleMissing == KS_MISSING_IGNORE or ignoreAll:
+            continue
+        if num > 0:
+            continue
+        rc = anaconda.intf.messageWindow(_("Missing Package"),
+                                _("You have specified that the "
+                                  "package '%s' should be installed.  "
+                                  "This package does not exist. "
+                                  "Would you like to continue or "
+                                  "abort this installation?") %(pkg,),
+                                type="custom",
+                                custom_buttons=[_("_Abort"),
+                                                _("_Ignore All"),
+                                                _("_Continue")])
+        if rc == 0:
+            sys.exit(1)
+        elif rc == 1:
+            ignoreAll = True
+
+    ksdata.packages.groupList.insert(0, Group("Core"))
+
+    if ksdata.packages.addBase:
+        ksdata.packages.groupList.insert(1, Group("Base"))
+    else:
+        log.warning("not adding Base group")
+
+    for grp in ksdata.packages.groupList:
+        default = False
+        optional = False
+
+        if grp.include == GROUP_DEFAULT:
+            default = True
+        elif grp.include == GROUP_ALL:
+            default = True
+            optional = True
+
+        try:
+            anaconda.backend.selectGroup(grp.name, (default, optional))
+        except NoSuchGroup, e:
+            if ksdata.packages.handleMissing == KS_MISSING_IGNORE or ignoreAll:
+                pass
+            else:
+                rc = anaconda.intf.messageWindow(_("Missing Group"),
+                                        _("You have specified that the "
+                                          "group '%s' should be installed. "
+                                          "This group does not exist. "
+                                          "Would you like to continue or "
+                                          "abort this installation?")
+                                        %(grp.name,),
+                                        type="custom",
+                                        custom_buttons=[_("_Abort"),
+                                                        _("_Ignore All"),
+                                                        _("_Continue")])
+                if rc == 0:
+                    sys.exit(1)
+                elif rc == 1:
+                    ignoreAll = True
+
+    map(anaconda.backend.deselectPackage, ksdata.packages.excludedList)
+    map(lambda g: anaconda.backend.deselectGroup(g.name),
+        ksdata.packages.excludedGroupList)
+
+def setSteps(anaconda):
+    def havePackages(packages):
+        return len(packages.groupList) > 0 or len(packages.packageList) > 0 or \
+               len(packages.excludedList) > 0 or len(packages.excludedGroupList) > 0
+
+    dispatch = anaconda.dispatch
+    ksdata = anaconda.ksdata
+    interactive = ksdata.interactive.interactive
+
+    if ksdata.upgrade.upgrade:
+        upgrade.setSteps(anaconda)
+
+        # we have no way to specify migrating yet
+        dispatch.skipStep("upgrademigfind")
+        dispatch.skipStep("upgrademigratefs")
+        dispatch.skipStep("upgradecontinue")
+        dispatch.skipStep("findinstall", permanent = 1)
+        dispatch.skipStep("language")
+        dispatch.skipStep("keyboard")
+        dispatch.skipStep("betanag")
+        dispatch.skipStep("installtype")
+    else:
+        anaconda.instClass.setSteps(anaconda)
+        dispatch.skipStep("findrootparts")
+
+    if interactive or flags.autostep:
+        dispatch.skipStep("installtype")
+        dispatch.skipStep("bootdisk")
+
+    dispatch.skipStep("bootdisk")
+    dispatch.skipStep("betanag")
+    dispatch.skipStep("installtype")
+    dispatch.skipStep("network")
+
+    # Storage is initialized for us right when kickstart processing starts.
+    dispatch.skipStep("storageinit")
+
+    if not interactive:
+        # Don't show confirmation screens on non-interactive installs.
+        dispatch.skipStep("confirminstall")
+        dispatch.skipStep("confirmupgrade")
+        dispatch.skipStep("welcome")
+
+        # Since ignoredisk is optional and not specifying it means you want to
+        # consider all possible disks, we should not stop on the filter steps
+        # unless it's an interactive install.
+        dispatch.skipStep("filter")
+        dispatch.skipStep("filtertype")
+
+    # Make sure to automatically reboot even in interactive if told to.
+    if interactive and ksdata.reboot.action in [KS_REBOOT, KS_SHUTDOWN]:
+        dispatch.skipStep("complete")
+
+    # If the package section included anything, skip group selection unless
+    # they're in interactive.
+    if ksdata.upgrade.upgrade:
+        ksdata.skipSteps.extend(["tasksel", "group-selection"])
+
+        # Special check for this, since it doesn't make any sense.
+        if ksdata.packages.seen:
+            warnings.warn("Ignoring contents of %packages section due to upgrade.")
+    elif havePackages(ksdata.packages):
+        if interactive:
+            ksdata.showSteps.extend(["tasksel", "group-selection"])
+        else:
+            ksdata.skipSteps.extend(["tasksel", "group-selection"])
+    else:
+        if ksdata.packages.seen:
+            ksdata.skipSteps.extend(["tasksel", "group-selection"])
+        else:
+            ksdata.showSteps.extend(["tasksel", "group-selection"])
+
+    if not interactive:
+        for n in ksdata.skipSteps:
+            dispatch.skipStep(n)
+        for n in ksdata.permanentSkipSteps:
+            dispatch.skipStep(n, permanent=1)
+    for n in ksdata.showSteps:
+        dispatch.skipStep(n, skip = 0)
+
+    # Text mode doesn't have all the steps that graphical mode does, so we
+    # can't stop and prompt for missing information.  Make sure we've got
+    # everything that would be provided by a missing section now and error
+    # out if we don't.
+    if anaconda.displayMode == "t":
+        missingSteps = [("bootloader", "Bootloader configuration"),
+                        ("filter", "Disks to use in installation"),
+                        ("cleardiskssel", "Disks to clear"),
+                        ("group-selection", "Package selection")]
+        errors = []
+
+        for (step, msg) in missingSteps:
+            if not dispatch.stepInSkipList(step):
+                errors.append(msg)
+
+        if len(errors) > 0:
+            anaconda.intf.kickstartErrorWindow(_("The kickstart configuration "
+                "file is missing required information that anaconda cannot "
+                "prompt for.  Please add the following sections and try "
+                "again:\n%s") % ", ".join(errors))
+            sys.exit(0)
diff --git a/pyanaconda/language.py b/pyanaconda/language.py
new file mode 100644
index 0000000..4de330c
--- /dev/null
+++ b/pyanaconda/language.py
@@ -0,0 +1,280 @@
+#
+# language.py: install data component that stores information about both
+#              installer runtime language choice and installed system
+#              language support.
+#
+# Copyright (C) 2001, 2002, 2003, 2004, 2005, 2009  Red Hat, Inc.
+# 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 as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# 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, see <http://www.gnu.org/licenses/>.
+#
+
+import os
+import string
+import locale
+
+import gettext
+from simpleconfig import SimpleConfigFile
+import system_config_keyboard.keyboard as keyboard
+
+import logging
+log = logging.getLogger("anaconda")
+
+# Converts a single language into a "language search path". For example,
+# fr_FR.utf8@euro would become "fr_FR.utf8@eueo fr_FR.utf8 fr_FR fr"
+def expandLangs(astring):
+    langs = [astring]
+    charset = None
+    base = None
+
+    # remove charset ...
+    if '.' in astring:
+        langs.append(string.split(astring, '.')[0])
+
+    if '@' in astring:
+        charset = string.split(astring, '@')[1]
+
+    if '_' in astring:
+        base = string.split(astring, '_')[0]
+
+        if charset:
+            langs.append("%s@%s" % (base, charset))
+
+        langs.append(base)
+    else:
+        langs.append(astring[:2])
+
+    return langs
+
+class Language(object):
+    def _setInstLang(self, value):
+        # Always store in its full form so we know what we're comparing with.
+        try:
+            self._instLang = self._canonLang(value)
+        except ValueError:
+            # If the language isn't listed in lang-table, we won't know what
+            # keyboard/font/etc. to use.  However, we can still set the $LANG
+            # to that and make sure it works in the installed system.
+            self._instLang = value
+
+        # If we're running in text mode, value may not be a supported language
+        # to display.  We need to default to en_US.UTF-8 for now.
+        if self.displayMode == 't':
+            for (lang, info) in self.localeInfo.iteritems():
+                # If there's no font, it's not a supported language.
+                if lang == self._instLang and info[2] == "none":
+                    self._instLang = self._default
+                    break
+
+        # Now set some things to make sure the language setting takes effect
+        # right now.
+        os.environ["LANG"] = self._instLang
+        os.environ["LC_NUMERIC"] = "C"
+
+        try:
+            locale.setlocale(locale.LC_ALL, "")
+        except locale.Error:
+            pass
+
+        # XXX: oh ick.  this is the sort of thing which you should never do...
+        # but we switch languages at runtime and thus need to invalidate
+        # the set of languages/mofiles which gettext knows about
+        gettext._translations = {}
+
+    def _getInstLang(self):
+        # If we were given a language that's not in lang-table, lie and say
+        # we're using the default.  This prevents us from having to check all
+        # over the place.  Unfortunately, it also means anaconda will be
+        # running with the wrong font and keyboard in these cases.
+        if self._instLang in self.localeInfo.keys():
+            return self._instLang
+        else:
+            return self._default
+
+    # The language being displayed while anaconda is running.
+    instLang = property(lambda s: s._getInstLang(), lambda s, v: s._setInstLang(v))
+
+    def _setSystemLang(self, value):
+        # Always store in its full form so we know what we're comparing with.
+        try:
+            self._systemLang = self._canonLang(value)
+        except ValueError:
+            # If the language isn't listed in lang-table, we won't know what
+            # keyboard/font/etc. to use.  However, we can still set the $LANG
+            # to that and make sure it works in the installed system.
+            self._systemLang = value
+
+        # Now set a bunch of other things that'll get written to
+        # /etc/sysconfig/i18n on the installed system.
+        self.info["LANG"] = self._systemLang
+
+        if not self.localeInfo.has_key(self._systemLang):
+            return
+
+        if self.localeInfo[self._systemLang][2] == "none":
+            self.info["SYSFONT"] = None
+        else:
+            self.info["SYSFONT"] = self.localeInfo[self._systemLang][2]
+
+        # XXX hack - because of exceptional cases on the var - zh_CN.GB2312
+        if self._systemLang == "zh_CN.GB18030":
+            self.info["LANGUAGE"] = "zh_CN.GB18030:zh_CN.GB2312:zh_CN"
+
+    # The language to use on the installed system.  This can differ from the
+    # language being used during anaconda.  For instance, text installs cannot
+    # display all languages (CJK, Indic, etc.).
+    systemLang = property(lambda s: s._systemLang, lambda s, v: s._setSystemLang(v))
+
+    def __init__ (self, display_mode = 'g'):
+        self._default = "en_US.UTF-8"
+        self.displayMode = display_mode
+        self.info = {}
+        self.localeInfo = {}
+        self.nativeLangNames = {}
+
+        # English name -> native name mapping
+        search = ('lang-names', '/usr/share/anaconda/lang-names')
+        for path in search:
+            if os.access(path, os.R_OK):
+                f = open(path, 'r')
+                for line in f.readlines():
+                    lang, native = string.split(line, '\t')
+                    native = native.strip()
+                    self.nativeLangNames[lang] = native
+
+                f.close()
+                break
+
+        # nick -> (name, short name, font, keyboard, timezone) mapping
+        search = ('lang-table', '/tmp/updates/lang-table', '/etc/lang-table',
+                  '/usr/share/anaconda/lang-table')
+        for path in search:
+            if os.access(path, os.R_OK):
+                f = open(path, "r")
+                for line in f.readlines():
+                    string.strip(line)
+                    l = string.split(line, '\t')
+
+                    # throw out invalid lines
+                    if len(l) < 6:
+                        continue
+
+                    self.localeInfo[l[3]] = (l[0], l[1], l[2], l[4], string.strip(l[5]))
+
+                f.close()
+                break
+
+        # Hard code this to prevent errors in the build environment.
+        self.localeInfo['C'] = self.localeInfo[self._default]
+
+        # instLang must be set after localeInfo is populated, in case the
+        # current setting is unsupported by anaconda..
+        self.instLang = os.environ.get("LANG", self._default)
+        self.systemLang = os.environ.get("LANG", self._default)
+
+    def _canonLang(self, lang):
+        """Convert the shortened form of a language name into the full
+           version.  If it's not found, raise ValueError.
+
+           Example:  fr    -> fr_FR.UTF-8
+                     fr_FR -> fr_FR.UTF-8
+                     fr_CA -> ValueError
+        """
+        for key in self.localeInfo.keys():
+            if lang in expandLangs(key):
+                return key
+
+        raise ValueError
+
+    def available(self):
+        return self.nativeLangNames.keys()
+
+    def dracutSetupString(self):
+        args=""
+
+        for (key, val) in self.info.iteritems():
+            if val != None:
+                args += " %s=%s" % (key, val)
+
+        return args
+
+    def getCurrentLangSearchList(self):
+        return expandLangs(self.systemLang) + ['C']
+
+    def getDefaultKeyboard(self, instPath):
+        try:
+            return self.localeInfo[self.systemLang][3]
+        except KeyError:
+            try:
+                kbd = keyboard.Keyboard()
+                kbd.read(instPath)
+                return kbd.get()
+            except:
+                return self.localeInfo[self._default][3]
+
+    def getDefaultTimeZone(self, instPath):
+        try:
+            return self.localeInfo[self.systemLang][4]
+        except KeyError:
+            # If doing an upgrade and the system language is something not
+            # recognized by anaconda, we should try to see if we can figure
+            # it out from the running system.
+            if os.path.exists(instPath + "/etc/sysconfig/clock"):
+                cfg = SimpleConfigFile()
+                cfg.read(instPath + "/etc/sysconfig/clock")
+
+                try:
+                    return cfg.get("ZONE")
+                except:
+                    return self.localeInfo[self._default][4]
+            else:
+                return self.localeInfo[self._default][4]
+
+    def getFontFile(self, lang):
+        # Note: in /etc/fonts.cgz fonts are named by the map
+        # name as that's unique, font names are not
+        try:
+            l = self._canonLang(lang)
+        except ValueError:
+            l = self._default
+
+        return self.localeInfo[l][2]
+
+    def getLangName(self, lang):
+        try:
+            l = self._canonLang(lang)
+        except ValueError:
+            l = self._default
+
+        return self.localeInfo[l][0]
+
+    def getLangByName(self, name):
+        for (key, val) in self.localeInfo.iteritems():
+            if val[0] == name:
+                return key
+
+    def getNativeLangName(self, lang):
+        return self.nativeLangNames[lang]
+
+    def write(self, instPath):
+        f = open(instPath + "/etc/sysconfig/i18n", "w")
+
+        for (key, val) in self.info.iteritems():
+            if val != None:
+                f.write("%s=\"%s\"\n" % (key, val))
+
+        f.close()
+
+    def writeKS(self, f):
+        f.write("lang %s\n" % self.info['LANG'])
diff --git a/pyanaconda/livecd.py b/pyanaconda/livecd.py
new file mode 100644
index 0000000..9df91b4
--- /dev/null
+++ b/pyanaconda/livecd.py
@@ -0,0 +1,469 @@
+#
+# livecd.py: An anaconda backend to do an install from a live CD image
+#
+# The basic idea is that with a live CD, we already have an install
+# and should be able to just copy those bits over to the disk.  So we dd
+# the image, move things to the "right" filesystem as needed, and then
+# resize the rootfs to the size of its container.
+#
+# Copyright (C) 2007  Red Hat, Inc.  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 as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# 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, see <http://www.gnu.org/licenses/>.
+#
+# Author(s): Jeremy Katz <katzj@xxxxxxxxxx>
+#
+
+import os, sys
+import stat
+import shutil
+import time
+import subprocess
+import storage
+
+import selinux
+
+from flags import flags
+from constants import *
+
+import gettext
+_ = lambda x: gettext.ldgettext("anaconda", x)
+
+import backend
+import isys
+import iutil
+
+import packages
+
+import logging
+log = logging.getLogger("anaconda")
+
+class Error(EnvironmentError):
+    pass
+def copytree(src, dst, symlinks=False, preserveOwner=False,
+             preserveSelinux=False):
+    def tryChown(src, dest):
+        try:
+            os.chown(dest, os.stat(src)[stat.ST_UID], os.stat(src)[stat.ST_GID])
+        except OverflowError:
+            log.error("Could not set owner and group on file %s" % dest)
+
+    def trySetfilecon(src, dest):
+        try:
+            selinux.lsetfilecon(dest, selinux.lgetfilecon(src)[1])
+        except:
+            log.error("Could not set selinux context on file %s" % dest)
+
+    # copy of shutil.copytree which doesn't require dst to not exist
+    # and which also has options to preserve the owner and selinux contexts
+    names = os.listdir(src)
+    if not os.path.isdir(dst):
+        os.makedirs(dst)
+    errors = []
+    for name in names:
+        srcname = os.path.join(src, name)
+        dstname = os.path.join(dst, name)
+        try:
+            if symlinks and os.path.islink(srcname):
+                linkto = os.readlink(srcname)
+                os.symlink(linkto, dstname)
+                if preserveSelinux:
+                    trySetfilecon(srcname, dstname)
+            elif os.path.isdir(srcname):
+                copytree(srcname, dstname, symlinks, preserveOwner, preserveSelinux)
+            else:
+                shutil.copyfile(srcname, dstname)
+                if preserveOwner:
+                    tryChown(srcname, dstname)
+
+                if preserveSelinux:
+                    trySetfilecon(srcname, dstname)
+
+                shutil.copystat(srcname, dstname)
+        except (IOError, os.error), why:
+            errors.append((srcname, dstname, str(why)))
+        # catch the Error from the recursive copytree so that we can
+        # continue with other files
+        except Error, err:
+            errors.extend(err.args[0])
+    try:
+        if preserveOwner:
+            tryChown(src, dst)
+        if preserveSelinux:
+            trySetfilecon(src, dst)
+
+        shutil.copystat(src, dst)
+    except OSError as e:
+        errors.extend((src, dst, e.strerror))
+    if errors:
+        raise Error, errors
+
+class LiveCDCopyBackend(backend.AnacondaBackend):
+    def __init__(self, anaconda):
+        backend.AnacondaBackend.__init__(self, anaconda)
+        flags.livecdInstall = True
+        self.supportsUpgrades = False
+        self.supportsPackageSelection = False
+        self.skipFormatRoot = True
+
+        self.osimg = anaconda.methodstr[8:]
+        if not stat.S_ISBLK(os.stat(self.osimg)[stat.ST_MODE]):
+            anaconda.intf.messageWindow(_("Unable to find image"),
+                               _("The given location isn't a valid %s "
+                                 "live CD to use as an installation source.")
+                               %(productName,), type = "custom",
+                               custom_icon="error",
+                               custom_buttons=[_("Exit installer")])
+            sys.exit(0)
+        self.rootFsType = isys.readFSType(self.osimg)
+
+    def _getLiveBlockDevice(self):
+        return os.path.normpath(self.osimg)
+
+    def _getLiveSize(self):
+        def parseField(output, field):
+            for line in output.split("\n"):
+                if line.startswith(field + ":"):
+                    return line[len(field) + 1:].strip()
+            raise KeyError("Failed to find field '%s' in output" % field)
+
+        output = subprocess.Popen(['/sbin/dumpe2fs', '-h', self.osimg],
+                                  stdout=subprocess.PIPE,
+                                  stderr=open('/dev/null', 'w')
+                                  ).communicate()[0]
+        blkcnt = int(parseField(output, "Block count"))
+        blksize = int(parseField(output, "Block size"))
+        return blkcnt * blksize
+
+    def _getLiveSizeMB(self):
+        return self._getLiveSize() / 1048576
+
+    def _unmountNonFstabDirs(self, anaconda):
+        # unmount things that aren't listed in /etc/fstab.  *sigh*
+        dirs = []
+        if flags.selinux:
+            dirs.append("/selinux")
+        for dir in dirs:
+            try:
+                isys.umount("%s/%s" %(anaconda.rootPath,dir), removeDir = False)
+            except Exception, e:
+                log.error("unable to unmount %s: %s" %(dir, e))
+
+    def postAction(self, anaconda):
+        self._unmountNonFstabDirs(anaconda)
+        try:
+            anaconda.storage.umountFilesystems(swapoff = False)
+            os.rmdir(anaconda.rootPath)
+        except Exception, e:
+            log.error("Unable to unmount filesystems: %s" % e) 
+
+    def doPreInstall(self, anaconda):
+        if anaconda.dir == DISPATCH_BACK:
+            self._unmountNonFstabDirs(anaconda)
+            return
+        anaconda.storage.umountFilesystems(swapoff = False)
+
+    def doInstall(self, anaconda):
+        log.info("Preparing to install packages")
+
+        progress = anaconda.intf.instProgress
+        progress.set_label(_("Copying live image to hard drive."))
+        progress.processEvents()
+
+        osimg = self._getLiveBlockDevice() # the real image
+        osfd = os.open(osimg, os.O_RDONLY)
+
+        rootDevice = anaconda.storage.rootDevice
+        rootDevice.setup()
+        rootfd = os.open(rootDevice.path, os.O_WRONLY)
+
+        readamt = 1024 * 1024 * 8 # 8 megs at a time
+        size = self._getLiveSize()
+        copied = 0
+        while copied < size:
+            try:
+                buf = os.read(osfd, readamt)
+                written = os.write(rootfd, buf)
+            except:
+                rc = anaconda.intf.messageWindow(_("Error"),
+                        _("There was an error installing the live image to "
+                          "your hard drive.  This could be due to bad media.  "
+                          "Please verify your installation media.\n\nIf you "
+                          "exit, your system will be left in an inconsistent "
+                          "state that will require reinstallation."),
+                        type="custom", custom_icon="error",
+                        custom_buttons=[_("_Exit installer"), _("_Retry")])
+
+                if rc == 0:
+                    sys.exit(0)
+                else:
+                    os.lseek(osfd, 0, 0)
+                    os.lseek(rootfd, 0, 0)
+                    copied = 0
+                    continue
+
+            if (written < readamt) and (written < len(buf)):
+                raise RuntimeError, "error copying filesystem!"
+            copied += written
+            progress.set_fraction(pct = copied / float(size))
+            progress.processEvents()
+
+        os.close(osfd)
+        os.close(rootfd)
+
+        anaconda.intf.setInstallProgressClass(None)
+
+    def _doFilesystemMangling(self, anaconda):
+        log.info("doing post-install fs mangling")
+        wait = anaconda.intf.waitWindow(_("Post-Installation"),
+                                        _("Performing post-installation filesystem changes.  This may take several minutes."))
+
+        # resize rootfs first, since it is 100% full due to genMinInstDelta
+        self._resizeRootfs(anaconda, wait)
+
+        # remount filesystems
+        anaconda.storage.mountFilesystems()
+
+        # restore the label of / to what we think it is
+        rootDevice = anaconda.storage.rootDevice
+        rootDevice.setup()
+        # ensure we have a random UUID on the rootfs
+        # FIXME: this should be abstracted per filesystem type
+        iutil.execWithRedirect("tune2fs",
+                               ["-U",
+                                "random",
+                                rootDevice.path],
+                               stdout="/dev/tty5",
+                               stderr="/dev/tty5")
+        # and now set the uuid in the storage layer
+        rootDevice.updateSysfsPath()
+        iutil.notify_kernel("/sys%s" %rootDevice.sysfsPath)
+        storage.udev.udev_settle()
+        rootDevice.updateSysfsPath()
+        info = storage.udev.udev_get_block_device(rootDevice.sysfsPath)
+        rootDevice.format.uuid = storage.udev.udev_device_get_uuid(info)
+        log.info("reset the rootdev (%s) to have a uuid of %s" %(rootDevice.sysfsPath, rootDevice.format.uuid))
+
+        # for any filesystem that's _not_ on the root, we need to handle
+        # moving the bits from the livecd -> the real filesystems.
+        # this is pretty distasteful, but should work with things like
+        # having a separate /usr/local
+
+        def _setupFilesystems(mounts, chroot="", teardown=False):
+            """ Setup or teardown all filesystems except for "/" """
+            mountpoints = sorted(mounts.keys(),
+                                 reverse=teardown is True)
+            if teardown:
+                method = "teardown"
+                kwargs = {}
+            else:
+                method = "setup"
+                kwargs = {"chroot": chroot}
+
+            mountpoints.remove("/")
+            for mountpoint in mountpoints:
+                device = mounts[mountpoint]
+                getattr(device.format, method)(**kwargs)
+
+        # Start by sorting the mountpoints in decreasing-depth order.
+        mountpoints = sorted(anaconda.storage.mountpoints.keys(),
+                             reverse=True)
+        # We don't want to copy the root filesystem.
+        mountpoints.remove("/")
+        stats = {} # mountpoint: posix.stat_result
+
+        # unmount the filesystems, except for /
+        _setupFilesystems(anaconda.storage.mountpoints, teardown=True)
+
+        # mount all of the filesystems under /mnt so we can copy in content
+        _setupFilesystems(anaconda.storage.mountpoints,
+                          chroot=anaconda.rootPath + "/mnt")
+
+        # And now let's do the real copies
+        for tocopy in mountpoints:
+            device = anaconda.storage.mountpoints[tocopy]
+
+            # FIXME: all calls to wait.refresh() are kind of a hack... we
+            # should do better about not doing blocking things in the
+            # main thread.  but threading anaconda is a job for another
+            # time.
+            wait.refresh()
+
+            if not os.path.exists("%s/%s" % (anaconda.rootPath, tocopy)):
+                # the directory does not exist in the live image, so there's
+                # nothing to move
+                continue
+
+            copytree("%s/%s" % (anaconda.rootPath, tocopy),
+                     "%s/mnt/%s" % (anaconda.rootPath, tocopy),
+                     True, True, flags.selinux)
+            wait.refresh()
+            shutil.rmtree("%s/%s" % (anaconda.rootPath, tocopy))
+            wait.refresh()
+
+        # now unmount each fs, collect stat info for the mountpoint, then
+        # remove the entire tree containing the mountpoint
+        for tocopy in mountpoints:
+            device = anaconda.storage.mountpoints[tocopy]
+            device.format.teardown()
+            if not os.path.exists("%s/%s" % (anaconda.rootPath, tocopy)):
+                continue
+
+            try:
+                stats[tocopy]= os.stat("%s/mnt/%s" % (anaconda.rootPath,
+                                                      tocopy))
+            except Exception as e:
+                log.info("failed to get stat info for mountpoint %s: %s"
+                            % (tocopy, e))
+
+            shutil.rmtree("%s/mnt/%s" % (anaconda.rootPath,
+                                         tocopy.split("/")[1]))
+            wait.refresh()
+
+        # now mount all of the filesystems so that post-install writes end
+        # up where they're supposed to end up
+        _setupFilesystems(anaconda.storage.mountpoints,
+                          chroot=anaconda.rootPath)
+
+        # restore stat info for each mountpoint
+        for mountpoint in reversed(mountpoints):
+            if mountpoint not in stats:
+                # there's no info to restore since the mountpoint did not
+                # exist in the live image
+                continue
+
+            dest = "%s/%s" % (anaconda.rootPath, mountpoint)
+            st = stats[mountpoint]
+
+            # restore the correct stat info for this mountpoint
+            os.utime(dest, (st.st_atime, st.st_mtime))
+            os.chown(dest, st.st_uid, st.st_gid)
+            os.chmod(dest, stat.S_IMODE(st.st_mode))
+
+        # ensure that non-fstab filesystems are mounted in the chroot
+        if flags.selinux:
+            try:
+                isys.mount("/selinux", anaconda.rootPath + "/selinux", "selinuxfs")
+            except Exception, e:
+                log.error("error mounting selinuxfs: %s" %(e,))
+
+        wait.pop()
+
+    def _resizeRootfs(self, anaconda, win = None):
+        log.info("going to do resize")
+        rootDevice = anaconda.storage.rootDevice
+
+        # FIXME: we'd like to have progress here to give an idea of
+        # how long it will take.  or at least, to give an indefinite
+        # progress window.  but, not for this time
+        cmd = ["resize2fs", rootDevice.path, "-p"]
+        out = open("/dev/tty5", "w")
+        proc = subprocess.Popen(cmd, stdout=out, stderr=out)
+        rc = proc.poll()
+        while rc is None:
+            win and win.refresh()
+            time.sleep(0.5)
+            rc = proc.poll()
+
+        if rc:
+            log.error("error running resize2fs; leaving filesystem as is")
+            return
+
+        # we should also do a fsck afterwards
+        cmd = ["e2fsck", "-f", "-y", rootDevice.path]
+        out = open("/dev/tty5", "w")
+        proc = subprocess.Popen(cmd, stdout=out, stderr=out)
+        rc = proc.poll()
+        while rc is None:
+            win and win.refresh()
+            time.sleep(0.5)
+            rc = proc.poll()
+
+    def doPostInstall(self, anaconda):
+        import rpm
+
+        self._doFilesystemMangling(anaconda)
+
+        # setup /etc/rpm/ for the post-install environment
+        iutil.writeRpmPlatform(anaconda.rootPath)
+
+        storage.writeEscrowPackets(anaconda)
+
+        packages.rpmSetupGraphicalSystem(anaconda)
+
+        # now write out the "real" fstab and mtab
+        anaconda.storage.write(anaconda.rootPath)
+        f = open(anaconda.rootPath + "/etc/mtab", "w+")
+        f.write(anaconda.storage.mtab)
+        f.close()        
+        
+        # copy over the modprobe.conf
+        if os.path.exists("/etc/modprobe.conf"):
+            shutil.copyfile("/etc/modprobe.conf", 
+                            anaconda.rootPath + "/etc/modprobe.conf")
+        # set the same keyboard the user selected in the keyboard dialog:
+        anaconda.keyboard.write(anaconda.rootPath)
+
+        # rebuild the initrd(s)
+        vers = self.kernelVersionList(anaconda.rootPath)
+        for (n, arch, tag) in vers:
+            packages.recreateInitrd(n, anaconda.rootPath)
+
+    def writeConfiguration(self):
+        pass
+
+    def kernelVersionList(self, rootPath = "/"):
+        return packages.rpmKernelVersionList(rootPath)
+
+    def getMinimumSizeMB(self, part):
+        if part == "/":
+            return self._getLiveSizeMB()
+        return 0
+
+    def doBackendSetup(self, anaconda):
+        # ensure there's enough space on the rootfs
+        # FIXME: really, this should be in the general sanity checking, but
+        # trying to weave that in is a little tricky at present.
+        ossize = self._getLiveSizeMB()
+        slash = anaconda.storage.rootDevice
+        if slash.size < ossize:
+            rc = anaconda.intf.messageWindow(_("Error"),
+                                        _("The root filesystem you created is "
+                                          "not large enough for this live "
+                                          "image (%.2f MB required).") % ossize,
+                                        type = "custom",
+                                        custom_icon = "error",
+                                        custom_buttons=[_("_Back"),
+                                                        _("_Exit installer")])
+            if rc == 0:
+                return DISPATCH_BACK
+            else:
+                sys.exit(1)
+
+    # package/group selection doesn't apply for this backend
+    def groupExists(self, group):
+        pass
+    def selectGroup(self, group, *args):
+        pass
+    def deselectGroup(self, group, *args):
+        pass
+    def selectPackage(self, pkg, *args):
+        pass
+    def deselectPackage(self, pkg, *args):
+        pass
+    def packageExists(self, pkg):
+        return True
+    def getDefaultGroups(self, anaconda):
+        return []
+    def writePackagesKS(self, f, anaconda):
+        pass
diff --git a/pyanaconda/network.py b/pyanaconda/network.py
new file mode 100644
index 0000000..2c19349
--- /dev/null
+++ b/pyanaconda/network.py
@@ -0,0 +1,839 @@
+#
+# network.py - network configuration install data
+#
+# Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007  Red Hat, Inc.
+#               2008, 2009
+#
+# 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; either version 2 of the License, or
+# (at your option) any later version.
+#
+# 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, see <http://www.gnu.org/licenses/>.
+#
+# Author(s): Matt Wilson <ewt@xxxxxxxxxx>
+#            Erik Troan <ewt@xxxxxxxxxx>
+#            Mike Fulbright <msf@xxxxxxxxxx>
+#            Brent Fox <bfox@xxxxxxxxxx>
+#            David Cantrell <dcantrell@xxxxxxxxxx>
+#
+
+import string
+import shutil
+import isys
+import iutil
+import socket
+import struct
+import os
+import time
+import dbus
+from flags import flags
+from simpleconfig import SimpleConfigFile
+
+import gettext
+_ = lambda x: gettext.ldgettext("anaconda", x)
+
+import logging
+log = logging.getLogger("anaconda")
+
+class IPError(Exception):
+    pass
+
+class IPMissing(Exception):
+    pass
+
+def sanityCheckHostname(hostname):
+    if len(hostname) < 1:
+        return None
+
+    if len(hostname) > 255:
+        return _("Hostname must be 255 or fewer characters in length.")
+
+    validStart = string.ascii_letters + string.digits
+    validAll = validStart + ".-"
+
+    if string.find(validStart, hostname[0]) == -1:
+        return _("Hostname must start with a valid character in the ranges "
+                 "'a-z', 'A-Z', or '0-9'")
+
+    for i in range(1, len(hostname)):
+        if string.find(validAll, hostname[i]) == -1:
+            return _("Hostnames can only contain the characters 'a-z', 'A-Z', '0-9', '-', or '.'")
+
+    return None
+
+# Try to determine what the hostname should be for this system
+def getDefaultHostname(anaconda):
+    isys.resetResolv()
+
+    hn = None
+    bus = dbus.SystemBus()
+    nm = bus.get_object(isys.NM_SERVICE, isys.NM_MANAGER_PATH)
+    nm_props_iface = dbus.Interface(nm, isys.DBUS_PROPS_IFACE)
+
+    active_connections = nm_props_iface.Get(isys.NM_MANAGER_IFACE, "ActiveConnections")
+
+    # XXX: account for Ip6Config objects when NetworkManager supports them
+    for connection in active_connections:
+        active_connection = bus.get_object(isys.NM_SERVICE, connection)
+        active_connection_props_iface = dbus.Interface(active_connection, isys.DBUS_PROPS_IFACE)
+        devices = active_connection_props_iface.Get(isys.NM_MANAGER_IFACE, 'Devices')
+
+        for device_path in devices:
+            device = bus.get_object(isys.NM_SERVICE, device_path)
+            device_props_iface = dbus.Interface(device, isys.DBUS_PROPS_IFACE)
+
+            ip4_config_path = device_props_iface.Get(isys.NM_MANAGER_IFACE, 'Ip4Config')
+            ip4_config_obj = bus.get_object(isys.NM_SERVICE, ip4_config_path)
+            ip4_config_props = dbus.Interface(ip4_config_obj, isys.DBUS_PROPS_IFACE)
+
+            # addresses (3-element list:  ipaddr, netmask, gateway)
+            addrs = ip4_config_props.Get(isys.NM_MANAGER_IFACE, "Addresses")[0]
+            try:
+                tmp = struct.pack('I', addrs[0])
+                ipaddr = socket.inet_ntop(socket.AF_INET, tmp)
+                hinfo = socket.gethostbyaddr(ipaddr)
+
+                if len(hinfo) == 3:
+                    hn = hinfo[0]
+                else:
+                    continue
+            except:
+                continue
+
+    if hn and hn != 'localhost' and hn != 'localhost.localdomain':
+        return hn
+
+    try:
+        hn = anaconda.network.hostname
+    except:
+        hn = None
+
+    if not hn or hn == '(none)' or hn == 'localhost' or hn == 'localhost.localdomain':
+        hn = socket.gethostname()
+
+    if not hn or hn == '(none)' or hn == 'localhost':
+        hn = 'localhost.localdomain'
+
+    return hn
+
+# return if the device is of a type that requires a ptpaddr to be specified
+def isPtpDev(devname):
+    if devname.startswith("ctc"):
+        return True
+    return False
+
+def _anyUsing(method):
+    # method names that NetworkManager might use
+    if method == 'auto':
+        methods = (method, 'dhcp')
+    else:
+        methods = (method)
+
+    try:
+        bus = dbus.SystemBus()
+        nm = bus.get_object(isys.NM_SERVICE, isys.NM_MANAGER_PATH)
+        nm_props_iface = dbus.Interface(nm, isys.DBUS_PROPS_IFACE)
+        active_connections = nm_props_iface.Get(isys.NM_MANAGER_IFACE, "ActiveConnections")
+
+        for path in active_connections:
+            active = bus.get_object(isys.NM_SERVICE, path)
+            active_props_iface = dbus.Interface(active, isys.DBUS_PROPS_IFACE)
+
+            active_service_name = active_props_iface.Get(isys.NM_ACTIVE_CONNECTION_IFACE, "ServiceName")
+            active_path = active_props_iface.Get(isys.NM_ACTIVE_CONNECTION_IFACE, "Connection")
+
+            connection = bus.get_object(active_service_name, active_path)
+            connection_iface = dbus.Interface(connection, isys.NM_CONNECTION_IFACE)
+            settings = connection_iface.GetSettings()
+
+            # XXX: add support for Ip6Config when it appears
+            ip4_setting = settings['ipv4']
+            if not ip4_setting or not ip4_setting['method'] or ip4_setting['method'] in methods:
+                return True
+
+            return False
+    except:
+        return False
+
+# determine whether any active at boot devices are using dhcp or dhcpv6
+def anyUsingDHCP():
+    return _anyUsing('auto')
+
+# determine whether any active at boot devices are using static IP config
+def anyUsingStatic():
+    return _anyUsing('manual')
+
+# sanity check an IP string.
+def sanityCheckIPString(ip_string):
+    if ip_string.strip() == "":
+        raise IPMissing, _("IP address is missing.")
+
+    if ip_string.find(':') == -1 and ip_string.find('.') > 0:
+        family = socket.AF_INET
+        errstr = _("IPv4 addresses must contain four numbers between 0 and 255, separated by periods.")
+    elif ip_string.find(':') > 0 and ip_string.find('.') == -1:
+        family = socket.AF_INET6
+        errstr = _("'%s' is not a valid IPv6 address.") % ip_string
+    else:
+        raise IPError, _("'%s' is an invalid IP address.") % ip_string
+
+    try:
+        socket.inet_pton(family, ip_string)
+    except socket.error:
+        raise IPError, errstr
+
+def hasActiveNetDev():
+    try:
+        bus = dbus.SystemBus()
+        nm = bus.get_object(isys.NM_SERVICE, isys.NM_MANAGER_PATH)
+        props = dbus.Interface(nm, isys.DBUS_PROPS_IFACE)
+        state = props.Get(isys.NM_SERVICE, "State")
+
+        if int(state) == isys.NM_STATE_CONNECTED:
+            return True
+        else:
+            return False
+    except:
+        return False
+
+# Return a list of device names (e.g., eth0) for all active devices.
+# Returning a list here even though we will almost always have one
+# device.  NM uses lists throughout its D-Bus communication, so trying
+# to follow suit here.  Also, if this uses a list now, we can think
+# about multihomed hosts during installation later.
+def getActiveNetDevs():
+    active_devs = set()
+
+    bus = dbus.SystemBus()
+    nm = bus.get_object(isys.NM_SERVICE, isys.NM_MANAGER_PATH)
+    nm_props_iface = dbus.Interface(nm, isys.DBUS_PROPS_IFACE)
+
+    active_connections = nm_props_iface.Get(isys.NM_MANAGER_IFACE, "ActiveConnections")
+
+    for connection in active_connections:
+        active_connection = bus.get_object(isys.NM_SERVICE, connection)
+        active_connection_props_iface = dbus.Interface(active_connection, isys.DBUS_PROPS_IFACE)
+        devices = active_connection_props_iface.Get(isys.NM_MANAGER_IFACE, 'Devices')
+
+        for device_path in devices:
+            device = bus.get_object(isys.NM_SERVICE, device_path)
+            device_props_iface = dbus.Interface(device, isys.DBUS_PROPS_IFACE)
+
+            interface_name = device_props_iface.Get(isys.NM_MANAGER_IFACE, 'Interface')
+            active_devs.add(interface_name)
+
+    ret = list(active_devs)
+    ret.sort()
+    return ret
+
+class NetworkDevice(SimpleConfigFile):
+    def __str__(self):
+        s = ""
+        s = s + "DEVICE=" + self.info["DEVICE"] + "\n"
+        keys = self.info.keys()
+        keys.sort()
+        keys.remove("DEVICE")
+        if "DESC" in keys:
+            keys.remove("DESC")
+        if "KEY" in keys:
+            keys.remove("KEY")
+        if iutil.isS390() and ("HWADDR" in keys):
+            keys.remove("HWADDR")
+
+        for key in keys:
+            if (key == 'NAME') or \
+               (key == 'NM_CONTROLLED' and not flags.livecdInstall):
+                continue
+            # make sure we include autoneg in the ethtool line
+            elif key == 'ETHTOOL_OPTS' and self.info[key].find("autoneg")== -1:
+                s = s + key + """="autoneg off %s"\n""" % (self.info[key])
+            elif self.info[key] is not None:
+                s = s + key + "=" + self.info[key] + "\n"
+
+        return s
+
+    def __init__(self, dev):
+        self.info = { "DEVICE" : dev }
+        if dev.startswith('ctc'):
+            self.info["TYPE"] = "CTC"
+
+class Network:
+    def __init__(self):
+        self.netdevices = {}
+        self.ksdevice = None
+        self.domains = []
+        self.hostname = socket.gethostname()
+        self.overrideDHCPhostname = False
+
+        # populate self.netdevices
+        devhash = isys.getDeviceProperties(dev=None)
+        for dev in devhash.keys():
+            self.netdevices[dev] = NetworkDevice(dev)
+            ifcfg_contents = self.readIfcfgContents(dev)
+
+            # if NM_CONTROLLED is set to yes, we read in settings from
+            # NetworkManager first, then fill in the gaps with the data
+            # from the ifcfg file
+            useNetworkManager = False
+            if ifcfg_contents.has_key('NM_CONTROLLED') and \
+               not ifcfg_contents['NM_CONTROLLED'].lower() == 'no':
+                useNetworkManager = True
+
+            # this interface is managed by NetworkManager, so read from
+            # NetworkManager first
+            if useNetworkManager:
+                props = devhash[dev]
+
+                if isys.isDeviceDHCP(dev):
+                    self.netdevices[dev].set(('BOOTPROTO', 'dhcp'))
+                else:
+                    self.netdevices[dev].unset('BOOTPROTO')
+                    bus = dbus.SystemBus()
+                    config_path = props.Get(isys.NM_MANAGER_IFACE, 'Ip4Config')
+                    config = bus.get_object(isys.NM_SERVICE, config_path)
+                    config_props = dbus.Interface(config, isys.DBUS_PROPS_IFACE)
+
+                    # addresses (3-element list:  ipaddr, netmask, gateway)
+                    addrs = config_props.Get(isys.NM_MANAGER_IFACE, 'Addresses')[0]
+                    try:
+                        tmp = struct.pack('I', addrs[0])
+                        ipaddr = socket.inet_ntop(socket.AF_INET, tmp)
+                        self.netdevices[dev].set(('IPADDR', ipaddr))
+                    except:
+                        pass
+
+                    try:
+                        tmp = struct.pack('I', addrs[1])
+                        netmask = socket.inet_ntop(socket.AF_INET, tmp)
+                        self.netdevices[dev].set(('NETMASK', netmask))
+                    except:
+                        pass
+
+                    try:
+                        tmp = struct.pack('I', addrs[2])
+                        gateway = socket.inet_ntop(socket.AF_INET, tmp)
+                        self.netdevices[dev].set(('GATEWAY', gateway))
+                    except:
+                        pass
+
+                self.hostname = socket.gethostname()
+
+            # read in remaining settings from ifcfg file
+            for key in ifcfg_contents.keys():
+                if key == 'GATEWAY':
+                    self.netdevices[dev].set((key, ifcfg_contents[key]))
+                elif key == 'DOMAIN':
+                    self.domains.append(ifcfg_contents[key])
+                elif key == 'HOSTNAME':
+                    self.hostname = ifcfg_contents[key]
+                elif self.netdevices[dev].get(key) == '':
+                    self.netdevices[dev].set((key, ifcfg_contents[key]))
+
+        # now initialize remaining devices
+        # XXX we just throw return away, the method initialize a
+        # object member so we dont need to
+        available_devices = self.available()
+
+        if len(available_devices) > 0:
+            # set first device to start up onboot
+            oneactive = 0
+            for dev in available_devices.keys():
+                try:
+                    if available_devices[dev].get("ONBOOT") == "yes":
+                        oneactive = 1
+                        break
+                except:
+                    continue
+
+    def readIfcfgContents(self, dev):
+        ifcfg = "/etc/sysconfig/network-scripts/ifcfg-%s" % (dev,)
+        contents = {}
+
+        try:
+            f = open(ifcfg, "r")
+            lines = f.readlines()
+            f.close()
+
+            for line in lines:
+                line = line.strip()
+                if line.startswith('#') or line == '':
+                    continue
+
+                var = string.splitfields(line, '=', 1)
+                if len(var) == 2:
+                    var[1] = var[1].replace('"', '')
+                    contents[var[0]] = string.strip(var[1])
+        except:
+            return {}
+
+        return contents
+
+    def getDevice(self, device):
+        return self.netdevices[device]
+
+    def available(self):
+        ksdevice = None
+        if flags.cmdline.has_key('ksdevice'):
+            ksdevice = flags.cmdline['ksdevice']
+
+        for dev in isys.getDeviceProperties().keys():
+            if not self.netdevices.has_key(dev):
+                self.netdevices[dev] = NetworkDevice(dev)
+
+            hwaddr = isys.getMacAddress(dev)
+
+            self.netdevices[dev].set(('HWADDR', hwaddr))
+            self.netdevices[dev].set(('DESC', isys.getNetDevDesc(dev)))
+
+            if not ksdevice:
+                continue
+
+            if ksdevice == 'link' and isys.getLinkStatus(dev):
+                self.ksdevice = dev
+            elif ksdevice == dev:
+                self.ksdevice = dev
+            elif ksdevice.find(':') != -1:
+                if ksdevice.upper() == hwaddr:
+                    self.ksdevice = dev
+
+        return self.netdevices
+
+    def getKSDevice(self):
+        if self.ksdevice is None:
+            return None
+
+        try:
+            return self.netdevices[self.ksdevice]
+        except:
+            return None
+
+    def setHostname(self, hn):
+        self.hostname = hn
+
+    def setDNS(self, ns, device):
+        dns = ns.split(',')
+        i = 1
+        for addr in dns:
+            addr = addr.strip()
+            dnslabel = "DNS%d" % (i,)
+            self.netdevices[device].set((dnslabel, addr))
+            i += 1
+
+    def setGateway(self, gw, device):
+        self.netdevices[device].set(('GATEWAY', gw))
+
+    def lookupHostname(self):
+        # can't look things up if they don't exist!
+        if not self.hostname or self.hostname == "localhost.localdomain":
+            return None
+
+        if not hasActiveNetDev():
+            log.warning("no network devices were available to look up host name")
+            return None
+
+        try:
+            (family, socktype, proto, canonname, sockaddr) = \
+                socket.getaddrinfo(self.hostname, None, socket.AF_INET)[0]
+            (ip, port) = sockaddr
+        except:
+            try:
+                (family, socktype, proto, canonname, sockaddr) = \
+                    socket.getaddrinfo(self.hostname, None, socket.AF_INET6)[0]
+                (ip, port, flowinfo, scopeid) = sockaddr
+            except:
+                return None
+
+        return ip
+
+    def writeKS(self, f):
+        devNames = self.netdevices.keys()
+        devNames.sort()
+
+        if len(devNames) == 0:
+            return
+
+        for devName in devNames:
+            dev = self.netdevices[devName]
+
+            if dev.get('bootproto').lower() == 'dhcp' or dev.get('ipaddr'):
+                f.write("network --device %s" % dev.get('device'))
+
+                if dev.get('MTU') and dev.get('MTU') != 0:
+                    f.write(" --mtu=%s" % dev.get('MTU'))
+
+                onboot = dev.get("onboot")
+                if onboot and onboot == "no":
+                    f.write(" --onboot no")
+                if dev.get('bootproto').lower() == 'dhcp':
+                    f.write(" --bootproto dhcp")
+                    if dev.get('dhcpclass'):
+                        f.write(" --dhcpclass %s" % dev.get('dhcpclass'))
+                    if self.overrideDHCPhostname:
+                        if (self.hostname and
+                            self.hostname != "localhost.localdomain"):
+                            f.write(" --hostname %s" % self.hostname)
+                else:
+                    f.write(" --bootproto static --ip %s" % dev.get('ipaddr'))
+
+                    if dev.get('netmask'):
+                        f.write(" --netmask %s" % dev.get('netmask'))
+
+                    if dev.get('GATEWAY'):
+                        f.write(" --gateway %s" % (dev.get('GATEWAY'),))
+
+                    dnsline = ''
+                    for key in dev.info.keys():
+                        if key.upper().startswith('DNS'):
+                            if dnsline == '':
+                                dnsline = dev.get(key)
+                            else:
+                                dnsline += "," + dev.get(key)
+
+                    if dnsline != '':
+                        f.write(" --nameserver %s" % (dnsline,))
+
+                    if (self.hostname and
+                        self.hostname != "localhost.localdomain"):
+                        f.write(" --hostname %s" % self.hostname)
+
+                f.write("\n")
+
+    def hasNameServers(self, hash):
+        if hash.keys() == []:
+            return False
+
+        for key in hash.keys():
+            if key.upper().startswith('DNS'):
+                return True
+
+        return False
+
+    def write(self, instPath='', anaconda=None, devices=None):
+
+        if devices is None:
+            devices = self.netdevices.values()
+
+        if len(devices) == 0:
+            return
+
+        sysconfig = "%s/etc/sysconfig" % (instPath,)
+        netscripts = "%s/network-scripts" % (sysconfig,)
+        destnetwork = "%s/network" % (sysconfig,)
+
+        if not os.path.isdir(netscripts):
+            iutil.mkdirChain(netscripts)
+
+        # /etc/sysconfig/network-scripts/ifcfg-*
+        for dev in devices:
+            device = dev.get('DEVICE')
+
+            cfgfile = "%s/ifcfg-%s" % (netscripts, device,)
+            if (instPath) and (os.path.isfile(cfgfile)):
+                continue
+
+            bootproto = dev.get('BOOTPROTO').lower()
+            ipv6addr = dev.get('IPV6ADDR').lower()
+            ipv6prefix = dev.get('IPV6PREFIX').lower()
+            ipv6autoconf = dev.get('IPV6_AUTOCONF').lower()
+            dhcpv6c = dev.get('DHCPV6C').lower()
+
+            newifcfg = "/tmp/ifcfg-%s.new" % (device,)
+            f = open(newifcfg, "w")
+            if len(dev.get("DESC")) > 0:
+                f.write("# %s\n" % (dev.get("DESC"),))
+
+            # if bootproto is dhcp, unset any static settings (#218489)
+            # *but* don't unset if either IPv4 or IPv6 is manual (#433290)
+            if bootproto == 'dhcp':
+                dev.unset('IPADDR')
+                dev.unset('NETMASK')
+                dev.unset('GATEWAY')
+
+            # handle IPv6 settings correctly for the ifcfg file
+            dev.unset('IPV6ADDR')
+            dev.unset('IPV6PREFIX')
+
+            if ipv6addr == 'dhcp':
+                dev.set(('IPV6INIT', 'yes'))
+                dev.set(('DHCPV6C', 'yes'))
+            elif ipv6addr != '' and ipv6addr is not None:
+                dev.set(('IPV6INIT', 'yes'))
+
+                if ipv6prefix != '' and ipv6prefix is not None:
+                    dev.set(('IPV6ADDR', ipv6addr + '/' + ipv6prefix))
+                else:
+                    dev.set(('IPV6ADDR', ipv6addr))
+
+            if dev.get('IPV6_AUTOCONF').lower() == 'yes':
+                dev.set(('IPV6INIT', 'yes'))
+
+            f.write(str(dev))
+
+            # write out the hostname as DHCP_HOSTNAME if given (#81613)
+            if (bootproto == 'dhcp' and self.hostname and
+                self.overrideDHCPhostname):
+                f.write("DHCP_HOSTNAME=%s\n" %(self.hostname,))
+
+            if dev.get('MTU') and dev.get('MTU') != 0:
+                f.write("MTU=%s\n" % dev.get('MTU'))
+
+            # tell NetworkManager not to touch any interfaces used during
+            # installation when / is on a network backed device.
+            if anaconda is not None:
+                import storage
+                rootdev = anaconda.storage.rootDevice
+                # FIXME: use d.host_address to only add "NM_CONTROLLED=no"
+                # for interfaces actually used enroute to the device
+                for d in anaconda.storage.devices:
+                    if isinstance(d, storage.devices.NetworkStorageDevice) and\
+                       (rootdev.dependsOn(d) or d.nic == device):
+                        f.write("NM_CONTROLLED=no\n")
+                        break
+
+            f.close()
+            os.chmod(newifcfg, 0644)
+
+            # move the new ifcfg in place
+            destcfg = "%s/ifcfg-%s" % (netscripts, device,)
+            try:
+                os.remove(destcfg)
+            except OSError as e:
+                if e.errno != 2:
+                    raise
+            shutil.move(newifcfg, destcfg)
+
+            # XXX: is this necessary with NetworkManager?
+            # handle the keys* files if we have those
+            if dev.get("KEY"):
+                cfgfile = "%s/keys-%s" % (netscripts, device,)
+                if not instPath == '' and os.path.isfile(cfgfile):
+                    continue
+
+                newkey = "%s/keys-%s.new" % (netscripts, device,)
+                f = open(newkey, "w")
+                f.write("KEY=%s\n" % (dev.get('KEY'),))
+                f.close()
+                os.chmod(newkey, 0600)
+
+                destkey = "%s/keys-%s" % (netscripts, device,)
+                shutil.move(newkey, destkey)
+
+            # /etc/dhclient-DEVICE.conf
+            dhclientconf = '/etc/dhclient-' + device + '.conf'
+            if os.path.isfile(dhclientconf):
+                destdhclientconf = '%s%s' % (instPath, dhclientconf,)
+                try:
+                    shutil.copy(dhclientconf, destdhclientconf)
+                except:
+                    log.warning("unable to copy %s to target system" % (dhclientconf,))
+
+        # /etc/sysconfig/network
+        if (not instPath) or (not os.path.isfile(destnetwork)) or flags.livecdInstall:
+            newnetwork = "%s.new" % (destnetwork,)
+
+            f = open(newnetwork, "w")
+            f.write("NETWORKING=yes\n")
+            f.write("HOSTNAME=")
+
+            # use instclass hostname if set(kickstart) to override
+            if self.hostname:
+                f.write(self.hostname + "\n")
+            else:
+                f.write("localhost.localdomain\n")
+
+            if dev.get('GATEWAY'):
+                f.write("GATEWAY=%s\n" % (dev.get('GATEWAY'),))
+
+            if dev.get('IPV6_DEFAULTGW'):
+                f.write("IPV6_DEFAULTGW=%s\n" % (dev.get('IPV6_DEFAULTGW'),))
+
+            f.close()
+            shutil.move(newnetwork, destnetwork)
+
+        # If the hostname was not looked up, but typed in by the user,
+        # domain might not be computed, so do it now.
+        domainname = None
+        if "." in self.hostname:
+            fqdn = self.hostname
+        else:
+            fqdn = socket.getfqdn(self.hostname)
+
+        if fqdn in [ "localhost.localdomain", "localhost",
+                     "localhost6.localdomain6", "localhost6",
+                     self.hostname ] or "." not in fqdn:
+            fqdn = None
+
+        if fqdn:
+            domainname = fqdn.split('.', 1)[1]
+            if domainname in [ "localdomain", "localdomain6" ]:
+                domainname = None
+        else:
+            domainname = None
+
+        if self.domains == ["localdomain"] or not self.domains:
+            if domainname:
+                self.domains = [domainname]
+
+        # /etc/resolv.conf
+        if (not instPath) or (not os.path.isfile(instPath + '/etc/resolv.conf')) or flags.livecdInstall:
+            if os.path.isfile('/etc/resolv.conf') and instPath != '':
+                destresolv = "%s/etc/resolv.conf" % (instPath,)
+                shutil.copy('/etc/resolv.conf', destresolv)
+            elif (self.domains != ['localdomain'] and self.domains) or \
+                self.hasNameServers(dev.info):
+                resolv = "%s/etc/resolv.conf" % (instPath,)
+
+                f = open(resolv, "w")
+
+                if self.domains != ['localdomain'] and self.domains:
+                    f.write("search %s\n" % (string.joinfields(self.domains, ' '),))
+
+                for key in dev.info.keys():
+                    if key.upper().startswith('DNS'):
+                        f.write("nameserver %s\n" % (dev.get(key),))
+
+                f.close()
+
+        # /etc/udev/rules.d/70-persistent-net.rules
+        rules = "/etc/udev/rules.d/70-persistent-net.rules"
+        destRules = instPath + rules
+        if (not instPath) or (not os.path.isfile(destRules)) or \
+           flags.livecdInstall:
+            if not os.path.isdir("%s/etc/udev/rules.d" %(instPath,)):
+                iutil.mkdirChain("%s/etc/udev/rules.d" %(instPath,))
+
+            if os.path.isfile(rules) and rules != destRules:
+                shutil.copy(rules, destRules)
+            else:
+                f = open(destRules, "w")
+                f.write("""
+# This file was automatically generated by the /lib/udev/write_net_rules
+# program run by the persistent-net-generator.rules rules file.
+#
+# You can modify it, as long as you keep each rule on a single line.
+
+""")
+                for dev in self.netdevices.values():
+                    addr = dev.get("HWADDR")
+                    if not addr:
+                        continue
+                    devname = dev.get("DEVICE")
+                    basename = devname
+                    while basename != "" and basename[-1] in string.digits:
+                        basename = basename[:-1]
+
+                    # rules are case senstive for address. Lame.
+                    addr = addr.lower()
+
+                    s = ""
+                    if len(dev.get("DESC")) > 0:
+                        s = "# %s (rule written by anaconda)\n" % (dev.get("DESC"),)
+                    else:
+                        s = "# %s (rule written by anaconda)\n" % (devname,)
+                        s = s + 'SUBSYSTEM==\"net\", ACTION==\"add\", DRIVERS=="?*", ATTR{address}=="%s", ATTR{type}=="1", KERNEL=="%s*", NAME="%s"\n' % (addr, basename, devname,)
+
+                    f.write(s)
+
+                f.close()
+
+    # write out current configuration state and wait for NetworkManager
+    # to bring the device up, watch NM state and return to the caller
+    # once we have a state
+    def bringUp(self, devices=None):
+        self.write(devices=devices)
+
+        bus = dbus.SystemBus()
+        nm = bus.get_object(isys.NM_SERVICE, isys.NM_MANAGER_PATH)
+        props = dbus.Interface(nm, isys.DBUS_PROPS_IFACE)
+
+        i = 0
+        while i < 45:
+            state = props.Get(isys.NM_SERVICE, "State")
+            if int(state) == isys.NM_STATE_CONNECTED:
+                isys.resetResolv()
+                return True
+            i += 1
+            time.sleep(1)
+
+        state = props.Get(isys.NM_SERVICE, "State")
+        if int(state) == isys.NM_STATE_CONNECTED:
+            isys.resetResolv()
+            return True
+
+        return False
+
+    # get a kernel cmdline string for dracut needed for access to host host
+    def dracutSetupString(self, networkStorageDevice):
+        netargs=""
+
+        if networkStorageDevice.nic:
+            # Storage bound to a specific nic (ie FCoE)
+            nic = networkStorageDevice.nic
+        else:
+            # Storage bound through ip, find out which interface leads to host
+            host = networkStorageDevice.host_address
+            route = iutil.execWithCapture("ip", [ "route", "get", "to", host ])
+            if not route:
+                log.error("Could net get interface for route to %s" % host)
+                return ""
+
+            routeInfo = route.split()
+            if routeInfo[0] != host or len(routeInfo) < 5 or \
+               "dev" not in routeInfo or routeInfo.index("dev") > 3:
+                log.error('Unexpected "ip route get to %s" reply: %s' %
+                          (host, routeInfo))
+                return ""
+
+            nic = routeInfo[routeInfo.index("dev") + 1]
+
+        if nic not in self.netdevices.keys():
+            log.error('Unknown network interface: %s' % nic)
+            return ""
+
+        dev = self.netdevices[nic]
+
+        if networkStorageDevice.host_address:
+            if dev.get('bootproto').lower() == 'dhcp':
+                netargs += "ip=%s:dhcp" % nic
+            else:
+                if dev.get('GATEWAY'):
+                    gateway = dev.get('GATEWAY')
+                else:
+                    gateway = ""
+
+                if self.hostname:
+                    hostname = self.hostname
+                else:
+                    hostname = ""
+
+                netargs += "ip=%s::%s:%s:%s:%s:none" % (dev.get('ipaddr'),
+                           gateway, dev.get('netmask'), hostname, nic)
+
+        hwaddr = dev.get("HWADDR")
+        if hwaddr:
+            if netargs != "":
+                netargs += " "
+
+            netargs += "ifname=%s:%s" % (nic, hwaddr.lower())
+
+        nettype = dev.get("NETTYPE")
+        subchannels = dev.get("SUBCHANNELS")
+        if iutil.isS390() and nettype and subchannels:
+            if netargs != "":
+                netargs += " "
+
+            netargs += "rd_CCW=%s,%s" % (nettype, subchannels)
+
+            options = dev.get("OPTIONS").strip("'\"")
+            if options:
+                options = filter(lambda x: x != '', options.split(' '))
+                netargs += ",%s" % (','.join(options))
+
+        return netargs
diff --git a/pyanaconda/packages.py b/pyanaconda/packages.py
new file mode 100644
index 0000000..6381c12
--- /dev/null
+++ b/pyanaconda/packages.py
@@ -0,0 +1,360 @@
+#
+# packages.py: package management - mainly package installation
+#
+# Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006  Red Hat, Inc.
+# 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 as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# 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, see <http://www.gnu.org/licenses/>.
+#
+# Author(s): Erik Troan <ewt@xxxxxxxxxx>
+#            Matt Wilson <msw@xxxxxxxxxx>
+#            Michael Fulbright <msf@xxxxxxxxxx>
+#            Jeremy Katz <katzj@xxxxxxxxxx>
+#
+
+import glob
+import iutil
+import isys
+import os
+import time
+import sys
+import string
+import language
+import shutil
+import traceback
+from flags import flags
+from product import *
+from constants import *
+from upgrade import bindMountDevDirectory
+from storage.errors import *
+
+import logging
+log = logging.getLogger("anaconda")
+
+import gettext
+_ = lambda x: gettext.ldgettext("anaconda", x)
+
+def doPostAction(anaconda):
+    anaconda.instClass.postAction(anaconda)
+
+def firstbootConfiguration(anaconda):
+    if anaconda.firstboot == FIRSTBOOT_RECONFIG:
+        f = open(anaconda.rootPath + '/etc/reconfigSys', 'w+')
+        f.close()
+    elif anaconda.firstboot == FIRSTBOOT_SKIP:
+        f = open(anaconda.rootPath + '/etc/sysconfig/firstboot', 'w+')
+        f.write('RUN_FIRSTBOOT=NO')
+        f.close()
+
+    return
+
+def writeKSConfiguration(anaconda):
+    log.info("Writing autokickstart file")
+    fn = anaconda.rootPath + "/root/anaconda-ks.cfg"
+
+    anaconda.writeKS(fn)
+
+def copyAnacondaLogs(anaconda):
+    log.info("Copying anaconda logs")
+    for (fn, dest) in (("/tmp/anaconda.log", "anaconda.log"),
+                       ("/tmp/syslog", "anaconda.syslog"),
+                       ("/tmp/X.log", "anaconda.xlog"),
+                       ("/tmp/program.log", "anaconda.program.log"),
+                       ("/tmp/storage.log", "anaconda.storage.log"),
+                       ("/tmp/yum.log", "anaconda.yum.log")):
+        if os.access(fn, os.R_OK):
+            try:
+                shutil.copyfile(fn, "%s/var/log/%s" %(anaconda.rootPath, dest))
+                os.chmod("%s/var/log/%s" %(anaconda.rootPath, dest), 0600)
+            except:
+                pass
+
+def turnOnFilesystems(anaconda):
+    if anaconda.dir == DISPATCH_BACK:
+        if not anaconda.upgrade:
+            log.info("unmounting filesystems")
+            anaconda.storage.umountFilesystems()
+        return DISPATCH_NOOP
+
+    if not anaconda.upgrade:
+        if not anaconda.storage.fsset.active:
+            # turn off any swaps that we didn't turn on
+            # needed for live installs
+            iutil.execWithRedirect("swapoff", ["-a"],
+                                   stdout = "/dev/tty5", stderr="/dev/tty5")
+        anaconda.storage.devicetree.teardownAll()
+
+    upgrade_migrate = False
+    if anaconda.upgrade:
+        for d in anaconda.storage.migratableDevices:
+            if d.format.migrate:
+                upgrade_migrate = True
+
+    title = None
+    message = None
+    details = None
+
+    try:
+        anaconda.storage.doIt()
+    except FSResizeError as (msg, device):
+        title = _("Resizing Failed")
+        message = _("There was an error encountered while "
+                    "resizing the device %s.") % (device,)
+
+        if os.path.exists("/tmp/resize.out"):
+            details = open("/tmp/resize.out", "r").read()
+        else:
+            details = "%s" %(msg,)
+    except FSMigrateError as (msg, device):
+        title = _("Migration Failed")
+        message = _("An error was encountered while "
+                    "migrating filesystem on device %s.") % (device,)
+        details = msg
+    except Exception as e:
+        raise
+
+    if title:
+        rc = anaconda.intf.detailedMessageWindow(title, message, details,
+                        type = "custom",
+                        custom_buttons = [_("_File Bug"), _("_Exit installer")])
+
+        if rc == 0:
+            raise
+        elif rc == 1:
+            sys.exit(1)
+
+    if not anaconda.upgrade:
+        anaconda.storage.turnOnSwap()
+        anaconda.storage.mountFilesystems(raiseErrors=False,
+                                          readOnly=False,
+                                          skipRoot=anaconda.backend.skipFormatRoot)
+    else:
+        if upgrade_migrate:
+            # we should write out a new fstab with the migrated fstype
+            shutil.copyfile("%s/etc/fstab" % anaconda.rootPath,
+                            "%s/etc/fstab.anaconda" % anaconda.rootPath)
+            anaconda.storage.fsset.write(anaconda.rootPath)
+
+        # and make sure /dev is mounted so we can read the bootloader
+        bindMountDevDirectory(anaconda.rootPath)
+
+
+def setupTimezone(anaconda):
+    # we don't need this on an upgrade or going backwards
+    if anaconda.upgrade or anaconda.dir == DISPATCH_BACK:
+        return
+
+    os.environ["TZ"] = anaconda.timezone.tz
+    tzfile = "/usr/share/zoneinfo/" + anaconda.timezone.tz
+    tzlocalfile = "/etc/localtime"
+    if not os.access(tzfile, os.R_OK):
+        log.error("unable to set timezone")
+    else:
+        try:
+            os.remove(tzlocalfile)
+        except OSError:
+            pass
+        try:
+            shutil.copyfile(tzfile, tzlocalfile)
+        except OSError as e:
+            log.error("Error copying timezone (from %s): %s" %(tzfile, e.strerror))
+
+    if iutil.isS390():
+        return
+    args = [ "--hctosys" ]
+    if anaconda.timezone.utc:
+        args.append("-u")
+
+    try:
+        iutil.execWithRedirect("/usr/sbin/hwclock", args, stdin = None,
+                               stdout = "/dev/tty5", stderr = "/dev/tty5")
+    except RuntimeError:
+        log.error("Failed to set clock")
+
+
+# FIXME: this is a huge gross hack.  hard coded list of files
+# created by anaconda so that we can not be killed by selinux
+def setFileCons(anaconda):
+    if flags.selinux:
+        log.info("setting SELinux contexts for anaconda created files")
+
+        files = ["/etc/rpm/macros",
+                 "/etc/lilo.conf.anaconda", "/lib64", "/usr/lib64",
+                 "/etc/blkid.tab", "/etc/blkid.tab.old", 
+                 "/etc/mtab", "/etc/fstab", "/etc/resolv.conf",
+                 "/etc/modprobe.conf", "/etc/modprobe.conf~",
+                 "/var/log/wtmp", "/var/run/utmp", "/etc/crypttab",
+                 "/dev/log", "/var/lib/rpm", "/", "/etc/raidtab",
+                 "/etc/mdadm.conf", "/etc/sysconfig/network",
+                 "/etc/udev/rules.d/70-persistent-net.rules",
+                 "/root/install.log", "/root/install.log.syslog",
+                 "/etc/shadow", "/etc/shadow-", "/etc/gshadow"] + \
+                glob.glob('/etc/dhclient-*.conf')
+
+        vgs = ["/dev/%s" % vg.name for vg in anaconda.storage.vgs]
+
+        # ugh, this is ugly
+        for dir in ["/etc/sysconfig/network-scripts", "/var/lib/rpm", "/etc/lvm", "/dev/mapper", "/etc/iscsi", "/var/lib/iscsi", "/root", "/var/log", "/etc/modprobe.d", "/etc/sysconfig" ] + vgs:
+            def addpath(x): return dir + "/" + x
+
+            if not os.path.isdir(anaconda.rootPath + dir):
+                continue
+            dirfiles = os.listdir(anaconda.rootPath + dir)
+            files.extend(map(addpath, dirfiles))
+            files.append(dir)
+
+        for f in files:
+            if not os.access("%s/%s" %(anaconda.rootPath, f), os.R_OK):
+                log.warning("%s doesn't exist" %(f,))
+                continue
+            ret = isys.resetFileContext(os.path.normpath(f),
+                                        anaconda.rootPath)
+            log.info("set fc of %s to %s" %(f, ret))
+
+    return
+
+# FIXME: using rpm directly here is kind of lame, but in the yum backend
+# we don't want to use the metadata as the info we need would require
+# the filelists.  and since we only ever call this after an install is
+# done, we can be guaranteed this will work.  put here because it's also
+# used for livecd installs
+def rpmKernelVersionList(rootPath = "/"):
+    import rpm
+
+    def get_version(header):
+        for f in header['filenames']:
+            if f.startswith('/boot/vmlinuz-'):
+                return f[14:]
+            elif f.startswith('/boot/efi/EFI/redhat/vmlinuz-'):
+                return f[29:]
+        return ""
+
+    def get_tag(header):
+        if header['name'] == "kernel":
+            return "base"
+        elif header['name'].startswith("kernel-"):
+            return header['name'][7:]
+        return ""
+
+    versions = []
+
+    iutil.resetRpmDb(rootPath)
+    ts = rpm.TransactionSet(rootPath)
+
+    mi = ts.dbMatch('provides', 'kernel')
+    for h in mi:
+        v = get_version(h)
+        tag = get_tag(h)
+        if v == "" or tag == "":
+            log.warning("Unable to determine kernel type/version for %s-%s-%s.%s" %(h['name'], h['version'], h['release'], h['arch'])) 
+            continue
+        # rpm really shouldn't return the same kernel more than once... but
+        # sometimes it does (#467822)
+        if (v, h['arch'], tag) in versions:
+            continue
+        versions.append( (v, h['arch'], tag) )
+
+    return versions
+
+def rpmSetupGraphicalSystem(anaconda):
+    import rpm
+
+    iutil.resetRpmDb(anaconda.rootPath)
+    ts = rpm.TransactionSet(anaconda.rootPath)
+
+    # Only add "rhgb quiet" on non-s390, non-serial installs
+    if iutil.isConsoleOnVirtualTerminal() and \
+       (ts.dbMatch('provides', 'rhgb').count() or \
+        ts.dbMatch('provides', 'plymouth').count()):
+        anaconda.bootloader.args.append("rhgb quiet")
+
+    if ts.dbMatch('provides', 'service(graphical-login)').count() and \
+       anaconda.displayMode == 'g' and not flags.usevnc:
+        anaconda.desktop.setDefaultRunLevel(5)
+
+#Recreate initrd for use when driver disks add modules
+def recreateInitrd (kernelTag, instRoot):
+    log.info("recreating initrd for %s" % (kernelTag,))
+    iutil.execWithRedirect("/sbin/new-kernel-pkg",
+                           [ "--mkinitrd", "--dracut", "--depmod", "--install", kernelTag ],
+                           stdout = "/dev/null", stderr = "/dev/null",
+                           root = instRoot)
+
+def betaNagScreen(anaconda):
+    publicBetas = { "Red Hat Linux": "Red Hat Linux Public Beta",
+                    "Red Hat Enterprise Linux": "Red Hat Enterprise Linux Public Beta",
+                    "Fedora Core": "Fedora Core",
+                    "Fedora": "Fedora" }
+
+    
+    if anaconda.dir == DISPATCH_BACK:
+	return DISPATCH_NOOP
+
+    fileagainst = None
+    for (key, val) in publicBetas.items():
+        if productName.startswith(key):
+            fileagainst = val
+    if fileagainst is None:
+        fileagainst = "%s Beta" %(productName,)
+    
+    while 1:
+	rc = anaconda.intf.messageWindow(_("Warning"),
+				 _("Warning!  This is pre-release software!\n\n"
+                                   "Thank you for downloading this "
+				   "pre-release of %(productName)s.\n\n"
+				   "This is not a final "
+				   "release and is not intended for use "
+				   "on production systems.  The purpose of "
+				   "this release is to collect feedback "
+				   "from testers, and it is not suitable "
+				   "for day to day usage.\n\n"
+				   "To report feedback, please visit:\n\n"
+				   "   %(bugzillaUrl)s\n\n"
+				   "and file a report against '%(fileagainst)s'.\n")
+				 % {'productName': productName,
+				    'bugzillaUrl': bugzillaUrl,
+				    'fileagainst': fileagainst},
+				   type="custom", custom_icon="warning",
+				   custom_buttons=[_("_Exit"), _("_Install Anyway")])
+
+	if not rc:
+            msg =  _("Your system will now be rebooted...")
+            buttons = [_("_Back"), _("_Reboot")]
+	    rc = anaconda.intf.messageWindow( _("Warning! This is pre-release software!"),
+                                     msg,
+                                     type="custom", custom_icon="warning",
+                                     custom_buttons=buttons)
+	    if rc:
+		sys.exit(0)
+	else:
+	    break
+
+def doReIPL(anaconda):
+#   # This is here as an example to fix the screen during the TUI debugging path
+#   anaconda.intf.screen.suspend ()
+#   import pdb
+#   pdb.set_trace ()
+
+    if not iutil.isS390() or anaconda.dir == DISPATCH_BACK:
+        return DISPATCH_NOOP
+
+    messageInfo = iutil.reIPL(anaconda, os.getppid())
+
+    if messageInfo:
+        (errorMessage, rebootInstr) = messageInfo
+
+        # errorMessage intentionally not shown in UI
+        anaconda.reIPLMessage = rebootInstr
+
+    return DISPATCH_FORWARD
diff --git a/pyanaconda/partIntfHelpers.py b/pyanaconda/partIntfHelpers.py
new file mode 100644
index 0000000..3aaba71
--- /dev/null
+++ b/pyanaconda/partIntfHelpers.py
@@ -0,0 +1,354 @@
+#
+# partIntfHelpers.py: partitioning interface helper functions
+#
+# Copyright (C) 2002  Red Hat, Inc.  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 as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# 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, see <http://www.gnu.org/licenses/>.
+#
+# Author(s): Matt Wilson <msw@xxxxxxxxxx>
+#            Jeremy Katz <katzj@xxxxxxxxxx>
+#            Mike Fulbright <msf@xxxxxxxxxx>
+#            Harald Hoyer <harald@xxxxxxxxx>
+#
+
+"""Helper functions shared between partitioning interfaces."""
+
+import string
+from constants import *
+import parted
+import iutil
+from storage.formats import getFormat
+
+import gettext
+_ = lambda x: gettext.ldgettext("anaconda", x)
+
+def sanityCheckVolumeGroupName(volname):
+    """Make sure that the volume group name doesn't contain invalid chars."""
+    badNames = ['lvm', 'root', '.', '..' ]
+
+    if not volname:
+	return _("Please enter a volume group name.")
+
+    # ripped the value for this out of linux/include/lvm.h
+    if len(volname) > 128:
+        return _("Volume Group Names must be less than 128 characters")
+
+    if volname in badNames:
+	return _("Error - the volume group name %s is not valid." % (volname,))
+
+    for i in range(0, len(volname)):
+	rc = string.find(string.letters + string.digits + '.' + '_' + '-', volname[i])
+	if rc == -1:
+	    return _("Error - the volume group name contains illegal "
+		     "characters or spaces.  Acceptable characters "
+		     "are letters, digits, '.' or '_'.")
+    return None
+
+def sanityCheckLogicalVolumeName(logvolname):
+    """Make sure that the logical volume name doesn't contain invalid chars."""
+    badNames = ['group', '.', '..' ]
+    
+    if not logvolname:
+	return _("Please enter a logical volume name.")
+
+    # ripped the value for this out of linux/include/lvm.h
+    if len(logvolname) > 128:
+        return _("Logical Volume Names must be less than 128 characters")
+    
+
+    if logvolname in badNames:
+	return _("Error - the logical volume name %s is not "
+                 "valid." % (logvolname,))
+
+    for i in range(0, len(logvolname)):
+	rc = string.find(string.letters + string.digits + '.' + '_', logvolname[i])
+	if rc == -1:
+	    return _("Error - the logical volume name contains illegal "
+		     "characters or spaces.  Acceptable characters "
+		     "are letters, digits, '.' or '_'.")
+    return None
+
+def sanityCheckMountPoint(mntpt, fstype, preexisting, format):
+    """Sanity check that the mountpoint is valid.
+
+    mntpt is the mountpoint being used.
+    fstype is the file system being used on the request.
+    preexisting is whether the request was preexisting (request.preexist)
+    format is whether the request is being formatted or not
+    """
+    if mntpt:
+        passed = 1
+        if not mntpt:
+            passed = 0
+        else:
+            if mntpt[0] != '/' or (len(mntpt) > 1 and mntpt[-1:] == '/'):
+                passed = 0
+	    elif mntpt.find(' ') > -1:
+		passed = 0
+                
+        if not passed:
+            return _("The mount point %s is invalid.  Mount points must start "
+                     "with '/' and cannot end with '/', and must contain "
+                     "printable characters and no spaces." % mntpt)
+        else:
+            return None
+    else:
+        if (fstype and fstype.mountable and (not preexisting or format)):
+            return _("Please specify a mount point for this partition.")
+        else:
+            # its an existing partition so don't force a mount point
+            return None
+
+def doDeleteDevice(intf, storage, device, confirm=1, quiet=0):
+    """Delete a partition from the request list.
+
+    intf is the interface
+    storage is the storage instance
+    device is the device to delete
+    """
+    if not device:
+        intf.messageWindow(_("Unable To Delete"),
+                           _("You must first select a partition to delete."),
+			   custom_icon="error")
+        return False
+
+    reason = storage.deviceImmutable(device)
+    if reason:
+        intf.messageWindow(_("Unable To Delete"),
+                           reason,
+                           custom_icon="error")
+        return False
+
+    if confirm and not confirmDelete(intf, device):
+        return False
+
+    deps = storage.deviceDeps(device)
+    while deps:
+        leaves = [d for d in deps if d.isleaf]
+        for leaf in leaves:
+            storage.destroyDevice(leaf)
+            deps.remove(leaf)
+
+    storage.destroyDevice(device)
+    return True
+
+def doClearPartitionedDevice(intf, storage, device, confirm=1, quiet=0):
+    """ Remove all devices/partitions currently on device.
+
+            device -- a partitioned device such as a disk
+
+     """
+    if confirm:
+	rc = intf.messageWindow(_("Confirm Delete"),
+				_("You are about to delete all partitions on "
+				  "the device '%s'.") % (device.path,),
+				type="custom", custom_icon="warning",
+				custom_buttons=[_("Cancel"), _("_Delete")])
+
+	if not rc:
+	    return False
+
+    immutable = []
+    partitions = [p for p in storage.partitions if p.disk == device]
+    if not partitions:
+        return False
+
+    partitions.sort(key=lambda p: p.partedPartition.number, reverse=True)
+    for p in partitions:
+        deps = storage.deviceDeps(p)
+        clean = True    # true if part and its deps were removed
+        while deps:
+            leaves = [d for d in deps if d.isleaf]
+            for leaf in leaves:
+                if leaf in immutable:
+                    # this device was removed from deps at the same time it
+                    # was added to immutable, so it won't appear in leaves
+                    # in the next iteration
+                    continue
+
+                if storage.deviceImmutable(leaf):
+                    immutable.append(leaf)
+                    for dep in [d for d in deps if d != leaf]:
+                        # mark devices this device depends on as immutable
+                        # to prevent getting stuck with non-leaf deps
+                        # protected by immutable leaf devices
+                        if leaf.dependsOn(dep):
+                            deps.remove(dep)
+                            if dep not in immutable:
+                                immutable.append(dep)
+                    clean = False
+                else:
+                    storage.destroyDevice(leaf)
+                deps.remove(leaf)
+
+        if storage.deviceImmutable(p):
+            immutable.append(p)
+            clean = False
+
+        if clean:
+            storage.destroyDevice(p)
+
+    if immutable and not quiet:
+        remaining = "\t" + "\n\t".join(p.path for p in immutable) + "\n"
+        intf.messageWindow(_("Notice"),
+                           _("The following partitions were not deleted "
+                             "because they are in use:\n\n%s") % remaining,
+			   custom_icon="warning")
+
+    return True
+
+def checkForSwapNoMatch(anaconda):
+    """Check for any partitions of type 0x82 which don't have a swap fs."""
+    for device in anaconda.storage.partitions:
+        if not device.exists:
+            # this is only for existing partitions
+            continue
+
+        if device.getFlag(parted.PARTITION_SWAP) and \
+           not device.format.type == "swap":
+            rc = anaconda.intf.messageWindow(_("Format as Swap?"),
+                                    _("%s has a partition type of 0x82 "
+                                      "(Linux swap) but does not appear to "
+                                      "be formatted as a Linux swap "
+                                      "partition.\n\n"
+                                      "Would you like to format this "
+                                      "partition as a swap partition?")
+                                    % device.path, type = "yesno",
+                                    custom_icon="question")
+            if rc == 1:
+                format = getFormat("swap", device=device.path)
+                anaconda.storage.formatDevice(device, format)
+
+    return
+
+def mustHaveSelectedDrive(intf):
+    txt =_("You need to select at least one hard drive to install %s.") % (productName,)
+    intf.messageWindow(_("Error"), txt, custom_icon="error")
+     
+def queryNoFormatPreExisting(intf):
+    """Ensure the user wants to use a partition without formatting."""
+    txt = _("You have chosen to use a pre-existing "
+            "partition for this installation without formatting it. "
+            "We recommend that you format this partition "
+            "to make sure files from a previous operating system installation "
+            "do not cause problems with this installation of Linux. "
+            "However, if this partition contains files that you need "
+            "to keep, such as home directories, then "
+            "continue without formatting this partition.")
+    rc = intf.messageWindow(_("Format?"), txt, type = "custom", custom_buttons=[_("_Modify Partition"), _("Do _Not Format")], custom_icon="warning")
+    return rc
+
+def partitionSanityErrors(intf, errors):
+    """Errors were found sanity checking.  Tell the user they must fix."""
+    rc = 1
+    if errors:
+        errorstr = string.join(errors, "\n\n")
+        rc = intf.messageWindow(_("Error with Partitioning"),
+                                _("The following critical errors exist "
+                                  "with your requested partitioning "
+                                  "scheme. "
+                                  "These errors must be corrected prior "
+                                  "to continuing with your install of "
+                                  "%(productName)s.\n\n%(errorstr)s") \
+                                % {'productName': productName,
+                                   'errorstr': errorstr},
+                                custom_icon="error")
+    return rc
+
+def partitionSanityWarnings(intf, warnings):
+    """Sanity check found warnings.  Make sure the user wants to continue."""
+    rc = 1
+    if warnings:
+        warningstr = string.join(warnings, "\n\n")
+        rc = intf.messageWindow(_("Partitioning Warning"),
+                                     _("The following warnings exist with "
+                                       "your requested partition scheme.\n\n%s"
+                                       "\n\nWould you like to continue with "
+                                       "your requested partitioning "
+                                       "scheme?") % (warningstr),
+                                     type="yesno", custom_icon="warning")
+    return rc
+
+
+def partitionPreExistFormatWarnings(intf, warnings):
+    """Double check that preexistings being formatted are fine."""
+    rc = 1
+    if warnings:
+
+        labelstr1 = _("The following pre-existing partitions have been "
+                      "selected to be formatted, destroying all data.")
+
+        labelstr2 = _("Select 'Yes' to continue and format these "
+                      "partitions, or 'No' to go back and change these "
+                      "settings.")
+        commentstr = ""
+        for (dev, type, mntpt) in warnings:
+            commentstr = commentstr + "/dev/%s %s %s\n" % (dev,type,mntpt)
+        rc = intf.messageWindow(_("Format Warning"), "%s\n\n%s\n\n%s" %
+                                (labelstr1, labelstr2, commentstr),
+                                type="yesno", custom_icon="warning")
+    return rc
+
+def getPreExistFormatWarnings(storage):
+    """Return a list of preexisting devices being formatted."""
+    devices = []
+    for device in storage.devicetree.devices:
+        if device.exists and not device.format.exists and \
+           not device.format.hidden:
+            devices.append(device)
+
+    devices.sort(key=lambda d: d.name)
+    rc = []
+    for device in devices:
+        rc.append((device.path,
+                   device.format.name,
+                   getattr(device.format, "mountpoint", "")))
+    return rc
+            
+def confirmDelete(intf, device):
+    """Confirm the deletion of a device."""
+    if not device:
+	return
+    
+    if device.type == "lvmvg":
+	errmsg = (_("You are about to delete the volume group \"%s\"."
+                    "\n\nALL logical volumes in this volume group "
+                    "will be lost!") % device.name)
+    elif device.type == "lvmlv":
+	errmsg = (_("You are about to delete the logical volume \"%s\".")
+                  % device.name)
+    elif device.type == "mdarray":
+	errmsg = _("You are about to delete a RAID device.")
+    elif device.type == "partition":
+	errmsg = (_("You are about to delete the %s partition.")
+                  % device.path)
+    else:
+        # we may want something a little bit prettier than device.type
+        errmsg = (_("You are about to delete the %(type)s %(name)s") \
+                  % {'type': device.type, 'name': device.name})
+
+    rc = intf.messageWindow(_("Confirm Delete"), errmsg, type="custom",
+				custom_buttons=[_("Cancel"), _("_Delete")],
+			    custom_icon="question")
+
+    return rc
+
+def confirmResetPartitionState(intf):
+    """Confirm reset of partitioning to that present on the system."""
+    rc = intf.messageWindow(_("Confirm Reset"),
+                            _("Are you sure you want to reset the "
+                              "partition table to its original state?"),
+                            type="yesno", custom_icon="question")
+    return rc
+
diff --git a/pyanaconda/platform.py b/pyanaconda/platform.py
new file mode 100644
index 0000000..e3d4480
--- /dev/null
+++ b/pyanaconda/platform.py
@@ -0,0 +1,574 @@
+#
+# platform.py:  Architecture-specific information
+#
+# Copyright (C) 2009
+# Red Hat, Inc.  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 as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# 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, see <http://www.gnu.org/licenses/>.
+#
+# Authors: Chris Lumens <clumens@xxxxxxxxxx>
+#
+
+import iutil
+import parted
+import storage
+from storage.errors import *
+from storage.formats import *
+from storage.partspec import *
+
+import gettext
+_ = lambda x: gettext.ldgettext("anaconda", x)
+N_ = lambda x: x
+
+class Platform(object):
+    """Platform
+
+       A class containing platform-specific information and methods for use
+       during installation.  The intent is to eventually encapsulate all the
+       architecture quirks in one place to avoid lots of platform checks
+       throughout anaconda."""
+    _bootFSTypes = ["ext3"]
+    _diskLabelType = "msdos"
+    _isEfi = iutil.isEfi()
+    _minimumSector = 0
+    _packages = []
+    _supportsMdRaidBoot = False
+    _minBootPartSize = 50
+    _maxBootPartSize = 0
+
+    def __init__(self, anaconda):
+        """Creates a new Platform object.  This is basically an abstract class.
+           You should instead use one of the platform-specific classes as
+           returned by getPlatform below.  Not all subclasses need to provide
+           all the methods in this class."""
+        self.anaconda = anaconda
+
+    def _mntDict(self):
+        """Return a dictionary mapping mount points to devices."""
+        ret = {}
+        for device in [d for d in self.anaconda.storage.devices if d.format.mountable]:
+            ret[device.format.mountpoint] = device
+
+        return ret
+
+    def bootDevice(self):
+        """Return the device where /boot is mounted."""
+        if self.__class__ is Platform:
+            raise NotImplementedError("bootDevice not implemented for this platform")
+
+        mntDict = self._mntDict()
+        return mntDict.get("/boot", mntDict.get("/"))
+
+    @property
+    def defaultBootFSType(self):
+        """Return the default filesystem type for the boot partition."""
+        return self._bootFSTypes[0]
+
+    @property
+    def bootFSTypes(self):
+        """Return a list of all valid filesystem types for the boot partition."""
+        return self._bootFSTypes
+
+    def bootloaderChoices(self, bl):
+        """Return the default list of places to install the bootloader.
+           This is returned as a dictionary of locations to (device, identifier)
+           tuples.  If there is no boot device, an empty dictionary is
+           returned."""
+        if self.__class__ is Platform:
+            raise NotImplementedError("bootloaderChoices not implemented for this platform")
+
+        bootDev = self.bootDevice()
+        ret = {}
+
+        if not bootDev:
+            return ret
+
+        if bootDev.type == "mdarray":
+            ret["boot"] = (bootDev.name, N_("RAID Device"))
+            ret["mbr"] = (bl.drivelist[0], N_("Master Boot Record (MBR)"))
+        else:
+            ret["boot"] = (bootDev.name, N_("First sector of boot partition"))
+            ret["mbr"] = (bl.drivelist[0], N_("Master Boot Record (MBR)"))
+
+        return ret
+
+    def checkBootRequest(self, req):
+        """Perform an architecture-specific check on the boot device.  Not all
+           platforms may need to do any checks.  Returns a list of errors if
+           there is a problem, or [] otherwise."""
+        errors = []
+
+        if not req:
+            return [_("You have not created a bootable partition.")]
+
+        # most arches can't have boot on RAID
+        if req.type == "mdarray":
+            if not self.supportsMdRaidBoot:
+                errors.append(_("Bootable partitions cannot be on a RAID device."))
+            elif req.type == "mdarray" and req.level != 1:
+                errors.append(_("Bootable partitions can only be on RAID1 devices."))
+            else:
+                for p in req.parents:
+                    if p.type != "partition":
+                        errors.append(_("Bootable RAID1 set members must be partitions."))
+                        break
+
+        # can't have bootable partition on LV
+        if req.type == "lvmlv":
+            errors.append(_("Bootable partitions cannot be on a logical volume."))
+
+        # Make sure /boot is on a supported FS type.  This prevents crazy
+        # things like boot on vfat.
+        if not req.format.bootable or \
+           (getattr(req.format, "mountpoint", None) == "/boot" and
+            req.format.type not in self.bootFSTypes):
+            errors.append(_("Bootable partitions cannot be on an %s filesystem.") % req.format.type)
+
+        if req.type == "luks/dm-crypt":
+            # Handle encrypted boot on a partition.
+            errors.append(_("Bootable partitions cannot be on an encrypted block device"))
+        else:
+            # Handle encrypted boot on more complicated devices.
+            for dev in filter(lambda d: d.type == "luks/dm-crypt", self.anaconda.storage.devices):
+                if req in self.anaconda.storage.deviceDeps(dev):
+                    errors.append(_("Bootable partitions cannot be on an encrypted block device"))
+
+        return errors
+
+    def diskLabelType(self, deviceType):
+        """Return the disk label type as a string."""
+        return self._diskLabelType
+
+    @property
+    def isEfi(self):
+        return self._isEfi
+
+    @property
+    def minimumSector(self, disk):
+        """Return the minimum starting sector for the provided disk."""
+        return self._minimumSector
+
+    @property
+    def packages (self):
+        return self._packages
+
+    def setDefaultPartitioning(self):
+        """Return the default platform-specific partitioning information."""
+        return [PartSpec(mountpoint="/boot", fstype=self.defaultBootFSType, size=500,
+                         weight=self.weight(mountpoint="/boot"))]
+
+    @property
+    def supportsMdRaidBoot(self):
+        """Does the platform support /boot on MD RAID?"""
+        return self._supportsMdRaidBoot
+
+    @property
+    def minBootPartSize(self):
+        return self._minBootPartSize
+
+    @property
+    def maxBootPartSize(self):
+        return self._maxBootPartSize
+
+    def validBootPartSize(self, size):
+        """ Is the given size (in MB) acceptable for a boot device? """
+        if not isinstance(size, int) and not isinstance(size, float):
+            return False
+
+        return ((not self.minBootPartSize or size >= self.minBootPartSize)
+                and
+                (not self.maxBootPartSize or size <= self.maxBootPartSize))
+
+    def weight(self, fstype=None, mountpoint=None):
+        """ Given an fstype (as a string) or a mountpoint, return an integer
+            for the base sorting weight.  This is used to modify the sort
+            algorithm for partition requests, mainly to make sure bootable
+            partitions and /boot are placed where they need to be."""
+        return 0
+
+class EFI(Platform):
+    _bootFSTypes = ["ext4", "ext3", "ext2"]
+    _diskLabelType = "gpt"
+    _minBootPartSize = 50
+    _maxBootPartSize = 256
+
+    def bootDevice(self):
+        mntDict = self._mntDict()
+        return mntDict.get("/boot/efi")
+
+    def bootloaderChoices(self, bl):
+        bootDev = self.bootDevice()
+        ret = {}
+
+        if not bootDev:
+            return ret
+
+        ret["boot"] = (bootDev.name, N_("EFI System Partition"))
+        return ret
+
+    def checkBootRequest(self, req):
+        """ Perform architecture-specific checks on the boot device.
+
+            Returns a list of error strings.
+
+            NOTE: X86 does not have a separate checkBootRequest method,
+                  so this one must work for x86 as well as EFI.
+        """
+        if not req:
+            return [_("You have not created a /boot/efi partition.")]
+
+        errors = Platform.checkBootRequest(self, req)
+
+        if req.format.mountpoint == "/boot/efi":
+            if req.format.type != "efi":
+                errors.append(_("/boot/efi is not EFI."))
+
+        # Don't try to check the disklabel on lv's etc, using lv for /boot
+        # is already checked in the generic Platform.checkBootRequest()
+        partitions = []
+        if req.type == "partition":
+            partitions = [ req ]
+        elif req.type == "mdarray":
+            partitions = filter(lambda d: d.type == "partition", req.parents)
+
+        # Check that we've got a correct disk label.
+        for p in partitions:        
+            partedDisk = p.disk.format.partedDisk
+            labelType = self.diskLabelType(partedDisk.device.type)
+            # Allow using gpt with x86, but not msdos with EFI
+            if partedDisk.type != labelType and partedDisk.type != "gpt":
+                errors.append(_("%s must have a %s disk label.")
+                              % (p.disk.name, labelType.upper()))
+
+        return errors
+
+    def setDefaultPartitioning(self):
+        ret = Platform.setDefaultPartitioning(self)
+
+        # Only add the EFI partition to the default set if there's not already
+        # one on the system.
+        if len(filter(lambda dev: dev.format.type == "efi" and self.validBootPartSize(dev.size),
+                      self.anaconda.storage.partitions)) == 0:
+            ret.append(PartSpec(mountpoint="/boot/efi", fstype="efi", size=20,
+                                maxSize=200, grow=True, weight=self.weight(fstype="efi")))
+
+        return ret
+
+    def weight(self, fstype=None, mountpoint=None):
+        if fstype and fstype == "efi" or mountpoint and mountpoint == "/boot/efi":
+            return 5000
+        elif mountpoint and mountpoint == "/boot":
+            return 2000
+        else:
+            return 0
+
+class Alpha(Platform):
+    _diskLabelType = "bsd"
+
+    def checkBootRequest(self, req):
+        errors = Platform.checkBootRequest(self, req)
+
+        if not req or req.type != "partition" or not req.disk:
+            return errors
+
+        disk = req.disk.format.partedDisk
+
+        # Check that we're a BSD disk label
+        if not disk.type == self._diskLabelType:
+            errors.append(_("%s must have a bsd disk label.") % req.disk.name)
+
+        # The first free space should start at the beginning of the drive and
+        # span for a megabyte or more.
+        free = disk.getFirstPartition()
+        while free:
+            if free.type & parted.PARTITION_FREESPACE:
+                break
+
+            free = free.nextPartition()
+
+        if not free or free.geoemtry.start != 1L or free.getSize(unit="MB") < 1:
+            errors.append(_("The disk %s requires at least 1MB of free space at the beginning.") % req.disk.name)
+
+        return errors
+
+class IA64(EFI):
+    _packages = ["elilo"]
+
+    def __init__(self, anaconda):
+        EFI.__init__(self, anaconda)
+
+class PPC(Platform):
+    _bootFSTypes = ["ext4", "ext3", "ext2"]
+    _packages = ["yaboot"]
+    _ppcMachine = iutil.getPPCMachine()
+    _supportsMdRaidBoot = True
+
+    @property
+    def ppcMachine(self):
+        return self._ppcMachine
+
+class IPSeriesPPC(PPC):
+    _minBootPartSize = 4
+    _maxBootPartSize = 10
+
+    def bootDevice(self):
+        bootDev = None
+
+        # We want the first PReP partition.
+        for device in self.anaconda.storage.partitions:
+            if device.format.type == "prepboot":
+                bootDev = device
+                break
+
+        return bootDev
+
+    def bootloaderChoices(self, bl):
+        ret = {}
+
+        bootDev = self.bootDevice()
+        if not bootDev:
+            return ret
+
+        if bootDev.type == "mdarray":
+            ret["boot"] = (bootDev.name, N_("RAID Device"))
+            ret["mbr"] = (bl.drivelist[0], N_("Master Boot Record (MBR)"))
+        else:
+            ret["boot"] = (bootDev.name, N_("PPC PReP Boot"))
+
+        return ret
+
+    def checkBootRequest(self, req):
+        errors = PPC.checkBootRequest(self, req)
+
+        bootPart = getattr(req, "partedPartition", None)
+        if not bootPart:
+            return errors
+
+        # All of the above just checks the PPC PReP boot partitions.  We still
+        # need to make sure that whatever /boot is on also meets these criteria.
+        if req == self.bootDevice():
+            # However, this check only applies to prepboot.
+            if bootPart.geometry.end * bootPart.geometry.device.sectorSize / (1024.0 * 1024) > 4096:
+                errors.append(_("The boot partition must be within the first 4MB of the disk."))
+
+            try:
+                req = self.anaconda.storage.mountpoints["/boot"]
+            except KeyError:
+                req = self.anaconda.storage.rootDevice
+
+            return errors + self.checkBootRequest(req)
+        else:
+            return errors
+
+    def setDefaultPartitioning(self):
+        ret = PPC.setDefaultPartitioning(self)
+        ret.append(PartSpec(fstype="PPC PReP Boot", size=4,
+                            weight=self.weight(fstype="prepboot")))
+        return ret
+
+    def weight(self, fstype=None, mountpoint=None):
+        if fstype and fstype == "prepboot":
+            return 5000
+        elif mountpoint and mountpoint == "/boot":
+            return 2000
+        else:
+            return 0
+
+class NewWorldPPC(PPC):
+    _diskLabelType = "mac"
+    _minBootPartSize = (800.00 / 1024.00)
+    _maxBootPartSize = 1
+
+    def bootDevice(self):
+        bootDev = None
+
+        for part in self.anaconda.storage.partitions:
+            if part.format.type == "appleboot" and self.validBootPartSize(part.size):
+                bootDev = part
+                # if we're only picking one, it might as well be the first
+                break
+
+        return bootDev
+
+    def bootloaderChoices(self, bl):
+        ret = {}
+
+        bootDev = self.bootDevice()
+        if not bootDev:
+            return ret
+
+        if bootDev.type == "mdarray":
+            ret["boot"] = (bootDev.name, N_("RAID Device"))
+            ret["mbr"] = (bl.drivelist[0], N_("Master Boot Record (MBR)"))
+        else:
+            ret["boot"] = (bootDev.name, N_("Apple Bootstrap"))
+            for (n, device) in enumerate(self.anaconda.storage.partitions):
+                if device.format.type == "appleboot" and device.path != bootDev.path:
+                    ret["boot%d" % n] = (device.path, N_("Apple Bootstrap"))
+
+        return ret
+
+    def checkBootRequest(self, req):
+        errors = PPC.checkBootRequest(self, req)
+
+        if not req or req.type != "partition" or not req.disk:
+            return errors
+
+        disk = req.disk.format.partedDisk
+
+        # Check that we're a Mac disk label
+        if not disk.type == self._diskLabelType:
+            errors.append(_("%s must have a mac disk label.") % req.disk.name)
+
+        # All of the above just checks the appleboot partitions.  We still
+        # need to make sure that whatever /boot is on also meets these criteria.
+        if req == self.bootDevice():
+            try:
+                req = self.anaconda.storage.mountpoints["/boot"]
+            except KeyError:
+                req = self.anaconda.storage.rootDevice
+
+            return errors + self.checkBootRequest(req)
+        else:
+            return errors
+
+    def setDefaultPartitioning(self):
+        ret = Platform.setDefaultPartitioning(self)
+        ret.append(PartSpec(fstype="Apple Bootstrap", size=1, maxSize=1,
+                            weight=self.weight(fstype="appleboot")))
+        return ret
+
+    def weight(self, fstype=None, mountpoint=None):
+        if fstype and fstype == "appleboot":
+            return 5000
+        elif mountpoint and mountpoint == "/boot":
+            return 2000
+        else:
+            return 0
+
+class PS3(PPC):
+    _diskLabelType = "msdos"
+
+    def __init__(self, anaconda):
+        PPC.__init__(self, anaconda)
+
+class S390(Platform):
+    _packages = ["s390utils"]
+
+    def __init__(self, anaconda):
+        Platform.__init__(self, anaconda)
+
+    def diskLabelType(self, deviceType):
+        """Return the disk label type as a string."""
+        if deviceType == parted.DEVICE_DASD:
+            return "dasd"
+        else:
+            return Platform.diskLabelType(self, deviceType)
+
+class Sparc(Platform):
+    _diskLabelType = "sun"
+    _packages = ["silo"]
+
+    @property
+    def minimumSector(self, disk):
+        (cylinders, heads, sectors) = disk.device.biosGeometry
+        start = long(sectors * heads)
+        start /= long(1024 / disk.device.sectorSize)
+        return start+1
+
+class X86(EFI):
+    _bootFSTypes = ["ext4", "ext3", "ext2"]
+    _packages = ["grub"]
+    _supportsMdRaidBoot = True
+
+    def __init__(self, anaconda):
+        EFI.__init__(self, anaconda)
+
+        if self.isEfi:
+            self._diskLabelType = "gpt"
+        else:
+            self._diskLabelType = "msdos"
+
+    def bootDevice(self):
+        if self.isEfi:
+            return EFI.bootDevice(self)
+        else:
+            return Platform.bootDevice(self)
+
+    def bootloaderChoices(self, bl):
+        if self.isEfi:
+            return EFI.bootloaderChoices(self, bl)
+
+        bootDev = self.bootDevice()
+        ret = {}
+
+        if not bootDev:
+            return {}
+
+        if bootDev.type == "mdarray":
+            ret["boot"] = (bootDev.name, N_("RAID Device"))
+            ret["mbr"] = (bl.drivelist[0], N_("Master Boot Record (MBR)"))
+        else:
+            ret["boot"] = (bootDev.name, N_("First sector of boot partition"))
+            ret["mbr"] = (bl.drivelist[0], N_("Master Boot Record (MBR)"))
+
+        return ret
+
+    @property
+    def maxBootPartSize(self):
+        if self.isEfi:
+            return EFI._maxBootPartSize
+        else:
+            return Platform._maxBootPartSize
+
+    @property
+    def minBootPartSize(self):
+        if self.isEfi:
+            return EFI._minBootPartSize
+        else:
+            return Platform._minBootPartSize
+
+    def setDefaultPartitioning(self):
+        if self.isEfi:
+            return EFI.setDefaultPartitioning(self)
+        else:
+            return Platform.setDefaultPartitioning(self)
+
+def getPlatform(anaconda):
+    """Check the architecture of the system and return an instance of a
+       Platform subclass to match.  If the architecture could not be determined,
+       raise an exception."""
+    if iutil.isAlpha():
+        return Alpha(anaconda)
+    elif iutil.isIA64():
+        return IA64(anaconda)
+    elif iutil.isPPC():
+        ppcMachine = iutil.getPPCMachine()
+
+        if (ppcMachine == "PMac" and iutil.getPPCMacGen() == "NewWorld"):
+            return NewWorldPPC(anaconda)
+        elif ppcMachine in ["iSeries", "pSeries"]:
+            return IPSeriesPPC(anaconda)
+        elif ppcMachine == "PS3":
+            return PS3(anaconda)
+        else:
+            raise SystemError, "Unsupported PPC machine type"
+    elif iutil.isS390():
+        return S390(anaconda)
+    elif iutil.isSparc():
+        return Sparc(anaconda)
+    elif iutil.isX86():
+        return X86(anaconda)
+    else:
+        raise SystemError, "Could not determine system architecture."
diff --git a/pyanaconda/product.py b/pyanaconda/product.py
new file mode 100644
index 0000000..68df00c
--- /dev/null
+++ b/pyanaconda/product.py
@@ -0,0 +1,63 @@
+#
+# product.py: product identification string
+#
+# Copyright (C) 2003  Red Hat, Inc.  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 as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# 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, see <http://www.gnu.org/licenses/>.
+#
+
+import os
+
+if os.access("/tmp/product/.buildstamp", os.R_OK):
+    path = "/tmp/product/.buildstamp"
+elif os.access("/.buildstamp", os.R_OK):
+    path = "/.buildstamp"
+elif os.environ.has_key("PRODBUILDPATH") and \
+         os.access(os.environ["PRODBUILDPATH"], os.R_OK):
+    path = os.environ["PRODBUILDPATH"]
+else:
+    path = None
+
+productStamp = ""
+productName = "anaconda"
+productVersion = "bluesky"
+productPath = "Packages"
+productArch = None
+bugUrl = "your distribution provided bug reporting tool."
+
+if path is not None:
+    f = open(path, "r")
+    lines = f.readlines()
+    del f
+    if len(lines) >= 3:
+        productStamp = lines[0][:-1]
+        productArch = productStamp[productStamp.index(".")+1:]
+        productName = lines[1][:-1]
+        productVersion = lines[2][:-1]
+    if len(lines) >= 4:
+        bugUrl = lines[3][:-1]
+
+if os.environ.has_key("ANACONDA_PRODUCTNAME"):
+    productName = os.environ["ANACONDA_PRODUCTNAME"]
+if os.environ.has_key("ANACONDA_PRODUCTVERSION"):
+    productVersion = os.environ["ANACONDA_PRODUCTVERSION"]
+if os.environ.has_key("ANACONDA_PRODUCTPATH"):
+    productPath = os.environ["ANACONDA_PRODUCTPATH"]
+if os.environ.has_key("ANACONDA_PRODUCTARCH"):
+    productArch = os.environ["ANACONDA_PRODUCTARCH"]
+if os.environ.has_key("ANACONDA_BUGURL"):
+    bugUrl = os.environ["ANACONDA_BUGURL"]
+
+if productVersion == "development": # hack to transform for now
+    productVersion = "rawhide"
diff --git a/pyanaconda/pyudev.py b/pyanaconda/pyudev.py
new file mode 100644
index 0000000..e51ee33
--- /dev/null
+++ b/pyanaconda/pyudev.py
@@ -0,0 +1,225 @@
+from __future__ import print_function
+
+import sys
+import os
+import fnmatch
+from ctypes import *
+
+
+# XXX this one may need some tweaking...
+def find_library(name, somajor=0):
+    env = os.environ.get("LD_LIBRARY_PATH")
+    common = ["/lib64", "/lib"]
+
+    if env:
+        libdirs = env.split(":") + common
+    else:
+        libdirs = common
+
+    libdirs = filter(os.path.isdir, libdirs)
+
+    for dir in libdirs:
+        files = fnmatch.filter(os.listdir(dir), "lib%s.so.%d" % (name, somajor))
+        files = [os.path.join(dir, file) for file in files]
+
+        if files:
+            break
+
+    if files:
+        return files[0]
+    else:
+        return None
+
+# find the udev library
+libudev = find_library(name="udev", somajor=0)
+
+if not libudev or not os.path.exists(libudev):
+    raise ImportError, "No library named %s" % libudev
+
+# load the udev library
+libudev = CDLL(libudev)
+
+
+# create aliases for needed functions and set the return types where needed
+libudev_udev_new = libudev.udev_new
+libudev_udev_new.argtypes = []
+libudev_udev_new.restype = c_void_p
+libudev_udev_unref = libudev.udev_unref
+libudev_udev_unref.argtypes = [ c_void_p ]
+
+libudev_udev_device_new_from_syspath = libudev.udev_device_new_from_syspath
+libudev_udev_device_new_from_syspath.restype = c_void_p
+libudev_udev_device_new_from_syspath.argtypes = [ c_void_p, c_char_p ]
+libudev_udev_device_unref = libudev.udev_device_unref
+libudev_udev_device_unref.argtypes = [ c_void_p ]
+
+libudev_udev_device_get_syspath = libudev.udev_device_get_syspath
+libudev_udev_device_get_syspath.restype = c_char_p
+libudev_udev_device_get_syspath.argtypes = [ c_void_p ]
+libudev_udev_device_get_sysname = libudev.udev_device_get_sysname
+libudev_udev_device_get_sysname.restype = c_char_p
+libudev_udev_device_get_sysname.argtypes = [ c_void_p ]
+libudev_udev_device_get_devpath = libudev.udev_device_get_devpath
+libudev_udev_device_get_devpath.restype = c_char_p
+libudev_udev_device_get_devpath.argtypes = [ c_void_p ]
+libudev_udev_device_get_devtype = libudev.udev_device_get_devtype
+libudev_udev_device_get_devtype.restype = c_char_p
+libudev_udev_device_get_devtype.argtypes = [ c_void_p ]
+libudev_udev_device_get_devnode = libudev.udev_device_get_devnode
+libudev_udev_device_get_devnode.restype = c_char_p
+libudev_udev_device_get_devnode.argtypes = [ c_void_p ]
+libudev_udev_device_get_subsystem = libudev.udev_device_get_subsystem
+libudev_udev_device_get_subsystem.restype = c_char_p
+libudev_udev_device_get_subsystem.argtypes = [ c_void_p ]
+libudev_udev_device_get_sysnum = libudev.udev_device_get_sysnum
+libudev_udev_device_get_sysnum.restype = c_char_p
+libudev_udev_device_get_sysnum.argtypes = [ c_void_p ]
+
+libudev_udev_device_get_properties_list_entry = libudev.udev_device_get_properties_list_entry
+libudev_udev_device_get_properties_list_entry.restype = c_void_p
+libudev_udev_device_get_properties_list_entry.argtypes = [ c_void_p ]
+libudev_udev_list_entry_get_next = libudev.udev_list_entry_get_next
+libudev_udev_list_entry_get_next.restype = c_void_p
+libudev_udev_list_entry_get_next.argtypes = [ c_void_p ]
+
+libudev_udev_list_entry_get_name = libudev.udev_list_entry_get_name
+libudev_udev_list_entry_get_name.restype = c_char_p
+libudev_udev_list_entry_get_name.argtypes = [ c_void_p ]
+libudev_udev_list_entry_get_value = libudev.udev_list_entry_get_value
+libudev_udev_list_entry_get_value.restype = c_char_p
+libudev_udev_list_entry_get_value.argtypes = [ c_void_p ]
+
+libudev_udev_enumerate_new = libudev.udev_enumerate_new
+libudev_udev_enumerate_new.restype = c_void_p
+libudev_udev_enumerate_new.argtypes = [ c_void_p ]
+libudev_udev_enumerate_unref = libudev.udev_enumerate_unref
+libudev_udev_enumerate_unref.argtypes = [ c_void_p ]
+
+libudev_udev_enumerate_add_match_subsystem = libudev.udev_enumerate_add_match_subsystem
+libudev_udev_enumerate_add_match_subsystem.restype = c_int
+libudev_udev_enumerate_add_match_subsystem.argtypes = [ c_void_p, c_char_p ]
+libudev_udev_enumerate_scan_devices = libudev.udev_enumerate_scan_devices
+libudev_udev_enumerate_scan_devices.restype = c_int
+libudev_udev_enumerate_scan_devices.argtypes = [ c_void_p ]
+libudev_udev_enumerate_get_list_entry = libudev.udev_enumerate_get_list_entry
+libudev_udev_enumerate_get_list_entry.restype = c_void_p
+libudev_udev_enumerate_get_list_entry.argtypes = [ c_void_p ]
+
+libudev_udev_device_get_devlinks_list_entry = libudev.udev_device_get_devlinks_list_entry
+libudev_udev_device_get_devlinks_list_entry.restype = c_void_p
+libudev_udev_device_get_devlinks_list_entry.argtypes = [ c_void_p ]
+
+
+class UdevDevice(dict):
+
+    def __init__(self, udev, sysfs_path):
+        dict.__init__(self)
+
+        # create new udev device from syspath
+        udev_device = libudev_udev_device_new_from_syspath(udev, sysfs_path)
+        if not udev_device:
+            # device does not exist
+            return
+
+        # set syspath and sysname properties
+        self.syspath = libudev_udev_device_get_syspath(udev_device)
+        self.sysname = libudev_udev_device_get_sysname(udev_device)
+
+        # get the devlinks list
+        devlinks = []
+        devlinks_entry = libudev_udev_device_get_devlinks_list_entry(udev_device)
+
+        while devlinks_entry:
+            path = libudev_udev_list_entry_get_name(devlinks_entry)
+            devlinks.append(path)
+
+            devlinks_entry = libudev_udev_list_entry_get_next(devlinks_entry)
+
+        # add devlinks list to the dictionary
+        self["symlinks"] = devlinks
+
+        # get the first property entry
+        property_entry = libudev_udev_device_get_properties_list_entry(udev_device)
+
+        while property_entry:
+            name = libudev_udev_list_entry_get_name(property_entry)
+            value = libudev_udev_list_entry_get_value(property_entry)
+
+            # XXX some of the strings contain a list of values in them,
+            # we want to split them and make a list
+            if value.count(" %s=" % name):
+                value = value.split(" %s=" % name)
+
+            self[name] = value
+
+            # get next property entry
+            property_entry = libudev_udev_list_entry_get_next(property_entry)
+
+        # set additional properties
+        self.devpath = libudev_udev_device_get_devpath(udev_device)
+        self.subsystem = libudev_udev_device_get_subsystem(udev_device)
+        self.devtype = libudev_udev_device_get_devtype(udev_device)
+        self.sysnum = libudev_udev_device_get_sysnum(udev_device)
+        self.devnode = libudev_udev_device_get_devnode(udev_device)
+
+        # cleanup
+        libudev_udev_device_unref(udev_device)
+
+
+class Udev(object):
+
+    def __init__(self):
+        self.udev = libudev_udev_new()
+
+    def create_device(self, sysfs_path):
+        return UdevDevice(self.udev, sysfs_path)
+
+    def enumerate_devices(self, subsystem=None):
+        enumerate = libudev_udev_enumerate_new(self.udev)
+
+        # add the match subsystem
+        if subsystem is not None:
+            rc = libudev_udev_enumerate_add_match_subsystem(enumerate, subsystem)
+            if not rc == 0:
+                print("error: unable to add the match subsystem", file=sys.stderr)
+                libudev_udev_enumerate_unref(enumerate)
+                return []
+
+        # scan the devices
+        rc = libudev_udev_enumerate_scan_devices(enumerate)
+        if not rc == 0:
+            print("error: unable to enumerate the devices", file=sys.stderr)
+            libudev_udev_enumerate_unref(enumerate)
+            return []
+
+        # create the list of sysfs paths
+        sysfs_paths = []
+
+        # get the first list entry
+        list_entry = libudev_udev_enumerate_get_list_entry(enumerate)
+
+        while list_entry:
+            sysfs_path = libudev_udev_list_entry_get_name(list_entry)
+            sysfs_paths.append(sysfs_path)
+
+            # get next list entry
+            list_entry = libudev_udev_list_entry_get_next(list_entry)
+
+        # cleanup
+        libudev_udev_enumerate_unref(enumerate)
+
+        return sysfs_paths
+
+    def scan_devices(self, sysfs_paths=None):
+        if sysfs_paths is None:
+            sysfs_paths = self.enumerate_devices()
+
+        for sysfs_path in sysfs_paths:
+            device = self.create_device(sysfs_path)
+
+            if device:
+                yield device
+
+    def unref(self):
+        libudev_udev_unref(self.udev)
+        self.udev = None
diff --git a/pyanaconda/rescue.py b/pyanaconda/rescue.py
new file mode 100644
index 0000000..92d5a09
--- /dev/null
+++ b/pyanaconda/rescue.py
@@ -0,0 +1,508 @@
+#
+# rescue.py - anaconda rescue mode setup
+#
+# Copyright (C) 2001, 2002, 2003, 2004  Red Hat, Inc.  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 as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# 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, see <http://www.gnu.org/licenses/>.
+#
+# Author(s): Mike Fulbright <msf@xxxxxxxxxx>
+#            Jeremy Katz <katzj@xxxxxxxxxx>
+#
+
+import upgrade
+from snack import *
+from constants import *
+from constants_text import *
+from text import WaitWindow, OkCancelWindow, ProgressWindow, PassphraseEntryWindow, stepToClasses
+from flags import flags
+import sys
+import os
+import isys
+from storage import mountExistingSystem
+from installinterfacebase import InstallInterfaceBase
+from add_drive_text import addDriveDialog
+import iutil
+import shutil
+import time
+import network
+import subprocess
+
+import gettext
+_ = lambda x: gettext.ldgettext("anaconda", x)
+
+import logging
+log = logging.getLogger("anaconda")
+
+class RescueInterface(InstallInterfaceBase):
+    def waitWindow(self, title, text):
+        return WaitWindow(self.screen, title, text)
+
+    def progressWindow(self, title, text, total):
+        return ProgressWindow(self.screen, title, text, total)
+
+    def detailedMessageWindow(self, title, text, longText=None, type="ok",
+                              default=None, custom_icon=None,
+                              custom_buttons=[], expanded=False):
+        return self.messageWindow(title, text, type, default, custom_icon,
+                                  custom_buttons)
+
+    def messageWindow(self, title, text, type = "ok", default = None,
+                      custom_icon=None, custom_buttons=[]):
+	if type == "ok":
+	    ButtonChoiceWindow(self.screen, title, text,
+			       buttons=[TEXT_OK_BUTTON])
+        elif type == "yesno":
+            if default and default == "no":
+                btnlist = [TEXT_NO_BUTTON, TEXT_YES_BUTTON]
+            else:
+                btnlist = [TEXT_YES_BUTTON, TEXT_NO_BUTTON]
+	    rc = ButtonChoiceWindow(self.screen, title, text,
+			       buttons=btnlist)
+            if rc == "yes":
+                return 1
+            else:
+                return 0
+	elif type == "custom":
+	    tmpbut = []
+	    for but in custom_buttons:
+		tmpbut.append(string.replace(but,"_",""))
+
+	    rc = ButtonChoiceWindow(self.screen, title, text, width=60,
+				    buttons=tmpbut)
+
+	    idx = 0
+	    for b in tmpbut:
+		if string.lower(b) == rc:
+		    return idx
+		idx = idx + 1
+	    return 0
+	else:
+	    return OkCancelWindow(self.screen, title, text)
+
+    def enableNetwork(self, anaconda):
+        if len(anaconda.network.netdevices) == 0:
+            return False
+        from netconfig_text import NetworkConfiguratorText
+        w = NetworkConfiguratorText(self.screen, anaconda)
+        ret = w.run()
+        return ret != INSTALL_BACK
+
+    def passphraseEntryWindow(self, device):
+        w = PassphraseEntryWindow(self.screen, device)
+        (passphrase, isglobal) = w.run()
+        w.pop()
+        return (passphrase, isglobal)
+
+    def resetInitializeDiskQuestion(self):
+        self._initLabelAnswers = {}
+
+    def resetReinitInconsistentLVMQuestion(self):
+        self._inconsistentLVMAnswers = {}
+
+    def questionInitializeDisk(self, path, description, size, details=""):
+        # Never initialize disks in rescue mode!
+        return False
+
+    def questionReinitInconsistentLVM(self, pv_names=None, lv_name=None, vg_name=None):
+        # Never reinit VG's in rescue mode!
+        return False
+
+    def questionInitializeDASD(self, c, devs):
+        # Special return value to let dasd.py know we're rescue mode
+        return 1
+
+    def shutdown (self):
+        pass
+
+    def suspend(self):
+        pass
+
+    def resume(self):
+        pass
+
+    def __init__(self, screen):
+        InstallInterfaceBase.__init__(self)
+        self.screen = screen
+
+# XXX grub-install is stupid and uses df output to figure out
+# things when installing grub.  make /etc/mtab be at least
+# moderately useful.  
+def makeMtab(instPath, storage):
+    try:
+        f = open(instPath + "/etc/mtab", "w+")
+    except IOError, e:
+        log.info("failed to open /etc/mtab for write: %s" % e)
+        return
+
+    try:
+        f.write(storage.mtab)
+    finally:
+        f.close()
+
+def makeFStab(instPath = ""):
+    if os.access("/proc/mounts", os.R_OK):
+        f = open("/proc/mounts", "r")
+        buf = f.read()
+        f.close()
+    else:
+        buf = ""
+
+    try:
+        f = open(instPath + "/etc/fstab", "a")
+        if buf:
+            f.write(buf)
+        f.close()
+    except IOError, e:
+        log.info("failed to write /etc/fstab: %s" % e)
+
+# make sure they have a resolv.conf in the chroot
+def makeResolvConf(instPath):
+    if not os.access("/etc/resolv.conf", os.R_OK):
+        return
+
+    if os.access("%s/etc/resolv.conf" %(instPath,), os.R_OK):
+        f = open("%s/etc/resolv.conf" %(instPath,), "r")
+        buf = f.read()
+        f.close()
+    else:
+        buf = ""
+
+    # already have a nameserver line, don't worry about it
+    if buf.find("nameserver") != -1:
+        return
+
+    f = open("/etc/resolv.conf", "r")
+    buf = f.read()
+    f.close()
+
+    # no nameserver, we can't do much about it
+    if buf.find("nameserver") == -1:
+        return
+
+    shutil.copyfile("%s/etc/resolv.conf" %(instPath,),
+                    "%s/etc/resolv.conf.bak" %(instPath,))
+    f = open("%s/etc/resolv.conf" %(instPath,), "w+")
+    f.write(buf)
+    f.close()
+
+#
+# Write out something useful for networking and start interfaces
+#
+def startNetworking(network, intf):
+    # do lo first
+    try:
+        os.system("/usr/sbin/ifconfig lo 127.0.0.1")
+    except:
+        log.error("Error trying to start lo in rescue.py::startNetworking()")
+
+    # start up dhcp interfaces first
+    if not network.bringUp():
+        log.error("Error bringing up network interfaces")
+
+def runShell(screen = None, msg=""):
+    if screen:
+        screen.suspend()
+
+    print
+    if msg:
+        print (msg)
+    print(_("When finished please exit from the shell and your "
+            "system will reboot."))
+    print
+
+    proc = None
+
+    if os.path.exists("/usr/bin/firstaidkit-qs"):
+        proc = subprocess.Popen(["/usr/bin/firstaidkit-qs"])
+        proc.wait()
+    
+    if proc is None or proc.returncode!=0:
+        if os.path.exists("/bin/bash"):
+            iutil.execConsole()
+        else:
+            print(_("Unable to find /bin/sh to execute!  Not starting shell"))
+            time.sleep(5)
+
+    if screen:
+        screen.finish()
+
+def runRescue(anaconda):
+    for file in [ "services", "protocols", "group", "joe", "man.config",
+                  "nsswitch.conf", "selinux", "mke2fs.conf" ]:
+        try:
+            os.symlink('/mnt/runtime/etc/' + file, '/etc/' + file)
+        except:
+            pass
+
+    # see if they would like networking enabled
+    if not network.hasActiveNetDev():
+        screen = SnackScreen()
+
+        while True:
+            rc = ButtonChoiceWindow(screen, _("Setup Networking"),
+                _("Do you want to start the network interfaces on "
+                  "this system?"), [_("Yes"), _("No")])
+
+            if rc != string.lower(_("No")):
+                anaconda.intf = RescueInterface(screen)
+
+                if not anaconda.intf.enableNetwork(anaconda):
+                    anaconda.intf.messageWindow(_("No Network Available"),
+                        _("Unable to activate a networking device.  Networking "
+                          "will not be available in rescue mode."))
+                    break
+
+                startNetworking(anaconda.network, anaconda.intf)
+                break
+            else:
+                break
+
+        anaconda.intf = None
+        screen.finish()
+
+    # Early shell access with no disk access attempts
+    if not anaconda.rescue_mount:
+        # the %post should be responsible for mounting all needed file systems
+        # NOTE: 1st script must be bash or simple python as nothing else might be available in the rescue image
+        if anaconda.ksdata:
+           from kickstart import runPostScripts
+           runPostScripts(anaconda)
+        else:
+           runShell()
+
+        sys.exit(0)
+
+    screen = SnackScreen()
+    anaconda.intf = RescueInterface(screen)
+
+    if anaconda.ksdata:
+        if anaconda.ksdata.rescue and anaconda.ksdata.rescue.romount:
+            readOnly = 1
+        else:
+            readOnly = 0
+    else:
+        # prompt to see if we should try and find root filesystem and mount
+        # everything in /etc/fstab on that root
+        while True:
+            rc = ButtonChoiceWindow(screen, _("Rescue"),
+                _("The rescue environment will now attempt to find your "
+                  "Linux installation and mount it under the directory "
+                  "%s.  You can then make any changes required to your "
+                  "system.  If you want to proceed with this step choose "
+                  "'Continue'.  You can also choose to mount your file systems "
+                  "read-only instead of read-write by choosing 'Read-Only'.  "
+                  "If you need to activate SAN devices choose 'Advanced'."
+                  "\n\n"
+                  "If for some reason this process fails you can choose 'Skip' "
+                  "and this step will be skipped and you will go directly to a "
+                  "command shell.\n\n") % (anaconda.rootPath,),
+                  [_("Continue"), _("Read-Only"), _("Skip"), _("Advanced")] )
+
+            if rc == string.lower(_("Skip")):
+                runShell(screen)
+                sys.exit(0)
+            elif rc == string.lower(_("Advanced")):
+                addDialog = addDriveDialog(anaconda)
+                addDialog.addDriveDialog(screen)
+                continue
+            elif rc == string.lower(_("Read-Only")):
+                readOnly = 1
+            else:
+                readOnly = 0
+            break
+
+    import storage
+    storage.storageInitialize(anaconda)
+
+    disks = upgrade.findExistingRoots(anaconda, upgradeany=True)
+
+    if not disks:
+        root = None
+    elif (len(disks) == 1) or anaconda.ksdata:
+        root = disks[0]
+    else:
+        height = min (len (disks), 12)
+        if height == 12:
+            scroll = 1
+        else:
+            scroll = 0
+
+        devList = []
+        for (device, relstr) in disks:
+            if getattr(device.format, "label", None):
+                devList.append("%s (%s) - %s" % (device.name, device.format.label, relstr))
+            else:
+                devList.append("%s - %s" % (device.name, relstr))
+
+        (button, choice) = \
+            ListboxChoiceWindow(screen, _("System to Rescue"),
+                                _("Which device holds the root partition "
+                                  "of your installation?"), devList,
+                                [ _("OK"), _("Exit") ], width = 30,
+                                scroll = scroll, height = height,
+                                help = "multipleroot")
+
+        if button == string.lower (_("Exit")):
+            root = None
+        else:
+            root = disks[choice]
+
+    rootmounted = 0
+
+    if root:
+        try:
+            rc = mountExistingSystem(anaconda, root,
+                                     allowDirty = 1, warnDirty = 1,
+                                     readOnly = readOnly)
+
+            if rc == -1:
+                if anaconda.ksdata:
+                    log.error("System had dirty file systems which you chose not to mount")
+                else:
+                    ButtonChoiceWindow(screen, _("Rescue"),
+                        _("Your system had dirty file systems which you chose not "
+                          "to mount.  Press return to get a shell from which "
+                          "you can fsck and mount your partitions.  The system "
+                          "will reboot automatically when you exit from the "
+                          "shell."), [_("OK")], width = 50)
+                rootmounted = 0
+            else:
+                if anaconda.ksdata:
+                    log.info("System has been mounted under: %s" % anaconda.rootPath)
+                else:
+                    ButtonChoiceWindow(screen, _("Rescue"),
+                       _("Your system has been mounted under %(rootPath)s.\n\n"
+                         "Press <return> to get a shell. If you would like to "
+                         "make your system the root environment, run the command:\n\n"
+                         "\tchroot %(rootPath)s\n\nThe system will reboot "
+                         "automatically when you exit from the shell.") %
+                                       {'rootPath': anaconda.rootPath},
+                                       [_("OK")] )
+                rootmounted = 1
+
+                # now turn on swap
+                if not readOnly:
+                    try:
+                        anaconda.storage.turnOnSwap()
+                    except:
+                        log.error("Error enabling swap")
+
+                # and /selinux too
+                if flags.selinux and os.path.isdir("%s/selinux" %(anaconda.rootPath,)):
+                    try:
+                        isys.mount("/selinux", "%s/selinux" %(anaconda.rootPath,),
+                                   "selinuxfs")
+                    except Exception, e:
+                        log.error("error mounting selinuxfs: %s" %(e,))
+
+                    # we have to catch the possible exception
+                    # because we support read-only mounting
+                    try:
+                        fd = open("%s/.autorelabel" % anaconda.rootPath, "w+")
+                        fd.close()
+                    except Exception, e:
+                        log.warning("cannot touch /.autorelabel")
+
+                # set a library path to use mounted fs
+                libdirs = os.environ["LD_LIBRARY_PATH"].split(":")
+                mounted = map(lambda dir: "/mnt/sysimage%s" % dir, libdirs)
+                os.environ["LD_LIBRARY_PATH"] = ":".join(libdirs + mounted)
+
+                # find groff data dir
+                try:
+                    glst = os.listdir("/mnt/sysimage/usr/share/groff")
+
+                    # find a directory which is a numeral, its where
+                    # data files are
+                    gversion = None
+                    for gdir in glst:
+                        try:
+                            isone = 1
+                            for idx in range(0, len(gdir)):
+                                if string.find(string.digits + '.', gdir[idx]) == -1:
+                                    isone = 0
+                                    break
+                            if isone:
+                                gversion = gdir
+                                break
+                        except:
+                            gversion = None
+                            continue
+                except:
+                    gversion = None
+
+                if gversion is not None:
+                    gpath = "/mnt/sysimage/usr/share/groff/"+gversion
+                    os.environ["GROFF_FONT_PATH"] = gpath + '/font'
+                    os.environ["GROFF_TMAC_PATH"] = "%s:/mnt/sysimage/usr/share/groff/site-tmac" % (gpath + '/tmac',)
+
+                # do we have bash?
+                try:
+                    if os.access("/usr/bin/bash", os.R_OK):
+                        os.symlink ("/usr/bin/bash", "/bin/bash")
+                except:
+                    pass
+        except:
+            # This looks horrible, but all it does is catch every exception,
+            # and reraise those in the tuple check. This lets programming
+            # errors raise exceptions, while any runtime error will
+            # still result in a shell
+            (exc, val) = sys.exc_info()[0:2]
+            log.error(str(exc)+": "+str(val))
+            if exc in (IndexError, ValueError, SyntaxError):
+                raise exc, val, sys.exc_info()[2]
+
+            if anaconda.ksdata:
+                log.error("An error occurred trying to mount some or all of your system")
+            else:
+                ButtonChoiceWindow(screen, _("Rescue"),
+                    _("An error occurred trying to mount some or all of your "
+                      "system. Some of it may be mounted under %s.\n\n"
+                      "Press <return> to get a shell. The system will reboot "
+                      "automatically when you exit from the shell.") % (anaconda.rootPath,),
+                      [_("OK")] )
+    else:
+        if anaconda.ksdata:
+            log.info("No Linux partitions found")
+            screen.finish()
+            print(_("You don't have any Linux partitions.  Rebooting.\n"))
+            sys.exit(0)
+        else:
+            ButtonChoiceWindow(screen, _("Rescue Mode"),
+                               _("You don't have any Linux partitions. Press "
+                                 "return to get a shell. The system will reboot "
+                                 "automatically when you exit from the shell."),
+                               [ _("OK") ], width = 50)
+
+    msgStr = ""
+
+    if rootmounted and not readOnly:
+        makeMtab(anaconda.rootPath, anaconda.storage)
+        try:
+            makeResolvConf(anaconda.rootPath)
+        except Exception, e:
+            log.error("error making a resolv.conf: %s" %(e,))
+        msgStr = _("Your system is mounted under the %s directory.") % (anaconda.rootPath,)
+
+    #create /etc/fstab in ramdisk, so it is easier to work with RO mounted filesystems
+    makeFStab()
+
+    # run %post if we've mounted everything
+    if anaconda.ksdata:
+        from kickstart import runPostScripts
+        runPostScripts(anaconda)
+    else:
+        runShell(screen, msgStr)
+
+    sys.exit(0)
diff --git a/pyanaconda/run_test.py b/pyanaconda/run_test.py
new file mode 100755
index 0000000..2a7ad2d
--- /dev/null
+++ b/pyanaconda/run_test.py
@@ -0,0 +1,109 @@
+#!/usr/bin/python
+#-*- coding:utf-8 -*-
+
+from distutils.sysconfig import get_python_lib
+import sys
+
+REQUIRED_PATHS = ["%s/pyanaconda" % get_python_lib(plat_specific=1),
+                  "/usr/share/system-config-date"]
+sys.path.extend(REQUIRED_PATHS)
+
+import unittest
+import tests
+import string
+from optparse import OptionParser
+
+
+def getFullTestName(test, full_test_names):
+    tests = []
+    for full_test_name in full_test_names:
+        if full_test_name.lower().find(test) != -1:
+            tests.append(full_test_name)
+
+    return tests
+
+
+if __name__ == "__main__":
+    usage = "usage: %prog [options] [test1 test2 ...]"
+    parser = OptionParser(usage)
+    parser.add_option("-l", "--list", action="store_true", default=False,
+                      help="print all available tests and exit")
+
+    (options, args) = parser.parse_args(sys.argv[1:])
+
+    print "Searching for test suites"
+    available_suites = tests.getAvailableSuites()
+    test_keys = available_suites.keys()
+    if not test_keys:
+        print "No test suites available, exiting"
+        sys.exit(1)
+
+    test_keys.sort()
+
+    if options.list:
+        print "\nAvailable tests:"
+        for test_name in test_keys:
+            print test_name
+        sys.exit(0)
+
+    tests_to_run = []
+
+    if len(args) == 0:
+        # interactive mode
+        print "Running in interactive mode"
+        print "\nAvailable tests:"
+        test_num = 0
+        for test_name in test_keys:
+            print "[%3d] %s" % (test_num, test_name)
+            test_num += 1
+        print
+
+        try:
+            input_string = raw_input("Type in the test you want to run, "
+                                     "or \"all\" to run all listed tests: ")
+        except KeyboardInterrupt as e:
+            print "\nAborted by user"
+            sys.exit(1)
+
+        for arg in input_string.split():
+            if arg.isdigit():
+                arg = int(arg)
+                try:
+                    args.append(test_keys[arg])
+                except KeyError as e:
+                    pass
+            else:
+                args.append(arg)
+
+    args = map(string.lower, args)
+    if "all" in args:
+        tests_to_run = test_keys[:]
+    else:
+        for arg in args:
+            matching_tests = getFullTestName(arg, test_keys)
+            tests_to_run.extend(filter(lambda test: test not in tests_to_run,
+                                       matching_tests))
+
+    # run the tests
+    if tests_to_run:
+        tests_to_run.sort()
+        print "Running tests: %s" % tests_to_run
+        test_suite = unittest.TestSuite([available_suites[test]
+                                         for test in tests_to_run])
+
+        try:
+            result = unittest.TextTestRunner(verbosity=2).run(test_suite)
+        except KeyboardInterrupt as e:
+            print "\nAborted by user"
+            sys.exit(1)
+
+        if result.wasSuccessful():
+            print "\nAll tests OK"
+            sys.exit(0)
+        else:
+            print "\nTests finished with %d errors and %d failures" % (len(result.errors),
+                                                                       len(result.failures))
+            sys.exit(2)
+    else:
+        print "No test suites matching your criteria found, exiting"
+        sys.exit(1)
diff --git a/pyanaconda/security.py b/pyanaconda/security.py
new file mode 100644
index 0000000..219d465
--- /dev/null
+++ b/pyanaconda/security.py
@@ -0,0 +1,87 @@
+#
+# security.py - security install data and installation
+#
+# Copyright (C) 2004  Red Hat, Inc.  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 as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# 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, see <http://www.gnu.org/licenses/>.
+#
+# Author(s): Jeremy Katz <katzj@xxxxxxxxxx>
+#
+
+import iutil, shlex
+from flags import flags
+from pykickstart.constants import *
+
+import logging
+log = logging.getLogger("anaconda")
+
+selinux_states = { SELINUX_DISABLED: "disabled",
+                   SELINUX_ENFORCING: "enforcing",
+                   SELINUX_PERMISSIVE: "permissive" }
+
+class Security:
+    def __init__(self):
+        self.auth = "--enableshadow --passalgo=sha512 --enablefingerprint"
+
+        if flags.selinux == 1:
+            self.selinux = SELINUX_ENFORCING
+        else:
+            self.selinux = SELINUX_DISABLED
+
+    def setSELinux(self, val):
+        if not selinux_states.has_key(val):
+            log.error("Tried to set to invalid SELinux state: %s" %(val,))
+            val = SELINUX_DISABLED
+
+        self.selinux = val
+
+    def getSELinux(self):
+        return self.selinux
+
+    def writeKS(self, f):
+        if not selinux_states.has_key(self.selinux):
+            log.error("unknown selinux state: %s" %(self.selinux,))
+            return
+
+	f.write("selinux --%s\n" %(selinux_states[self.selinux],))
+
+        if self.auth.strip() != "":
+            f.write("authconfig %s\n" % self.auth)
+
+    def write(self, instPath):
+        args = []
+
+        if not selinux_states.has_key(self.selinux):
+            log.error("unknown selinux state: %s" %(self.selinux,))
+            return
+
+        args = args + [ "--selinux=%s" %(selinux_states[self.selinux],) ]
+
+        try:
+            iutil.execWithRedirect("/usr/sbin/lokkit", args,
+                                   root = instPath, stdout = "/dev/null",
+                                   stderr = "/dev/null")
+        except RuntimeError, msg:
+            log.error ("lokkit run failed: %s" %(msg,))
+        except OSError as e:
+            log.error ("lokkit run failed: %s" % e.strerror)
+
+        args = ["--update", "--nostart"] + shlex.split(self.auth)
+
+        try:
+            iutil.execWithRedirect("/usr/sbin/authconfig", args,
+                                   stdout = "/dev/tty5", stderr = "/dev/tty5",
+                                   root = instPath)
+        except RuntimeError, msg:
+                log.error("Error running %s: %s", args, msg)
diff --git a/pyanaconda/simpleconfig.py b/pyanaconda/simpleconfig.py
new file mode 100644
index 0000000..b3e6c90
--- /dev/null
+++ b/pyanaconda/simpleconfig.py
@@ -0,0 +1,88 @@
+#
+# simpleconifg.py - representation of a simple configuration file (sh-like)
+#
+# Matt Wilson <msw@xxxxxxxxxx>
+# Jeremy Katz <katzj@xxxxxxxxxx>
+#
+# Copyright 1999-2002 Red Hat, Inc.
+#
+# This software may be freely redistributed under the terms of the GNU
+# library public license.
+#
+# You should have received a copy of the GNU Library Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+
+import string
+import os
+
+# use our own ASCII only uppercase function to avoid locale issues
+# not going to be fast but not important
+def uppercase_ASCII_string(str):
+    newstr = ""
+    for i in range(0,len(str)):
+	if str[i] in string.lowercase:
+	    newstr += chr(ord(str[i])-32)
+	else:
+	    newstr += str[i]
+
+    return newstr
+
+class SimpleConfigFile:
+    def __str__ (self):
+        s = ""
+        keys = self.info.keys ()
+        keys.sort ()
+        for key in keys:
+            # FIXME - use proper escaping
+            if type (self.info[key]) == type(""):
+                s = s + key + "=\"" + self.info[key] + "\"\n"
+        return s
+
+    def __init__ (self):
+        self.info = {}
+
+    def write(self, file):
+        f = open(file, "w")
+        f.write(self.__str__())
+        f.close()
+
+    def read(self, file):
+        if not os.access(file, os.R_OK):
+            return
+
+        f = open(file, "r")
+        lines = f.readlines()
+        f.close()
+
+        for line in lines:
+            fields = line[:-1].split('=', 2)
+            if len(fields) < 2:
+                # how am I supposed to know what to do here?
+                continue
+            key = uppercase_ASCII_string(fields[0])
+            value = fields[1]
+            # XXX hack
+            value = value.replace('"', '')
+            value = value.replace("'", '')
+            self.info[key] = value
+
+    def set (self, *args):
+        for (key, data) in args:
+            self.info[uppercase_ASCII_string(key)] = data
+
+    def unset (self, *keys):
+        for key in keys:
+            key = uppercase_ASCII_string(key)
+            if self.info.has_key (key):
+               del self.info[key]
+
+    def get (self, key):
+        key = uppercase_ASCII_string(key)
+        if self.info.has_key (key):
+            return self.info[key]
+        else:
+            return ""
+
+
diff --git a/pyanaconda/sitecustomize.py b/pyanaconda/sitecustomize.py
new file mode 100644
index 0000000..8246ed0
--- /dev/null
+++ b/pyanaconda/sitecustomize.py
@@ -0,0 +1,22 @@
+#
+# sitecustomize.py: The python site init code for the Red Hat Installer
+#
+# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007
+# Red Hat, Inc.  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 as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# 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, see <http://www.gnu.org/licenses/>.
+#
+
+import sys
+sys.setdefaultencoding('utf-8')
diff --git a/pyanaconda/sortedtransaction.py b/pyanaconda/sortedtransaction.py
new file mode 100644
index 0000000..d7384bb
--- /dev/null
+++ b/pyanaconda/sortedtransaction.py
@@ -0,0 +1,87 @@
+#
+# sortedtransaction.py
+#
+# Copyright (C) 2007  Red Hat, Inc.  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 as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# 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, see <http://www.gnu.org/licenses/>.
+#
+
+from yum.transactioninfo import TransactionData, TransactionMember, SortableTransactionData
+from yum.constants import *
+from yum.Errors import YumBaseError
+
+import urlparse
+urlparse.uses_fragment.append('media')
+
+import logging
+log = logging.getLogger("anaconda")
+
+
+class SplitMediaTransactionData(SortableTransactionData):
+    def __init__(self):
+        SortableTransactionData.__init__(self)
+        self.reqmedia = {}
+        self.curmedia = 0 
+
+    def __getMedia(self, po):
+        try:
+            uri = po.returnSimple('basepath')
+            (scheme, netloc, path, query, fragid) = urlparse.urlsplit(uri)
+            if scheme != "media" or not fragid:
+                return -99
+            else:
+                return int(fragid)
+        except (KeyError, AttributeError):
+            return -99
+
+    def getMembers(self, pkgtup=None):
+        if not self.curmedia:
+            return TransactionData.getMembers(self, pkgtup)
+        if pkgtup is None:
+            returnlist = []
+            for ele in self.reqmedia[self.curmedia]:
+                returnlist.extend(self.pkgdict[ele])
+
+            return returnlist
+
+        if pkgtup in self.reqmedia[self.curmedia]:
+            return self.pkgdict[pkgtup]
+        else:
+            return []
+
+    def add(self, txmember):
+        if txmember.output_state in TS_INSTALL_STATES:
+            id = self.__getMedia(txmember.po)
+            if id:
+                if id not in self.reqmedia.keys():
+                    self.reqmedia[id] = [ txmember.pkgtup ]
+                elif txmember.pkgtup not in self.reqmedia[id]:
+                    self.reqmedia[id].append(txmember.pkgtup)
+        SortableTransactionData.add(self, txmember)
+
+    def remove(self, pkgtup):
+        if not self.pkgdict.has_key(pkgtup):
+            return
+        txmembers = self.pkgdict[pkgtup]
+        if len(txmembers) > 0:
+            for txmbr in txmembers:
+                if txmbr.output_state not in TS_INSTALL_STATES:
+                    continue
+                id = self.__getMedia(txmbr.po)
+                if id:
+                    self.reqmedia[id].remove(pkgtup)
+                    if len(self.reqmedia[id]) == 0:
+                        self.reqmedia.pop(id)
+                del txmbr
+                SortableTransactionData.remove(self, pkgtup)
diff --git a/pyanaconda/storage/Makefile.am b/pyanaconda/storage/Makefile.am
new file mode 100644
index 0000000..7347694
--- /dev/null
+++ b/pyanaconda/storage/Makefile.am
@@ -0,0 +1,26 @@
+# storage/Makefile.am for anaconda
+#
+# Copyright (C) 2009  Red Hat, Inc.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License as published
+# by the Free Software Foundation; either version 2.1 of the License, or
+# (at your option) any later version.
+#
+# 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 Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+#
+# Author: David Cantrell <dcantrell@xxxxxxxxxx>
+
+pkgpyexecdir = $(pyexecdir)/py$(PACKAGE_NAME)
+storagedir = $(pkgpyexecdir)/storage
+storage_PYTHON = *.py
+
+SUBDIRS = devicelibs formats
+
+MAINTAINERCLEANFILES = Makefile.in
diff --git a/pyanaconda/storage/__init__.py b/pyanaconda/storage/__init__.py
new file mode 100644
index 0000000..a5366b0
--- /dev/null
+++ b/pyanaconda/storage/__init__.py
@@ -0,0 +1,2252 @@
+# __init__.py
+# Entry point for anaconda's storage configuration module.
+#
+# Copyright (C) 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, or (at your option) any later version.
+# 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.
+#
+# Red Hat Author(s): Dave Lehman <dlehman@xxxxxxxxxx>
+#
+
+import os
+import time
+import stat
+import errno
+import sys
+import statvfs
+
+import nss.nss
+import parted
+
+import isys
+import iutil
+from constants import *
+from pykickstart.constants import *
+from flags import flags
+
+import storage_log
+from errors import *
+from devices import *
+from devicetree import DeviceTree
+from deviceaction import *
+from formats import getFormat
+from formats import get_device_format_class
+from formats import get_default_filesystem_type
+from devicelibs.lvm import safeLvmName
+from devicelibs.dm import name_from_dm_node
+from devicelibs.crypto import generateBackupPassphrase
+from devicelibs.mpath import MultipathConfigWriter
+from devicelibs.edd import get_edd_dict
+from udev import *
+import iscsi
+import fcoe
+import zfcp
+import dasd
+
+import shelve
+import contextlib
+
+import gettext
+_ = lambda x: gettext.ldgettext("anaconda", x)
+
+import logging
+log = logging.getLogger("storage")
+
+def storageInitialize(anaconda):
+    storage = anaconda.storage
+
+    storage.shutdown()
+
+    if anaconda.dir == DISPATCH_BACK:
+        return
+
+    # touch /dev/.in_sysinit so that /lib/udev/rules.d/65-md-incremental.rules
+    # does not mess with any mdraid sets
+    open("/dev/.in_sysinit", "w")
+
+    # XXX I don't understand why I have to do this, but this is needed to
+    #     populate the udev db
+    udev_trigger(subsystem="block", action="change")
+
+    # Before we set up the storage system, we need to know which disks to
+    # ignore, etc.  Luckily that's all in the kickstart data.
+    if anaconda.ksdata:
+        anaconda.storage.zeroMbr = anaconda.ksdata.zerombr.zerombr
+        anaconda.storage.ignoredDisks = anaconda.ksdata.ignoredisk.ignoredisk
+        anaconda.storage.exclusiveDisks = anaconda.ksdata.ignoredisk.onlyuse
+
+        if anaconda.ksdata.clearpart.type is not None:
+            anaconda.storage.clearPartType = anaconda.ksdata.clearpart.type
+            anaconda.storage.clearPartDisks = anaconda.ksdata.clearpart.drives
+            if anaconda.ksdata.clearpart.initAll:
+                anaconda.storage.reinitializeDisks = anaconda.ksdata.clearpart.initAll
+
+    anaconda.intf.resetInitializeDiskQuestion()
+    anaconda.intf.resetReinitInconsistentLVMQuestion()
+
+    # Set up the protected partitions list now.
+    if anaconda.protected:
+        storage.protectedDevSpecs.extend(anaconda.protected)
+        storage.reset()
+
+        if not flags.livecdInstall and not storage.protectedDevices:
+            if anaconda.upgrade:
+                return
+            else:
+                anaconda.intf.messageWindow(_("Unknown Device"),
+                    _("The installation source given by device %s "
+                      "could not be found.  Please check your "
+                      "parameters and try again.") % anaconda.protected,
+                    type="custom", custom_buttons = [_("_Exit installer")])
+                sys.exit(1)
+    else:
+        storage.reset()
+
+    if not storage.disks:
+        rc = anaconda.intf.messageWindow(_("No disks found"),
+                _("No usable disks have been found."),
+                type="custom",
+                custom_buttons = [_("Back"), _("_Exit installer")],
+                default=0)
+        if rc == 0:
+            return DISPATCH_BACK
+        sys.exit(1)
+
+# dispatch.py helper function
+def storageComplete(anaconda):
+    if anaconda.dir == DISPATCH_BACK:
+        rc = anaconda.intf.messageWindow(_("Installation cannot continue."),
+                                _("The storage configuration you have "
+                                  "chosen has already been activated. You "
+                                  "can no longer return to the disk editing "
+                                  "screen. Would you like to continue with "
+                                  "the installation process?"),
+                                type = "yesno")
+        if rc == 0:
+            sys.exit(0)
+        return DISPATCH_FORWARD
+
+    devs = anaconda.storage.devicetree.getDevicesByType("luks/dm-crypt")
+    existing_luks = False
+    new_luks = False
+    for dev in devs:
+        if dev.exists:
+            existing_luks = True
+        else:
+            new_luks = True
+
+    if (anaconda.storage.encryptedAutoPart or new_luks) and \
+       not anaconda.storage.encryptionPassphrase:
+        while True:
+            (passphrase, retrofit) = anaconda.intf.getLuksPassphrase(preexist=existing_luks)
+            if passphrase:
+                anaconda.storage.encryptionPassphrase = passphrase
+                anaconda.storage.encryptionRetrofit = retrofit
+                break
+            else:
+                rc = anaconda.intf.messageWindow(_("Encrypt device?"),
+                            _("You specified block device encryption "
+                              "should be enabled, but you have not "
+                              "supplied a passphrase. If you do not "
+                              "go back and provide a passphrase, "
+                              "block device encryption will be "
+                              "disabled."),
+                              type="custom",
+                              custom_buttons=[_("Back"), _("Continue")],
+                              default=0)
+                if rc == 1:
+                    log.info("user elected to not encrypt any devices.")
+                    undoEncryption(anaconda.storage)
+                    anaconda.storage.encryptedAutoPart = False
+                    break
+
+    if anaconda.storage.encryptionPassphrase:
+        for dev in anaconda.storage.devices:
+            if dev.format.type == "luks" and not dev.format.exists:
+                dev.format.passphrase = anaconda.storage.encryptionPassphrase
+
+    if anaconda.ksdata:
+        return
+
+    rc = anaconda.intf.messageWindow(_("Confirm"),
+                                _("The partitioning options you have selected "
+                                  "will now be written to disk.  Any "
+                                  "data on deleted or reformatted partitions "
+                                  "will be lost."),
+                                type = "custom", custom_icon="warning",
+                                custom_buttons=[_("Go _Back"),
+                                                _("_Write Changes to Disk")],
+                                default = 0)
+
+    # Make sure that all is down, even the disks that we setup after popluate.
+    anaconda.storage.devicetree.teardownAll()
+
+    if rc == 0:
+        return DISPATCH_BACK
+
+def writeEscrowPackets(anaconda):
+    escrowDevices = filter(lambda d: d.format.type == "luks" and \
+                                     d.format.escrow_cert,
+                           anaconda.storage.devices)
+
+    if not escrowDevices:
+        return
+
+    log.debug("escrow: writeEscrowPackets start")
+
+    wait_win = anaconda.intf.waitWindow(_("Running..."),
+                                        _("Storing encryption keys"))
+
+    nss.nss.nss_init_nodb() # Does nothing if NSS is already initialized
+
+    backupPassphrase = generateBackupPassphrase()
+    try:
+        for device in escrowDevices:
+            log.debug("escrow: device %s: %s" %
+                      (repr(device.path), repr(device.format.type)))
+            device.format.escrow(anaconda.rootPath + "/root",
+                                 backupPassphrase)
+
+        wait_win.pop()
+    except (IOError, RuntimeError) as e:
+        wait_win.pop()
+        anaconda.intf.messageWindow(_("Error"),
+                                    _("Error storing an encryption key: "
+                                      "%s\n") % str(e), type="custom",
+                                    custom_icon="error",
+                                    custom_buttons=[_("_Exit installer")])
+        sys.exit(1)
+
+    log.debug("escrow: writeEscrowPackets done")
+
+
+def undoEncryption(storage):
+    for device in storage.devicetree.getDevicesByType("luks/dm-crypt"):
+        if device.exists:
+            continue
+
+        slave = device.slave
+        format = device.format
+
+        # set any devices that depended on the luks device to now depend on
+        # the former slave device
+        for child in storage.devicetree.getChildren(device):
+            child.parents.remove(device)
+            device.removeChild()
+            child.parents.append(slave)
+
+        storage.devicetree.registerAction(ActionDestroyFormat(device))
+        storage.devicetree.registerAction(ActionDestroyDevice(device))
+        storage.devicetree.registerAction(ActionDestroyFormat(slave))
+        storage.devicetree.registerAction(ActionCreateFormat(slave, format))
+
+class Storage(object):
+    def __init__(self, anaconda):
+        self.anaconda = anaconda
+
+        # storage configuration variables
+        self.ignoredDisks = []
+        self.exclusiveDisks = []
+        self.doAutoPart = False
+        self.clearPartType = None
+        self.clearPartDisks = []
+        self.encryptedAutoPart = False
+        self.encryptionPassphrase = None
+        self.escrowCertificates = {}
+        self.autoPartEscrowCert = None
+        self.autoPartAddBackupPassphrase = False
+        self.encryptionRetrofit = False
+        self.reinitializeDisks = False
+        self.zeroMbr = None
+        self.protectedDevSpecs = []
+        self.autoPartitionRequests = []
+        self.eddDict = {}
+
+        self.__luksDevs = {}
+
+        self.iscsi = iscsi.iscsi()
+        self.fcoe = fcoe.fcoe()
+        self.zfcp = zfcp.ZFCP()
+        self.dasd = dasd.DASD()
+
+        self._nextID = 0
+        self.defaultFSType = get_default_filesystem_type()
+        self.defaultBootFSType = get_default_filesystem_type(boot=True)
+        self._dumpFile = "/tmp/storage.state"
+
+        # these will both be empty until our reset method gets called
+        self.devicetree = DeviceTree(intf=self.anaconda.intf,
+                                     ignored=self.ignoredDisks,
+                                     exclusive=self.exclusiveDisks,
+                                     type=self.clearPartType,
+                                     clear=self.clearPartDisks,
+                                     reinitializeDisks=self.reinitializeDisks,
+                                     protected=self.protectedDevSpecs,
+                                     zeroMbr=self.zeroMbr,
+                                     passphrase=self.encryptionPassphrase,
+                                     luksDict=self.__luksDevs,
+                                     iscsi=self.iscsi,
+                                     dasd=self.dasd)
+        self.fsset = FSSet(self.devicetree, self.anaconda.rootPath)
+
+    def doIt(self):
+        self.devicetree.processActions()
+        self.doEncryptionPassphraseRetrofits()
+
+        # now set the boot partition's flag
+        try:
+            boot = self.anaconda.platform.bootDevice()
+            if boot.type == "mdarray":
+                bootDevs = boot.parents
+            else:
+                bootDevs = [boot]
+        except DeviceError:
+            bootDevs = []
+        else:
+            for dev in bootDevs:
+                if hasattr(dev, "bootable"):
+                    # Dos labels can only have one partition marked as active
+                    # and unmarking ie the windows partition is not a good idea
+                    skip = False
+                    if dev.disk.format.partedDisk.type == "msdos":
+                        for p in dev.disk.format.partedDisk.partitions:
+                            if p.type == parted.PARTITION_NORMAL and \
+                               p.getFlag(parted.PARTITION_BOOT):
+                                skip = True
+                                break
+                    if skip:
+                         log.info("not setting boot flag on %s as there is"
+                                  "another active partition" % dev.name)
+                         continue
+                    log.info("setting boot flag on %s" % dev.name)
+                    dev.bootable = True
+                    dev.disk.setup()
+                    dev.disk.format.commitToDisk()
+
+        self.dumpState("final")
+
+    @property
+    def nextID(self):
+        id = self._nextID
+        self._nextID += 1
+        return id
+
+    def shutdown(self):
+        try:
+            self.devicetree.teardownAll()
+        except Exception as e:
+            log.error("failure tearing down device tree: %s" % e)
+
+        self.zfcp.shutdown()
+
+        # TODO: iscsi.shutdown()
+
+    def reset(self):
+        """ Reset storage configuration to reflect actual system state.
+
+            This should rescan from scratch but not clobber user-obtained
+            information like passphrases, iscsi config, &c
+
+        """
+        # save passphrases for luks devices so we don't have to reprompt
+        self.encryptionPassphrase = None
+        for device in self.devices:
+            if device.format.type == "luks" and device.format.exists:
+                self.__luksDevs[device.format.uuid] = device.format._LUKS__passphrase
+
+        w = self.anaconda.intf.waitWindow(_("Finding Devices"),
+                                          _("Finding storage devices"))
+        self.iscsi.startup(self.anaconda.intf)
+        self.fcoe.startup(self.anaconda.intf)
+        self.zfcp.startup()
+        self.dasd.startup(self.anaconda.intf, self.exclusiveDisks, self.zeroMbr)
+        if self.anaconda.upgrade:
+            clearPartType = CLEARPART_TYPE_NONE
+        else:
+            clearPartType = self.clearPartType
+
+        self.devicetree = DeviceTree(intf=self.anaconda.intf,
+                                     ignored=self.ignoredDisks,
+                                     exclusive=self.exclusiveDisks,
+                                     type=clearPartType,
+                                     clear=self.clearPartDisks,
+                                     reinitializeDisks=self.reinitializeDisks,
+                                     protected=self.protectedDevSpecs,
+                                     zeroMbr=self.zeroMbr,
+                                     passphrase=self.encryptionPassphrase,
+                                     luksDict=self.__luksDevs,
+                                     iscsi=self.iscsi,
+                                     dasd=self.dasd)
+        self.devicetree.populate()
+        self.fsset = FSSet(self.devicetree, self.anaconda.rootPath)
+        self.eddDict = get_edd_dict(self.partitioned)
+        self.anaconda.rootParts = None
+        self.anaconda.upgradeRoot = None
+        self.dumpState("initial")
+        w.pop()
+
+    @property
+    def devices(self):
+        """ A list of all the devices in the device tree. """
+        devices = self.devicetree.devices
+        devices.sort(key=lambda d: d.name)
+        return devices
+
+    @property
+    def disks(self):
+        """ A list of the disks in the device tree.
+
+            Ignored disks are not included, as are disks with no media present.
+
+            This is based on the current state of the device tree and
+            does not necessarily reflect the actual on-disk state of the
+            system's disks.
+        """
+        disks = []
+        for device in self.devicetree.devices:
+            if device.isDisk:
+                if not device.mediaPresent:
+                    log.info("Skipping disk: %s: No media present" % device.name)
+                    continue
+                disks.append(device)
+        disks.sort(key=lambda d: d.name, cmp=self.compareDisks)
+        return disks
+
+    @property
+    def partitioned(self):
+        """ A list of the partitioned devices in the device tree.
+
+            Ignored devices are not included, nor disks with no media present.
+
+            Devices of types for which partitioning is not supported are also
+            not included.
+
+            This is based on the current state of the device tree and
+            does not necessarily reflect the actual on-disk state of the
+            system's disks.
+        """
+        partitioned = []
+        for device in self.devicetree.devices:
+            if not device.partitioned:
+                continue
+
+            if not device.mediaPresent:
+                log.info("Skipping device: %s: No media present" % device.name)
+                continue
+
+            partitioned.append(device)
+
+        partitioned.sort(key=lambda d: d.name)
+        return partitioned
+
+    @property
+    def partitions(self):
+        """ A list of the partitions in the device tree.
+
+            This is based on the current state of the device tree and
+            does not necessarily reflect the actual on-disk state of the
+            system's disks.
+        """
+        partitions = self.devicetree.getDevicesByInstance(PartitionDevice)
+        partitions.sort(key=lambda d: d.name)
+        return partitions
+
+    @property
+    def vgs(self):
+        """ A list of the LVM Volume Groups in the device tree.
+
+            This is based on the current state of the device tree and
+            does not necessarily reflect the actual on-disk state of the
+            system's disks.
+        """
+        vgs = self.devicetree.getDevicesByType("lvmvg")
+        vgs.sort(key=lambda d: d.name)
+        return vgs
+
+    @property
+    def lvs(self):
+        """ A list of the LVM Logical Volumes in the device tree.
+
+            This is based on the current state of the device tree and
+            does not necessarily reflect the actual on-disk state of the
+            system's disks.
+        """
+        lvs = self.devicetree.getDevicesByType("lvmlv")
+        lvs.sort(key=lambda d: d.name)
+        return lvs
+
+    @property
+    def pvs(self):
+        """ A list of the LVM Physical Volumes in the device tree.
+
+            This is based on the current state of the device tree and
+            does not necessarily reflect the actual on-disk state of the
+            system's disks.
+        """
+        devices = self.devicetree.devices
+        pvs = [d for d in devices if d.format.type == "lvmpv"]
+        pvs.sort(key=lambda d: d.name)
+        return pvs
+
+    def unusedPVs(self, vg=None):
+        unused = []
+        for pv in self.pvs:
+            used = False
+            for _vg in self.vgs:
+                if _vg.dependsOn(pv) and _vg != vg:
+                    used = True
+                    break
+                elif _vg == vg:
+                    break
+            if not used:
+                unused.append(pv)
+        return unused
+
+    @property
+    def mdarrays(self):
+        """ A list of the MD arrays in the device tree.
+
+            This is based on the current state of the device tree and
+            does not necessarily reflect the actual on-disk state of the
+            system's disks.
+        """
+        arrays = self.devicetree.getDevicesByType("mdarray")
+        arrays.sort(key=lambda d: d.name)
+        return arrays
+
+    @property
+    def mdcontainers(self):
+        """ A list of the MD containers in the device tree. """
+        arrays = self.devicetree.getDevicesByType("mdcontainer")
+        arrays.sort(key=lambda d: d.name)
+        return arrays
+
+    @property
+    def mdmembers(self):
+        """ A list of the MD member devices in the device tree.
+
+            This is based on the current state of the device tree and
+            does not necessarily reflect the actual on-disk state of the
+            system's disks.
+        """
+        devices = self.devicetree.devices
+        members = [d for d in devices if d.format.type == "mdmember"]
+        members.sort(key=lambda d: d.name)
+        return members
+
+    def unusedMDMembers(self, array=None):
+        unused = []
+        for member in self.mdmembers:
+            used = False
+            for _array in self.mdarrays + self.mdcontainers:
+                if _array.dependsOn(member) and _array != array:
+                    used = True
+                    break
+                elif _array == array:
+                    break
+            if not used:
+                unused.append(member)
+        return unused
+
+    @property
+    def unusedMDMinors(self):
+        """ Return a list of unused minors for use in RAID. """
+        raidMinors = range(0,32)
+        for array in self.mdarrays + self.mdcontainers:
+            if array.minor is not None and array.minor in raidMinors:
+                raidMinors.remove(array.minor)
+        return raidMinors
+
+    @property
+    def swaps(self):
+        """ A list of the swap devices in the device tree.
+
+            This is based on the current state of the device tree and
+            does not necessarily reflect the actual on-disk state of the
+            system's disks.
+        """
+        devices = self.devicetree.devices
+        swaps = [d for d in devices if d.format.type == "swap"]
+        swaps.sort(key=lambda d: d.name)
+        return swaps
+
+    @property
+    def protectedDevices(self):
+        devices = self.devicetree.devices
+        protected = [d for d in devices if d.protected]
+        protected.sort(key=lambda d: d.name)
+        return protected
+
+    def exceptionDisks(self):
+        """ Return a list of removable devices to save exceptions to.
+
+            FIXME: This raises the problem that the device tree can be
+                   in a state that does not reflect that actual current
+                   state of the system at any given point.
+
+                   We need a way to provide direct scanning of disks,
+                   partitions, and filesystems without relying on the
+                   larger objects' correctness.
+
+                   Also, we need to find devices that have just been made
+                   available for the purpose of storing the exception
+                   report.
+        """
+        # When a usb is connected from before the start of the installation,
+        # it is not correctly detected.
+        udev_trigger(subsystem="block", action="change")
+        self.reset()
+
+        dests = []
+
+        for disk in self.disks:
+            if not disk.removable and \
+                    disk.format is not None  and \
+                    disk.format.mountable:
+                dests.append([disk.path, disk.name])
+
+        for part in self.partitions:
+            if not part.disk.removable:
+                continue
+
+            elif part.partedPartition.active and \
+                    not part.partedPartition.getFlag(parted.PARTITION_RAID) and \
+                    not part.partedPartition.getFlag(parted.PARTITION_LVM) and \
+                    part.format is not None and part.format.mountable:
+                dests.append([part.path, part.name])
+
+        return dests
+
+    def deviceImmutable(self, device, ignoreProtected=False):
+        """ Return any reason the device cannot be modified/removed.
+
+            Return False if the device can be removed.
+
+            Devices that cannot be removed include:
+
+                - protected partitions
+                - devices that are part of an md array or lvm vg
+                - extended partition containing logical partitions that
+                  meet any of the above criteria
+
+        """
+        if not isinstance(device, Device):
+            raise ValueError("arg1 (%s) must be a Device instance" % device)
+
+        if not ignoreProtected and device.protected:
+            return _("This partition is holding the data for the hard "
+                      "drive install.")
+        elif isinstance(device, PartitionDevice) and device.isProtected:
+            # LDL formatted DASDs always have one partition, you'd have to
+            # reformat the DASD in CDL mode to get rid of it
+            return _("You cannot delete a partition of a LDL formatted "
+                     "DASD.")
+        elif device.format.type == "mdmember":
+            for array in self.mdarrays + self.mdcontainers:
+                if array.dependsOn(device):
+                    if array.minor is not None:
+                        return _("This device is part of the RAID "
+                                 "device %s.") % (array.path,)
+                    else:
+                        return _("This device is part of a RAID device.")
+        elif device.format.type == "lvmpv":
+            for vg in self.vgs:
+                if vg.dependsOn(device):
+                    if vg.name is not None:
+                        return _("This device is part of the LVM "
+                                 "volume group '%s'.") % (vg.name,)
+                    else:
+                        return _("This device is part of a LVM volume "
+                                 "group.")
+        elif device.format.type == "luks":
+            try:
+                luksdev = self.devicetree.getChildren(device)[0]
+            except IndexError:
+                pass
+            else:
+                return self.deviceImmutable(luksdev)
+        elif isinstance(device, PartitionDevice) and device.isExtended:
+            reasons = {}
+            for dep in self.deviceDeps(device):
+                reason = self.deviceImmutable(dep)
+                if reason:
+                    reasons[dep.path] = reason
+            if reasons:
+                msg =  _("This device is an extended partition which "
+                         "contains logical partitions that cannot be "
+                         "deleted:\n\n")
+                for dev in reasons:
+                    msg += "%s: %s" % (dev, reasons[dev])
+                return msg
+
+        for i in self.devicetree.immutableDevices:
+            if i[0] == device.name:
+                return i[1]
+
+        return False
+
+    def deviceDeps(self, device):
+        return self.devicetree.getDependentDevices(device)
+
+    def newPartition(self, *args, **kwargs):
+        """ Return a new PartitionDevice instance for configuring. """
+        if kwargs.has_key("fmt_type"):
+            kwargs["format"] = getFormat(kwargs.pop("fmt_type"),
+                                         mountpoint=kwargs.pop("mountpoint",
+                                                               None),
+                                         **kwargs.pop("fmt_args", {}))
+
+        if kwargs.has_key("disks"):
+            parents = kwargs.pop("disks")
+            if isinstance(parents, Device):
+                kwargs["parents"] = [parents]
+            else:
+                kwargs["parents"] = parents
+
+        if kwargs.has_key("name"):
+            name = kwargs.pop("name")
+        else:
+            name = "req%d" % self.nextID
+
+        return PartitionDevice(name, *args, **kwargs)
+
+    def newMDArray(self, *args, **kwargs):
+        """ Return a new MDRaidArrayDevice instance for configuring. """
+        if kwargs.has_key("fmt_type"):
+            kwargs["format"] = getFormat(kwargs.pop("fmt_type"),
+                                         mountpoint=kwargs.pop("mountpoint",
+                                                               None))
+
+        if kwargs.has_key("minor"):
+            kwargs["minor"] = int(kwargs["minor"])
+        else:
+            kwargs["minor"] = self.unusedMDMinors[0]
+
+        if kwargs.has_key("name"):
+            name = kwargs.pop("name")
+        else:
+            name = "md%d" % kwargs["minor"]
+
+        return MDRaidArrayDevice(name, *args, **kwargs)
+
+    def newVG(self, *args, **kwargs):
+        """ Return a new LVMVolumeGroupDevice instance. """
+        pvs = kwargs.pop("pvs", [])
+        for pv in pvs:
+            if pv not in self.devices:
+                raise ValueError("pv is not in the device tree")
+
+        if kwargs.has_key("name"):
+            name = kwargs.pop("name")
+        else:
+            name = self.createSuggestedVGName(self.anaconda.network)
+
+        if name in [d.name for d in self.devices]:
+            raise ValueError("name already in use")
+
+        return LVMVolumeGroupDevice(name, pvs, *args, **kwargs)
+
+    def newLV(self, *args, **kwargs):
+        """ Return a new LVMLogicalVolumeDevice instance. """
+        if kwargs.has_key("vg"):
+            vg = kwargs.pop("vg")
+
+        mountpoint = kwargs.pop("mountpoint", None)
+        if kwargs.has_key("fmt_type"):
+            kwargs["format"] = getFormat(kwargs.pop("fmt_type"),
+                                         mountpoint=mountpoint)
+
+        if kwargs.has_key("name"):
+            name = kwargs.pop("name")
+        else:
+            if kwargs.get("format") and kwargs["format"].type == "swap":
+                swap = True
+            else:
+                swap = False
+            name = self.createSuggestedLVName(vg,
+                                              swap=swap,
+                                              mountpoint=mountpoint)
+
+        if name in [d.name for d in self.devices]:
+            raise ValueError("name already in use")
+
+        return LVMLogicalVolumeDevice(name, vg, *args, **kwargs)
+
+    def createDevice(self, device):
+        """ Schedule creation of a device.
+
+            TODO: We could do some things here like assign the next
+                  available raid minor if one isn't already set.
+        """
+        self.devicetree.registerAction(ActionCreateDevice(device))
+        if device.format.type:
+            self.devicetree.registerAction(ActionCreateFormat(device))
+
+    def destroyDevice(self, device):
+        """ Schedule destruction of a device. """
+        if device.format.exists and device.format.type:
+            # schedule destruction of any formatting while we're at it
+            self.devicetree.registerAction(ActionDestroyFormat(device))
+
+        action = ActionDestroyDevice(device)
+        self.devicetree.registerAction(action)
+
+    def formatDevice(self, device, format):
+        """ Schedule formatting of a device. """
+        self.devicetree.registerAction(ActionDestroyFormat(device))
+        self.devicetree.registerAction(ActionCreateFormat(device, format))
+
+    def formatByDefault(self, device):
+        """Return whether the device should be reformatted by default."""
+        formatlist = ['/boot', '/var', '/tmp', '/usr']
+        exceptlist = ['/home', '/usr/local', '/opt', '/var/www']
+
+        if not device.format.linuxNative:
+            return False
+
+        if device.format.mountable:
+            if not device.format.mountpoint:
+                return False
+
+            if device.format.mountpoint == "/" or \
+               device.format.mountpoint in formatlist:
+                return True
+
+            for p in formatlist:
+                if device.format.mountpoint.startswith(p):
+                    for q in exceptlist:
+                        if device.format.mountpoint.startswith(q):
+                            return False
+                    return True
+        elif device.format.type == "swap":
+            return True
+
+        # be safe for anything else and default to off
+        return False
+
+    def extendedPartitionsSupported(self):
+        """ Return whether any disks support extended partitions."""
+        for disk in self.partitioned:
+            if disk.format.partedDisk.supportsFeature(parted.DISK_TYPE_EXTENDED):
+                return True
+        return False
+
+    def createSuggestedVGName(self, network):
+        """ Return a reasonable, unused VG name. """
+        # try to create a volume group name incorporating the hostname
+        hn = network.hostname
+        vgnames = [vg.name for vg in self.vgs]
+        if hn is not None and hn != '':
+            if hn == 'localhost' or hn == 'localhost.localdomain':
+                vgtemplate = "VolGroup"
+            elif hn.find('.') != -1:
+                template = "vg_%s" % (hn.split('.')[0].lower(),)
+                vgtemplate = safeLvmName(template)
+            else:
+                template = "vg_%s" % (hn.lower(),)
+                vgtemplate = safeLvmName(template)
+        else:
+            vgtemplate = "VolGroup"
+
+        if vgtemplate not in vgnames and \
+                vgtemplate not in lvm.lvm_vg_blacklist:
+            return vgtemplate
+        else:
+            i = 0
+            while 1:
+                tmpname = "%s%02d" % (vgtemplate, i,)
+                if not tmpname in vgnames and \
+                        tmpname not in lvm.lvm_vg_blacklist:
+                    break
+
+                i += 1
+                if i > 99:
+                    tmpname = ""
+
+            return tmpname
+
+    def createSuggestedLVName(self, vg, swap=None, mountpoint=None):
+        """ Return a suitable, unused name for a new logical volume. """
+        # FIXME: this is not at all guaranteed to work
+        if mountpoint:
+            # try to incorporate the mountpoint into the name
+            if mountpoint == '/':
+                lvtemplate = 'lv_root'
+            else:
+                if mountpoint.startswith("/"):
+                    template = "lv_%s" % mountpoint[1:]
+                else:
+                    template = "lv_%s" % (mountpoint,)
+
+                lvtemplate = safeLvmName(template)
+        else:
+            if swap:
+                if len([s for s in self.swaps if s in vg.lvs]):
+                    idx = len([s for s in self.swaps if s in vg.lvs])
+                    while True:
+                        lvtemplate = "lv_swap%02d" % idx
+                        if lvtemplate in [lv.lvname for lv in vg.lvs]:
+                            idx += 1
+                        else:
+                            break
+                else:
+                    lvtemplate = "lv_swap"
+            else:
+                idx = len(vg.lvs)
+                while True:
+                    lvtemplate = "LogVol%02d" % idx
+                    if lvtemplate in [l.lvname for l in vg.lvs]:
+                        idx += 1
+                    else:
+                        break
+
+        return lvtemplate
+
+    def doEncryptionPassphraseRetrofits(self):
+        """ Add the global passphrase to all preexisting LUKS devices.
+
+            This establishes a common passphrase for all encrypted devices
+            in the system so that users only have to enter one passphrase
+            during system boot.
+        """
+        if not self.encryptionRetrofit:
+            return
+
+        for device in self.devices:
+            if device.format.type == "luks" and \
+               device.format._LUKS__passphrase != self.encryptionPassphrase:
+                log.info("adding new passphrase to preexisting encrypted "
+                         "device %s" % device.path)
+                try:
+                    device.format.addPassphrase(self.encryptionPassphrase)
+                except CryptoError:
+                    log.error("failed to add new passphrase to existing "
+                              "device %s" % device.path)
+
+    def sanityCheck(self):
+        """ Run a series of tests to verify the storage configuration.
+
+            This function is called at the end of partitioning so that
+            we can make sure you don't have anything silly (like no /,
+            a really small /, etc).  Returns (errors, warnings) where
+            each is a list of strings.
+        """
+        checkSizes = [('/usr', 250), ('/tmp', 50), ('/var', 384),
+                      ('/home', 100), ('/boot', 75)]
+        warnings = []
+        errors = []
+
+        mustbeonlinuxfs = ['/', '/var', '/tmp', '/usr', '/home', '/usr/share', '/usr/lib']
+        mustbeonroot = ['/bin','/dev','/sbin','/etc','/lib','/root', '/mnt', 'lost+found', '/proc']
+
+        filesystems = self.mountpoints
+        root = self.fsset.rootDevice
+        swaps = self.fsset.swapDevices
+        try:
+            boot = self.anaconda.platform.bootDevice()
+        except DeviceError:
+            boot = None
+
+        if not root:
+            errors.append(_("You have not defined a root partition (/), "
+                            "which is required for installation of %s "
+                            "to continue.") % (productName,))
+
+        if root and root.size < 250:
+            warnings.append(_("Your root partition is less than 250 "
+                              "megabytes which is usually too small to "
+                              "install %s.") % (productName,))
+
+        if (root and
+            root.size < self.anaconda.backend.getMinimumSizeMB("/")):
+            errors.append(_("Your / partition is less than %(min)s "
+                            "MB which is lower than recommended "
+                            "for a normal %(productName)s install.")
+                          % {'min': self.anaconda.backend.getMinimumSizeMB("/"),
+                             'productName': productName})
+
+        # livecds have to have the rootfs type match up
+        if (root and
+            self.anaconda.backend.rootFsType and
+            root.format.type != self.anaconda.backend.rootFsType):
+            errors.append(_("Your / partition does not match the "
+                            "the live image you are installing from.  "
+                            "It must be formatted as %s.")
+                          % (self.anaconda.backend.rootFsType,))
+
+        for (mount, size) in checkSizes:
+            if mount in filesystems and filesystems[mount].size < size:
+                warnings.append(_("Your %(mount)s partition is less than "
+                                  "%(size)s megabytes which is lower than "
+                                  "recommended for a normal %(productName)s "
+                                  "install.")
+                                % {'mount': mount, 'size': size,
+                                   'productName': productName})
+
+        usb_disks = []
+        firewire_disks = []
+        for disk in self.disks:
+            if isys.driveUsesModule(disk.name, ["usb-storage", "ub"]):
+                usb_disks.append(disk)
+            elif isys.driveUsesModule(disk.name, ["sbp2", "firewire-sbp2"]):
+                firewire_disks.append(disk)
+
+        uses_usb = False
+        uses_firewire = False
+        for device in filesystems.values():
+            for disk in usb_disks:
+                if device.dependsOn(disk):
+                    uses_usb = True
+                    break
+
+            for disk in firewire_disks:
+                if device.dependsOn(disk):
+                    uses_firewire = True
+                    break
+
+        if uses_usb:
+            warnings.append(_("Installing on a USB device.  This may "
+                              "or may not produce a working system."))
+        if uses_firewire:
+            warnings.append(_("Installing on a FireWire device.  This may "
+                              "or may not produce a working system."))
+
+        errors.extend(self.anaconda.platform.checkBootRequest(boot))
+
+        if not swaps:
+            if iutil.memInstalled() < isys.EARLY_SWAP_RAM:
+                errors.append(_("You have not specified a swap partition.  "
+                                "Due to the amount of memory present, a "
+                                "swap partition is required to complete "
+                                "installation."))
+            else:
+                warnings.append(_("You have not specified a swap partition.  "
+                                  "Although not strictly required in all cases, "
+                                  "it will significantly improve performance "
+                                  "for most installations."))
+
+        for (mountpoint, dev) in filesystems.items():
+            if mountpoint in mustbeonroot:
+                errors.append(_("This mount point is invalid.  The %s directory must "
+                                "be on the / file system.") % mountpoint)
+
+            if mountpoint in mustbeonlinuxfs and (not dev.format.mountable or not dev.format.linuxNative):
+                errors.append(_("The mount point %s must be on a linux file system.") % mountpoint)
+
+        return (errors, warnings)
+
+    def isProtected(self, device):
+        """ Return True is the device is protected. """
+        return device.protected
+
+    def checkNoDisks(self):
+        """Check that there are valid disk devices."""
+        if not self.disks:
+            self.anaconda.intf.messageWindow(_("No Drives Found"),
+                               _("An error has occurred - no valid devices were "
+                                 "found on which to create new file systems. "
+                                 "Please check your hardware for the cause "
+                                 "of this problem."))
+            return True
+        return False
+
+    def dumpState(self, suffix):
+        """ Dump the current device list to the storage shelf. """
+        key = "devices.%d.%s" % (time.time(), suffix)
+        with contextlib.closing(shelve.open(self._dumpFile)) as shelf:
+            shelf[key] = [d.dict for d in self.devices]
+
+    def write(self, instPath):
+        self.fsset.write(instPath)
+        self.iscsi.write(instPath, self.anaconda)
+        self.fcoe.write(instPath, self.anaconda)
+        self.zfcp.write(instPath)
+        self.dasd.write(instPath)
+
+    def writeKS(self, f):
+        def useExisting(lst):
+            foundCreateDevice = False
+            foundCreateFormat = False
+
+            for l in lst:
+                if isinstance(l, ActionCreateDevice):
+                    foundCreateDevice = True
+                elif isinstance(l, ActionCreateFormat):
+                    foundCreateFormat = True
+
+            return (foundCreateFormat and not foundCreateDevice)
+
+        log.warning("Storage.writeKS not completely implemented")
+        f.write("# The following is the partition information you requested\n")
+        f.write("# Note that any partitions you deleted are not expressed\n")
+        f.write("# here so unless you clear all partitions first, this is\n")
+        f.write("# not guaranteed to work\n")
+
+        # clearpart
+        if self.clearPartType is None or self.clearPartType == CLEARPART_TYPE_NONE:
+            args = ["--none"]
+        elif self.clearPartType == CLEARPART_TYPE_LINUX:
+            args = ["--linux"]
+        else:
+            args = ["--all"]
+
+        if self.clearPartDisks:
+            args += ["--drives=%s" % ",".join(self.clearPartDisks)]
+        if self.reinitializeDisks:
+            args += ["--initlabel"]
+
+        f.write("#clearpart %s\n" % " ".join(args))
+
+        # ignoredisks
+        if self.ignoredDisks:
+            f.write("#ignoredisk --drives=%s\n" % ",".join(self.ignoredDisks))
+        elif self.exclusiveDisks:
+            f.write("#ignoredisk --only-use=%s\n" % ",".join(self.exclusiveDisks))
+
+        # the various partitioning commands
+        dict = {}
+        actions = filter(lambda x: x.device.format.type != "luks",
+                         self.devicetree.findActions(type="create"))
+
+        for action in actions:
+            if dict.has_key(action.device.path):
+                dict[action.device.path].append(action)
+            else:
+                dict[action.device.path] = [action]
+
+        for device in self.devices:
+            # If there's no action for the given device, it must be one
+            # we are reusing.
+            if not dict.has_key(device.path):
+                noformat = True
+                preexisting = True
+            else:
+                noformat = False
+                preexisting = useExisting(dict[device.path])
+
+            device.writeKS(f, preexisting=preexisting, noformat=noformat)
+            f.write("\n")
+
+        self.iscsi.writeKS(f)
+        self.fcoe.writeKS(f)
+        self.zfcp.writeKS(f)
+
+    def turnOnSwap(self, upgrading=None):
+        self.fsset.turnOnSwap(self.anaconda, upgrading=upgrading)
+
+    def mountFilesystems(self, raiseErrors=None, readOnly=None, skipRoot=False):
+        self.fsset.mountFilesystems(self.anaconda, raiseErrors=raiseErrors,
+                                    readOnly=readOnly, skipRoot=skipRoot)
+
+    def umountFilesystems(self, ignoreErrors=True, swapoff=True):
+        self.fsset.umountFilesystems(ignoreErrors=ignoreErrors, swapoff=swapoff)
+
+    def parseFSTab(self):
+        self.fsset.parseFSTab()
+
+    def mkDevRoot(self):
+        self.fsset.mkDevRoot()
+
+    def createSwapFile(self, device, size):
+        self.fsset.createSwapFile(device, size)
+
+    @property
+    def fsFreeSpace(self):
+        return self.fsset.fsFreeSpace()
+
+    @property
+    def mtab(self):
+        return self.fsset.mtab()
+
+    @property
+    def mountpoints(self):
+        return self.fsset.mountpoints
+
+    @property
+    def migratableDevices(self):
+        return self.fsset.migratableDevices
+
+    @property
+    def rootDevice(self):
+        return self.fsset.rootDevice
+
+    def compareDisks(self, first, second):
+        if self.eddDict.has_key(first) and self.eddDict.has_key(second):
+            one = self.eddDict[first]
+            two = self.eddDict[second]
+            if (one < two):
+                return -1
+            elif (one > two):
+                return 1
+
+        # if one is in the BIOS and the other not prefer the one in the BIOS
+        if self.eddDict.has_key(first):
+            return -1
+        if self.eddDict.has_key(second):
+            return 1
+
+        if first.startswith("hd"):
+            type1 = 0
+        elif first.startswith("sd"):
+            type1 = 1
+        elif (first.startswith("vd") or first.startswith("xvd")):
+            type1 = -1
+        else:
+            type1 = 2
+
+        if second.startswith("hd"):
+            type2 = 0
+        elif second.startswith("sd"):
+            type2 = 1
+        elif (second.startswith("vd") or second.startswith("xvd")):
+            type2 = -1
+        else:
+            type2 = 2
+
+        if (type1 < type2):
+            return -1
+        elif (type1 > type2):
+            return 1
+        else:
+            len1 = len(first)
+            len2 = len(second)
+
+            if (len1 < len2):
+                return -1
+            elif (len1 > len2):
+                return 1
+            else:
+                if (first < second):
+                    return -1
+                elif (first > second):
+                    return 1
+
+        return 0
+
+def getReleaseString(mountpoint):
+    relName = None
+    relVer = None
+
+    filename = "%s/etc/redhat-release" % mountpoint
+    if os.access(filename, os.R_OK):
+        with open(filename) as f:
+            try:
+                relstr = f.readline().strip()
+            except (IOError, AttributeError):
+                relstr = ""
+
+        # get the release name and version
+        # assumes that form is something
+        # like "Red Hat Linux release 6.2 (Zoot)"
+        (product, sep, version) = relstr.partition(" release ")
+        if sep:
+            relName = product
+            relVer = version.split()[0]
+
+    return (relName, relVer)
+
+def findExistingRootDevices(anaconda, upgradeany=False):
+    """ Return a list of all root filesystems in the device tree. """
+    rootDevs = []
+
+    if not os.path.exists(anaconda.rootPath):
+        iutil.mkdirChain(anaconda.rootPath)
+
+    roots = []
+    for device in anaconda.storage.devicetree.leaves:
+        if not device.format.linuxNative or not device.format.mountable:
+            continue
+
+        if device.protected:
+            # can't upgrade the part holding hd: media so why look at it?
+            continue
+
+        try:
+            device.setup()
+        except Exception as e:
+            log.warning("setup of %s failed: %s" % (device.name, e))
+            continue
+
+        try:
+            device.format.mount(options="ro", mountpoint=anaconda.rootPath)
+        except Exception as e:
+            log.warning("mount of %s as %s failed: %s" % (device.name,
+                                                          device.format.type,
+                                                          e))
+            device.teardown()
+            continue
+
+        if os.access(anaconda.rootPath + "/etc/fstab", os.R_OK):
+            (product, version) = getReleaseString(anaconda.rootPath)
+            if upgradeany or \
+               anaconda.instClass.productUpgradable(product, version):
+                rootDevs.append((device, "%s %s" % (product, version)))
+            else:
+                log.info("product %s version %s found on %s is not upgradable"
+                         % (product, version, device.name))
+
+        # this handles unmounting the filesystem
+        device.teardown(recursive=True)
+
+    return rootDevs
+
+def mountExistingSystem(anaconda, rootEnt,
+                        allowDirty=None, warnDirty=None,
+                        readOnly=None):
+    """ Mount filesystems specified in rootDevice's /etc/fstab file. """
+    rootDevice = rootEnt[0]
+    rootPath = anaconda.rootPath
+    fsset = anaconda.storage.fsset
+    if readOnly:
+        readOnly = "ro"
+    else:
+        readOnly = ""
+
+    if rootDevice.protected and os.path.ismount("/mnt/isodir"):
+        isys.mount("/mnt/isodir",
+                   rootPath,
+                   fstype=rootDevice.format.type,
+                   bindMount=True)
+    else:
+        rootDevice.setup()
+        rootDevice.format.mount(chroot=rootPath,
+                                mountpoint="/",
+                                options=readOnly)
+
+    fsset.parseFSTab()
+
+    # check for dirty filesystems
+    dirtyDevs = []
+    for device in fsset.devices:
+        if not hasattr(device.format, "isDirty"):
+            continue
+
+        try:
+            device.setup()
+        except DeviceError as e:
+            # we'll catch this in the main loop
+            continue
+
+        if device.format.isDirty:
+            log.info("%s contains a dirty %s filesystem" % (device.path,
+                                                            device.format.type))
+            dirtyDevs.append(device.path)
+
+    messageWindow = anaconda.intf.messageWindow
+    if not allowDirty and dirtyDevs:
+        messageWindow(_("Dirty File Systems"),
+                      _("The following file systems for your Linux system "
+                        "were not unmounted cleanly.  Please boot your "
+                        "Linux installation, let the file systems be "
+                        "checked and shut down cleanly to upgrade.\n"
+                        "%s") % "\n".join(dirtyDevs))
+        anaconda.storage.devicetree.teardownAll()
+        sys.exit(0)
+    elif warnDirty and dirtyDevs:
+        rc = messageWindow(_("Dirty File Systems"),
+                           _("The following file systems for your Linux "
+                             "system were not unmounted cleanly.  Would "
+                             "you like to mount them anyway?\n"
+                             "%s") % "\n".join(dirtyDevs),
+                             type = "yesno")
+        if rc == 0:
+            return -1
+
+    fsset.mountFilesystems(anaconda, readOnly=readOnly, skipRoot=True)
+
+
+class BlkidTab(object):
+    """ Dictionary-like interface to blkid.tab with device path keys """
+    def __init__(self, chroot=""):
+        self.chroot = chroot
+        self.devices = {}
+
+    def parse(self):
+        path = "%s/etc/blkid/blkid.tab" % self.chroot
+        log.debug("parsing %s" % path)
+        with open(path) as f:
+            for line in f.readlines():
+                # this is pretty ugly, but an XML parser is more work than
+                # is justifiable for this purpose
+                if not line.startswith("<device "):
+                    continue
+
+                line = line[len("<device "):-len("</device>\n")]
+                (data, sep, device) = line.partition(">")
+                if not device:
+                    continue
+
+                self.devices[device] = {}
+                for pair in data.split():
+                    try:
+                        (key, value) = pair.split("=")
+                    except ValueError:
+                        continue
+
+                    self.devices[device][key] = value[1:-1] # strip off quotes
+
+    def __getitem__(self, key):
+        return self.devices[key]
+
+    def get(self, key, default=None):
+        return self.devices.get(key, default)
+
+
+class CryptTab(object):
+    """ Dictionary-like interface to crypttab entries with map name keys """
+    def __init__(self, devicetree, blkidTab=None, chroot=""):
+        self.devicetree = devicetree
+        self.blkidTab = blkidTab
+        self.chroot = chroot
+        self.mappings = {}
+
+    def parse(self, chroot=""):
+        """ Parse /etc/crypttab from an existing installation. """
+        if not chroot or not os.path.isdir(chroot):
+            chroot = ""
+
+        path = "%s/etc/crypttab" % chroot
+        log.debug("parsing %s" % path)
+        with open(path) as f:
+            if not self.blkidTab:
+                try:
+                    self.blkidTab = BlkidTab(chroot=chroot)
+                    self.blkidTab.parse()
+                except Exception:
+                    self.blkidTab = None
+
+            for line in f.readlines():
+                (line, pound, comment) = line.partition("#")
+                fields = line.split()
+                if not 2 <= len(fields) <= 4:
+                    continue
+                elif len(fields) == 2:
+                    fields.extend(['none', ''])
+                elif len(fields) == 3:
+                    fields.append('')
+
+                (name, devspec, keyfile, options) = fields
+
+                # resolve devspec to a device in the tree
+                device = self.devicetree.resolveDevice(devspec,
+                                                       blkidTab=self.blkidTab)
+                if device:
+                    self.mappings[name] = {"device": device,
+                                           "keyfile": keyfile,
+                                           "options": options}
+
+    def populate(self):
+        """ Populate the instance based on the device tree's contents. """
+        for device in self.devicetree.devices:
+            # XXX should we put them all in there or just the ones that
+            #     are part of a device containing swap or a filesystem?
+            #
+            #       Put them all in here -- we can filter from FSSet
+            if device.format.type != "luks":
+                continue
+
+            key_file = device.format.keyFile
+            if not key_file:
+                key_file = "none"
+
+            options = device.format.options
+            if not options:
+                options = ""
+
+            self.mappings[device.format.mapName] = {"device": device,
+                                                    "keyfile": key_file,
+                                                    "options": options}
+
+    def crypttab(self):
+        """ Write out /etc/crypttab """
+        crypttab = ""
+        for name in self.mappings:
+            entry = self[name]
+            crypttab += "%s UUID=%s %s %s\n" % (name,
+                                                entry['device'].format.uuid,
+                                                entry['keyfile'],
+                                                entry['options'])
+        return crypttab                       
+
+    def __getitem__(self, key):
+        return self.mappings[key]
+
+    def get(self, key, default=None):
+        return self.mappings.get(key, default)
+
+def get_containing_device(path, devicetree):
+    """ Return the device that a path resides on. """
+    if not os.path.exists(path):
+        return None
+
+    st = os.stat(path)
+    major = os.major(st.st_dev)
+    minor = os.minor(st.st_dev)
+    link = "/sys/dev/block/%s:%s" % (major, minor)
+    if not os.path.exists(link):
+        return None
+
+    try:
+        device_name = os.path.basename(os.readlink(link))
+    except Exception:
+        return None
+
+    if device_name.startswith("dm-"):
+        # have I told you lately that I love you, device-mapper?
+        device_name = name_from_dm_node(device_name)
+
+    return devicetree.getDeviceByName(device_name)
+
+
+class FSSet(object):
+    """ A class to represent a set of filesystems. """
+    def __init__(self, devicetree, rootpath):
+        self.devicetree = devicetree
+        self.rootpath = rootpath
+        self.cryptTab = None
+        self.blkidTab = None
+        self.origFStab = None
+        self.active = False
+        self._dev = None
+        self._devpts = None
+        self._sysfs = None
+        self._proc = None
+        self._devshm = None
+        self.preserveLines = []     # lines we just ignore and preserve
+
+    @property
+    def sysfs(self):
+        if not self._sysfs:
+            self._sysfs = NoDevice(format=getFormat("sysfs",
+                                                    device="sys",
+                                                    mountpoint="/sys"))
+        return self._sysfs
+
+    @property
+    def dev(self):
+        if not self._dev:
+            self._dev = DirectoryDevice("/dev", format=getFormat("bind",
+                                                                 device="/dev",
+                                                                 mountpoint="/dev",
+                                                                 exists=True),
+                                        exists=True)
+
+        return self._dev
+
+    @property
+    def devpts(self):
+        if not self._devpts:
+            self._devpts = NoDevice(format=getFormat("devpts",
+                                                     device="devpts",
+                                                     mountpoint="/dev/pts"))
+        return self._devpts
+
+    @property
+    def proc(self):
+        if not self._proc:
+            self._proc = NoDevice(format=getFormat("proc",
+                                                   device="proc",
+                                                   mountpoint="/proc"))
+        return self._proc
+
+    @property
+    def devshm(self):
+        if not self._devshm:
+            self._devshm = NoDevice(format=getFormat("tmpfs",
+                                                     device="tmpfs",
+                                                     mountpoint="/dev/shm"))
+        return self._devshm
+
+    @property
+    def devices(self):
+        return sorted(self.devicetree.devices, key=lambda d: d.path)
+
+    @property
+    def mountpoints(self):
+        filesystems = {}
+        for device in self.devices:
+            if device.format.mountable and device.format.mountpoint:
+                filesystems[device.format.mountpoint] = device
+        return filesystems
+
+    def _parseOneLine(self, (devspec, mountpoint, fstype, options, dump, passno)):
+        # find device in the tree
+        device = self.devicetree.resolveDevice(devspec,
+                                               cryptTab=self.cryptTab,
+                                               blkidTab=self.blkidTab)
+        if device:
+            # fall through to the bottom of this block
+            pass
+        elif devspec.startswith("/dev/loop"):
+            # FIXME: create devices.LoopDevice
+            log.warning("completely ignoring your loop mount")
+        elif ":" in devspec and fstype.startswith("nfs"):
+            # NFS -- preserve but otherwise ignore
+            device = NFSDevice(devspec,
+                               format=getFormat(fstype,
+                                                device=devspec))
+        elif devspec.startswith("/") and fstype == "swap":
+            # swap file
+            device = FileDevice(devspec,
+                                parents=get_containing_device(devspec, self.devicetree),
+                                format=getFormat(fstype,
+                                                 device=devspec,
+                                                 exists=True),
+                                exists=True)
+        elif fstype == "bind" or "bind" in options:
+            # bind mount... set fstype so later comparison won't
+            # turn up false positives
+            fstype = "bind"
+
+            # This is probably not going to do anything useful, so we'll
+            # make sure to try again from FSSet.mountFilesystems. The bind
+            # mount targets should be accessible by the time we try to do
+            # the bind mount from there.
+            parents = get_containing_device(devspec, self.devicetree)
+            device = DirectoryDevice(devspec, parents=parents, exists=True)
+            device.format = getFormat("bind",
+                                      device=device.path,
+                                      exists=True)
+        elif mountpoint in ("/proc", "/sys", "/dev/shm", "/dev/pts"):
+            # drop these now -- we'll recreate later
+            return None
+        else:
+            # nodev filesystem -- preserve or drop completely?
+            format = getFormat(fstype)
+            if devspec == "none" or \
+               isinstance(format, get_device_format_class("nodev")):
+                device = NoDevice(format=format)
+            else:
+                device = StorageDevice(devspec, format=format)
+
+        if device is None:
+            log.error("failed to resolve %s (%s) from fstab" % (devspec,
+                                                                fstype))
+            raise UnrecognizedFSTabEntryError()
+
+        if device.format.type is None:
+            log.info("Unrecognized filesystem type for %s (%s)"
+                     % (device.name, fstype))
+            raise UnrecognizedFSTabEntryError()
+
+        # make sure, if we're using a device from the tree, that
+        # the device's format we found matches what's in the fstab
+        fmt = getFormat(fstype, device=device.path)
+        if fmt.type != device.format.type:
+            raise StorageError("scanned format (%s) differs from fstab "
+                        "format (%s)" % (device.format.type, fstype))
+
+        if device.format.mountable:
+            device.format.mountpoint = mountpoint
+            device.format.mountopts = options
+
+        # is this useful?
+        try:
+            device.format.options = options
+        except AttributeError:
+            pass
+
+        return device
+
+    def parseFSTab(self, chroot=None):
+        """ parse /etc/fstab
+
+            preconditions:
+                all storage devices have been scanned, including filesystems
+            postconditions:
+
+            FIXME: control which exceptions we raise
+
+            XXX do we care about bind mounts?
+                how about nodev mounts?
+                loop mounts?
+        """
+        if not chroot or not os.path.isdir(chroot):
+            chroot = self.rootpath
+
+        path = "%s/etc/fstab" % chroot
+        if not os.access(path, os.R_OK):
+            # XXX should we raise an exception instead?
+            log.info("cannot open %s for read" % path)
+            return
+
+        blkidTab = BlkidTab(chroot=chroot)
+        try:
+            blkidTab.parse()
+            log.debug("blkid.tab devs: %s" % blkidTab.devices.keys())
+        except Exception as e:
+            log.info("error parsing blkid.tab: %s" % e)
+            blkidTab = None
+
+        cryptTab = CryptTab(self.devicetree, blkidTab=blkidTab, chroot=chroot)
+        try:
+            cryptTab.parse(chroot=chroot)
+            log.debug("crypttab maps: %s" % cryptTab.mappings.keys())
+        except Exception as e:
+            log.info("error parsing crypttab: %s" % e)
+            cryptTab = None
+
+        self.blkidTab = blkidTab
+        self.cryptTab = cryptTab
+
+        with open(path) as f:
+            log.debug("parsing %s" % path)
+
+            lines = f.readlines()
+
+            # save the original file
+            self.origFStab = ''.join(lines)
+
+            for line in lines:
+                # strip off comments
+                (line, pound, comment) = line.partition("#")
+                fields = line.split()
+
+                if not 4 <= len(fields) <= 6:
+                    continue
+                elif len(fields) == 4:
+                    fields.extend([0, 0])
+                elif len(fields) == 5:
+                    fields.append(0)
+
+                (devspec, mountpoint, fstype, options, dump, passno) = fields
+
+                try:
+                    device = self._parseOneLine((devspec, mountpoint, fstype, options, dump, passno))
+                except UnrecognizedFSTabEntryError:
+                    # just write the line back out as-is after upgrade
+                    self.preserveLines.append(line)
+                    continue
+                except Exception as e:
+                    raise Exception("fstab entry %s is malformed: %s" % (devspec, e))
+
+                if not device:
+                    continue
+
+                if device not in self.devicetree.devices:
+                    try:
+                        self.devicetree._addDevice(device)
+                    except ValueError:
+                        # just write duplicates back out post-install
+                        self.preserveLines.append(line)
+
+    def fsFreeSpace(self, chroot=None):
+        if not chroot:
+            chroot = self.rootpath
+
+        space = []
+        for device in self.devices:
+            if not device.format.mountable or \
+               not device.format.mountpoint or \
+               not device.format.status:
+                continue
+
+            path = "%s/%s" % (chroot, device.format.mountpoint)
+
+            ST_RDONLY = 1   # this should be in python's posix module
+            if not os.path.exists(path) or os.statvfs(path)[statvfs.F_FLAG] & ST_RDONLY:
+                continue
+
+            try:
+                space.append((device.format.mountpoint,
+                              isys.pathSpaceAvailable(path)))
+            except SystemError:
+                log.error("failed to calculate free space for %s" % (device.format.mountpoint,))
+
+        space.sort(key=lambda s: s[1])
+        return space
+
+    def mtab(self):
+        format = "%s %s %s %s 0 0\n"
+        mtab = ""
+        devices = self.mountpoints.values() + self.swapDevices
+        devices.extend([self.devshm, self.devpts, self.sysfs, self.proc])
+        devices.sort(key=lambda d: getattr(d.format, "mountpoint", None))
+        for device in devices:
+            if not device.format.status:
+                continue
+            if not device.format.mountable:
+                continue
+            if device.format.mountpoint:
+                options = device.format.mountopts
+                if options:
+                    options = options.replace("defaults,", "")
+                    options = options.replace("defaults", "")
+
+                if options:
+                    options = "rw," + options
+                else:
+                    options = "rw"
+                mtab = mtab + format % (device.path,
+                                        device.format.mountpoint,
+                                        device.format.type,
+                                        options)
+        return mtab
+
+    def turnOnSwap(self, anaconda, upgrading=None):
+        def swapErrorDialog(msg, device):
+            if not anaconda.intf:
+                sys.exit(0)
+
+            buttons = [_("Skip"), _("Format"), _("_Exit")]
+            ret = anaconda.intf.messageWindow(_("Error"), msg, type="custom",
+                                              custom_buttons=buttons,
+                                              custom_icon="warning")
+
+            if ret == 0:
+                self.devicetree._removeDevice(device)
+                return False
+            elif ret == 1:
+                device.format.create(force=True)
+                return True
+            else:
+                sys.exit(0)
+
+        for device in self.swapDevices:
+            if isinstance(device, FileDevice):
+                # set up FileDevices' parents now that they are accessible
+                targetDir = "%s/%s" % (anaconda.rootPath, device.path)
+                parent = get_containing_device(targetDir, self.devicetree)
+                if not parent:
+                    log.error("cannot determine which device contains "
+                              "directory %s" % device.path)
+                    device.parents = []
+                    self.devicetree._removeDevice(device)
+                    continue
+                else:
+                    device.parents = [parent]
+
+            while True:
+                try:
+                    device.setup()
+                    device.format.setup()
+                except OldSwapError:
+                    msg = _("The swap device:\n\n     %s\n\n"
+                            "is an old-style Linux swap partition.  If "
+                            "you want to use this device for swap space, "
+                            "you must reformat as a new-style Linux swap "
+                            "partition.") \
+                          % device.path
+
+                    if swapErrorDialog(msg, device):
+                        continue
+                except SuspendError:
+                    if upgrading:
+                        msg = _("The swap device:\n\n     %s\n\n"
+                                "in your /etc/fstab file is currently in "
+                                "use as a software suspend device, "
+                                "which means your system is hibernating. "
+                                "To perform an upgrade, please shut down "
+                                "your system rather than hibernating it.") \
+                              % device.path
+                    else:
+                        msg = _("The swap device:\n\n     %s\n\n"
+                                "in your /etc/fstab file is currently in "
+                                "use as a software suspend device, "
+                                "which means your system is hibernating. "
+                                "If you are performing a new install, "
+                                "make sure the installer is set "
+                                "to format all swap devices.") \
+                              % device.path
+
+                    if swapErrorDialog(msg, device):
+                        continue
+                except UnknownSwapError:
+                    msg = _("The swap device:\n\n     %s\n\n"
+                            "does not contain a supported swap volume.  In "
+                            "order to continue installation, you will need "
+                            "to format the device or skip it.") \
+                          % device.path
+
+                    if swapErrorDialog(msg, device):
+                        continue
+                except DeviceError as (msg, name):
+                    if anaconda.intf:
+                        if upgrading:
+                            err = _("Error enabling swap device %(name)s: "
+                                    "%(msg)s\n\n"
+                                    "The /etc/fstab on your upgrade partition "
+                                    "does not reference a valid swap "
+                                    "device.\n\nPress OK to exit the "
+                                    "installer") % {'name': name, 'msg': msg}
+                        else:
+                            err = _("Error enabling swap device %(name)s: "
+                                    "%(msg)s\n\n"
+                                    "This most likely means this swap "
+                                    "device has not been initialized.\n\n"
+                                    "Press OK to exit the installer.") % \
+                                  {'name': name, 'msg': msg}
+                        anaconda.intf.messageWindow(_("Error"), err)
+                    sys.exit(0)
+
+                break
+
+    def mountFilesystems(self, anaconda, raiseErrors=None, readOnly=None,
+                         skipRoot=False):
+        intf = anaconda.intf
+        devices = self.mountpoints.values() + self.swapDevices
+        devices.extend([self.dev, self.devshm, self.devpts, self.sysfs, self.proc])
+        devices.sort(key=lambda d: getattr(d.format, "mountpoint", None))
+
+        for device in devices:
+            if not device.format.mountable or not device.format.mountpoint:
+                continue
+
+            if skipRoot and device.format.mountpoint == "/":
+                continue
+
+            options = device.format.options
+            if "noauto" in options.split(","):
+                continue
+
+            if device.format.type == "bind" and device != self.dev:
+                # set up the DirectoryDevice's parents now that they are
+                # accessible
+                #
+                # -- bind formats' device and mountpoint are always both
+                #    under the chroot. no exceptions. none, damn it.
+                targetDir = "%s/%s" % (anaconda.rootPath, device.path)
+                parent = get_containing_device(targetDir, self.devicetree)
+                if not parent:
+                    log.error("cannot determine which device contains "
+                              "directory %s" % device.path)
+                    device.parents = []
+                    self.devicetree._removeDevice(device)
+                    continue
+                else:
+                    device.parents = [parent]
+
+            try:
+                device.setup()
+            except Exception as msg:
+                # FIXME: need an error popup
+                continue
+
+            if readOnly:
+                options = "%s,%s" % (options, readOnly)
+
+            try:
+                device.format.setup(options=options,
+                                    chroot=anaconda.rootPath)
+            except OSError as e:
+                log.error("OSError: (%d) %s" % (e.errno, e.strerror))
+
+                if intf:
+                    if e.errno == errno.EEXIST:
+                        intf.messageWindow(_("Invalid mount point"),
+                                           _("An error occurred when trying "
+                                             "to create %s.  Some element of "
+                                             "this path is not a directory. "
+                                             "This is a fatal error and the "
+                                             "install cannot continue.\n\n"
+                                             "Press <Enter> to exit the "
+                                             "installer.")
+                                           % (device.format.mountpoint,))
+                    else:
+                        na = {'mountpoint': device.format.mountpoint,
+                              'msg': e.strerror}
+                        intf.messageWindow(_("Invalid mount point"),
+                                           _("An error occurred when trying "
+                                             "to create %(mountpoint)s: "
+                                             "%(msg)s.  This is "
+                                             "a fatal error and the install "
+                                             "cannot continue.\n\n"
+                                             "Press <Enter> to exit the "
+                                             "installer.") % na)
+                sys.exit(0)
+            except SystemError as (num, msg):
+                log.error("SystemError: (%d) %s" % (num, msg) )
+
+                if raiseErrors:
+                    raise
+                if intf and not device.format.linuxNative:
+                    na = {'path': device.path,
+                          'mountpoint': device.format.mountpoint}
+                    ret = intf.messageWindow(_("Unable to mount filesystem"),
+                                             _("An error occurred mounting "
+                                             "device %(path)s as "
+                                             "%(mountpoint)s.  You may "
+                                             "continue installation, but "
+                                             "there may be problems.") % na,
+                                             type="custom",
+                                             custom_icon="warning",
+                                             custom_buttons=[_("_Exit installer"),
+                                                            _("_Continue")])
+
+                    if ret == 0:
+                        sys.exit(0)
+                    else:
+                        continue
+
+                sys.exit(0)
+            except FSError as msg:
+                log.error("FSError: %s" % msg)
+
+                if intf:
+                    na = {'path': device.path,
+                          'mountpoint': device.format.mountpoint,
+                          'msg': msg}
+                    intf.messageWindow(_("Unable to mount filesystem"),
+                                       _("An error occurred mounting "
+                                         "device %(path)s as %(mountpoint)s: "
+                                         "%(msg)s. This is "
+                                         "a fatal error and the install "
+                                         "cannot continue.\n\n"
+                                         "Press <Enter> to exit the "
+                                         "installer.") % na)
+                sys.exit(0)
+
+        self.active = True
+
+    def umountFilesystems(self, ignoreErrors=True, swapoff=True):
+        devices = self.mountpoints.values() + self.swapDevices
+        devices.extend([self.dev, self.devshm, self.devpts, self.sysfs, self.proc])
+        devices.sort(key=lambda d: getattr(d.format, "mountpoint", None))
+        devices.reverse()
+        for device in devices:
+            if not device.format.mountable and \
+               (device.format.type != "swap" or swapoff):
+                continue
+
+            device.format.teardown()
+            device.teardown()
+
+        self.active = False
+
+    def createSwapFile(self, device, size, rootPath=None):
+        """ Create and activate a swap file under rootPath. """
+        if not rootPath:
+            rootPath = self.rootpath
+
+        filename = "/SWAP"
+        count = 0
+        basedir = os.path.normpath("%s/%s" % (rootPath,
+                                              device.format.mountpoint))
+        while os.path.exists("%s/%s" % (basedir, filename)) or \
+              self.devicetree.getDeviceByName(filename):
+            file = os.path.normpath("%s/%s" % (basedir, filename))
+            count += 1
+            filename = "/SWAP-%d" % count
+
+        dev = FileDevice(filename,
+                         size=size,
+                         parents=[device],
+                         format=getFormat("swap", device=filename))
+        dev.create()
+        dev.setup()
+        dev.format.create()
+        dev.format.setup()
+        # nasty, nasty
+        self.devicetree._addDevice(dev)
+
+    def mkDevRoot(self, instPath=None):
+        if not instPath:
+            instPath = self.rootpath
+
+        root = self.rootDevice
+        dev = "%s/%s" % (instPath, root.path)
+        if not os.path.exists("%s/dev/root" %(instPath,)) and os.path.exists(dev):
+            rdev = os.stat(dev).st_rdev
+            os.mknod("%s/dev/root" % (instPath,), stat.S_IFBLK | 0600, rdev)
+
+    @property
+    def swapDevices(self):
+        swaps = []
+        for device in self.devices:
+            if device.format.type == "swap":
+                swaps.append(device)
+        return swaps
+
+    @property
+    def rootDevice(self):
+        for path in ["/", self.rootpath]:
+            for device in self.devices:
+                try:
+                    mountpoint = device.format.mountpoint
+                except AttributeError:
+                    mountpoint = None
+
+                if mountpoint == path:
+                    return device
+
+    @property
+    def migratableDevices(self):
+        """ List of devices whose filesystems can be migrated. """
+        migratable = []
+        for device in self.devices:
+            if device.format.migratable and device.format.exists:
+                migratable.append(device)
+
+        return migratable
+
+    def write(self, instPath=None):
+        """ write out all config files based on the set of filesystems """
+        if not instPath:
+            instPath = self.rootpath
+
+        # /etc/fstab
+        fstab_path = os.path.normpath("%s/etc/fstab" % instPath)
+        fstab = self.fstab()
+        open(fstab_path, "w").write(fstab)
+
+        # /etc/crypttab
+        crypttab_path = os.path.normpath("%s/etc/crypttab" % instPath)
+        crypttab = self.crypttab()
+        open(crypttab_path, "w").write(crypttab)
+
+        # /etc/mdadm.conf
+        mdadm_path = os.path.normpath("%s/etc/mdadm.conf" % instPath)
+        mdadm_conf = self.mdadmConf()
+        if mdadm_conf:
+            open(mdadm_path, "w").write(mdadm_conf)
+
+        # /etc/multipath.conf
+        multipath_path = os.path.normpath("%s/etc/multipath.conf" % instPath)
+        multipath_conf = self.multipathConf()
+        if multipath_conf:
+            open(multipath_path, "w").write(multipath_conf)
+
+    def crypttab(self):
+        # if we are upgrading, do we want to update crypttab?
+        # gut reaction says no, but plymouth needs the names to be very
+        # specific for passphrase prompting
+        if not self.cryptTab:
+            self.cryptTab = CryptTab(self.devicetree)
+            self.cryptTab.populate()
+
+        devices = self.mountpoints.values() + self.swapDevices
+
+        # prune crypttab -- only mappings required by one or more entries
+        for name in self.cryptTab.mappings.keys():
+            keep = False
+            mapInfo = self.cryptTab[name]
+            cryptoDev = mapInfo['device']
+            for device in devices:
+                if device == cryptoDev or device.dependsOn(cryptoDev):
+                    keep = True
+                    break
+
+            if not keep:
+                del self.cryptTab.mappings[name]
+
+        return self.cryptTab.crypttab()
+
+    def mdadmConf(self):
+        """ Return the contents of mdadm.conf. """
+        arrays = self.devicetree.getDevicesByType("mdarray")
+        arrays.extend(self.devicetree.getDevicesByType("mdbiosraidarray"))
+        arrays.extend(self.devicetree.getDevicesByType("mdcontainer"))
+        # Sort it, this not only looks nicer, but this will also put
+        # containers (which get md0, md1, etc.) before their members
+        # (which get md127, md126, etc.). and lame as it is mdadm will not
+        # assemble the whole stack in one go unless listed in the proper order
+        # in mdadm.conf
+        arrays.sort(key=lambda d: d.path)
+
+        conf = "# mdadm.conf written out by anaconda\n"
+        conf += "MAILADDR root\n"
+        conf += "AUTO +imsm +1.x -all\n"
+        devices = self.mountpoints.values() + self.swapDevices
+        for array in arrays:
+            for device in devices:
+                if device == array or device.dependsOn(array):
+                    conf += array.mdadmConfEntry
+                    break
+
+        return conf
+
+    def multipathConf(self):
+        """ Return the contents of multipath.conf. """
+        mpaths = self.devicetree.getDevicesByType("dm-multipath")
+        if not mpaths:
+            return None
+        mpaths.sort(key=lambda d: d.name)
+        config = MultipathConfigWriter()
+        whitelist = []
+        for mpath in mpaths:
+            config.addMultipathDevice(mpath)
+            whitelist.append(mpath.name)
+            whitelist.extend([d.name for d in mpath.parents])
+
+        # blacklist everything we're not using and let the
+        # sysadmin sort it out.
+        for d in self.devicetree.devices:
+            if not d.name in whitelist:
+                config.addBlacklistDevice(d)
+
+        return config.write()
+
+    def fstab (self):
+        format = "%-23s %-23s %-7s %-15s %d %d\n"
+        fstab = """
+#
+# /etc/fstab
+# Created by anaconda on %s
+#
+# Accessible filesystems, by reference, are maintained under '/dev/disk'
+# See man pages fstab(5), findfs(8), mount(8) and/or blkid(8) for more info
+#
+""" % time.asctime()
+
+        devices = sorted(self.mountpoints.values(),
+                         key=lambda d: d.format.mountpoint)
+        devices += self.swapDevices
+        devices.extend([self.devshm, self.devpts, self.sysfs, self.proc])
+        netdevs = self.devicetree.getDevicesByInstance(NetworkStorageDevice)
+        for device in devices:
+            # why the hell do we put swap in the fstab, anyway?
+            if not device.format.mountable and device.format.type != "swap":
+                continue
+
+            # Don't write out lines for optical devices, either.
+            if isinstance(device, OpticalDevice):
+                continue
+
+            fstype = getattr(device.format, "mountType", device.format.type)
+            if fstype == "swap":
+                mountpoint = "swap"
+                options = device.format.options
+            else:
+                mountpoint = device.format.mountpoint
+                options = device.format.options
+                if not mountpoint:
+                    log.warning("%s filesystem on %s has no mountpoint" % \
+                                                            (fstype,
+                                                             device.path))
+                    continue
+
+            options = options or "defaults"
+            for netdev in netdevs:
+                if device.dependsOn(netdev):
+                    options = options + ",_netdev"
+                    break
+            devspec = device.fstabSpec
+            dump = device.format.dump
+            if device.format.check and mountpoint == "/":
+                passno = 1
+            elif device.format.check:
+                passno = 2
+            else:
+                passno = 0
+            fstab = fstab + device.fstabComment
+            fstab = fstab + format % (devspec, mountpoint, fstype,
+                                      options, dump, passno)
+
+        # now, write out any lines we were unable to process because of
+        # unrecognized filesystems or unresolveable device specifications
+        for line in self.preserveLines:
+            fstab += line
+
+        return fstab
diff --git a/pyanaconda/storage/dasd.py b/pyanaconda/storage/dasd.py
new file mode 100644
index 0000000..f113cfb
--- /dev/null
+++ b/pyanaconda/storage/dasd.py
@@ -0,0 +1,225 @@
+#
+# dasd.py - DASD class
+#
+# Copyright (C) 2009, 2010  Red Hat, Inc.  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 as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# 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, see <http://www.gnu.org/licenses/>.
+#
+# Red Hat Author(s): David Cantrell <dcantrell@xxxxxxxxxx>
+#
+
+import iutil
+import sys
+import os
+from storage.errors import DasdFormatError
+from storage.devices import deviceNameToDiskByPath
+from constants import *
+from flags import flags
+
+import logging
+log = logging.getLogger("anaconda")
+
+import gettext
+_ = lambda x: gettext.ldgettext("anaconda", x)
+P_ = lambda x, y, z: gettext.ldngettext("anaconda", x, y, z)
+
+def getDasdPorts():
+    """ Return comma delimited string of valid DASD ports. """
+    ports = []
+
+    f = open("/proc/dasd/devices", "r")
+    lines = map(lambda x: x.strip(), f.readlines())
+    f.close()
+
+    for line in lines:
+        if "unknown" in line:
+            continue
+
+        if "(FBA )" in line or "(ECKD)" in line:
+            ports.append(line.split('(')[0])
+
+    return ','.join(ports)
+
+class DASD:
+    """ Controlling class for DASD interaction before the storage code in
+        anaconda has initialized.
+
+        The DASD class can determine if any DASD devices on the system are
+        unformatted and can perform a dasdfmt on them.
+    """
+
+    def __init__(self):
+        self._dasdlist = []
+        self._devices = []                  # list of DASDDevice objects
+        self.totalCylinders = 0
+        self._completedCylinders = 0.0
+        self._maxFormatJobs = 0
+        self.dasdfmt = "/sbin/dasdfmt"
+        self.commonArgv = ["-y", "-d", "cdl", "-b", "4096"]
+        self.started = False
+
+    def __call__(self):
+        return self
+
+    def startup(self, intf, exclusiveDisks, zeroMbr):
+        """ Look for any unformatted DASDs in the system and offer the user
+            the option for format them with dasdfmt or exit the installer.
+        """
+        if self.started:
+            return
+
+        self.started = True
+        out = "/dev/tty5"
+        err = "/dev/tty5"
+
+        if not iutil.isS390():
+            return
+
+        log.info("Checking for unformatted DASD devices:")
+
+        for device in os.listdir("/sys/block"):
+            if not device.startswith("dasd"):
+                continue
+
+            statusfile = "/sys/block/%s/device/status" % (device,)
+            if not os.path.isfile(statusfile):
+                continue
+
+            f = open(statusfile, "r")
+            status = f.read().strip()
+            f.close()
+
+            if status in ["unformatted"] and device not in exclusiveDisks:
+                bypath = deviceNameToDiskByPath(device)
+                if not bypath:
+                    bypath = "/dev/" + device
+
+                log.info("    %s (%s) status is %s, needs dasdfmt" % (device,
+                                                                      bypath,
+                                                                      status,))
+                self._dasdlist.append((device, bypath))
+
+        if not len(self._dasdlist):
+            log.info("    no unformatted DASD devices found")
+            return
+
+        askUser = True
+
+        if zeroMbr:
+            askUser = False
+        elif not intf and not zeroMbr:
+            log.info("    non-interactive kickstart install without zerombr "
+                     "command, unable to run dasdfmt, exiting installer")
+            sys.exit(0)
+
+        c = len(self._dasdlist)
+
+        if intf and askUser:
+            devs = ''
+            for dasd, bypath in self._dasdlist:
+                devs += "%s\n" % (bypath,)
+
+            rc = intf.questionInitializeDASD(c, devs)
+            if rc == 1:
+                log.info("    not running dasdfmt, continuing installation")
+                return
+
+        # gather total cylinder count
+        argv = ["-t", "-v"] + self.commonArgv
+        for dasd, bypath in self._dasdlist:
+            buf = iutil.execWithCapture(self.dasdfmt, argv + ["/dev/" + dasd],
+                                        stderr=err)
+            for line in buf.splitlines():
+                if line.startswith("Drive Geometry: "):
+                    # line will look like this:
+                    # Drive Geometry: 3339 Cylinders * 15 Heads =  50085 Tracks
+                    cyls = long(filter(lambda s: s, line.split(' '))[2])
+                    self.totalCylinders += cyls
+                    break
+
+        # format DASDs
+        argv = ["-P"] + self.commonArgv
+        update = self._updateProgressWindow
+
+        title = P_("Formatting DASD Device", "Formatting DASD Devices", c)
+        msg = P_("Preparing %d DASD device for use with Linux..." % c,
+                 "Preparing %d DASD devices for use with Linux..." % c, c)
+
+        if intf:
+            if self.totalCylinders:
+                pw = intf.progressWindow(title, msg, 1.0)
+            else:
+                pw = intf.progressWindow(title, msg, 100, pulse=True)
+
+        for dasd, bypath in self._dasdlist:
+            log.info("Running dasdfmt on %s" % (bypath,))
+            arglist = argv + ["/dev/" + dasd]
+
+            try:
+                if intf and self.totalCylinders:
+                    rc = iutil.execWithCallback(self.dasdfmt, arglist,
+                                                stdout=out, stderr=err,
+                                                callback=update,
+                                                callback_data=pw,
+                                                echo=False)
+                elif intf:
+                    rc = iutil.execWithPulseProgress(self.dasdfmt, arglist,
+                                                     stdout=out, stderr=err,
+                                                     progress=pw)
+                else:
+                    rc = iutil.execWithRedirect(self.dasdfmt, arglist,
+                                                stdout=out, stderr=err)
+            except Exception as e:
+                raise DasdFormatError(e, bypath)
+
+            if rc:
+                raise DasdFormatError("dasdfmt failed: %s" % rc, bypath)
+
+        if intf:
+            pw.pop()
+
+    def addDASD(self, dasd):
+        """ Adds a DASDDevice to the internal list of DASDs. """
+        if dasd:
+            self._devices.append(dasd)
+
+    def write(self, instPath):
+        """ Write /etc/dasd.conf to target system for all DASD devices
+            configured during installation.
+        """
+        if self._devices == []:
+            return
+
+        f = open(os.path.realpath(instPath + "/etc/dasd.conf"), "w")
+        for dasd in self._devices:
+            fields = [dasd.busid] + dasd.getOpts()
+            f.write("%s\n" % (" ".join(fields),))
+        f.close()
+
+    def _updateProgressWindow(self, data, callback_data=None):
+        """ Reads progress output from dasdfmt and collects the number of
+            cylinders completed so the progress window can update.
+        """
+        if not callback_data:
+            return
+
+        if data == '\n':
+            # each newline we see in this output means one more cylinder done
+            self._completedCylinders += 1.0
+            callback_data.set(self._completedCylinders / self.totalCylinders)
+
+# Create DASD singleton
+DASD = DASD()
+
+# vim:tw=78:ts=4:et:sw=4
diff --git a/pyanaconda/storage/deviceaction.py b/pyanaconda/storage/deviceaction.py
new file mode 100644
index 0000000..4524e7c
--- /dev/null
+++ b/pyanaconda/storage/deviceaction.py
@@ -0,0 +1,376 @@
+# deviceaction.py
+# Device modification action classes for anaconda's storage configuration
+# module.
+#
+# Copyright (C) 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, or (at your option) any later version.
+# 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.
+#
+# Red Hat Author(s): Dave Lehman <dlehman@xxxxxxxxxx>
+#
+
+from udev import *
+
+from devices import StorageDevice, PartitionDevice
+from formats import getFormat
+from errors import *
+from parted import partitionFlag, PARTITION_LBA
+
+import gettext
+_ = lambda x: gettext.ldgettext("anaconda", x)
+
+import logging
+log = logging.getLogger("storage")
+
+
+# The values are just hints as to the ordering.
+# Eg: fsmod and devmod ordering depends on the mod (shrink -v- grow)
+ACTION_TYPE_NONE = 0
+ACTION_TYPE_DESTROY = 1000
+ACTION_TYPE_RESIZE = 500
+ACTION_TYPE_MIGRATE = 250
+ACTION_TYPE_CREATE = 100
+
+action_strings = {ACTION_TYPE_NONE: "None",
+                  ACTION_TYPE_DESTROY: "Destroy",
+                  ACTION_TYPE_RESIZE: "Resize",
+                  ACTION_TYPE_MIGRATE: "Migrate",
+                  ACTION_TYPE_CREATE: "Create"}
+
+ACTION_OBJECT_NONE = 0
+ACTION_OBJECT_FORMAT = 1
+ACTION_OBJECT_DEVICE = 2
+
+object_strings = {ACTION_OBJECT_NONE: "None",
+                  ACTION_OBJECT_FORMAT: "Format",
+                  ACTION_OBJECT_DEVICE: "Device"}
+
+RESIZE_SHRINK = 88
+RESIZE_GROW = 89
+
+resize_strings = {RESIZE_SHRINK: "Shrink",
+                  RESIZE_GROW: "Grow"}
+
+def action_type_from_string(type_string):
+    if type_string is None:
+        return None
+
+    for (k,v) in action_strings.items():
+        if v.lower() == type_string.lower():
+            return k
+
+    return resize_type_from_string(type_string)
+
+def action_object_from_string(type_string):
+    if type_string is None:
+        return None
+
+    for (k,v) in object_strings.items():
+        if v.lower() == type_string.lower():
+            return k
+
+def resize_type_from_string(type_string):
+    if type_string is None:
+        return None
+
+    for (k,v) in resize_strings.items():
+        if v.lower() == type_string.lower():
+            return k
+
+class DeviceAction(object):
+    """ An action that will be carried out in the future on a Device.
+
+        These classes represent actions to be performed on devices or
+        filesystems.
+
+        The operand Device instance will be modified according to the
+        action, but no changes will be made to the underlying device or
+        filesystem until the DeviceAction instance's execute method is
+        called. The DeviceAction instance's cancel method should reverse
+        any modifications made to the Device instance's attributes.
+
+        If the Device instance represents a pre-existing device, the
+        constructor should call any methods or set any attributes that the
+        action will eventually change. Device/DeviceFormat classes should verify
+        that the requested modifications are reasonable and raise an
+        exception if not.
+
+        Only one action of any given type/object pair can exist for any
+        given device at any given time. This is enforced by the
+        DeviceTree.
+
+        Basic usage:
+
+            a = DeviceAction(dev)
+            a.execute()
+
+            OR
+
+            a = DeviceAction(dev)
+            a.cancel()
+
+
+        XXX should we back up the device with a deep copy for forcibly
+            cancelling actions?
+
+            The downside is that we lose any checking or verification that
+            would get done when resetting the Device instance's attributes to
+            their original values.
+
+            The upside is that we would be guaranteed to achieve a total
+            reversal. No chance of, eg: resizes ending up altering Device
+            size due to rounding or other miscalculation.
+"""
+    type = ACTION_TYPE_NONE
+    obj = ACTION_OBJECT_NONE
+
+    def __init__(self, device):
+        if not isinstance(device, StorageDevice):
+            raise ValueError("arg 1 must be a StorageDevice instance")
+        self.device = device
+
+
+    def execute(self, intf=None):
+        """ perform the action """
+        pass
+
+    def cancel(self):
+        """ cancel the action """
+        pass
+
+    def isDestroy(self):
+        return self.type == ACTION_TYPE_DESTROY
+
+    def isCreate(self):
+        return self.type == ACTION_TYPE_CREATE
+
+    def isMigrate(self):
+        return self.type == ACTION_TYPE_MIGRATE
+
+    def isResize(self):
+        return self.type == ACTION_TYPE_RESIZE
+
+    def isShrink(self):
+        return (self.type == ACTION_TYPE_RESIZE and self.dir == RESIZE_SHRINK)
+
+    def isGrow(self):
+        return (self.type == ACTION_TYPE_RESIZE and self.dir == RESIZE_GROW)
+
+    def isDevice(self):
+        return self.obj == ACTION_OBJECT_DEVICE
+
+    def isFormat(self):
+        return self.obj == ACTION_OBJECT_FORMAT
+
+    @property
+    def format(self):
+        return self.device.format
+
+    def __str__(self):
+        s = "%s %s" % (action_strings[self.type], object_strings[self.obj])
+        if self.isResize():
+            s += " (%s)" % resize_strings[self.dir]
+        if self.isFormat():
+            s += " %s on" % self.format.type
+        if self.isMigrate():
+            s += " to %s" % self.format.migrationTarget
+        s += " %s %s (id %d)" % (self.device.type, self.device.name,
+                                 self.device.id)
+        return s
+
+class ActionCreateDevice(DeviceAction):
+    """ Action representing the creation of a new device. """
+    type = ACTION_TYPE_CREATE
+    obj = ACTION_OBJECT_DEVICE
+
+    def __init__(self, device):
+        # FIXME: assert device.fs is None
+        DeviceAction.__init__(self, device)
+
+    def execute(self, intf=None):
+        self.device.create(intf=intf)
+
+
+class ActionDestroyDevice(DeviceAction):
+    """ An action representing the deletion of an existing device. """
+    type = ACTION_TYPE_DESTROY
+    obj = ACTION_OBJECT_DEVICE
+
+    def __init__(self, device):
+        # XXX should we insist that device.fs be None?
+        DeviceAction.__init__(self, device)
+        if device.exists:
+            device.teardown()
+
+    def execute(self, intf=None):
+        self.device.destroy()
+
+        # Make sure libparted does not keep cached info for this device
+        # and returns it when we create a new device with the same name
+        if self.device.partedDevice:
+            self.device.partedDevice.removeFromCache()
+
+
+class ActionResizeDevice(DeviceAction):
+    """ An action representing the resizing of an existing device. """
+    type = ACTION_TYPE_RESIZE
+    obj = ACTION_OBJECT_DEVICE
+
+    def __init__(self, device, newsize):
+        if device.currentSize == newsize:
+            raise ValueError("new size same as old size")
+
+        if not device.resizable:
+            raise ValueError("device is not resizable")
+
+        DeviceAction.__init__(self, device)
+        if newsize > device.currentSize:
+            self.dir = RESIZE_GROW
+        else:
+            self.dir = RESIZE_SHRINK
+        self.origsize = device.targetSize
+        self.device.targetSize = newsize
+
+    def execute(self, intf=None):
+        self.device.resize(intf=intf)
+
+    def cancel(self):
+        self.device.targetSize = self.origsize
+
+
+class ActionCreateFormat(DeviceAction):
+    """ An action representing creation of a new filesystem. """
+    type = ACTION_TYPE_CREATE
+    obj = ACTION_OBJECT_FORMAT
+
+    def __init__(self, device, format=None):
+        DeviceAction.__init__(self, device)
+        if format:
+            self.origFormat = device.format
+            if self.device.format.exists:
+                self.device.format.teardown()
+            self.device.format = format
+        else:
+            self.origFormat = getFormat(None)
+
+    def execute(self, intf=None):
+        self.device.setup()
+
+        if isinstance(self.device, PartitionDevice):
+            for flag in partitionFlag.keys():
+                # Keep the LBA flag on pre-existing partitions
+                if flag in [ PARTITION_LBA, self.format.partedFlag ]:
+                    continue
+                self.device.unsetFlag(flag)
+
+            if self.format.partedFlag is not None:
+                self.device.setFlag(self.format.partedFlag)
+
+            if self.format.partedSystem is not None:
+                self.device.partedPartition.system = self.format.partedSystem
+
+            self.device.disk.format.commitToDisk()
+
+        self.device.format.create(intf=intf,
+                                  device=self.device.path,
+                                  options=self.device.formatArgs)
+        # Get the UUID now that the format is created
+        udev_settle()
+        self.device.updateSysfsPath()
+        info = udev_get_block_device(self.device.sysfsPath)
+        self.device.format.uuid = udev_device_get_uuid(info)
+
+    def cancel(self):
+        self.device.format = self.origFormat
+
+
+class ActionDestroyFormat(DeviceAction):
+    """ An action representing the removal of an existing filesystem.
+
+        XXX this seems unnecessary
+    """
+    type = ACTION_TYPE_DESTROY
+    obj = ACTION_OBJECT_FORMAT
+
+    def __init__(self, device):
+        DeviceAction.__init__(self, device)
+        self.origFormat = self.device.format
+        if device.format.exists:
+            device.format.teardown()
+        self.device.format = None
+
+    def execute(self, intf=None):
+        """ wipe the filesystem signature from the device """
+        if self.origFormat:
+            self.device.setup(orig=True)
+            self.origFormat.destroy()
+            udev_settle()
+            self.device.teardown()
+
+    def cancel(self):
+        self.device.format = self.origFormat
+
+    @property
+    def format(self):
+        return self.origFormat
+
+
+class ActionResizeFormat(DeviceAction):
+    """ An action representing the resizing of an existing filesystem.
+
+        XXX Do we even want to support resizing of a filesystem without
+            also resizing the device it resides on?
+    """
+    type = ACTION_TYPE_RESIZE
+    obj = ACTION_OBJECT_FORMAT
+
+    def __init__(self, device, newsize):
+        if device.format.targetSize == newsize:
+            raise ValueError("new size same as old size")
+
+        DeviceAction.__init__(self, device)
+        if newsize > device.format.currentSize:
+            self.dir = RESIZE_GROW
+        else:
+            self.dir = RESIZE_SHRINK
+        self.origSize = self.device.format.targetSize
+        self.device.format.targetSize = newsize
+
+    def execute(self, intf=None):
+        self.device.setup(orig=True)
+        self.device.format.doResize(intf=intf)
+
+    def cancel(self):
+        self.device.format.targetSize = self.origSize
+
+class ActionMigrateFormat(DeviceAction):
+    """ An action representing the migration of an existing filesystem. """
+    type = ACTION_TYPE_MIGRATE
+    obj = ACTION_OBJECT_FORMAT
+
+    def __init__(self, device):
+        if not device.format.migratable or not device.format.exists:
+            raise ValueError("device format is not migratable")
+
+        DeviceAction.__init__(self, device)
+        self.device.format.migrate = True
+
+    def execute(self, intf=None):
+        self.device.setup(orig=True)
+        self.device.format.doMigrate(intf=intf)
+
+    def cancel(self):
+        self.device.format.migrate = False
+
diff --git a/pyanaconda/storage/devicelibs/Makefile.am b/pyanaconda/storage/devicelibs/Makefile.am
new file mode 100644
index 0000000..86a7d5e
--- /dev/null
+++ b/pyanaconda/storage/devicelibs/Makefile.am
@@ -0,0 +1,24 @@
+# storage/devicelibs/Makefile.am for anaconda
+#
+# Copyright (C) 2009  Red Hat, Inc.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License as published
+# by the Free Software Foundation; either version 2.1 of the License, or
+# (at your option) any later version.
+#
+# 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 Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+#
+# Author: David Cantrell <dcantrell@xxxxxxxxxx>
+
+pkgpyexecdir = $(pyexecdir)/py$(PACKAGE_NAME)
+storagedevicelibsdir = $(pkgpyexecdir)/storage/devicelibs
+storagedevicelibs_PYTHON = *.py
+
+MAINTAINERCLEANFILES = Makefile.in
diff --git a/pyanaconda/storage/devicelibs/__init__.py b/pyanaconda/storage/devicelibs/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/pyanaconda/storage/devicelibs/crypto.py b/pyanaconda/storage/devicelibs/crypto.py
new file mode 100644
index 0000000..136435d
--- /dev/null
+++ b/pyanaconda/storage/devicelibs/crypto.py
@@ -0,0 +1,193 @@
+#
+# crypto.py
+#
+# Copyright (C) 2009  Red Hat, Inc.  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 as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# 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, see <http://www.gnu.org/licenses/>.
+#
+# Author(s): Dave Lehman <dlehman@xxxxxxxxxx>
+#            Martin Sivak <msivak@xxxxxxxxxx>
+#
+
+import os
+from pycryptsetup import CryptSetup
+import iutil
+
+from ..errors import *
+
+import gettext
+_ = lambda x: gettext.ldgettext("anaconda", x)
+
+# Keep the character set size a power of two to make sure all characters are
+# equally likely
+GENERATED_PASSPHRASE_CHARSET = ("0123456789"
+                                "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
+                                "abcdefghijklmnopqrstuvwxyz"
+                                "./")
+# 20 chars * 6 bits per char = 120 "bits of security"
+GENERATED_PASSPHRASE_LENGTH = 20
+
+def generateBackupPassphrase():
+    rnd = os.urandom(GENERATED_PASSPHRASE_LENGTH)
+    cs = GENERATED_PASSPHRASE_CHARSET
+    raw = "".join([cs[ord(c) % len(cs)] for c in rnd])
+
+    # Make the result easier to read
+    parts = []
+    for i in xrange(0, len(raw), 5):
+        parts.append(raw[i : i + 5])
+    return "-".join(parts)
+
+def askyes(question):
+    return True
+
+def dolog(priority, text):
+    pass
+
+def is_luks(device):
+    cs = CryptSetup(yesDialog = askyes, logFunc = dolog)
+    return cs.isLuks(device)
+
+def luks_uuid(device):
+    cs = CryptSetup(yesDialog = askyes, logFunc = dolog)
+    return cs.luksUUID(device).strip()
+
+def luks_status(name):
+    """True means active, False means inactive (or non-existent)"""
+    cs = CryptSetup(yesDialog = askyes, logFunc = dolog)
+    return cs.luksStatus(name)!=0
+
+def luks_format(device,
+                passphrase=None, key_file=None,
+                cipher=None, key_size=None):
+    cs = CryptSetup(yesDialog = askyes, logFunc = dolog)
+    key_file_unlink = False
+
+    if passphrase:
+        key_file = cs.prepare_passphrase_file(passphrase)
+        key_file_unlink = True
+    elif key_file and os.path.isfile(key_file):
+        pass
+    else:
+        raise ValueError("luks_format requires either a passphrase or a key file")
+
+    #None is not considered as default value and pycryptsetup doesn't accept it
+    #so we need to filter out all Nones
+    kwargs = {}
+    kwargs["device"] = device
+    if   cipher: kwargs["cipher"]  = cipher
+    if key_file: kwargs["keyfile"] = key_file
+    if key_size: kwargs["keysize"] = key_size
+
+    rc = cs.luksFormat(**kwargs)
+    if key_file_unlink: os.unlink(key_file)
+
+    if rc:
+        raise CryptoError("luks_format failed for '%s'" % device)
+
+def luks_open(device, name, passphrase=None, key_file=None):
+    cs = CryptSetup(yesDialog = askyes, logFunc = dolog)
+    key_file_unlink = False
+
+    if passphrase:
+        key_file = cs.prepare_passphrase_file(passphrase)
+        key_file_unlink = True
+    elif key_file and os.path.isfile(key_file):
+        pass
+    else:
+        raise ValueError("luks_open requires either a passphrase or a key file")
+
+    rc = cs.luksOpen(device = device, name = name, keyfile = key_file)
+    if key_file_unlink: os.unlink(key_file)
+    if rc:
+        raise CryptoError("luks_open failed for %s (%s)" % (device, name))
+
+def luks_close(name):
+    cs = CryptSetup(yesDialog = askyes, logFunc = dolog)
+    rc = cs.luksClose(name)
+    if rc:
+        raise CryptoError("luks_close failed for %s" % name)
+
+def luks_add_key(device,
+                 new_passphrase=None, new_key_file=None,
+                 passphrase=None, key_file=None):
+
+    params = ["-q"]
+
+    p = os.pipe()
+    if passphrase:
+        os.write(p[1], "%s\n" % passphrase)
+    elif key_file and os.path.isfile(key_file):
+        params.extend(["--key-file", key_file])
+    else:
+        raise CryptoError("luks_add_key requires either a passphrase or a key file")
+
+    params.extend(["luksAddKey", device])
+
+    if new_passphrase:
+        os.write(p[1], "%s\n" % new_passphrase)
+    elif new_key_file and os.path.isfile(new_key_file):
+        params.append("%s" % new_key_file)
+    else:
+        raise CryptoError("luks_add_key requires either a passphrase or a key file to add")
+
+    os.close(p[1])
+
+    rc = iutil.execWithRedirect("cryptsetup", params,
+                                stdin = p[0],
+                                stdout = "/dev/tty5",
+                                stderr = "/dev/tty5")
+
+    os.close(p[0])
+    if rc:
+        raise CryptoError("luks add key failed with errcode %d" % (rc,))
+
+def luks_remove_key(device,
+                    del_passphrase=None, del_key_file=None,
+                    passphrase=None, key_file=None):
+
+    params = []
+
+    p = os.pipe()
+    if del_passphrase: #the first question is about the key we want to remove
+        os.write(p[1], "%s\n" % del_passphrase)
+
+    if passphrase:
+        os.write(p[1], "%s\n" % passphrase)
+    elif key_file and os.path.isfile(key_file):
+        params.extend(["--key-file", key_file])
+    else:
+        raise CryptoError("luks_remove_key requires either a passphrase or a key file")
+
+    params.extend(["luksRemoveKey", device])
+
+    if del_passphrase:
+        pass
+    elif del_key_file and os.path.isfile(del_key_file):
+        params.append("%s" % del_key_file)
+    else:
+        raise CryptoError("luks_remove_key requires either a passphrase or a key file to remove")
+
+    os.close(p[1])
+
+    rc = iutil.execWithRedirect("cryptsetup", params,
+                                stdin = p[0],
+                                stdout = "/dev/tty5",
+                                stderr = "/dev/tty5")
+
+    os.close(p[0])
+    if rc:
+        raise CryptoError("luks_remove_key failed with errcode %d" % (rc,))
+
+
diff --git a/pyanaconda/storage/devicelibs/dm.py b/pyanaconda/storage/devicelibs/dm.py
new file mode 100644
index 0000000..02745e0
--- /dev/null
+++ b/pyanaconda/storage/devicelibs/dm.py
@@ -0,0 +1,130 @@
+#
+# dm.py
+# device-mapper functions
+#
+# Copyright (C) 2009  Red Hat, Inc.  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 as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# 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, see <http://www.gnu.org/licenses/>.
+#
+# Author(s): Dave Lehman <dlehman@xxxxxxxxxx>
+#
+
+import os
+
+import block
+import iutil
+from ..errors import *
+
+import gettext
+_ = lambda x: gettext.ldgettext("anaconda", x)
+
+import logging
+log = logging.getLogger("storage")
+
+def name_from_dm_node(dm_node):
+    name = block.getNameFromDmNode(dm_node)
+    if name is not None:
+        return name
+
+    st = os.stat("/dev/%s" % dm_node)
+    major = os.major(st.st_rdev)
+    minor = os.minor(st.st_rdev)
+    name = iutil.execWithCapture("dmsetup",
+                                 ["info", "--columns",
+                                  "--noheadings", "-o", "name",
+                                  "-j", str(major), "-m", str(minor)],
+                                 stderr="/dev/tty5")
+    log.debug("name_from_dm(%s) returning '%s'" % (dm_node, name.strip()))
+    return name.strip()
+
+def dm_node_from_name(map_name):
+    dm_node = block.getDmNodeFromName(map_name)
+    if dm_node is not None:
+        return dm_node
+
+    devnum = iutil.execWithCapture("dmsetup",
+                                   ["info", "--columns",
+                                    "--noheadings",
+                                    "-o", "devno",
+                                    map_name],
+                                    stderr="/dev/tty5")
+    (major, sep, minor) = devnum.strip().partition(":")
+    if not sep:
+        raise DMError("dm device does not exist")
+
+    dm_node = "dm-%d" % int(minor)
+    log.debug("dm_node_from_name(%s) returning '%s'" % (map_name, dm_node))
+    return dm_node
+
+def dm_is_multipath(info):
+    major = None
+    minor = None
+
+    if info.has_key('MAJOR'):
+        major = info['MAJOR']
+    elif info.has_key('DM_MAJOR'):
+        major = info['DM_MAJOR']
+    if info.has_key('MINOR'):
+        minor = info['MINOR']
+    elif info.has_key('DM_MINOR'):
+        minor = info['DM_MINOR']
+
+    if major is None or minor is None:
+        return False
+
+    for map in block.dm.maps():
+        dev = map.dev
+        if dev.major == int(major) and dev.minor == int(minor):
+            for table in map.table:
+                if table.type == 'multipath':
+                    return True
+
+def _get_backing_devnums_from_map(map_name):
+    ret = []
+    buf = iutil.execWithCapture("dmsetup",
+                                ["info", "--columns",
+                                 "--noheadings",
+                                 "-o", "devnos_used",
+                                 map_name],
+                                stderr="/dev/tty5")
+    dev_nums = buf.split()
+    for dev_num in dev_nums:
+        (major, colon, minor) = dev_num.partition(":")
+        ret.append((int(major), int(minor)))
+
+    return ret
+
+def get_backing_devnums(dm_node):
+    #dm_node = dm_node_from_name(map_name)
+    if not dm_node:
+        return None
+
+    top_dir = "/sys/block"
+    backing_devs = os.listdir("%s/%s/slaves/" % (top_dir, dm_node))
+    dev_nums = []
+    for backing_dev in backing_devs:
+        dev_num = open("%s/%s/dev" % (top_dir, backing_dev)).read().strip()
+        (_major, _minor) = dev_num.split(":")
+        dev_nums.append((int(_major), int(_minor)))
+
+    return dev_nums
+
+def get_backing_devs_from_name(map_name):
+    dm_node = dm_node_from_name(map_name)
+    if not dm_node:
+        return None
+
+    slave_devs = os.listdir("/sys/block/virtual/%s" % dm_node)
+    return slave_devs
+
diff --git a/pyanaconda/storage/devicelibs/edd.py b/pyanaconda/storage/devicelibs/edd.py
new file mode 100644
index 0000000..da03914
--- /dev/null
+++ b/pyanaconda/storage/devicelibs/edd.py
@@ -0,0 +1,97 @@
+#
+# edd.py
+# BIOS EDD data parsing functions
+#
+# Copyright (C) 2010  Red Hat, Inc.  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 as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# 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, see <http://www.gnu.org/licenses/>.
+#
+# Author(s): Hans de Goede <hdegoede@xxxxxxxxxx>
+#
+
+import os
+import struct
+
+import logging
+log = logging.getLogger("storage")
+
+def get_edd_dict(devices):
+    """Given an array of devices return a dict with the BIOS ID for them."""
+    edd_dict = {}
+
+    for biosdev in range(80, 80 + 15):
+        sysfspath = "/sys/firmware/edd/int13_dev%d" % biosdev
+        if not os.path.exists(sysfspath):
+            break # We are done
+
+        sysfspath = "/sys/firmware/edd/int13_dev%d/mbr_signature" % biosdev
+        if not os.path.exists(sysfspath):
+            log.warning("No mbrsig for biosdev: %d" % biosdev)
+            continue
+
+        try:
+            file = open(sysfspath, "r")
+            eddsig = file.read()
+            file.close()
+        except (IOError, OSError) as e:
+            log.warning("Error reading EDD mbrsig for %d: %s" %
+                        (biosdev, str(e)))
+            continue
+
+        sysfspath = "/sys/firmware/edd/int13_dev%d/sectors" % biosdev
+        try:
+            file = open(sysfspath, "r")
+            eddsize = file.read()
+            file.close()
+        except (IOError, OSError) as e:
+            eddsize = None
+
+        found = []
+        for dev in devices:
+            try:
+                fd = os.open(dev.path, os.O_RDONLY)
+                os.lseek(fd, 440, 0) 
+                mbrsig = struct.unpack('I', os.read(fd, 4))
+                os.close(fd)
+            except OSError as e:
+                log.warning("Error reading mbrsig from disk %s: %s" %
+                            (dev.name, str(e)))
+                continue
+
+            mbrsigStr = "0x%08x\n" % mbrsig
+            if mbrsigStr == eddsig:
+                if eddsize:
+                    sysfspath = "/sys%s/size" % dev.sysfsPath
+                    try:
+                        file = open(sysfspath, "r")
+                        size = file.read()
+                        file.close()
+                    except (IOError, OSError) as e:
+                        log.warning("Error getting size for: %s" % dev.name)
+                        continue
+                    if eddsize != size:
+                        continue
+                found.append(dev.name)
+
+        if not found:
+            log.error("No matching mbr signature found for biosdev %d" %
+                      biosdev)
+        elif len(found) > 1:
+            log.error("Multiple signature matches found for biosdev %d: %s" %
+                      (biosdev, str(found)))
+        else:
+            log.info("Found %s for biosdev %d" %(found[0], biosdev))
+            edd_dict[found[0]] = biosdev
+
+    return edd_dict
diff --git a/pyanaconda/storage/devicelibs/lvm.py b/pyanaconda/storage/devicelibs/lvm.py
new file mode 100644
index 0000000..fd74f56
--- /dev/null
+++ b/pyanaconda/storage/devicelibs/lvm.py
@@ -0,0 +1,419 @@
+#
+# lvm.py
+# lvm functions
+#
+# Copyright (C) 2009  Red Hat, Inc.  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 as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# 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, see <http://www.gnu.org/licenses/>.
+#
+# Author(s): Dave Lehman <dlehman@xxxxxxxxxx>
+#
+
+import os
+import math
+import re
+
+import iutil
+
+from ..errors import *
+from constants import *
+
+import gettext
+_ = lambda x: gettext.ldgettext("anaconda", x)
+
+MAX_LV_SLOTS = 256
+
+def has_lvm():
+    has_lvm = False
+    for path in os.environ["PATH"].split(":"):
+        if os.access("%s/lvm" % path, os.X_OK):
+            has_lvm = True
+            break
+
+    if has_lvm:
+        has_lvm = False
+        for line in open("/proc/devices").readlines():
+            if "device-mapper" in line.split():
+                has_lvm = True
+                break
+
+    return has_lvm
+
+# Start config_args handling code
+#
+# Theoretically we can handle all that can be handled with the LVM --config
+# argument.  For every time we call an lvm_cc (lvm compose config) funciton
+# we regenerate the config_args with all global info.
+config_args = [] # Holds the final argument list
+config_args_data = { "filterRejects": [],    # regular expressions to reject.
+                            "filterAccepts": [] }   # regexp to accept
+
+def _composeConfig():
+    """lvm command accepts lvm.conf type arguments preceded by --config. """
+    global config_args, config_args_data
+    config_args = []
+
+    filter_string = ""
+    rejects = config_args_data["filterRejects"]
+    # we don't need the accept for now.
+    # accepts = config_args_data["filterAccepts"]
+    # if len(accepts) > 0:
+    #   for i in range(len(rejects)):
+    #       filter_string = filter_string + ("\"a|%s|\", " % accpets[i])
+
+    if len(rejects) > 0:
+        for i in range(len(rejects)):
+            filter_string = filter_string + ("\"r|%s|\"," % rejects[i])
+
+
+    filter_string = " filter=[%s] " % filter_string.strip(",")
+
+    # As we add config strings we should check them all.
+    if filter_string == "":
+        # Nothing was really done.
+        return
+
+    # devices_string can have (inside the brackets) "dir", "scan",
+    # "preferred_names", "filter", "cache_dir", "write_cache_state",
+    # "types", "sysfs_scan", "md_component_detection".  see man lvm.conf.
+    devices_string = " devices {%s} " % (filter_string) # strings can be added
+    config_string = devices_string # more strings can be added.
+    config_args = ["--config", config_string]
+
+def lvm_cc_addFilterRejectRegexp(regexp):
+    """ Add a regular expression to the --config string."""
+    global config_args_data
+    config_args_data["filterRejects"].append(regexp)
+
+    # compoes config once more.
+    _composeConfig()
+
+def lvm_cc_resetFilter():
+    global config_args, config_args_data
+    config_args_data["filterRejects"] = []
+    config_args_data["filterAccepts"] = []
+    config_args = []
+# End config_args handling code.
+
+# Names that should not be used int the creation of VGs
+lvm_vg_blacklist = []
+def blacklistVG(name):
+    global lvm_vg_blacklist
+    lvm_vg_blacklist.append(name)
+
+def getPossiblePhysicalExtents(floor=0):
+    """Returns a list of integers representing the possible values for
+       the physical extent of a volume group.  Value is in KB.
+
+       floor - size (in KB) of smallest PE we care about.
+    """
+
+    possiblePE = []
+    curpe = 8
+    while curpe <= 16384*1024:
+	if curpe >= floor:
+	    possiblePE.append(curpe)
+	curpe = curpe * 2
+
+    return possiblePE
+
+def getMaxLVSize():
+    """ Return the maximum size (in MB) of a logical volume. """
+    if iutil.getArch() in ("x86_64", "ppc64", "alpha", "ia64", "s390", "sparc"): #64bit architectures
+        return (8*1024*1024*1024*1024) #Max is 8EiB (very large number..)
+    else:
+        return (16*1024*1024) #Max is 16TiB
+
+# LVM sources set the maximum length limit on VG and LV names at 128.  Set
+# our default to 2 below that to account for 0 through 99 entries we may
+# make with this name as a prefix.  LVM doesn't seem to impose a limit of
+# 99, but we do in anaconda.
+def safeLvmName(name, maxlen=126):
+    tmp = name.strip()
+    tmp = tmp.replace("/", "_")
+    tmp = re.sub("[^0-9a-zA-Z._]", "", tmp)
+    tmp = tmp.lstrip("_")
+
+    if len(tmp) > maxlen:
+        tmp = tmp[:maxlen]
+
+    return tmp
+
+def clampSize(size, pesize, roundup=None):
+    if roundup:
+        round = math.ceil
+    else:
+        round = math.floor
+
+    return long(round(float(size)/float(pesize)) * pesize)
+
+def lvm(args, progress=None):
+    rc = iutil.execWithPulseProgress("lvm", args,
+                                     stdout = "/dev/tty5",
+                                     stderr = "/dev/tty5",
+                                     progress=progress)
+    if not rc:
+        return
+
+    try:
+        # grab the last line of program.log and strip off the timestamp
+        msg = open("/tmp/program.log").readlines()[-1]
+        msg = msg.split("program: ", 1)[1].strip()
+    except Exception:
+        msg = ""
+
+    raise LVMError(msg)
+
+def pvcreate(device, progress=None):
+    args = ["pvcreate"] + \
+            config_args + \
+            [device]
+
+    try:
+        lvm(args, progress=progress)
+    except LVMError as msg:
+        raise LVMError("pvcreate failed for %s: %s" % (device, msg))
+
+def pvresize(device, size):
+    args = ["pvresize"] + \
+            ["--setphysicalvolumesize", ("%dm" % size)] + \
+            config_args + \
+            [device]
+
+    try:
+        lvm(args)
+    except LVMError as msg:
+        raise LVMError("pvresize failed for %s: %s" % (device, msg))
+
+def pvremove(device):
+    args = ["pvremove"] + \
+            config_args + \
+            [device]
+
+    try:
+        lvm(args)
+    except LVMError as msg:
+        raise LVMError("pvremove failed for %s: %s" % (device, msg))
+
+def pvinfo(device):
+    """
+        If the PV was created with '--metadacopies 0', lvm will do some
+        scanning of devices to determine from their metadata which VG
+        this PV belongs to.
+
+        pvs -o pv_name,pv_mda_count,vg_name,vg_uuid --config \
+            'devices { scan = "/dev" filter = ["a/loop0/", "r/.*/"] }'
+    """
+    #cfg = "'devices { scan = \"/dev\" filter = [\"a/%s/\", \"r/.*/\"] }'" 
+    args = ["pvs", "--noheadings"] + \
+            ["--units", "m"] + \
+            ["-o", "pv_name,pv_mda_count,vg_name,vg_uuid"] + \
+            config_args + \
+            [device]
+
+    rc = iutil.execWithCapture("lvm", args,
+                                stderr = "/dev/tty5")
+    vals = rc.split()
+    if not vals:
+        raise LVMError("pvinfo failed for %s" % device)
+
+    # don't raise an exception if pv is not a part of any vg
+    pv_name = vals[0]
+    try:
+        vg_name, vg_uuid = vals[2], vals[3]
+    except IndexError:
+        vg_name, vg_uuid = "", ""
+    
+    info = {'pv_name': pv_name,
+            'vg_name': vg_name,
+            'vg_uuid': vg_uuid}
+
+    return info
+
+def vgcreate(vg_name, pv_list, pe_size, progress=None):
+    argv = ["vgcreate"]
+    if pe_size:
+        argv.extend(["-s", "%dm" % pe_size])
+    argv.extend(config_args)
+    argv.append(vg_name)
+    argv.extend(pv_list)
+
+    try:
+        lvm(argv, progress=progress)
+    except LVMError as msg:
+        raise LVMError("vgcreate failed for %s: %s" % (vg_name, msg))
+
+def vgremove(vg_name):
+    args = ["vgremove", "--force"] + \
+            config_args +\
+            [vg_name]
+
+    try:
+        lvm(args)
+    except LVMError as msg:
+        raise LVMError("vgremove failed for %s: %s" % (vg_name, msg))
+
+def vgactivate(vg_name):
+    args = ["vgchange", "-a", "y"] + \
+            config_args + \
+            [vg_name]
+
+    try:
+        lvm(args)
+    except LVMError as msg:
+        raise LVMError("vgactivate failed for %s: %s" % (vg_name, msg))
+
+def vgdeactivate(vg_name):
+    args = ["vgchange", "-a", "n"] + \
+            config_args + \
+            [vg_name]
+
+    try:
+        lvm(args)
+    except LVMError as msg:
+        raise LVMError("vgdeactivate failed for %s: %s" % (vg_name, msg))
+
+def vgreduce(vg_name, pv_list, rm=False):
+    """ Reduce a VG.
+
+    rm -> with RemoveMissing option.
+    Use pv_list when rm=False, otherwise ignore pv_list and call vgreduce with
+    the --removemissing option.
+    """
+    args = ["vgreduce"]
+    if rm:
+        args.extend(["--removemissing", vg_name])
+    else:
+        args.extend([vg_name] + pv_list)
+
+    try:
+        lvm(args)
+    except LVMError as msg:
+        raise LVMError("vgreduce failed for %s: %s" % (vg_name, msg))
+
+def vginfo(vg_name):
+    args = ["vgs", "--noheadings", "--nosuffix"] + \
+            ["--units", "m"] + \
+            ["-o", "uuid,size,free,extent_size,extent_count,free_count,pv_count"] + \
+            config_args + \
+            [vg_name]
+
+    buf = iutil.execWithCapture("lvm",
+                                args,
+                                stderr="/dev/tty5")
+    info = buf.split()
+    if len(info) != 7:
+        raise LVMError(_("vginfo failed for %s" % vg_name))
+
+    d = {}
+    (d['uuid'],d['size'],d['free'],d['pe_size'],
+     d['pe_count'],d['pe_free'],d['pv_count']) = info
+    return d
+
+def lvs(vg_name):
+    args = ["lvs", "--noheadings", "--nosuffix"] + \
+            ["--units", "m"] + \
+            ["-o", "lv_name,lv_uuid,lv_size,lv_attr"] + \
+            config_args + \
+            [vg_name]
+
+    buf = iutil.execWithCapture("lvm",
+                                args,
+                                stderr="/dev/tty5")
+
+    lvs = {}
+    for line in buf.splitlines():
+        line = line.strip()
+        if not line:
+            continue
+        (name, uuid, size, attr) = line.split()
+        lvs[name] = {"size": size,
+                     "uuid": uuid,
+                     "attr": attr}
+
+    if not lvs:
+        raise LVMError(_("lvs failed for %s" % vg_name))
+
+    return lvs
+
+def lvorigin(vg_name, lv_name):
+    args = ["lvs", "--noheadings", "-o", "origin"] + \
+            config_args + \
+            ["%s/%s" % (vg_name, lv_name)]
+
+    buf = iutil.execWithCapture("lvm",
+                                args,
+                                stderr="/dev/tty5")
+
+    try:
+        origin = buf.splitlines()[0].strip()
+    except IndexError:
+        origin = ''
+
+    return origin
+
+def lvcreate(vg_name, lv_name, size, progress=None):
+    args = ["lvcreate"] + \
+            ["-L", "%dm" % size] + \
+            ["-n", lv_name] + \
+            config_args + \
+            [vg_name]
+
+    try:
+        lvm(args, progress=progress)
+    except LVMError as msg:
+        raise LVMError("lvcreate failed for %s/%s: %s" % (vg_name, lv_name, msg))
+
+def lvremove(vg_name, lv_name):
+    args = ["lvremove"] + \
+            config_args + \
+            ["%s/%s" % (vg_name, lv_name)]
+
+    try:
+        lvm(args)
+    except LVMError as msg:
+        raise LVMError("lvremove failed for %s: %s" % (lv_name, msg))
+
+def lvresize(vg_name, lv_name, size):
+    args = ["lvresize"] + \
+            ["--force", "-L", "%dm" % size] + \
+            config_args + \
+            ["%s/%s" % (vg_name, lv_name)]
+
+    try:
+        lvm(args)
+    except LVMError as msg:
+        raise LVMError("lvresize failed for %s: %s" % (lv_name, msg))
+
+def lvactivate(vg_name, lv_name):
+    # see if lvchange accepts paths of the form 'mapper/$vg-$lv'
+    args = ["lvchange", "-a", "y"] + \
+            config_args + \
+            ["%s/%s" % (vg_name, lv_name)]
+
+    try:
+        lvm(args)
+    except LVMError as msg:
+        raise LVMError("lvactivate failed for %s: %s" % (lv_name, msg))
+
+def lvdeactivate(vg_name, lv_name):
+    args = ["lvchange", "-a", "n"] + \
+            config_args + \
+            ["%s/%s" % (vg_name, lv_name)]
+
+    try:
+        lvm(args)
+    except LVMError as msg:
+        raise LVMError("lvdeactivate failed for %s: %s" % (lv_name, msg))
+
diff --git a/pyanaconda/storage/devicelibs/mdraid.py b/pyanaconda/storage/devicelibs/mdraid.py
new file mode 100644
index 0000000..a04965d
--- /dev/null
+++ b/pyanaconda/storage/devicelibs/mdraid.py
@@ -0,0 +1,236 @@
+#
+# mdraid.py
+# mdraid functions
+#
+# Copyright (C) 2009  Red Hat, Inc.  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 as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# 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, see <http://www.gnu.org/licenses/>.
+#
+# Author(s): Dave Lehman <dlehman@xxxxxxxxxx>
+#
+
+import os
+
+import iutil
+from ..errors import *
+
+import gettext
+_ = lambda x: gettext.ldgettext("anaconda", x)
+
+import logging
+log = logging.getLogger("storage")
+
+# raidlevels constants
+RAID10 = 10
+RAID6 = 6
+RAID5 = 5
+RAID4 = 4
+RAID1 = 1
+RAID0 = 0
+
+def getRaidLevels():
+    mdstat_descriptors = {
+        RAID10: ("[RAID10]", "[raid10]"),
+        RAID6: ("[RAID6]", "[raid6]"),
+        RAID5: ("[RAID5]", "[raid5]"),
+        RAID4: ("[RAID4]", "[raid4]"),
+        RAID1: ("[RAID1]", "[raid1]"),
+        RAID0: ("[RAID0]", "[raid0]"),
+    }
+    avail = []
+    try:
+        f = open("/proc/mdstat", "r")
+    except IOError:
+        pass
+    else:
+        for l in f.readlines():
+            if not l.startswith("Personalities"):
+                continue
+
+            lst = l.split()
+
+            for level in mdstat_descriptors:
+                for d in mdstat_descriptors[level]:
+                    if d in lst:
+                        avail.append(level)
+                        break
+
+        f.close()
+
+    avail.sort()
+    return avail
+
+raid_levels = getRaidLevels()
+
+def raidLevel(descriptor):
+    for level in raid_levels:
+        if isRaid(level, descriptor):
+            return level
+    else:
+        raise ValueError, "invalid raid level descriptor %s" % descriptor
+
+def isRaid(raid, raidlevel):
+    """Return whether raidlevel is a valid descriptor of raid"""
+    raid_descriptors = {RAID10: ("RAID10", "raid10", "10", 10),
+                        RAID6: ("RAID6", "raid6", "6", 6),
+                        RAID5: ("RAID5", "raid5", "5", 5),
+                        RAID4: ("RAID4", "raid4", "4", 4),
+                        RAID1: ("mirror", "RAID1", "raid1", "1", 1),
+                        RAID0: ("stripe", "RAID0", "raid0", "0", 0)}
+
+    if raid in raid_descriptors:
+        return raidlevel in raid_descriptors[raid]
+    else:
+        raise ValueError, "invalid raid level %d" % raid
+
+def get_raid_min_members(raidlevel):
+    """Return the minimum number of raid members required for raid level"""
+    raid_min_members = {RAID10: 2,
+                        RAID6: 4,
+                        RAID5: 3,
+                        RAID4: 3,
+                        RAID1: 2,
+                        RAID0: 2}
+
+    for raid, min_members in raid_min_members.items():
+        if isRaid(raid, raidlevel):
+            return min_members
+
+    raise ValueError, "invalid raid level %d" % raidlevel
+
+def get_raid_max_spares(raidlevel, nummembers):
+    """Return the maximum number of raid spares for raidlevel."""
+    raid_max_spares = {RAID10: lambda: max(0, nummembers - get_raid_min_members(RAID10)),
+                       RAID6: lambda: max(0, nummembers - get_raid_min_members(RAID6)),
+                       RAID5: lambda: max(0, nummembers - get_raid_min_members(RAID5)),
+                       RAID4: lambda: max(0, nummembers - get_raid_min_members(RAID4)),
+                       RAID1: lambda: max(0, nummembers - get_raid_min_members(RAID1)),
+                       RAID0: lambda: 0}
+
+    for raid, max_spares_func in raid_max_spares.items():
+        if isRaid(raid, raidlevel):
+            return max_spares_func()
+
+    raise ValueError, "invalid raid level %d" % raidlevel
+
+def mdadm(args, progress=None):
+    rc = iutil.execWithPulseProgress("mdadm", args,
+                                     stdout = "/dev/tty5",
+                                     stderr = "/dev/tty5",
+                                     progress=progress)
+    if not rc:
+        return
+
+    try:
+        # grab the last line of program.log and strip off the timestamp
+        msg = open("/tmp/program.log").readlines()[-1]
+        msg = msg.split("program: ", 1)[1].strip()
+    except Exception:
+        msg = ""
+
+    raise MDRaidError(msg)
+
+def mdcreate(device, level, disks, spares=0, metadataVer=None, bitmap=False,
+             progress=None):
+    argv = ["--create", device, "--run", "--level=%s" % level]
+    raid_devs = len(disks) - spares
+    argv.append("--raid-devices=%d" % raid_devs)
+    if spares:
+        argv.append("--spare-devices=%d" % spares)
+    if metadataVer:
+        argv.append("--metadata=%s" % metadataVer)
+    if bitmap:
+        argv.append("--bitmap=internal")
+    argv.extend(disks)
+    
+    try:
+        mdadm(argv, progress=progress)
+    except MDRaidError as msg:
+        raise MDRaidError("mdcreate failed for %s: %s" % (device, msg))
+
+def mddestroy(device):
+    args = ["--zero-superblock", device]
+
+    try:
+        mdadm(args)
+    except MDRaidError as msg:
+        raise MDRaidError("mddestroy failed for %s: %s" % (device, msg))
+
+def mdadd(device, no_degraded=False):
+    args = ["--incremental", "--quiet"]
+    if no_degraded:
+        args.append("--no-degraded")
+    args.append(device)
+
+    try:
+        mdadm(args)
+    except MDRaidError as msg:
+        raise MDRaidError("mdadd failed for %s: %s" % (device, msg))
+
+def mdactivate(device, members=[], super_minor=None, update_super_minor=False,
+               uuid=None):
+    if super_minor is None and not uuid:
+        raise ValueError("mdactivate requires either a uuid or a super-minor")
+    
+    if uuid:
+        identifier = "--uuid=%s" % uuid
+    elif super_minor is not None:
+        identifier = "--super-minor=%d" % super_minor
+    else:
+        identifier = ""
+
+    if update_super_minor:
+        extra_args = ["--update=super-minor"]
+    else:
+        extra_args = [ ]
+
+    args = ["--assemble", device, identifier, "--run", "--auto=md"]
+    args += extra_args
+    args += members
+
+    try:
+        mdadm(args)
+    except MDRaidError as msg:
+        raise MDRaidError("mdactivate failed for %s: %s" % (device, msg))
+
+def mddeactivate(device):
+    args = ["--stop", device]
+
+    try:
+        mdadm(args)
+    except MDRaidError as msg:
+        raise MDRaidError("mddeactivate failed for %s: %s" % (device, msg))
+
+def mdexamine(device):
+    vars = iutil.execWithCapture("mdadm",
+                                 ["--examine", "--brief", device],
+                                 stderr="/dev/tty5").split()
+
+    info = {}
+    if vars:
+        try:
+            info["device"] = vars[1]
+            vars = vars[2:]
+        except IndexError:
+            return {}
+
+    for var in vars:
+        (name, equals, value) = var.partition("=")
+        if not equals:
+            continue
+
+        info[name.lower()] = value.strip()
+
+    return info
+
diff --git a/pyanaconda/storage/devicelibs/mpath.py b/pyanaconda/storage/devicelibs/mpath.py
new file mode 100644
index 0000000..adb2644
--- /dev/null
+++ b/pyanaconda/storage/devicelibs/mpath.py
@@ -0,0 +1,228 @@
+from ..udev import *
+import iutil
+
+def parseMultipathOutput(output):
+    # this function parses output from "multipath -d", so we can use its
+    # logic for our topology.
+    # The input looks like:
+    # create: mpathb (1ATA     ST3120026AS                                         5M) undef ATA,ST3120026AS
+    # size=112G features='0' hwhandler='0' wp=undef
+    # `-+- policy='round-robin 0' prio=1 status=undef
+    #   `- 2:0:0:0 sda 8:0  undef ready running
+    # create: mpatha (36006016092d21800703762872c60db11) undef DGC,RAID 5
+    # size=10G features='1 queue_if_no_path' hwhandler='1 emc' wp=undef
+    # `-+- policy='round-robin 0' prio=2 status=undef
+    #   |- 6:0:0:0 sdb 8:16 undef ready running
+    #   `- 7:0:0:0 sdc 8:32 undef ready running
+    #
+    # (In anaconda, the first one there won't be included because we blacklist
+    # "ATA" as a vendor.)
+    #
+    # It returns a structure like:
+    # [ {'mpatha':['sdb','sdc']}, ... ]
+    mpaths = {}
+    if output is None:
+        return mpaths
+
+    name = None
+    devices = []
+
+    lines = output.split('\n')
+    for line in lines:
+        lexemes = line.split()
+        if not lexemes:
+            break
+        if lexemes[0] == 'create:':
+            if name and devices:
+                mpaths[name] = devices
+                name = None
+                devices = []
+            name = lexemes[1]
+        elif lexemes[0].startswith('size='):
+            pass
+        elif lexemes[0] == '`-+-':
+            pass
+        elif lexemes[0] in ['|-','`-']:
+            devices.append(lexemes[2].replace('!', '/'))
+    
+    if name and devices:
+        mpaths[name] = devices
+
+    return mpaths
+
+def identifyMultipaths(devices):
+    # this function does a couple of things
+    # 1) identifies multipath disks
+    # 2) sets their ID_FS_TYPE to multipath_member
+    # 3) removes the individual members of an mpath's partitions
+    # sample input with multipath pair [sdb,sdc]
+    # [sr0, sda, sda1, sdb, sdb1, sdb2, sdc, sdc1, sdd, sdd1, sdd2]
+    # sample output:
+    # [sda, sdd], [[sdb, sdc]], [sr0, sda1, sdd1, sdd2]]
+    log.info("devices to scan for multipath: %s" % [d['name'] for d in devices])
+
+    topology = parseMultipathOutput(iutil.execWithCapture("multipath", ["-d",]))
+    # find the devices that aren't in topology, and add them into it...
+    topodevs = reduce(lambda x,y: x.union(y), topology.values(), set())
+    for name in set([d['name'] for d in devices]).difference(topodevs):
+        topology[name] = [name]
+    
+    devmap = {}
+    non_disk_devices = {}
+    for d in devices:
+        if not udev_device_is_disk(d):
+            non_disk_devices[d['name']] = d
+            log.info("adding %s to non_disk_device list" % (d['name'],))
+            continue
+        devmap[d['name']] = d
+
+    singlepath_disks = []
+    multipaths = []
+
+    for name, disks in topology.items():
+        if len(disks) == 1:
+            if not non_disk_devices.has_key(disks[0]):
+                log.info("adding %s to singlepath_disks" % (disks[0],))
+                singlepath_disks.append(devmap[disks[0]])
+        else:
+            # some usb cardreaders use multiple lun's (for different slots)
+            # and report a fake disk serial which is the same for all the
+            # lun's (#517603)
+            all_usb = True
+            # see if we've got any non-disk devices on our mpath list.
+            # If so, they're probably false-positives.
+            non_disks = False
+            for disk in disks:
+                d = devmap[disk]
+                if d.get("ID_USB_DRIVER") != "usb-storage":
+                    all_usb = False
+                if (not devmap.has_key(disk)) and non_disk_devices.has_key(disk):
+                    log.warning("non-disk device %s is part of an mpath" %
+                                (disk,))
+                    non_disks = True
+
+            if all_usb:
+                log.info("adding multi lun usb mass storage device to singlepath_disks: %s" %
+                         (disks,))
+                singlepath_disks.extend([devmap[d] for d in disks])
+                continue
+
+            if non_disks:
+                for disk in disks:
+                    if devmap.has_key(disk):
+                        del devmap[disk]
+                    if topology.has_key(disk):
+                        del topology[disk]
+                continue
+
+            log.info("found multipath set: %s" % (disks,))
+            for disk in disks:
+                d = devmap[disk]
+                log.info("adding %s to multipath_disks" % (disk,))
+                d["ID_FS_TYPE"] = "multipath_member"
+                d["ID_MPATH_NAME"] = name
+            
+            multipaths.append([devmap[d] for d in disks])
+
+    non_disk_serials = {}
+    for name,device in non_disk_devices.items():
+        serial = udev_device_get_serial(device)
+        non_disk_serials.setdefault(serial, [])
+        non_disk_serials[serial].append(device)
+
+    for mpath in multipaths:
+        for serial in [d.get('ID_SERIAL_SHORT') for d in mpath]:
+            if non_disk_serials.has_key(serial):
+                log.info("filtering out non disk devices [%s]" % [d['name'] for d in non_disk_serials[serial]])
+                for name in [d['name'] for d in non_disk_serials[serial]]:
+                    if non_disk_devices.has_key(name):
+                        del non_disk_devices[name]
+
+    partition_devices = []
+    for device in non_disk_devices.values():
+        partition_devices.append(device)
+
+    # this is the list of devices we want to keep from the original
+    # device list, but we want to maintain its original order.
+    singlepath_disks = filter(lambda d: d in devices, singlepath_disks)
+    #multipaths = filter(lambda d: d in devices, multipaths)
+    partition_devices = filter(lambda d: d in devices, partition_devices)
+
+    mpathStr = "["
+    for mpath in multipaths:
+        mpathStr += str([d['name'] for d in mpath])
+    mpathStr += "]"
+
+    s = "(%s, %s, %s)" % ([d['name'] for d in singlepath_disks], \
+                          mpathStr, \
+                          [d['name'] for d in partition_devices])
+    log.info("devices post multipath scan: %s" % s)
+    return (singlepath_disks, multipaths, partition_devices)
+
+class MultipathConfigWriter:
+    def __init__(self):
+        self.blacklist_devices = []
+        self.mpaths = []
+
+    def addBlacklistDevice(self, device):
+        self.blacklist_devices.append(device)
+
+    def addMultipathDevice(self, mpath):
+        self.mpaths.append(mpath)
+
+    def write(self):
+        # if you add anything here, be sure and also add it to anaconda's
+        # multipath.conf
+        ret = ''
+        ret += """\
+# multipath.conf written by anaconda
+
+defaults {
+	user_friendly_names yes
+}
+blacklist {
+	devnode "^(ram|raw|loop|fd|md|dm-|sr|scd|st)[0-9]*"
+	devnode "^hd[a-z]"
+	devnode "^dcssblk[0-9]*"
+	device {
+		vendor "DGC"
+		product "LUNZ"
+	}
+	device {
+		vendor "IBM"
+		product "S/390.*"
+	}
+	# don't count normal SATA devices as multipaths
+	device {
+		vendor  "ATA"
+	}
+	# don't count 3ware devices as multipaths
+	device {
+		vendor  "3ware"
+	}
+	device {
+		vendor  "AMCC"
+	}
+	# nor highpoint devices
+	device {
+		vendor  "HPT"
+	}
+"""
+        for device in self.blacklist_devices:
+            if device.serial:
+                ret += '\twwid %s\n' % device.serial
+            elif device.vendor and device.model:
+                ret += '\tdevice {\n'
+                ret += '\t\tvendor %s\n' % device.vendor
+                ret += '\t\tproduct %s\n' % device.model
+                ret += '\t}\n'
+        ret += '}\n'
+        ret += 'multipaths {\n'
+        for mpath in self.mpaths:
+            ret += '\tmultipath {\n'
+            for k,v in mpath.config.items():
+                ret += '\t\t%s %s\n' % (k, v)
+            ret += '\t}\n'
+        ret += '}\n'
+
+        return ret
diff --git a/pyanaconda/storage/devicelibs/swap.py b/pyanaconda/storage/devicelibs/swap.py
new file mode 100644
index 0000000..92dfe93
--- /dev/null
+++ b/pyanaconda/storage/devicelibs/swap.py
@@ -0,0 +1,125 @@
+# swap.py
+# Python module for managing swap devices.
+#
+# Copyright (C) 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, or (at your option) any later version.
+# 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.
+#
+# Red Hat Author(s): Dave Lehman <dlehman@xxxxxxxxxx>
+#
+
+import resource
+
+import iutil
+import os
+
+from ..errors import *
+from . import dm
+
+import gettext
+_ = lambda x: gettext.ldgettext("anaconda", x)
+
+
+def mkswap(device, label='', progress=None):
+    # We use -f to force since mkswap tends to refuse creation on lvs with
+    # a message about erasing bootbits sectors on whole disks. Bah.
+    argv = ["-f"]
+    if label:
+        argv.extend(["-L", label])
+    argv.append(device)
+
+    rc = iutil.execWithPulseProgress("mkswap", argv,
+                                     stderr = "/dev/tty5",
+                                     stdout = "/dev/tty5",
+                                     progress=progress)
+
+    if rc:
+        raise SwapError("mkswap failed for '%s'" % device)
+
+def swapon(device, priority=None):
+    pagesize = resource.getpagesize()
+    buf = None
+    sig = None
+
+    if pagesize > 2048:
+        num = pagesize
+    else:
+        num = 2048
+
+    try:
+        fd = os.open(device, os.O_RDONLY)
+        buf = os.read(fd, num)
+    except OSError:
+        pass
+    finally:
+        try:
+            os.close(fd)
+        except (OSError, UnboundLocalError):
+            pass
+
+    if buf is not None and len(buf) == pagesize:
+        sig = buf[pagesize - 10:]
+        if sig == 'SWAP-SPACE':
+            raise OldSwapError
+        if sig == 'S1SUSPEND\x00' or sig == 'S2SUSPEND\x00':
+            raise SuspendError
+
+    if sig != 'SWAPSPACE2':
+        raise UnknownSwapError
+
+    argv = []
+    if isinstance(priority, int) and 0 <= priority <= 32767:
+        argv.extend(["-p", "%d" % priority])
+    argv.append(device)
+        
+    rc = iutil.execWithRedirect("swapon",
+                                argv,
+                                stderr = "/dev/tty5",
+                                stdout = "/dev/tty5")
+
+    if rc:
+        raise SwapError("swapon failed for '%s'" % device)
+
+def swapoff(device):
+    rc = iutil.execWithRedirect("swapoff", [device],
+                                stderr = "/dev/tty5",
+                                stdout = "/dev/tty5")
+
+    if rc:
+        raise SwapError("swapoff failed for '%s'" % device)
+
+def swapstatus(device):
+    alt_dev = None
+    if device.startswith("/dev/mapper/"):
+        # get the real device node for device-mapper devices since the ones
+        # with meaningful names are just symlinks
+        try:
+            alt_dev = "/dev/%s" % dm.dm_node_from_name(device.split("/")[-1])
+        except DMError:
+            alt_dev = None
+
+    lines = open("/proc/swaps").readlines()
+    status = False
+    for line in lines:
+        if not line.strip():
+            continue
+
+        swap_dev = line.split()[0]
+        if swap_dev in [device, alt_dev]:
+            status = True
+            break
+
+    return status
+
diff --git a/pyanaconda/storage/devices.py b/pyanaconda/storage/devices.py
new file mode 100644
index 0000000..d51cf6d
--- /dev/null
+++ b/pyanaconda/storage/devices.py
@@ -0,0 +1,3564 @@
+# devices.py
+# Device classes for anaconda's storage configuration module.
+# 
+# Copyright (C) 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, or (at your option) any later version.
+# 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.
+#
+# Red Hat Author(s): Dave Lehman <dlehman@xxxxxxxxxx>
+#
+
+
+"""
+    Device classes for use by anaconda.
+
+    This is the hierarchy of device objects that anaconda will use for
+    managing storage devices in the system. These classes will
+    individually make use of external support modules as needed to
+    perform operations specific to the type of device they represent.
+
+    TODO:
+        - see how to do network devices (NetworkManager may help)
+          - perhaps just a wrapper here
+        - document return values of all methods/functions
+        - find out what other kinds of wild and crazy devices we need to
+          represent here (iseries? xen? more mainframe? mac? ps?)
+            - PReP
+              - this is a prime candidate for a PseudoDevice
+            - DASD
+            - ZFCP
+            - XEN
+
+    What specifications do we allow?              new        existing
+        partitions                              
+            usage                                  +            +
+                filesystem, partition type are implicit
+            mountpoint                             +            +
+            size
+                exact                              +            -
+                range                              +            -
+                resize                             -            +
+            format                                 -            +
+            encryption                             +            +
+
+            disk                                                 
+                exact                              +            -
+                set                                +            -
+                    how will we specify this?
+                        partition w/ multiple parents cannot otherwise occur
+            primary                                +            -
+
+        mdraid sets
+            filesystem (*)                         +            +
+            mountpoint                             +            +
+            size?                                                
+            format                                 -            +
+            encryption                             +            +
+
+            level                                  +            ? 
+            device minor                           +            ? 
+            member devices                         +            ? 
+            spares                                 +            ? 
+            name?
+            bitmap? (boolean)                      +            -
+
+        volume groups
+            name                                   +            - 
+            member pvs                             +            +
+            pesize                                 +            ?
+
+        logical volumes
+            filesystem                             +            +
+            mountpoint                             +            +
+            size
+                exact                              +            ?
+            format                                 -            +
+            encryption                             +            +
+
+            name                                   +            ?
+            vgname                                 +            ?
+
+
+"""
+
+import os
+import math
+import copy
+import time
+
+# device backend modules
+from devicelibs import mdraid
+from devicelibs import lvm
+from devicelibs import dm
+import parted
+import _ped
+import platform
+import block
+
+from errors import *
+from iutil import notify_kernel, numeric_type
+from .storage_log import log_method_call
+from udev import *
+from formats import get_device_format_class, getFormat, DeviceFormat
+
+import gettext
+_ = lambda x: gettext.ldgettext("anaconda", x)
+P_ = lambda x, y, z: gettext.ldngettext("anaconda", x, y, z)
+
+import logging
+log = logging.getLogger("storage")
+
+def get_device_majors():
+    majors = {}
+    for line in open("/proc/devices").readlines():
+        try:
+            (major, device) = line.split()
+        except ValueError:
+            continue
+        try:
+            majors[int(major)] = device
+        except ValueError:
+            continue
+    return majors
+device_majors = get_device_majors()
+
+
+def devicePathToName(devicePath):
+    if devicePath.startswith("/dev/"):
+        name = devicePath[5:]
+    else:
+        name = devicePath
+
+    if name.startswith("mapper/"):
+        name = name[7:]
+
+    return name
+
+
+def deviceNameToDiskByPath(deviceName=None):
+    if not deviceName:
+        return ""
+
+    for dev in udev_get_block_devices():
+        if udev_device_get_name(dev) == deviceName:
+            return udev_device_get_by_path(dev)
+
+    return None
+
+
+class Device(object):
+    """ A generic device.
+
+        Device instances know which devices they depend upon (parents
+        attribute). They do not know which devices depend upon them, but
+        they do know whether or not they have any dependent devices
+        (isleaf attribute).
+
+        A Device's setup method should set up all parent devices as well
+        as the device itself. It should not run the resident format's
+        setup method.
+
+            Which Device types rely on their parents' formats being active?
+                DMCryptDevice
+
+        A Device's teardown method should accept the keyword argument
+        recursive, which takes a boolean value and indicates whether or
+        not to recursively close parent devices.
+
+        A Device's create method should create all parent devices as well
+        as the device itself. It should also run the Device's setup method
+        after creating the device. The create method should not create a
+        device's resident format.
+
+            Which device type rely on their parents' formats to be created
+            before they can be created/assembled?
+                VolumeGroup
+                DMCryptDevice
+
+        A Device's destroy method should destroy any resident format
+        before destroying the device itself.
+
+    """
+
+    # This is a counter for generating unique ids for Devices.
+    _id = 0
+
+    _type = "generic device"
+    _packages = []
+
+    def __init__(self, name, parents=None):
+        """ Create a Device instance.
+
+            Arguments:
+
+                name -- the device name (generally a device node's basename)
+
+            Keyword Arguments:
+
+                parents -- a list of required Device instances
+
+        """
+        self._name = name
+        if parents is None:
+            parents = []
+        elif not isinstance(parents, list):
+            raise ValueError("parents must be a list of Device instances")
+        self.parents = parents
+        self.kids = 0
+
+        # Set this instance's id and increment the counter.
+        self.id = Device._id
+        Device._id += 1
+
+        for parent in self.parents:
+            parent.addChild()
+
+    def __deepcopy__(self, memo):
+        """ Create a deep copy of a Device instance.
+
+            We can't do copy.deepcopy on parted objects, which is okay.
+            For these parted objects, we just do a shallow copy.
+        """
+        new = self.__class__.__new__(self.__class__)
+        memo[id(self)] = new
+        dont_copy_attrs = ('_raidSet',)
+        shallow_copy_attrs = ('_partedDevice', '_partedPartition')
+        for (attr, value) in self.__dict__.items():
+            if attr in dont_copy_attrs:
+                setattr(new, attr, value)
+            elif attr in shallow_copy_attrs:
+                setattr(new, attr, copy.copy(value))
+            else:
+                setattr(new, attr, copy.deepcopy(value, memo))
+
+        return new
+
+    def __str__(self):
+        s = ("%(type)s instance (%(id)s) --\n"
+             "  name = %(name)s  status = %(status)s"
+             "  parents = %(parents)s\n"
+             "  kids = %(kids)s\n"
+             "  id = %(dev_id)s\n" %
+             {"type": self.__class__.__name__, "id": "%#x" % id(self),
+              "name": self.name, "parents": self.parents, "kids": self.kids,
+              "status": self.status, "dev_id": self.id})
+        return s
+
+    @property
+    def dict(self):
+        d =  {"type": self.type, "name": self.name,
+              "parents": [p.name for p in self.parents]}
+        return d
+
+    def writeKS(self, f, preexisting=False, noformat=False, s=None):
+        return
+
+    def removeChild(self):
+        log_method_call(self, name=self.name, kids=self.kids)
+        self.kids -= 1
+
+    def addChild(self):
+        log_method_call(self, name=self.name, kids=self.kids)
+        self.kids += 1
+
+    def setup(self, intf=None):
+        """ Open, or set up, a device. """
+        raise NotImplementedError("setup method not defined for Device")
+
+    def teardown(self, recursive=None):
+        """ Close, or tear down, a device. """
+        raise NotImplementedError("teardown method not defined for Device")
+
+    def create(self, intf=None):
+        """ Create the device. """
+        raise NotImplementedError("create method not defined for Device")
+
+    def destroy(self):
+        """ Destroy the device. """
+        raise NotImplementedError("destroy method not defined for Device")
+
+    def setupParents(self, orig=False):
+        """ Run setup method of all parent devices. """
+        log_method_call(self, name=self.name, orig=orig, kids=self.kids)
+        for parent in self.parents:
+            parent.setup(orig=orig)
+
+    def teardownParents(self, recursive=None):
+        """ Run teardown method of all parent devices. """
+        for parent in self.parents:
+            parent.teardown(recursive=recursive)
+
+    def createParents(self):
+        """ Run create method of all parent devices. """
+        log.info("NOTE: recursive device creation disabled")
+        for parent in self.parents:
+            if not parent.exists:
+                raise DeviceError("parent device does not exist", self.name)
+            #parent.create()
+
+    def dependsOn(self, dep):
+        """ Return True if this device depends on dep. """
+        # XXX does a device depend on itself?
+        if dep in self.parents:
+            return True
+
+        for parent in self.parents:
+            if parent.dependsOn(dep):
+                return True
+
+        return False
+
+    def dracutSetupString(self):
+        return ""
+
+    @property
+    def status(self):
+        """ This device's status.
+
+            For now, this should return a boolean:
+                True    the device is open and ready for use
+                False   the device is not open
+        """
+        return False
+
+    @property
+    def name(self):
+        """ This device's name. """
+        return self._name
+
+    @property
+    def isleaf(self):
+        """ True if this device has no children. """
+        return self.kids == 0
+
+    @property
+    def typeDescription(self):
+        """ String describing the device type. """
+        return self._type
+
+    @property
+    def type(self):
+        """ Device type. """
+        return self._type
+
+    @property
+    def packages(self):
+        """ List of packages required to manage devices of this type.
+
+            This list includes the packages required by its parent devices.
+        """
+        packages = self._packages
+        for parent in self.parents:
+            for package in parent.packages:
+                if package not in packages:
+                    packages.append(package)
+
+        return packages
+
+    @property
+    def mediaPresent(self):
+        return True
+
+
+class NetworkStorageDevice(object):
+    """ Virtual base class for network backed storage devices """
+
+    def __init__(self, host_address=None, nic=None):
+        """ Create a NetworkStorage Device instance. Note this class is only
+            to be used as a baseclass and then only with multiple inheritance.
+            The only correct use is:
+            class MyStorageDevice(StorageDevice, NetworkStorageDevice):
+
+            The sole purpose of this class is to:
+            1) Be able to check if a StorageDevice is network backed
+               (using isinstance).
+            2) To be able to get the host address of the host (server) backing
+               the storage *or* the NIC through which the storage is connected
+
+            Arguments:
+
+                host_address -- host address of the backing server
+                nic -- nic to which the storage is bound
+        """
+        self.host_address = host_address
+        self.nic = nic
+
+
+class StorageDevice(Device):
+    """ A generic storage device.
+
+        A fully qualified path to the device node can be obtained via the
+        path attribute, although it is not guaranteed to be useful, or
+        even present, unless the StorageDevice's setup method has been
+        run.
+
+        StorageDevice instances can optionally contain a filesystem,
+        represented by an FS instance. A StorageDevice's create method
+        should create a filesystem if one has been specified.
+    """
+    _type = "storage device"
+    _devDir = "/dev"
+    sysfsBlockDir = "class/block"
+    _resizable = False
+    _partitionable = False
+    _isDisk = False
+
+    def __init__(self, device, format=None,
+                 size=None, major=None, minor=None,
+                 sysfsPath='', parents=None, exists=None, serial=None,
+                 vendor="", model="", bus=""):
+        """ Create a StorageDevice instance.
+
+            Arguments:
+
+                device -- the device name (generally a device node's basename)
+
+            Keyword Arguments:
+
+                size -- the device's size (units/format TBD)
+                major -- the device major
+                minor -- the device minor
+                sysfsPath -- sysfs device path
+                format -- a DeviceFormat instance
+                parents -- a list of required Device instances
+                serial -- the ID_SERIAL_SHORT for this device
+                vendor -- the manufacturer of this Device
+                model -- manufacturer's device model string
+                bus -- the interconnect this device uses
+
+        """
+        # allow specification of individual parents
+        if isinstance(parents, Device):
+            parents = [parents]
+
+        self.exists = exists
+        Device.__init__(self, device, parents=parents)
+
+        self.uuid = None
+        self._format = None
+        self._size = numeric_type(size)
+        self.major = numeric_type(major)
+        self.minor = numeric_type(minor)
+        self.sysfsPath = sysfsPath
+        self._serial = serial
+        self._vendor = vendor
+        self._model = model
+        self.bus = bus
+
+        self.protected = False
+
+        self.format = format
+        self.originalFormat = self.format
+        self.fstabComment = ""
+        self._targetSize = self._size
+
+        self._partedDevice = None
+
+    @property
+    def packages(self):
+        """ List of packages required to manage devices of this type.
+
+            This list includes the packages required by this device's
+            format type as well those required by all of its parent 
+            devices.
+        """
+        packages = super(StorageDevice, self).packages
+        packages.extend(self.format.packages)
+        for parent in self.parents:
+            for package in parent.format.packages:
+                if package not in packages:
+                    packages.append(package)
+
+        return packages
+
+    @property
+    def partedDevice(self):
+        if self.exists and self.status and not self._partedDevice:
+            log.debug("looking up parted Device: %s" % self.path)
+
+            # We aren't guaranteed to be able to get a device.  In
+            # particular, built-in USB flash readers show up as devices but
+            # do not always have any media present, so parted won't be able
+            # to find a device.
+            try:
+                self._partedDevice = parted.Device(path=self.path)
+            except (_ped.IOException, _ped.DeviceException):
+                pass
+
+        return self._partedDevice
+
+    def _getTargetSize(self):
+        return self._targetSize
+
+    def _setTargetSize(self, newsize):
+        self._targetSize = newsize
+
+    targetSize = property(lambda s: s._getTargetSize(),
+                          lambda s, v: s._setTargetSize(v),
+                          doc="Target size of this device")
+
+    def __str__(self):
+        s = Device.__str__(self)
+        s += ("  uuid = %(uuid)s  format = %(format)r  size = %(size)s\n"
+              "  major = %(major)s  minor = %(minor)r  exists = %(exists)s\n"
+              "  sysfs path = %(sysfs)s  partedDevice = %(partedDevice)r\n"
+              "  target size = %(targetSize)s  path = %(path)s\n"
+              "  format args = %(formatArgs)s  originalFormat = %(origFmt)s" %
+              {"uuid": self.uuid, "format": self.format, "size": self.size,
+               "major": self.major, "minor": self.minor, "exists": self.exists,
+               "sysfs": self.sysfsPath, "partedDevice": self.partedDevice,
+               "targetSize": self.targetSize, "path": self.path,
+               "formatArgs": self.formatArgs, "origFmt": self.originalFormat})
+        return s
+
+    @property
+    def dict(self):
+        d =  super(StorageDevice, self).dict
+        d.update({"uuid": self.uuid, "size": self.size,
+                  "format": self.format.dict, "removable": self.removable,
+                  "major": self.major, "minor": self.minor,
+                  "exists": self.exists, "sysfs": self.sysfsPath,
+                  "targetSize": self.targetSize, "path": self.path})
+        return d
+
+    @property
+    def path(self):
+        """ Device node representing this device. """
+        return "%s/%s" % (self._devDir, self.name)
+
+    def updateSysfsPath(self):
+        """ Update this device's sysfs path. """
+        log_method_call(self, self.name, status=self.status)
+        sysfsName = self.name.replace("/", "!")
+        path = os.path.join("/sys", self.sysfsBlockDir, sysfsName)
+        self.sysfsPath = os.path.realpath(path)[4:]
+        log.debug("%s sysfsPath set to %s" % (self.name, self.sysfsPath))
+
+    @property
+    def formatArgs(self):
+        """ Device-specific arguments to format creation program. """
+        return []
+
+    @property
+    def resizable(self):
+        """ Can this type of device be resized? """
+        return self._resizable and self.exists and \
+               ((self.format and self.format.resizable) or not self.format)
+
+    def notifyKernel(self):
+        """ Send a 'change' uevent to the kernel for this device. """
+        log_method_call(self, self.name, status=self.status)
+        if not self.exists:
+            log.debug("not sending change uevent for non-existent device")
+            return
+
+        if not self.status:
+            log.debug("not sending change uevent for inactive device")
+            return
+
+        path = os.path.normpath("/sys/%s" % self.sysfsPath)
+        try:
+            notify_kernel(path, action="change")
+        except Exception, e:
+            log.warning("failed to notify kernel of change: %s" % e)
+
+    @property
+    def fstabSpec(self):
+        spec = self.path
+        if self.format and self.format.uuid:
+            spec = "UUID=%s" % self.format.uuid
+        return spec
+
+    def resize(self, intf=None):
+        """ Resize the device.
+
+            New size should already be set.
+        """
+        raise NotImplementedError("resize method not defined for StorageDevice")
+
+    def setup(self, intf=None, orig=False):
+        """ Open, or set up, a device. """
+        log_method_call(self, self.name, orig=orig, status=self.status)
+        if not self.exists:
+            raise DeviceError("device has not been created", self.name)
+
+        self.setupParents(orig=orig)
+        for parent in self.parents:
+            if orig:
+                parent.originalFormat.setup()
+            else:
+                parent.format.setup()
+
+    def teardown(self, recursive=None):
+        """ Close, or tear down, a device. """
+        log_method_call(self, self.name, status=self.status)
+        if not self.exists and not recursive:
+            raise DeviceError("device has not been created", self.name)
+
+        if self.status:
+            if self.originalFormat.exists:
+                self.originalFormat.teardown()
+            if self.format.exists:
+                self.format.teardown()
+            udev_settle()
+
+        if recursive:
+            self.teardownParents(recursive=recursive)
+
+    def _getSize(self):
+        """ Get the device's size in MB, accounting for pending changes. """
+        if self.exists and not self.mediaPresent:
+            return 0
+
+        if self.exists and self.partedDevice:
+            self._size = self.currentSize
+
+        size = self._size
+        if self.exists and self.resizable and self.targetSize != size:
+            size = self.targetSize
+
+        return size
+
+    def _setSize(self, newsize):
+        """ Set the device's size to a new value. """
+        if newsize > self.maxSize:
+            raise DeviceError("device cannot be larger than %s MB" %
+                              (self.maxSize(),), self.name)
+        self._size = newsize
+
+    size = property(lambda x: x._getSize(),
+                    lambda x, y: x._setSize(y),
+                    doc="The device's size in MB, accounting for pending changes")
+
+    @property
+    def currentSize(self):
+        """ The device's actual size. """
+        size = 0
+        if self.exists and self.partedDevice:
+            size = self.partedDevice.getSize()
+        elif self.exists:
+            size = self._size
+        return size
+
+    @property
+    def minSize(self):
+        """ The minimum size this device can be. """
+        if self.format.minSize:
+            return self.format.minSize
+        else:
+            return self.size
+
+    @property
+    def maxSize(self):
+        """ The maximum size this device can be. """
+        if self.format.maxSize > self.currentSize:
+            return self.currentSize
+        else:
+            return self.format.maxSize
+
+    @property
+    def status(self):
+        """ This device's status.
+
+            For now, this should return a boolean:
+                True    the device is open and ready for use
+                False   the device is not open
+        """
+        if not self.exists:
+            return False
+        return os.access(self.path, os.W_OK)
+
+    def _setFormat(self, format):
+        """ Set the Device's format. """
+        if not format:
+            format = getFormat(None, device=self.path, exists=self.exists)
+        log_method_call(self, self.name, type=format.type,
+                        current=getattr(self._format, "type", None))
+        if self._format and self._format.status:
+            # FIXME: self.format.status doesn't mean much
+            raise DeviceError("cannot replace active format", self.name)
+
+        self._format = format
+
+    def _getFormat(self):
+        return self._format
+
+    format = property(lambda d: d._getFormat(),
+                      lambda d,f: d._setFormat(f),
+                      doc="The device's formatting.")
+
+    def preCommitFixup(self, *args, **kwargs):
+        """ Do any necessary pre-commit fixups."""
+        pass
+
+    def create(self, intf=None):
+        """ Create the device. """
+        log_method_call(self, self.name, status=self.status)
+        if self.exists:
+            raise DeviceError("device has already been created", self.name)
+
+        self.createParents()
+        self.setupParents()
+        self.exists = True
+        self.setup()
+
+    def destroy(self):
+        """ Destroy the device. """
+        log_method_call(self, self.name, status=self.status)
+        if not self.exists:
+            raise DeviceError("device has not been created", self.name)
+
+        if not self.isleaf:
+            raise DeviceError("Cannot destroy non-leaf device", self.name)
+
+        self.exists = False
+        # we already did this in DeviceTree._removeDevice
+        #for parent in self.parents:
+        #    parent.removeChild()
+
+    @property
+    def removable(self):
+        devpath = os.path.normpath("/sys/%s" % self.sysfsPath)
+        remfile = os.path.normpath("%s/removable" % devpath)
+        return (self.sysfsPath and os.path.exists(devpath) and
+                os.access(remfile, os.R_OK) and
+                open(remfile).readline().strip() == "1")
+
+    @property
+    def isDisk(self):
+        return self._isDisk
+
+    @property
+    def partitionable(self):
+        return self._partitionable
+
+    @property
+    def partitioned(self):
+        return self.format.type == "disklabel" and self.partitionable
+
+    @property
+    def serial(self):
+        return self._serial
+
+    @property
+    def model(self):
+        if not self._model:
+            self._model = getattr(self.partedDevice, "model", "")
+        return self._model
+
+    @property
+    def vendor(self):
+        return self._vendor
+
+class DiskDevice(StorageDevice):
+    """ A disk """
+    _type = "disk"
+    _partitionable = True
+    _isDisk = True
+
+    def __init__(self, device, format=None,
+                 size=None, major=None, minor=None, sysfsPath='',
+                 parents=None, serial=None, vendor="", model="", bus="",
+                 exists=True):
+        """ Create a DiskDevice instance.
+
+            Arguments:
+
+                device -- the device name (generally a device node's basename)
+
+            Keyword Arguments:
+
+                size -- the device's size (units/format TBD)
+                major -- the device major
+                minor -- the device minor
+                sysfsPath -- sysfs device path
+                format -- a DeviceFormat instance
+                parents -- a list of required Device instances
+                removable -- whether or not this is a removable device
+                serial -- the ID_SERIAL_SHORT for this device
+                vendor -- the manufacturer of this Device
+                model -- manufacturer's device model string
+                bus -- the interconnect this device uses
+
+
+            DiskDevices always exist.
+        """
+        StorageDevice.__init__(self, device, format=format, size=size,
+                               major=major, minor=minor, exists=exists,
+                               sysfsPath=sysfsPath, parents=parents,
+                               serial=serial, model=model,
+                               vendor=vendor, bus=bus)
+
+    def __str__(self):
+        s = StorageDevice.__str__(self)
+        s += ("  removable = %(removable)s  partedDevice = %(partedDevice)r" %
+              {"removable": self.removable, "partedDevice": self.partedDevice})
+        return s
+
+    @property
+    def mediaPresent(self):
+        if not self.partedDevice:
+            return False
+
+        # Some drivers (cpqarray <blegh>) make block device nodes for
+        # controllers with no disks attached and then report a 0 size,
+        # treat this as no media present
+        return self.partedDevice.getSize() != 0
+
+    @property
+    def description(self):
+        return self.model
+
+    @property
+    def size(self):
+        """ The disk's size in MB """
+        return super(DiskDevice, self).size
+    #size = property(StorageDevice._getSize)
+
+    def probe(self):
+        """ Probe for any missing information about this device.
+
+            pyparted should be able to tell us anything we want to know.
+            size, disklabel type, maybe even partition layout
+        """
+        log_method_call(self, self.name, size=self.size, partedDevice=self.partedDevice)
+
+    def destroy(self):
+        """ Destroy the device. """
+        log_method_call(self, self.name, status=self.status)
+        if not self.mediaPresent:
+            raise DeviceError("cannot destroy disk with no media", self.name)
+
+        self.teardown()
+
+    def setup(self, intf=None, orig=False):
+        """ Open, or set up, a device. """
+        log_method_call(self, self.name, orig=orig, status=self.status)
+        if not os.path.exists(self.path):
+            raise DeviceError("device does not exist", self.name)
+
+
+class PartitionDevice(StorageDevice):
+    """ A disk partition.
+
+        On types and flags...
+
+        We don't need to deal with numerical partition types at all. The
+        only type we are concerned with is primary/logical/extended. Usage
+        specification is accomplished through the use of flags, which we
+        will set according to the partition's format.
+    """
+    _type = "partition"
+    _resizable = True
+    defaultSize = 500
+
+    def __init__(self, name, format=None,
+                 size=None, grow=False, maxsize=None,
+                 major=None, minor=None, bootable=None,
+                 sysfsPath='', parents=None, exists=None,
+                 partType=None, primary=False, weight=0):
+        """ Create a PartitionDevice instance.
+
+            Arguments:
+
+                name -- the device name (generally a device node's basename)
+
+            Keyword Arguments:
+
+                exists -- indicates whether this is an existing device
+                format -- the device's format (DeviceFormat instance)
+
+                For existing partitions:
+
+                    parents -- the disk that contains this partition
+                    major -- the device major
+                    minor -- the device minor
+                    sysfsPath -- sysfs device path
+
+                For new partitions:
+
+                    partType -- primary,extended,&c (as parted constant)
+                    grow -- whether or not to grow the partition
+                    maxsize -- max size for growable partitions (in MB)
+                    size -- the device's size (in MB)
+                    bootable -- whether the partition is bootable
+                    parents -- a list of potential containing disks
+                    weight -- an initial sorting weight to assign
+        """
+        self.req_disks = []
+        self.req_partType = None
+        self.req_primary = None
+        self.req_grow = None
+        self.req_bootable = None
+        self.req_size = 0
+        self.req_base_size = 0
+        self.req_max_size = 0
+        self.req_base_weight = 0
+
+        self._bootable = False
+
+        StorageDevice.__init__(self, name, format=format, size=size,
+                               major=major, minor=minor, exists=exists,
+                               sysfsPath=sysfsPath, parents=parents)
+
+        if not exists:
+            # this is a request, not a partition -- it has no parents
+            self.req_disks = self.parents[:]
+            for dev in self.parents:
+                dev.removeChild()
+            self.parents = []
+
+        # FIXME: Validate partType, but only if this is a new partition
+        #        Otherwise, overwrite it with the partition's type.
+        self._partType = None
+        self.partedFlags = {}
+        self._partedPartition = None
+        self._origPath = None
+        self._currentSize = 0
+
+        # FIXME: Validate size, but only if this is a new partition.
+        #        For existing partitions we will get the size from
+        #        parted.
+
+        if self.exists:
+            log.debug("looking up parted Partition: %s" % self.path)
+            self._partedPartition = self.disk.format.partedDisk.getPartitionByPath(self.path)
+            if not self._partedPartition:
+                raise DeviceError("cannot find parted partition instance", self.name)
+
+            self._origPath = self.path
+            # collect information about the partition from parted
+            self.probe()
+            if self.getFlag(parted.PARTITION_PREP):
+                # the only way to identify a PPC PReP Boot partition is to
+                # check the partition type/flags, so do it here.
+                self.format = getFormat("prepboot", device=self.path, exists=True)
+        else:
+            # XXX It might be worthwhile to create a shit-simple
+            #     PartitionRequest class and pass one to this constructor
+            #     for new partitions.
+            if not self._size:
+                # default size for new partition requests
+                self._size = self.defaultSize
+            self.req_name = name
+            self.req_partType = partType
+            self.req_primary = primary
+            self.req_max_size = numeric_type(maxsize)
+            self.req_grow = grow
+            self.req_bootable = bootable
+
+            # req_size may be manipulated in the course of partitioning
+            self.req_size = self._size
+
+            # req_base_size will always remain constant
+            self.req_base_size = self._size
+
+            self.req_base_weight = weight
+
+    def __str__(self):
+        s = StorageDevice.__str__(self)
+        s += ("  grow = %(grow)s  max size = %(maxsize)s  bootable = %(bootable)s\n"
+              "  part type = %(partType)s  primary = %(primary)s\n"
+              "  partedPartition = %(partedPart)r  disk = %(disk)r\n" %
+              {"grow": self.req_grow, "maxsize": self.req_max_size,
+               "bootable": self.bootable, "partType": self.partType,
+               "primary": self.req_primary,
+               "partedPart": self.partedPartition, "disk": self.disk})
+
+        if self.partedPartition:
+            s += ("  start = %(start)s  end = %(end)s  length = %(length)s\n"
+                  "  flags = %(flags)s" %
+                  {"length": self.partedPartition.geometry.length,
+                   "start": self.partedPartition.geometry.start,
+                   "end": self.partedPartition.geometry.end,
+                   "flags": self.partedPartition.getFlagsAsString()})
+
+        return s
+
+    @property
+    def dict(self):
+        d = super(PartitionDevice, self).dict
+        d.update({"type": self.partType})
+        if not self.exists:
+            d.update({"grow": self.req_grow, "maxsize": self.req_max_size,
+                      "bootable": self.bootable,
+                      "primary": self.req_primary})
+
+        if self.partedPartition:
+            d.update({"length": self.partedPartition.geometry.length,
+                      "start": self.partedPartition.geometry.start,
+                      "end": self.partedPartition.geometry.end,
+                      "flags": self.partedPartition.getFlagsAsString()})
+        return d
+
+    def writeKS(self, f, preexisting=False, noformat=False, s=None):
+        args = []
+
+        if self.isExtended:
+            return
+
+        if self.req_grow:
+            args.append("--grow")
+        if self.req_max_size:
+            args.append("--maxsize=%s" % self.req_max_size)
+        if self.req_primary:
+            args.append("--asprimary")
+        if self.req_size:
+            args.append("--size=%s" % (self.req_size or self.defaultSize))
+        if preexisting:
+            if len(self.req_disks) == 1:
+                args.append("--ondisk=%s" % self.req_disks[0].name)
+            else:
+                args.append("--onpart=%s" % self.name)
+        if noformat:
+            args.append("--noformat")
+
+        f.write("#part ")
+        self.format.writeKS(f)
+        f.write(" %s" % " ".join(args))
+        if s:
+            f.write(" %s" % s)
+
+    def _setTargetSize(self, newsize):
+        if newsize != self.currentSize:
+            # change this partition's geometry in-memory so that other
+            # partitioning operations can complete (e.g., autopart)
+            self._targetSize = newsize
+            disk = self.disk.format.partedDisk
+
+            # resize the partition's geometry in memory
+            (constraint, geometry) = self._computeResize(self.partedPartition)
+            disk.setPartitionGeometry(partition=self.partedPartition,
+                                      constraint=constraint,
+                                      start=geometry.start, end=geometry.end)
+
+    @property
+    def path(self):
+        """ Device node representing this device. """
+        if not self.parents:
+            # Bogus, but code in various places compares devices by path
+            # So we must return something unique
+            return self.name
+
+        return "%s/%s" % (self.parents[0]._devDir, self.name)
+
+    @property
+    def partType(self):
+        """ Get the partition's type (as parted constant). """
+        try:
+            ptype = self.partedPartition.type
+        except AttributeError:
+            ptype = self._partType
+
+        if not self.exists and ptype is None:
+            ptype = self.req_partType
+
+        return ptype
+
+    @property
+    def isExtended(self):
+        return (self.partType is not None and
+                self.partType & parted.PARTITION_EXTENDED)
+
+    @property
+    def isLogical(self):
+        return (self.partType is not None and
+                self.partType & parted.PARTITION_LOGICAL)
+
+    @property
+    def isPrimary(self):
+        return (self.partType is not None and
+                self.partType == parted.PARTITION_NORMAL)
+
+    @property
+    def isProtected(self):
+        return (self.partType is not None and
+                self.partType & parted.PARTITION_PROTECTED)
+
+    @property
+    def fstabSpec(self):
+        spec = self.path
+        if self.disk and self.disk.type == 'dasd':
+            spec = deviceNameToDiskByPath(self.name)
+        elif self.format and self.format.uuid:
+            spec = "UUID=%s" % self.format.uuid
+        return spec
+
+    def _getPartedPartition(self):
+        return self._partedPartition
+
+    def _setPartedPartition(self, partition):
+        """ Set this PartitionDevice's parted Partition instance. """
+        log_method_call(self, self.name)
+        if partition is None:
+            path = None
+        elif isinstance(partition, parted.Partition):
+            path = partition.path
+        else:
+            raise ValueError("partition must be a parted.Partition instance")
+
+        log.debug("device %s new partedPartition %s has path %s" % (self.name,
+                                                                    partition,
+                                                                    path))
+        self._partedPartition = partition
+        self.updateName()
+
+    partedPartition = property(lambda d: d._getPartedPartition(),
+                               lambda d,p: d._setPartedPartition(p))
+
+    def preCommitFixup(self, *args, **kwargs):
+        """ Re-get self.partedPartition from the original disklabel. """
+        log_method_call(self, self.name)
+        if not self.exists:
+            return
+
+        # find the correct partition on the original parted.Disk since the
+        # name/number we're now using may no longer match
+        _disklabel = self.disk.originalFormat
+
+        if self.isExtended:
+            # getPartitionBySector doesn't work on extended partitions
+            _partition = _disklabel.extendedPartition
+            log.debug("extended lookup found partition %s"
+                        % devicePathToName(getattr(_partition, "path", None)))
+        else:
+            # lookup the partition by sector to avoid the renumbering
+            # nonsense entirely
+            _sector = self.partedPartition.geometry.start
+            _partition = _disklabel.partedDisk.getPartitionBySector(_sector)
+            log.debug("sector-based lookup found partition %s"
+                        % devicePathToName(getattr(_partition, "path", None)))
+
+        self.partedPartition = _partition
+
+    def _getWeight(self):
+        return self.req_base_weight
+
+    def _setWeight(self, weight):
+        self.req_base_weight = weight
+
+    weight = property(lambda d: d._getWeight(),
+                      lambda d,w: d._setWeight(w))
+
+    def updateSysfsPath(self):
+        """ Update this device's sysfs path. """
+        log_method_call(self, self.name, status=self.status)
+        if not self.parents:
+            self.sysfsPath = ''
+
+        elif self.parents[0]._devDir == "/dev/mapper":
+            dm_node = dm.dm_node_from_name(self.name)
+            path = os.path.join("/sys", self.sysfsBlockDir, dm_node)
+            self.sysfsPath = os.path.realpath(path)[4:]
+
+        else:
+            StorageDevice.updateSysfsPath(self)
+
+    def updateName(self):
+        if self.partedPartition is None:
+            self._name = self.req_name
+        else:
+            self._name = \
+                devicePathToName(self.partedPartition.getDeviceNodeName())
+
+    def dependsOn(self, dep):
+        """ Return True if this device depends on dep. """
+        if isinstance(dep, PartitionDevice) and dep.isExtended and \
+           self.isLogical and self.disk == dep.disk:
+            return True
+
+        return Device.dependsOn(self, dep)
+
+    def _setFormat(self, format):
+        """ Set the Device's format. """
+        log_method_call(self, self.name)
+        StorageDevice._setFormat(self, format)
+
+    def _setBootable(self, bootable):
+        """ Set the bootable flag for this partition. """
+        if self.partedPartition:
+            if iutil.isS390():
+                return
+            if self.flagAvailable(parted.PARTITION_BOOT):
+                if bootable:
+                    self.setFlag(parted.PARTITION_BOOT)
+                else:
+                    self.unsetFlag(parted.PARTITION_BOOT)
+            else:
+                raise DeviceError("boot flag not available for this partition", self.name)
+
+            self._bootable = bootable
+        else:
+            self.req_bootable = bootable
+
+    def _getBootable(self):
+        return self._bootable or self.req_bootable
+
+    bootable = property(_getBootable, _setBootable)
+
+    def flagAvailable(self, flag):
+        log_method_call(self, path=self.path, flag=flag)
+        if not self.partedPartition:
+            return
+
+        return self.partedPartition.isFlagAvailable(flag)
+
+    def getFlag(self, flag):
+        log_method_call(self, path=self.path, flag=flag)
+        if not self.partedPartition or not self.flagAvailable(flag):
+            return
+
+        return self.partedPartition.getFlag(flag)
+
+    def setFlag(self, flag):
+        log_method_call(self, path=self.path, flag=flag)
+        if not self.partedPartition or not self.flagAvailable(flag):
+            return
+
+        self.partedPartition.setFlag(flag)
+
+    def unsetFlag(self, flag):
+        log_method_call(self, path=self.path, flag=flag)
+        if not self.partedPartition or not self.flagAvailable(flag):
+            return
+
+        self.partedPartition.unsetFlag(flag)
+
+    def probe(self):
+        """ Probe for any missing information about this device.
+
+            size, partition type, flags
+        """
+        log_method_call(self, self.name, exists=self.exists)
+        if not self.exists:
+            return
+
+        # this is in MB
+        self._size = self.partedPartition.getSize()
+        self._currentSize = self._size
+        self.targetSize = self._size
+
+        self._partType = self.partedPartition.type
+
+        self._bootable = self.getFlag(parted.PARTITION_BOOT)
+
+    def create(self, intf=None):
+        """ Create the device. """
+        log_method_call(self, self.name, status=self.status)
+        if self.exists:
+            raise DeviceError("device already exists", self.name)
+
+        w = None
+        if intf:
+            w = intf.waitWindow(_("Creating"),
+                                _("Creating device %s") % (self.path,))
+
+        try:
+            self.createParents()
+            self.setupParents()
+
+            self.disk.format.addPartition(self.partedPartition)
+
+            try:
+                self.disk.format.commit()
+            except DiskLabelCommitError:
+                part = self.disk.format.partedDisk.getPartitionByPath(self.path)
+                self.disk.format.removePartition(part)
+                raise
+
+            if not self.isExtended:
+                # Ensure old metadata which lived in freespace so did not get
+                # explictly destroyed by a destroyformat action gets wiped
+                DeviceFormat(device=self.path, exists=True).destroy()
+        except Exception:
+            raise
+        else:
+            self.partedPartition = self.disk.format.partedDisk.getPartitionByPath(self.path)
+
+            self.exists = True
+            self._currentSize = self.partedPartition.getSize()
+            self.setup()
+        finally:
+            if w:
+                w.pop()
+
+    def _computeResize(self, partition):
+        log_method_call(self, self.name, status=self.status)
+
+        # compute new size for partition
+        currentGeom = partition.geometry
+        currentDev = currentGeom.device
+        newLen = long(self.targetSize * 1024 * 1024) / currentDev.sectorSize
+        newGeometry = parted.Geometry(device=currentDev,
+                                      start=currentGeom.start,
+                                      length=newLen)
+        # and align the end sector
+        newGeometry.end = self.disk.format.endAlignment.alignDown(newGeometry,
+                                                               newGeometry.end)
+        constraint = parted.Constraint(exactGeom=newGeometry)
+
+        return (constraint, newGeometry)
+
+    def resize(self, intf=None):
+        """ Resize the device.
+
+            self.targetSize must be set to the new size.
+        """
+        log_method_call(self, self.name, status=self.status)
+
+        if self.targetSize != self.currentSize:
+            # partedDisk has been restored to _origPartedDisk, so
+            # recalculate resize geometry because we may have new
+            # partitions on the disk, which could change constraints
+            partedDisk = self.disk.format.partedDisk
+            partition = partedDisk.getPartitionByPath(self.path)
+            (constraint, geometry) = self._computeResize(partition)
+
+            partedDisk.setPartitionGeometry(partition=partition,
+                                            constraint=constraint,
+                                            start=geometry.start,
+                                            end=geometry.end)
+
+            self.disk.format.commit()
+            self._currentSize = partition.getSize()
+
+    def destroy(self):
+        """ Destroy the device. """
+        log_method_call(self, self.name, status=self.status)
+        if not self.exists:
+            raise DeviceError("device has not been created", self.name)
+
+        if not self.sysfsPath:
+            return
+
+        if not self.isleaf:
+            raise DeviceError("Cannot destroy non-leaf device", self.name)
+
+        self.setupParents(orig=True)
+
+        # we should have already set self.partedPartition to point to the
+        # partition on the original disklabel
+        self.disk.originalFormat.removePartition(self.partedPartition)
+        self.disk.originalFormat.commit()
+
+        self.exists = False
+
+    def teardown(self, recursive=None):
+        """ Close, or tear down, a device. """
+        log_method_call(self, self.name, status=self.status)
+        if not self.exists and not recursive:
+            raise DeviceError("device has not been created", self.name)
+
+        if self.status:
+            if self.originalFormat.exists:
+                self.originalFormat.teardown()
+            if self.format.exists:
+                self.format.teardown()
+            if self.parents[0].type == 'dm-multipath':
+                devmap = block.getMap(major=self.major, minor=self.minor)
+                if devmap:
+                    try:
+                        block.removeDeviceMap(devmap)
+                    except Exception as e:
+                        raise DeviceTeardownError("failed to tear down device-mapper partition %s: %s" % (self.name, e))
+                udev_settle()
+
+        StorageDevice.teardown(self, recursive=recursive)
+
+    def _getSize(self):
+        """ Get the device's size. """
+        size = self._size
+        if self.partedPartition:
+            # this defaults to MB
+            size = self.partedPartition.getSize()
+        return size
+
+    def _setSize(self, newsize):
+        """ Set the device's size (for resize, not creation).
+
+            Arguments:
+
+                newsize -- the new size (in MB)
+
+        """
+        log_method_call(self, self.name,
+                        status=self.status, size=self._size, newsize=newsize)
+        if not self.exists:
+            raise DeviceError("device does not exist", self.name)
+
+        if newsize > self.disk.size:
+            raise ValueError("partition size would exceed disk size")
+
+        # this defaults to MB
+        maxAvailableSize = self.partedPartition.getMaxAvailableSize()
+
+        if newsize > maxAvailableSize:
+            raise ValueError("new size is greater than available space")
+
+         # now convert the size to sectors and update the geometry
+        geometry = self.partedPartition.geometry
+        physicalSectorSize = geometry.device.physicalSectorSize
+
+        new_length = (newsize * (1024 * 1024)) / physicalSectorSize
+        geometry.length = new_length
+
+    def _getDisk(self):
+        """ The disk that contains this partition."""
+        try:
+            disk = self.parents[0]
+        except IndexError:
+            disk = None
+        return disk
+
+    def _setDisk(self, disk):
+        """Change the parent.
+
+        Setting up a disk is not trivial.  It has the potential to change
+        the underlying object.  If necessary we must also change this object.
+        """
+        log_method_call(self, self.name, old=getattr(self.disk, "name", None),
+                        new=getattr(disk, "name", None))
+        if self.disk:
+            self.disk.removeChild()
+
+        if disk:
+            self.parents = [disk]
+            disk.addChild()
+        else:
+            self.parents = []
+
+    disk = property(lambda p: p._getDisk(), lambda p,d: p._setDisk(d))
+
+    @property
+    def maxSize(self):
+        """ The maximum size this partition can be. """
+        # XXX: this is MB by default
+        maxPartSize = self.partedPartition.getMaxAvailableSize()
+
+        if self.format.maxSize > maxPartSize:
+            return maxPartSize
+        else:
+            return self.format.maxSize
+
+    @property
+    def currentSize(self):
+        """ The device's actual size. """
+        if self.exists:
+            return self._currentSize
+        else:
+            return 0
+
+
+class DMDevice(StorageDevice):
+    """ A device-mapper device """
+    _type = "dm"
+    _devDir = "/dev/mapper"
+
+    def __init__(self, name, format=None, size=None, dmUuid=None,
+                 target=None, exists=None, parents=None, sysfsPath=''):
+        """ Create a DMDevice instance.
+
+            Arguments:
+
+                name -- the device name (generally a device node's basename)
+
+            Keyword Arguments:
+
+                target -- the device-mapper target type (string)
+                size -- the device's size (units/format TBD)
+                dmUuid -- the device's device-mapper UUID
+                sysfsPath -- sysfs device path
+                format -- a DeviceFormat instance
+                parents -- a list of required Device instances
+                exists -- indicates whether this is an existing device
+        """
+        StorageDevice.__init__(self, name, format=format, size=size,
+                               exists=exists,
+                               parents=parents, sysfsPath=sysfsPath)
+        self.target = target
+        self.dmUuid = dmUuid
+
+    def __str__(self):
+        s = StorageDevice.__str__(self)
+        s += ("  target = %(target)s  dmUuid = %(dmUuid)s" %
+              {"target": self.target, "dmUuid": self.dmUuid})
+        return s
+
+    @property
+    def dict(self):
+        d = super(DMDevice, self).dict
+        d.update({"target": self.target, "dmUuid": self.dmUuid})
+        return d
+
+    @property
+    def fstabSpec(self):
+        """ Return the device specifier for use in /etc/fstab. """
+        return self.path
+
+    @property
+    def mapName(self):
+        """ This device's device-mapper map name """
+        return self.name
+
+    @property
+    def status(self):
+        _status = False
+        for map in block.dm.maps():
+            if map.name == self.mapName:
+                _status = map.live_table and not map.suspended
+                break
+
+        return _status
+
+    def updateSysfsPath(self):
+        """ Update this device's sysfs path. """
+        log_method_call(self, self.name, status=self.status)
+        if not self.exists:
+            raise DeviceError("device has not been created", self.name)
+
+        if self.status:
+            dm_node = self.getDMNode()
+            path = os.path.join("/sys", self.sysfsBlockDir, dm_node)
+            self.sysfsPath = os.path.realpath(path)[4:]
+        else:
+            self.sysfsPath = ''
+
+    #def getTargetType(self):
+    #    return dm.getDmTarget(name=self.name)
+
+    def getDMNode(self):
+        """ Return the dm-X (eg: dm-0) device node for this device. """
+        log_method_call(self, self.name, status=self.status)
+        if not self.exists:
+            raise DeviceError("device has not been created", self.name)
+
+        return dm.dm_node_from_name(self.name)
+
+    def _setName(self, name):
+        """ Set the device's map name. """
+        log_method_call(self, self.name, status=self.status)
+        if self.status:
+            raise DeviceError("cannot rename active device", self.name)
+
+        self._name = name
+        #self.sysfsPath = "/dev/disk/by-id/dm-name-%s" % self.name
+
+    name = property(lambda d: d._name,
+                    lambda d,n: d._setName(n))
+
+
+class DMCryptDevice(DMDevice):
+    """ A dm-crypt device """
+    _type = "dm-crypt"
+
+    def __init__(self, name, format=None, size=None, uuid=None,
+                 exists=None, sysfsPath='', parents=None):
+        """ Create a DMCryptDevice instance.
+
+            Arguments:
+
+                name -- the device name (generally a device node's basename)
+
+            Keyword Arguments:
+
+                size -- the device's size (units/format TBD)
+                sysfsPath -- sysfs device path
+                format -- a DeviceFormat instance
+                parents -- a list of required Device instances
+                exists -- indicates whether this is an existing device
+        """
+        DMDevice.__init__(self, name, format=format, size=size,
+                          parents=parents, sysfsPath=sysfsPath,
+                          exists=exists, target="crypt")
+
+class LUKSDevice(DMCryptDevice):
+    """ A mapped LUKS device. """
+    _type = "luks/dm-crypt"
+
+    def __init__(self, name, format=None, size=None, uuid=None,
+                 exists=None, sysfsPath='', parents=None):
+        """ Create a LUKSDevice instance.
+
+            Arguments:
+
+                name -- the device name
+
+            Keyword Arguments:
+
+                size -- the device's size in MB
+                uuid -- the device's UUID
+                sysfsPath -- sysfs device path
+                format -- a DeviceFormat instance
+                parents -- a list of required Device instances
+                exists -- indicates whether this is an existing device
+        """
+        DMCryptDevice.__init__(self, name, format=format, size=size,
+                               parents=parents, sysfsPath=sysfsPath,
+                               uuid=None, exists=exists)
+
+    def writeKS(self, f, preexisting=False, noformat=False, s=None):
+        self.slave.writeKS(f, preexisting=preexisting, noformat=noformat, s=s)
+        self.format.writeKS(f)
+        if s:
+            f.write(" %s" % s)
+
+    @property
+    def size(self):
+        if not self.exists or not self.partedDevice:
+            # the LUKS header takes up 4040 512-byte sectors w/ a 512-bit key
+            size = float(self.slave.size) - ((4040 * 2.0) / 1024)
+        else:
+            size = self.partedDevice.getSize()
+        return size
+
+    def create(self, intf=None):
+        """ Create the device. """
+        log_method_call(self, self.name, status=self.status)
+        if self.exists:
+            raise DeviceError("device already exists", self.name)
+
+        self.createParents()
+        self.setupParents()
+
+        #if not self.slave.format.exists:
+        #    self.slave.format.create()
+        self._name = self.slave.format.mapName
+        self.exists = True
+        self.setup()
+
+    def setup(self, intf=None, orig=False):
+        """ Open, or set up, a device. """
+        log_method_call(self, self.name, orig=orig, status=self.status)
+        if not self.exists:
+            raise DeviceError("device has not been created", self.name)
+
+        self.slave.setup(orig=orig)
+        if orig:
+            self.slave.originalFormat.setup()
+        else:
+            self.slave.format.setup()
+        udev_settle()
+
+        # we always probe since the device may not be set up when we want
+        # information about it
+        self._size = self.currentSize
+
+    def teardown(self, recursive=False):
+        """ Close, or tear down, a device. """
+        log_method_call(self, self.name, status=self.status)
+        if not self.exists and not recursive:
+            raise DeviceError("device has not been created", self.name)
+
+        if self.status:
+            if self.originalFormat.exists:
+                self.originalFormat.teardown()
+            if self.format.exists:
+                self.format.teardown()
+            udev_settle()
+
+        if self.slave.originalFormat.exists:
+            self.slave.originalFormat.teardown()
+            udev_settle()
+
+        if self.slave.format.exists:
+            self.slave.format.teardown()
+            udev_settle()
+
+        if recursive:
+            self.teardownParents(recursive=recursive)
+
+    def destroy(self):
+        log_method_call(self, self.name, status=self.status)
+        self.format.teardown()
+        udev_settle()
+        self.teardown()
+
+    @property
+    def req_grow(self):
+        return getattr(self.slave, "req_grow", None)
+
+    @property
+    def slave(self):
+        """ This device's backing device. """
+        return self.parents[0]
+
+    def dracutSetupString(self):
+        return "rd_LUKS_UUID=luks-%s" % self.slave.format.uuid
+
+
+class LVMVolumeGroupDevice(DMDevice):
+    """ An LVM Volume Group
+
+        XXX Maybe this should inherit from StorageDevice instead of
+            DMDevice since there's no actual device.
+    """
+    _type = "lvmvg"
+
+    def __init__(self, name, parents, size=None, free=None,
+                 peSize=None, peCount=None, peFree=None, pvCount=None,
+                 lvNames=[], uuid=None, exists=None, sysfsPath=''):
+        """ Create a LVMVolumeGroupDevice instance.
+
+            Arguments:
+
+                name -- the device name (generally a device node's basename)
+                parents -- a list of physical volumes (StorageDevice)
+
+            Keyword Arguments:
+
+                peSize -- physical extent size (in MB)
+                exists -- indicates whether this is an existing device
+                sysfsPath -- sysfs device path
+
+                For existing VG's only:
+
+                    size -- the VG's size (in MB)
+                    free -- amount of free space in the VG
+                    peFree -- number of free extents
+                    peCount -- total number of extents
+                    pvCount -- number of PVs in this VG
+                    lvNames -- the names of this VG's LVs
+                    uuid -- the VG's UUID
+
+        """
+        self.pvClass = get_device_format_class("lvmpv")
+        if not self.pvClass:
+            raise StorageError("cannot find 'lvmpv' class")
+
+        if isinstance(parents, list):
+            for dev in parents:
+                if not isinstance(dev.format, self.pvClass):
+                    raise ValueError("constructor requires a list of PVs")
+        elif not isinstance(parents.format, self.pvClass):
+            raise ValueError("constructor requires a list of PVs")
+
+        DMDevice.__init__(self, name, parents=parents,
+                          exists=exists, sysfsPath=sysfsPath)
+
+        self.uuid = uuid
+        self.free = numeric_type(free)
+        self.peSize = numeric_type(peSize)
+        self.peCount = numeric_type(peCount)
+        self.peFree = numeric_type(peFree)
+        self.pvCount = numeric_type(pvCount)
+        self.lvNames = lvNames
+
+        # circular references, here I come
+        self._lvs = []
+
+        # TODO: validate peSize if given
+        if not self.peSize:
+            self.peSize = 32.0   # MB
+
+        #self.probe()
+
+    def __str__(self):
+        s = DMDevice.__str__(self)
+        s += ("  free = %(free)s  PE Size = %(peSize)s  PE Count = %(peCount)s\n"
+              "  PE Free = %(peFree)s  PV Count = %(pvCount)s\n"
+              "  LV Names = %(lvNames)s  modified = %(modified)s\n"
+              "  extents = %(extents)s  free space = %(freeSpace)s\n"
+              "  free extents = %(freeExtents)s\n"
+              "  PVs = %(pvs)s\n"
+              "  LVs = %(lvs)s" %
+              {"free": self.free, "peSize": self.peSize, "peCount": self.peCount,
+               "peFree": self.peFree, "pvCount": self.pvCount,
+               "lvNames": self.lvNames, "modified": self.isModified,
+               "extents": self.extents, "freeSpace": self.freeSpace,
+               "freeExtents": self.freeExtents, "pvs": self.pvs, "lvs": self.lvs})
+        return s
+
+    @property
+    def dict(self):
+        d = super(LVMVolumeGroupDevice, self).dict
+        d.update({"free": self.free, "peSize": self.peSize,
+                  "peCount": self.peCount, "peFree": self.peFree,
+                  "pvCount": self.pvCount, "extents": self.extents,
+                  "freeSpace": self.freeSpace,
+                  "freeExtents": self.freeExtents,
+                  "lvNames": [lv.name for lv in self.lvs]})
+        return d
+
+    def writeKS(self, f, preexisting=False, noformat=False, s=None):
+        args = ["--pesize=%s" % int(self.peSize * 1024)]
+        pvs = []
+
+        for pv in self.pvs:
+            pvs.append("pv.%s" % pv.format.uuid)
+
+        if preexisting:
+            args.append("--useexisting")
+        if noformat:
+            args.append("--noformat")
+
+        f.write("#volgroup %s %s %s" % (self.name, " ".join(args), " ".join(pvs)))
+        if s:
+            f.write(" %s" % s)
+
+    def probe(self):
+        """ Probe for any information about this device. """
+        log_method_call(self, self.name, status=self.status)
+        if not self.exists:
+            raise DeviceError("device has not been created", self.name)
+
+    @property
+    def mapName(self):
+        """ This device's device-mapper map name """
+        # Thank you lvm for this lovely hack.
+        return self.name.replace("-","--")
+
+    @property
+    def path(self):
+        """ Device node representing this device. """
+        return "%s/%s" % (self._devDir, self.mapName)
+
+    def updateSysfsPath(self):
+        """ Update this device's sysfs path. """
+        log_method_call(self, self.name, status=self.status)
+        if not self.exists:
+            raise DeviceError("device has not been created", self.name)
+
+        self.sysfsPath = ''
+
+    @property
+    def status(self):
+        """ The device's status (True means active). """
+        if not self.exists:
+            return False
+
+        # certainly if any of this VG's LVs are active then so are we
+        for lv in self.lvs:
+            if lv.status:
+                return True
+
+        # if any of our PVs are not active then we cannot be
+        for pv in self.pvs:
+            if not pv.status:
+                return False
+
+        # if we are missing some of our PVs we cannot be active
+        if len(self.pvs) != self.pvCount:
+            return False
+
+        return True
+
+    def _addDevice(self, device):
+        """ Add a new physical volume device to the volume group.
+
+            XXX This is for use by device probing routines and is not
+                intended for modification of the VG.
+        """
+        log_method_call(self,
+                        self.name,
+                        device=device.name,
+                        status=self.status)
+        if not self.exists:
+            raise DeviceError("device does not exist", self.name)
+
+        if not isinstance(device.format, self.pvClass):
+            raise ValueError("addDevice requires a PV arg")
+
+        if self.uuid and device.format.vgUuid != self.uuid:
+            raise ValueError("UUID mismatch")
+
+        if device in self.pvs:
+            raise ValueError("device is already a member of this VG")
+
+        self.parents.append(device)
+        device.addChild()
+
+        # now see if the VG can be activated
+        if len(self.parents) == self.pvCount:
+            self.setup()
+
+    def _removeDevice(self, device):
+        """ Remove a physical volume from the volume group.
+
+            This is for cases like clearing of preexisting partitions.
+        """
+        log_method_call(self,
+                        self.name,
+                        device=device.name,
+                        status=self.status)
+        try:
+            self.parents.remove(device)
+        except ValueError, e:
+            raise ValueError("cannot remove non-member PV device from VG")
+
+        device.removeChild()
+
+    def setup(self, intf=None, orig=False):
+        """ Open, or set up, a device.
+
+            XXX we don't do anything like "vgchange -ay" because we don't
+                want all of the LVs activated, just the VG itself.
+        """
+        log_method_call(self, self.name, orig=orig, status=self.status)
+        if not self.exists:
+            raise DeviceError("device has not been created", self.name)
+
+        if self.status:
+            return
+
+        if len(self.parents) < self.pvCount:
+            raise DeviceError("cannot activate VG with missing PV(s)", self.name)
+
+        self.setupParents(orig=orig)
+
+    def teardown(self, recursive=None):
+        """ Close, or tear down, a device. """
+        log_method_call(self, self.name, status=self.status)
+        if not self.exists and not recursive:
+            raise DeviceError("device has not been created", self.name)
+
+        if self.status:
+            lvm.vgdeactivate(self.name)
+
+        if recursive:
+            self.teardownParents(recursive=recursive)
+
+    def create(self, intf=None):
+        """ Create the device. """
+        log_method_call(self, self.name, status=self.status)
+        if self.exists:
+            raise DeviceError("device already exists", self.name)
+
+        w = None
+        if intf:
+            w = intf.progressWindow(_("Creating"),
+                                    _("Creating device %s")
+                                    % (self.path,),
+                                    100, pulse = True)
+        try:
+            self.createParents()
+            self.setupParents()
+
+            pv_list = [pv.path for pv in self.parents]
+            lvm.vgcreate(self.name, pv_list, self.peSize, progress=w)
+        except Exception:
+            raise
+        else:
+            # FIXME set / update self.uuid here
+            self.exists = True
+            self.setup()
+        finally:
+            if w:
+                w.pop()
+
+    def destroy(self):
+        """ Destroy the device. """
+        log_method_call(self, self.name, status=self.status)
+        if not self.exists:
+            raise DeviceError("device has not been created", self.name)
+
+        # set up the pvs since lvm needs access to them to do the vgremove
+        self.setupParents(orig=True)
+
+        # this sometimes fails for some reason.
+        try:
+            lvm.vgreduce(self.name, [], rm=True)
+            lvm.vgremove(self.name)
+        except lvm.LVMError:
+            raise DeviceError("Could not completely remove VG", self.name)
+        finally:
+            self.exists = False
+
+    def reduce(self, pv_list):
+        """ Remove the listed PVs from the VG. """
+        log_method_call(self, self.name, status=self.status)
+        if not self.exists:
+            raise DeviceError("device has not been created", self.name)
+
+        lvm.vgreduce(self.name, pv_list)
+        # XXX do we need to notify the kernel?
+
+    def _addLogVol(self, lv):
+        """ Add an LV to this VG. """
+        if lv in self._lvs:
+            raise ValueError("lv is already part of this vg")
+
+        # verify we have the space, then add it
+        # do not verify for growing vg (because of ks)
+        if not lv.exists and \
+           not [pv for pv in self.pvs if getattr(pv, "req_grow", None)] and \
+           lv.size > self.freeSpace:
+            raise DeviceError("new lv is too large to fit in free space", self.name)
+
+        self._lvs.append(lv)
+
+    def _removeLogVol(self, lv):
+        """ Remove an LV from this VG. """
+        if lv not in self.lvs:
+            raise ValueError("specified lv is not part of this vg")
+
+        self._lvs.remove(lv)
+
+    def _addPV(self, pv):
+        """ Add a PV to this VG. """
+        if pv in self.pvs:
+            raise ValueError("pv is already part of this vg")
+
+        # for the time being we will not allow vgextend
+        if self.exists:
+            raise DeviceError("cannot add pv to existing vg", self.name)
+
+        self.parents.append(pv)
+        pv.addChild()
+
+    def _removePV(self, pv):
+        """ Remove an PV from this VG. """
+        if not pv in self.pvs:
+            raise ValueError("specified pv is not part of this vg")
+
+        # for the time being we will not allow vgreduce
+        if self.exists:
+            raise DeviceError("cannot remove pv from existing vg", self.name)
+
+        self.parents.remove(pv)
+        pv.removeChild()
+
+    # We can't rely on lvm to tell us about our size, free space, &c
+    # since we could have modifications queued, unless the VG and all of
+    # its PVs already exist.
+    #
+    #        -- liblvm may contain support for in-memory devices
+
+    @property
+    def isModified(self):
+        """ Return True if the VG has changes queued that LVM is unaware of. """
+        modified = True
+        if self.exists and not filter(lambda d: not d.exists, self.pvs):
+            modified = False
+
+        return modified
+
+    @property
+    def size(self):
+        """ The size of this VG """
+        # TODO: just ask lvm if isModified returns False
+
+        # sum up the sizes of the PVs and align to pesize
+        size = 0
+        for pv in self.pvs:
+            size += max(0, self.align(pv.size - pv.format.peStart))
+
+        return size
+
+    @property
+    def extents(self):
+        """ Number of extents in this VG """
+        # TODO: just ask lvm if isModified returns False
+
+        return self.size / self.peSize
+
+    @property
+    def freeSpace(self):
+        """ The amount of free space in this VG (in MB). """
+        # TODO: just ask lvm if isModified returns False
+
+        # total the sizes of any LVs
+        used = 0
+        size = self.size
+        log.debug("%s size is %dMB" % (self.name, size))
+        for lv in self.lvs:
+            log.debug("lv %s uses %dMB" % (lv.name, lv.vgSpaceUsed))
+            used += self.align(lv.vgSpaceUsed, roundup=True)
+
+        free = self.size - used
+        log.debug("vg %s has %dMB free" % (self.name, free))
+        return free
+
+    @property
+    def freeExtents(self):
+        """ The number of free extents in this VG. """
+        # TODO: just ask lvm if isModified returns False
+        return self.freeSpace / self.peSize
+
+    def align(self, size, roundup=None):
+        """ Align a size to a multiple of physical extent size. """
+        size = numeric_type(size)
+
+        if roundup:
+            round = math.ceil
+        else:
+            round = math.floor
+
+        # we want Kbytes as a float for our math
+        size *= 1024.0
+        pesize = self.peSize * 1024.0
+        return long((round(size / pesize) * pesize) / 1024)
+
+    @property
+    def pvs(self):
+        """ A list of this VG's PVs """
+        return self.parents[:]  # we don't want folks changing our list
+
+    @property
+    def lvs(self):
+        """ A list of this VG's LVs """
+        return self._lvs[:]     # we don't want folks changing our list
+
+    @property
+    def complete(self):
+        """Check if the vg has all its pvs in the system
+        Return True if complete.
+        """
+        return len(self.pvs) == self.pvCount or not self.exists
+
+
+class LVMLogicalVolumeDevice(DMDevice):
+    """ An LVM Logical Volume """
+    _type = "lvmlv"
+    _resizable = True
+
+    def __init__(self, name, vgdev, size=None, uuid=None,
+                 stripes=1, logSize=0, snapshotSpace=0,
+                 format=None, exists=None, sysfsPath='',
+                 grow=None, maxsize=None, percent=None):
+        """ Create a LVMLogicalVolumeDevice instance.
+
+            Arguments:
+
+                name -- the device name (generally a device node's basename)
+                vgdev -- volume group (LVMVolumeGroupDevice instance)
+
+            Keyword Arguments:
+
+                size -- the device's size (in MB)
+                uuid -- the device's UUID
+                stripes -- number of copies in the vg (>1 for mirrored lvs)
+                logSize -- size of log volume (for mirrored lvs)
+                snapshotSpace -- sum of sizes of snapshots of this lv
+                sysfsPath -- sysfs device path
+                format -- a DeviceFormat instance
+                exists -- indicates whether this is an existing device
+
+                For new (non-existent) LVs only:
+
+                    grow -- whether to grow this LV
+                    maxsize -- maximum size for growable LV (in MB)
+                    percent -- percent of VG space to take
+
+        """
+        if isinstance(vgdev, list):
+            if len(vgdev) != 1:
+                raise ValueError("constructor requires a single LVMVolumeGroupDevice instance")
+            elif not isinstance(vgdev[0], LVMVolumeGroupDevice):
+                raise ValueError("constructor requires a LVMVolumeGroupDevice instance")
+        elif not isinstance(vgdev, LVMVolumeGroupDevice):
+            raise ValueError("constructor requires a LVMVolumeGroupDevice instance")
+        DMDevice.__init__(self, name, size=size, format=format,
+                          sysfsPath=sysfsPath, parents=vgdev,
+                          exists=exists)
+
+        self.uuid = uuid
+        self.snapshotSpace = snapshotSpace
+        self.stripes = stripes
+        self.logSize = logSize
+
+        self.req_grow = None
+        self.req_max_size = 0
+        self.req_size = 0   
+        self.req_percent = 0
+
+        if not self.exists:
+            self.req_grow = grow
+            self.req_max_size = numeric_type(maxsize)
+            # XXX should we enforce that req_size be pe-aligned?
+            self.req_size = self._size
+            self.req_percent = numeric_type(percent)
+
+        # here we go with the circular references
+        self.vg._addLogVol(self)
+
+    def __str__(self):
+        s = DMDevice.__str__(self)
+        s += ("  VG device = %(vgdev)r  percent = %(percent)s\n"
+              "  mirrored = %(mirrored)s stripes = %(stripes)d"
+              "  snapshot total =  %(snapshots)dMB\n"
+              "  VG space used = %(vgspace)dMB" %
+              {"vgdev": self.vg, "percent": self.req_percent,
+               "mirrored": self.mirrored, "stripes": self.stripes,
+               "snapshots": self.snapshotSpace, "vgspace": self.vgSpaceUsed })
+        return s
+
+    @property
+    def dict(self):
+        d = super(LVMLogicalVolumeDevice, self).dict
+        if self.exists:
+            d.update({"mirrored": self.mirrored, "stripes": self.stripes,
+                      "snapshots": self.snapshotSpace,
+                      "vgspace": self.vgSpaceUsed})
+        else:
+            d.update({"percent": self.req_percent})
+
+        return d
+
+    def writeKS(self, f, preexisting=False, noformat=False, s=None):
+        args = ["--name=%s" % self.lvname,
+                "--vgname=%s" % self.vg.name]
+
+        if self.req_grow:
+            args.extend(["--grow", "--size=%s" % (self.req_size or 1)])
+
+            if self.req_max_size > 0:
+                args.append("--maxsize=%s" % self.req_max_size)
+        else:
+            if self.req_percent > 0:
+                args.append("--percent=%s" % self.req_percent)
+            elif self.req_size > 0:
+                args.append("--size=%s" % self.req_size)
+
+        if preexisting:
+            args.append("--useexisting")
+        if noformat:
+            args.append("--noformat")
+
+        f.write("#logvol ")
+        self.format.writeKS(f)
+        f.write(" %s" % " ".join(args))
+        if s:
+            f.write(" %s" % s)
+
+    @property
+    def mirrored(self):
+        return self.stripes > 1
+
+    def _setSize(self, size):
+        size = self.vg.align(numeric_type(size))
+        log.debug("trying to set lv %s size to %dMB" % (self.name, size))
+        if size <= (self.vg.freeSpace + self._size):
+            self._size = size
+            self.targetSize = size
+        else:
+            log.debug("failed to set size: %dMB short" % (size - (self.vg.freeSpace + self._size),))
+            raise ValueError("not enough free space in volume group")
+
+    size = property(StorageDevice._getSize, _setSize)
+
+    @property
+    def vgSpaceUsed(self):
+        return self.size * self.stripes + self.logSize + self.snapshotSpace
+
+    @property
+    def vg(self):
+        """ This Logical Volume's Volume Group. """
+        return self.parents[0]
+
+    @property
+    def mapName(self):
+        """ This device's device-mapper map name """
+        # Thank you lvm for this lovely hack.
+        return "%s-%s" % (self.vg.mapName, self._name.replace("-","--"))
+
+    @property
+    def path(self):
+        """ Device node representing this device. """
+        return "%s/%s" % (self._devDir, self.mapName)
+
+    def getDMNode(self):
+        """ Return the dm-X (eg: dm-0) device node for this device. """
+        log_method_call(self, self.name, status=self.status)
+        if not self.exists:
+            raise DeviceError("device has not been created", self.name)
+
+        return dm.dm_node_from_name(self.mapName)
+
+    @property
+    def name(self):
+        """ This device's name. """
+        return "%s-%s" % (self.vg.name, self._name)
+
+    @property
+    def lvname(self):
+        """ The LV's name (not including VG name). """
+        return self._name
+
+    @property
+    def complete(self):
+        """ Test if vg exits and if it has all pvs. """
+        return self.vg.complete
+
+    def setup(self, intf=None, orig=False):
+        """ Open, or set up, a device. """
+        log_method_call(self, self.name, orig=orig, status=self.status)
+        if not self.exists:
+            raise DeviceError("device has not been created", self.name)
+
+        if self.status:
+            return
+
+        self.vg.setup(orig=orig)
+        lvm.lvactivate(self.vg.name, self._name)
+
+        # we always probe since the device may not be set up when we want
+        # information about it
+        self._size = self.currentSize
+
+    def teardown(self, recursive=None):
+        """ Close, or tear down, a device. """
+        log_method_call(self, self.name, status=self.status)
+        if not self.exists and not recursive:
+            raise DeviceError("device has not been created", self.name)
+
+        if self.status:
+            if self.originalFormat.exists:
+                self.originalFormat.teardown()
+            if self.format.exists:
+                self.format.teardown()
+            udev_settle()
+
+        if self.status:
+            lvm.lvdeactivate(self.vg.name, self._name)
+
+        if recursive:
+            # It's likely that teardown of a VG will fail due to other
+            # LVs being active (filesystems mounted, &c), so don't let
+            # it bring everything down.
+            try:
+                self.vg.teardown(recursive=recursive)
+            except Exception as e:
+                log.debug("vg %s teardown failed; continuing" % self.vg.name)
+
+    def create(self, intf=None):
+        """ Create the device. """
+        log_method_call(self, self.name, status=self.status)
+        if self.exists:
+            raise DeviceError("device already exists", self.name)
+
+        w = None
+        if intf:
+            w = intf.progressWindow(_("Creating"),
+                                    _("Creating device %s")
+                                    % (self.path,),
+                                    100, pulse = True)
+        try:
+            self.createParents()
+            self.setupParents()
+
+            # should we use --zero for safety's sake?
+            lvm.lvcreate(self.vg.name, self._name, self.size, progress=w)
+        except Exception:
+            raise
+        else:
+            # FIXME set / update self.uuid here
+            self.exists = True
+            self.setup()
+        finally:
+            if w:
+                w.pop()
+
+    def destroy(self):
+        """ Destroy the device. """
+        log_method_call(self, self.name, status=self.status)
+        if not self.exists:
+            raise DeviceError("device has not been created", self.name)
+
+        self.teardown()
+        # set up the vg's pvs so lvm can remove the lv
+        self.vg.setupParents(orig=True)
+        lvm.lvremove(self.vg.name, self._name)
+        self.exists = False
+
+    def resize(self, intf=None):
+        # XXX resize format probably, right?
+        log_method_call(self, self.name, status=self.status)
+        if not self.exists:
+            raise DeviceError("device has not been created", self.name)
+
+        # Setup VG parents (in case they are dmraid partitions for example)
+        self.vg.setupParents(orig=True)
+
+        if self.originalFormat.exists:
+            self.originalFormat.teardown()
+        if self.format.exists:
+            self.format.teardown()
+
+        udev_settle()
+        lvm.lvresize(self.vg.name, self._name, self.size)
+
+    def dracutSetupString(self):
+        # Note no mapName usage here, this is a lvm cmdline name, which
+        # is different (ofcourse)
+        return "rd_LVM_LV=%s/%s" % (self.vg.name, self._name)
+
+
+class MDRaidArrayDevice(StorageDevice):
+    """ An mdraid (Linux RAID) device. """
+    _type = "mdarray"
+
+    def __init__(self, name, level=None, major=None, minor=None, size=None,
+                 memberDevices=None, totalDevices=None,
+                 uuid=None, format=None, exists=None,
+                 parents=None, sysfsPath=''):
+        """ Create a MDRaidArrayDevice instance.
+
+            Arguments:
+
+                name -- the device name (generally a device node's basename)
+
+            Keyword Arguments:
+
+                level -- the device's RAID level (a string, eg: '1' or 'raid1')
+                parents -- list of member devices (StorageDevice instances)
+                size -- the device's size (units/format TBD)
+                uuid -- the device's UUID
+                minor -- the device minor
+                sysfsPath -- sysfs device path
+                format -- a DeviceFormat instance
+                exists -- indicates whether this is an existing device
+        """
+        StorageDevice.__init__(self, name, format=format, exists=exists,
+                               major=major, minor=minor, size=size,
+                               parents=parents, sysfsPath=sysfsPath)
+
+        self.level = level
+        if level == "container":
+            self._type = "mdcontainer"
+        elif level is not None:
+            self.level = mdraid.raidLevel(level)
+
+        # For new arrays check if we have enough members
+        if (not exists and parents and
+                len(parents) < mdraid.get_raid_min_members(self.level)):
+            raise ValueError, P_("A RAID%d set requires at least %d member",
+                                 "A RAID%d set requires at least %d members",
+                                 mdraid.get_raid_min_members(self.level)) % \
+                                 (self.level, mdraid.get_raid_min_members(self.level))
+
+        self.uuid = uuid
+        self._totalDevices = numeric_type(totalDevices)
+        self._memberDevices = numeric_type(memberDevices)
+        self.sysfsPath = "/devices/virtual/block/%s" % name
+        self.chunkSize = 64.0 / 1024.0          # chunk size in MB
+        self.superBlockSize = 128.0 / 1024.0    # superblock size in MB
+
+        self.createMetadataVer = "1.1"
+        # bitmaps are not meaningful on raid0 according to mdadm-3.0.3
+        self.createBitmap = self.level != 0
+
+        # For container members probe size now, as we cannot determine it
+        # when teared down.
+        if self.parents and self.parents[0].type == "mdcontainer":
+            self._size = self.currentSize
+            self._type = "mdbiosraidarray"
+
+        self.formatClass = get_device_format_class("mdmember")
+        if not self.formatClass:
+            raise DeviceError("cannot find class for 'mdmember'", self.name)
+
+        if self.exists and self.uuid:
+            # this is a hack to work around mdadm's insistence on giving
+            # really high minors to arrays it has no config entry for
+            open("/etc/mdadm.conf", "a").write("ARRAY %s UUID=%s\n"
+                                                % (self.path, self.uuid))
+
+    @property
+    def smallestMember(self):
+        try:
+            smallest = sorted(self.devices, key=lambda d: d.size)[0]
+        except IndexError:
+            smallest = None
+        return smallest
+
+    @property
+    def size(self):
+        if not self.devices:
+            return 0
+
+        # For container members return probed size, as we cannot determine it
+        # when teared down.
+        if self.type == "mdbiosraidarray":
+            return self._size
+
+        size = 0
+        smallestMemberSize = self.smallestMember.size - self.superBlockSize
+        if not self.exists or not self.partedDevice:
+            if self.level == mdraid.RAID0:
+                size = self.memberDevices * smallestMemberSize
+                size -= size % self.chunkSize
+            elif self.level == mdraid.RAID1:
+                size = smallestMemberSize
+            elif self.level == mdraid.RAID4:
+                size = (self.memberDevices - 1) * smallestMemberSize
+                size -= size % self.chunkSize
+            elif self.level == mdraid.RAID5:
+                size = (self.memberDevices - 1) * smallestMemberSize
+                size -= size % self.chunkSize
+            elif self.level == mdraid.RAID6:
+                size = (self.memberDevices - 2) * smallestMemberSize
+                size -= size % self.chunkSize
+            elif self.level == mdraid.RAID10:
+                size = (self.memberDevices / 2.0) * smallestMemberSize
+                size -= size % self.chunkSize
+        else:
+            size = self.partedDevice.getSize()
+
+        return size
+
+    @property
+    def description(self):
+        if self.level == mdraid.RAID0:
+            levelstr = "stripe"
+        elif self.level == mdraid.RAID1:
+            levelstr = "mirror"
+        else:
+            levelstr = "raid%s" % self.level
+
+        if self.type == "mdcontainer":
+            return "BIOS RAID container"
+        elif self.type == "mdbiosraidarray":
+            return "BIOS RAID set (%s)" % levelstr
+        else:
+            return "MDRAID set (%s)" % levelstr
+
+    def __str__(self):
+        s = StorageDevice.__str__(self)
+        s += ("  level = %(level)s  spares = %(spares)s\n"
+              "  members = %(memberDevices)s\n"
+              "  total devices = %(totalDevices)s" %
+              {"level": self.level, "spares": self.spares,
+               "memberDevices": self.memberDevices, "totalDevices": self.totalDevices})
+        return s
+
+    @property
+    def dict(self):
+        d = super(MDRaidArrayDevice, self).dict
+        d.update({"level": self.level,
+                  "spares": self.spares, "memberDevices": self.memberDevices,
+                  "totalDevices": self.totalDevices})
+        return d
+
+    def writeKS(self, f, preexisting=False, noformat=False, s=None):
+        args = ["--level=%s" % self.level,
+                "--device=%s" % self.name]
+        mems = []
+
+        if self.spares > 0:
+            args.append("--spares=%s" % self.spares)
+        if preexisting:
+            args.append("--useexisting")
+        if noformat:
+            args.append("--noformat")
+
+        for mem in self.parents:
+            mems.append("raid.%s" % mem.format.uuid)
+
+        f.write("#raid ")
+        self.format.writeKS(f)
+        f.write(" %s" % " ".join(args))
+        f.write(" %s" % " ".join(mems))
+        if s:
+            f.write(" %s" % s)
+
+    @property
+    def mdadmConfEntry(self):
+        """ This array's mdadm.conf entry. """
+        if self.level is None or self.memberDevices is None or not self.uuid:
+            raise DeviceError("array is not fully defined", self.name)
+
+        # containers and the sets within must only have a UUID= parameter
+        if self.type == "mdcontainer" or self.type == "mdbiosraidarray":
+            fmt = "ARRAY %s UUID=%s\n"
+            return fmt % (self.path, self.uuid)
+
+        fmt = "ARRAY %s level=raid%d num-devices=%d UUID=%s\n"
+        return fmt % (self.path, self.level, self.memberDevices, self.uuid)
+
+    @property
+    def totalDevices(self):
+        """ Total number of devices in the array, including spares. """
+        count = len(self.parents)
+        if not self.exists:
+            count = self._totalDevices
+        return count
+
+    def _getMemberDevices(self):
+        return self._memberDevices
+
+    def _setMemberDevices(self, number):
+        if not isinstance(number, int):
+            raise ValueError("memberDevices is an integer")
+
+        if number > self.totalDevices:
+            raise ValueError("memberDevices cannot be greater than totalDevices")
+        self._memberDevices = number
+
+    memberDevices = property(_getMemberDevices, _setMemberDevices,
+                             doc="number of member devices")
+
+    def _getSpares(self):
+        spares = 0
+        if self.memberDevices is not None:
+            if self.totalDevices is not None:
+                spares = self.totalDevices - self.memberDevices
+            else:
+                spares = self.memberDevices
+                self._totalDevices = self.memberDevices
+        return spares
+
+    def _setSpares(self, spares):
+        # FIXME: this is too simple to be right
+        if self.totalDevices > spares:
+            self.memberDevices = self.totalDevices - spares
+
+    spares = property(_getSpares, _setSpares)
+
+    def probe(self):
+        """ Probe for any missing information about this device.
+
+            I'd like to avoid paying any attention to "Preferred Minor"
+            as it seems problematic.
+        """
+        log_method_call(self, self.name, status=self.status)
+        if not self.exists:
+            raise DeviceError("device has not been created", self.name)
+
+        try:
+            self.devices[0].setup()
+        except Exception:
+            return
+
+        info = mdraid.mdexamine(self.devices[0].path)
+        if self.level is None:
+            self.level = mdraid.raidLevel(info['level'])
+
+    def updateSysfsPath(self):
+        """ Update this device's sysfs path. """
+        log_method_call(self, self.name, status=self.status)
+        if not self.exists:
+            raise DeviceError("device has not been created", self.name)
+
+        if self.status:
+            self.sysfsPath = "/devices/virtual/block/%s" % self.name
+        else:
+            self.sysfsPath = ''
+
+    def _addDevice(self, device):
+        """ Add a new member device to the array.
+
+            XXX This is for use when probing devices, not for modification
+                of arrays.
+        """
+        log_method_call(self,
+                        self.name,
+                        device=device.name,
+                        status=self.status)
+        if not self.exists:
+            raise DeviceError("device has not been created", self.name)
+
+        if not isinstance(device.format, self.formatClass):
+            raise ValueError("invalid device format for mdraid member")
+
+        if self.uuid and device.format.mdUuid != self.uuid:
+            raise ValueError("cannot add member with non-matching UUID")
+
+        if device in self.devices:
+            raise ValueError("device is already a member of this array")
+
+        # we added it, so now set up the relations
+        self.devices.append(device)
+        device.addChild()
+
+        device.setup()
+        udev_settle()
+        try:
+            mdraid.mdadd(device.path, len(self.devices) < self.memberDevices)
+            # mdadd causes udev events
+            udev_settle()
+        except MDRaidError as e:
+            log.warning("failed to add member %s to md array %s: %s"
+                        % (device.path, self.path, e))
+
+        if self.status:
+            # we always probe since the device may not be set up when we want
+            # information about it
+            self._size = self.currentSize
+
+    def _removeDevice(self, device):
+        """ Remove a component device from the array.
+
+            XXX This is for use by clearpart, not for reconfiguration.
+        """
+        log_method_call(self,
+                        self.name,
+                        device=device.name,
+                        status=self.status)
+
+        if device not in self.devices:
+            raise ValueError("cannot remove non-member device from array")
+
+        self.devices.remove(device)
+        device.removeChild()
+
+    @property
+    def status(self):
+        """ This device's status.
+
+            For now, this should return a boolean:
+                True    the device is open and ready for use
+                False   the device is not open
+        """
+        # check the status in sysfs
+        status = False
+        if not self.exists:
+            return status
+
+        state_file = "/sys/%s/md/array_state" % self.sysfsPath
+        if os.access(state_file, os.R_OK):
+            state = open(state_file).read().strip()
+            log.debug("%s state is %s" % (self.name, state))
+            if state in ("clean", "active", "active-idle", "readonly", "read-auto"):
+                status = True
+            # mdcontainers have state inactive when started (clear if stopped)
+            if self.type == "mdcontainer" and state == "inactive":
+                status = True
+
+        return status
+
+    @property
+    def degraded(self):
+        """ Return True if the array is running in degraded mode. """
+        rc = False
+        degraded_file = "/sys/%s/md/degraded" % self.sysfsPath
+        if os.access(degraded_file, os.R_OK):
+            val = open(degraded_file).read().strip()
+            log.debug("%s degraded is %s" % (self.name, val))
+            if val == "1":
+                rc = True
+
+        return rc
+
+    @property
+    def devices(self):
+        """ Return a list of this array's member device instances. """
+        return self.parents
+
+    def setup(self, intf=None, orig=False):
+        """ Open, or set up, a device. """
+        log_method_call(self, self.name, orig=orig, status=self.status)
+        if not self.exists:
+            raise DeviceError("device has not been created", self.name)
+
+        if self.status:
+            return
+
+        disks = []
+        for member in self.devices:
+            member.setup(orig=orig)
+            disks.append(member.path)
+
+        update_super_minor = True
+        if self.type == "mdcontainer" or self.type == "mdbiosraidarray":
+            update_super_minor = False
+
+        mdraid.mdactivate(self.path,
+                          members=disks,
+                          super_minor=self.minor,
+                          update_super_minor=update_super_minor,
+                          uuid=self.uuid)
+
+        udev_settle()
+
+        # we always probe since the device may not be set up when we want
+        # information about it
+        self._size = self.currentSize
+
+    def teardown(self, recursive=None):
+        """ Close, or tear down, a device. """
+        log_method_call(self, self.name, status=self.status)
+        if not self.exists and not recursive:
+            raise DeviceError("device has not been created", self.name)
+
+        if self.status:
+            if self.originalFormat.exists:
+                self.originalFormat.teardown()
+            if self.format.exists:
+                self.format.teardown()
+            udev_settle()
+
+        # Since BIOS RAID sets (containers in mdraid terminology) never change
+        # there is no need to stop them and later restart them. Not stopping
+        # (and thus also not starting) them also works around bug 523334
+        if self.type == "mdcontainer" or self.type == "mdbiosraidarray":
+            return
+
+        # We don't really care what the array's state is. If the device
+        # file exists, we want to deactivate it. mdraid has too many
+        # states.
+        if self.exists and os.path.exists(self.path):
+            mdraid.mddeactivate(self.path)
+
+        if recursive:
+            self.teardownParents(recursive=recursive)
+
+    def preCommitFixup(self, *args, **kwargs):
+        """ Determine create parameters for this set """
+        mountpoints = kwargs.pop("mountpoints")
+        log_method_call(self, self.name, mountpoints)
+
+        if "/boot" in mountpoints:
+            bootmountpoint = "/boot"
+        else:
+            bootmountpoint = "/"
+
+        # If we are used to boot from we cannot use 1.1 metadata
+        if getattr(self.format, "mountpoint", None) == bootmountpoint or \
+           getattr(self.format, "mountpoint", None) == "/boot/efi" or \
+           self.format.type == "prepboot":
+            self.createMetadataVer = "1.0"
+
+        # Bitmaps are not useful for swap and small partitions
+        if self.size < 1000 or self.format.type == "swap":
+            self.createBitmap = False
+
+    def create(self, intf=None):
+        """ Create the device. """
+        log_method_call(self, self.name, status=self.status)
+        if self.exists:
+            raise DeviceError("device already exists", self.name)
+
+        w = None
+        if intf:
+            w = intf.progressWindow(_("Creating"),
+                                    _("Creating device %s")
+                                    % (self.path,),
+                                    100, pulse = True)
+        try:
+            self.createParents()
+            self.setupParents()
+
+            disks = [disk.path for disk in self.devices]
+            spares = len(self.devices) - self.memberDevices
+            mdraid.mdcreate(self.path,
+                            self.level,
+                            disks,
+                            spares,
+                            metadataVer=self.createMetadataVer,
+                            bitmap=self.createBitmap,
+                            progress=w)
+        except Exception:
+            raise
+        else:
+            self.exists = True
+            # the array is automatically activated upon creation, but...
+            self.setup()
+            udev_settle()
+            self.updateSysfsPath()
+            info = udev_get_block_device(self.sysfsPath)
+            self.uuid = udev_device_get_md_uuid(info)
+            for member in self.devices:
+                member.mdUuid = self.uuid
+        finally:
+            if w:
+                w.pop()
+
+    @property
+    def formatArgs(self):
+        formatArgs = []
+        if self.format.type == "ext2":
+            if self.level == mdraid.RAID5:
+                formatArgs = ['-R',
+                              'stride=%d' % ((self.memberDevices - 1) * 16)]
+            if self.level == mdraid.RAID4:
+                formatArgs = ['-R',
+                              'stride=%d' % ((self.memberDevices - 1) * 16)]
+            elif self.level == mdraid.RAID0:
+                formatArgs = ['-R',
+                              'stride=%d' % (self.memberDevices * 16)]
+
+    def destroy(self):
+        """ Destroy the device. """
+        log_method_call(self, self.name, status=self.status)
+        if not self.exists:
+            raise DeviceError("device has not been created", self.name)
+
+        self.teardown()
+
+        # The destruction of the formatting on the member devices does the
+        # real work, but it isn't our place to do it from here.
+        self.exists = False
+
+    @property
+    def mediaPresent(self):
+        # Containers should not get any format handling done
+        # (the device node does not allow read / write calls)
+        if self.type == "mdcontainer":
+            return False
+        # BIOS RAID sets should show as present even when teared down
+        elif self.type == "mdbiosraidarray":
+            return True
+        else:
+            return self.partedDevice is not None
+
+    @property
+    def model(self):
+        return self.description
+
+    @property
+    def partitionable(self):
+        return self.type == "mdbiosraidarray"
+
+    @property
+    def isDisk(self):
+        return self.type == "mdbiosraidarray"
+
+    def dracutSetupString(self):
+        return "rd_MD_UUID=%s" % self.uuid
+
+
+class DMRaidArrayDevice(DMDevice):
+    """ A dmraid (device-mapper RAID) device """
+    _type = "dm-raid array"
+    _packages = ["dmraid"]
+    _partitionable = True
+    _isDisk = True
+
+    def __init__(self, name, raidSet=None, format=None,
+                 size=None, parents=None, sysfsPath=''):
+        """ Create a DMRaidArrayDevice instance.
+
+            Arguments:
+
+                name -- the dmraid name also the device node's basename
+
+            Keyword Arguments:
+
+                raidSet -- the RaidSet object from block
+                parents -- a list of the member devices
+                sysfsPath -- sysfs device path
+                size -- the device's size
+                format -- a DeviceFormat instance
+        """
+        if isinstance(parents, list):
+            for parent in parents:
+                if not parent.format or parent.format.type != "dmraidmember":
+                    raise ValueError("parent devices must contain dmraidmember format")
+        DMDevice.__init__(self, name, format=format, size=size,
+                          parents=parents, sysfsPath=sysfsPath, exists=True)
+
+        self.formatClass = get_device_format_class("dmraidmember")
+        if not self.formatClass:
+            raise StorageError("cannot find class for 'dmraidmember'")
+
+        self._raidSet = raidSet
+
+    @property
+    def raidSet(self):
+        return self._raidSet
+
+    def _addDevice(self, device):
+        """ Add a new member device to the array.
+
+            XXX This is for use when probing devices, not for modification
+                of arrays.
+        """
+        log_method_call(self, self.name, device=device.name, status=self.status)
+
+        if not self.exists:
+            raise DeviceError("device has not been created", self.name)
+
+        if not isinstance(device.format, self.formatClass):
+            raise ValueError("invalid device format for dmraid member")
+
+        if device in self.members:
+            raise ValueError("device is already a member of this array")
+
+        # we added it, so now set up the relations
+        self.devices.append(device)
+        device.addChild()
+
+    @property
+    def members(self):
+        return self.parents
+
+    @property
+    def devices(self):
+        """ Return a list of this array's member device instances. """
+        return self.parents
+
+    def deactivate(self):
+        """ Deactivate the raid set. """
+        log_method_call(self, self.name, status=self.status)
+        # This call already checks if the set is not active.
+        self._raidSet.deactivate()
+
+    def activate(self):
+        """ Activate the raid set. """
+        log_method_call(self, self.name, status=self.status)
+        # This call already checks if the set is active.
+        self._raidSet.activate(mknod=True)
+        udev_settle()
+
+    def setup(self, intf=None, orig=False):
+        """ Open, or set up, a device. """
+        log_method_call(self, self.name, orig=orig, status=self.status)
+        StorageDevice.setup(self, intf=intf, orig=orig)
+        self.activate()
+
+    def teardown(self, recursive=None):
+        """ Close, or tear down, a device. """
+        log_method_call(self, self.name, status=self.status)
+        if not self.exists and not recursive:
+            raise DeviceError("device has not been created", self.name)
+
+        log.debug("not tearing down dmraid device %s" % self.name)
+
+    @property
+    def description(self):
+        return "BIOS RAID set (%s)" % self._raidSet.rs.set_type
+
+    @property
+    def model(self):
+        return self.description
+
+    def dracutSetupString(self):
+        return "rd_DM_UUID=%s" % self.name
+
+class MultipathDevice(DMDevice):
+    """ A multipath device """
+    _type = "dm-multipath"
+    _packages = ["device-mapper-multipath"]
+    _partitionable = True
+    _isDisk = True
+
+    def __init__(self, name, info, format=None, size=None,
+                 parents=None, sysfsPath=''):
+        """ Create a MultipathDevice instance.
+
+            Arguments:
+
+                name -- the device name (generally a device node's basename)
+                info -- the udev info for this device
+
+            Keyword Arguments:
+
+                sysfsPath -- sysfs device path
+                size -- the device's size
+                format -- a DeviceFormat instance
+                parents -- a list of the backing devices (Device instances)
+        """
+
+        self._info = info
+        self.setupIdentity()
+        DMDevice.__init__(self, name, format=format, size=size,
+                          parents=parents, sysfsPath=sysfsPath,
+                          exists=True)
+
+        self.config = {
+            'wwid' : self.identity,
+            'alias' : self.name,
+            'mode' : '0600',
+            'uid' : '0',
+            'gid' : '0',
+        }
+
+    def setupIdentity(self):
+        """ Adds identifying remarks to MultipathDevice object.
+        
+            May be overridden by a sub-class for e.g. RDAC handling.
+        """
+        self._identity_short = self._info['ID_SERIAL_SHORT']
+        self._identity = self._info['ID_SERIAL']
+
+    @property
+    def identity(self):
+        """ Get identity set with setupIdentityFromInfo()
+        
+            May be overridden by a sub-class for e.g. RDAC handling.
+        """
+        if not hasattr(self, "_identity"):
+            raise RuntimeError, "setupIdentityFromInfo() has not been called."
+        return self._identity
+
+    @property
+    def wwid(self):
+        identity = self._identity_short
+        ret = []
+        while identity:
+            ret.append(identity[:2])
+            identity = identity[2:]
+        return ":".join(ret)
+
+    @property
+    def model(self):
+        if not self.parents:
+            return ""
+        return self.parents[0].model
+
+    @property
+    def vendor(self):
+        if not self.parents:
+            return ""
+        return self.parents[0].vendor
+
+    @property
+    def description(self):
+        return "WWID %s" % (self.wwid,)
+
+    def addParent(self, parent):
+        """ Add a parent device to the mpath. """
+        log_method_call(self, self.name, status=self.status)
+        if self.status:
+            self.teardown()
+            self.parents.append(parent)
+            self.setup()
+        else:
+            self.parents.append(parent)
+
+    def setupPartitions(self):
+        log_method_call(self, name=self.name, kids=self.kids)
+        rc = iutil.execWithRedirect("kpartx",
+                                ["-a", "-p", "p", "/dev/mapper/%s" % self.name],
+                                stdout = "/dev/tty5",
+                                stderr = "/dev/tty5")
+        if rc:
+            raise MPathError("multipath partition activation failed for '%s'" %
+                            self.name)
+        udev_settle()
+
+    def teardown(self, recursive=None):
+        """ Tear down the mpath device. """
+        log_method_call(self, self.name, status=self.status)
+
+        if not self.exists and not recursive:
+            raise DeviceError("device has not been created", self.name)
+
+        if self.exists and os.path.exists(self.path):
+            #self.teardownPartitions()
+            #rc = iutil.execWithRedirect("multipath",
+            #                    ['-f', self.name],
+            #                    stdout = "/dev/tty5",
+            #                    stderr = "/dev/tty5")
+            #if rc:
+            #    raise MPathError("multipath deactivation failed for '%s'" %
+            #                    self.name)
+            bdev = block.getDevice(self.name)
+            devmap = block.getMap(major=bdev[0], minor=bdev[1])
+            if devmap.open_count:
+                return
+            try:
+                block.removeDeviceMap(devmap)
+            except Exception as e:
+                raise MPathError("failed to tear down multipath device %s: %s"
+                                % (self.name, e))
+
+        if recursive:
+            self.teardownParents(recursive=recursive)
+
+    def setup(self, intf=None, orig=False):
+        """ Open, or set up, a device. """
+        log_method_call(self, self.name, orig=orig, status=self.status)
+
+        if self.status:
+            return
+
+        StorageDevice.setup(self, intf=intf, orig=orig)
+        udev_settle()
+        rc = iutil.execWithRedirect("multipath",
+                            [self.name],
+                            stdout = "/dev/tty5",
+                            stderr = "/dev/tty5")
+        if rc:
+            raise MPathError("multipath activation failed for '%s'" %
+                            self.name)
+        udev_settle()
+        self.setupPartitions()
+        udev_settle()
+
+class NoDevice(StorageDevice):
+    """ A nodev device for nodev filesystems like tmpfs. """
+    _type = "nodev"
+
+    def __init__(self, format=None):
+        """ Create a NoDevice instance.
+
+            Arguments:
+
+            Keyword Arguments:
+
+                format -- a DeviceFormat instance
+        """
+        if format:
+            name = format.type
+        else:
+            name = "none"
+
+        StorageDevice.__init__(self, name, format=format)
+
+    @property
+    def path(self):
+        """ Device node representing this device. """
+        return self.name
+
+    def probe(self):
+        """ Probe for any missing information about this device. """
+        log_method_call(self, self.name, status=self.status)
+
+    def setup(self, intf=None, orig=False):
+        """ Open, or set up, a device. """
+        log_method_call(self, self.name, orig=orig, status=self.status)
+
+    def teardown(self, recursive=False):
+        """ Close, or tear down, a device. """
+        log_method_call(self, self.name, status=self.status)
+
+    def create(self, intf=None):
+        """ Create the device. """
+        log_method_call(self, self.name, status=self.status)
+        self.setupParents()
+
+    def destroy(self):
+        """ Destroy the device. """
+        log_method_call(self, self.name, status=self.status)
+
+
+class FileDevice(StorageDevice):
+    """ A file on a filesystem.
+
+        This exists because of swap files.
+    """
+    _type = "file"
+    _devDir = ""
+
+    def __init__(self, path, format=None, size=None,
+                 exists=None, parents=None):
+        """ Create a FileDevice instance.
+
+            Arguments:
+
+                path -- full path to the file
+
+            Keyword Arguments:
+
+                format -- a DeviceFormat instance
+                size -- the file size (units TBD)
+                parents -- a list of required devices (Device instances)
+                exists -- indicates whether this is an existing device
+        """
+        StorageDevice.__init__(self, path, format=format, size=size,
+                               exists=exists, parents=parents)
+
+    def probe(self):
+        """ Probe for any missing information about this device. """
+        pass
+
+    @property
+    def fstabSpec(self):
+        return self.name
+
+    @property
+    def path(self):
+        path = self.name
+        root = ""
+        try:
+            status = self.parents[0].format.status
+        except (AttributeError, IndexError):
+            status = False
+
+        if status: 
+            # this is the actual active mountpoint
+            root = self.parents[0].format._mountpoint
+            # trim the mountpoint down to the chroot since we already have
+            # the otherwise fully-qualified path
+            mountpoint = self.parents[0].format.mountpoint
+            if mountpoint.endswith("/"):
+                mountpoint = mountpoint[:-1]
+            if mountpoint:
+                root = root[:-len(mountpoint)]
+
+        return os.path.normpath("%s/%s" % (root, path))
+
+    def setup(self, intf=None, orig=False):
+        StorageDevice.setup(self, orig=orig)
+        if self.format and self.format.exists and not self.format.status:
+            self.format.device = self.path
+
+        for parent in self.parents:
+            if orig:
+                parent.originalFormat.setup()
+            else:
+                parent.format.setup()
+
+    def teardown(self, recursive=None):
+        StorageDevice.teardown(self)
+        if self.format and self.format.exists and not self.format.status:
+            self.format.device = self.path
+
+    def create(self, intf=None):
+        """ Create the device. """
+        log_method_call(self, self.name, status=self.status)
+        if self.exists:
+            raise DeviceError("device already exists", self.name)
+
+        w = None
+        if intf:
+            w = intf.waitWindow(_("Creating"),
+                                _("Creating file %s") % (self.path,))
+
+        try:
+            # this only checks that parents exist
+            self.createParents()
+            self.setupParents()
+
+            fd = os.open(self.path, os.O_RDWR)
+            buf = '\0' * 1024 * 1024 * self.size
+            os.write(fd, buf)
+        except (OSError, TypeError) as e:
+            log.error("error writing out %s: %s" % (self.path, e))
+            raise DeviceError(e, self.name)
+        else:
+            self.exists = True
+        finally:
+            os.close(fd)
+            if w:
+                w.pop()
+
+    def destroy(self):
+        """ Destroy the device. """
+        log_method_call(self, self.name, status=self.status)
+        if not self.exists:
+            raise DeviceError("device has not been created", self.name)
+
+        os.unlink(self.path)
+        self.exists = False
+
+
+class DirectoryDevice(FileDevice):
+    """ A directory on a filesystem.
+
+        This exists because of bind mounts.
+    """
+    _type = "directory"
+
+    def create(self):
+        """ Create the device. """
+        log_method_call(self, self.name, status=self.status)
+        if self.exists:
+            raise DeviceError("device already exists", self.name)
+
+        self.createParents()
+        self.setupParents()
+        try:
+            iutil.mkdirChain(self.path)
+        except Exception, e:
+            raise DeviceError(e, self.name)
+
+        self.exists = True
+
+    def destroy(self):
+        """ Destroy the device. """
+        log_method_call(self, self.name, status=self.status)
+        if not self.exists:
+            raise DeviceError("device has not been created", self.name)
+
+        os.unlink(self.path)
+        self.exists = False
+
+
+class iScsiDiskDevice(DiskDevice, NetworkStorageDevice):
+    """ An iSCSI disk. """
+    _type = "iscsi"
+    _packages = ["iscsi-initiator-utils", "dracut-network"]
+
+    def __init__(self, device, **kwargs):
+        self.node = kwargs.pop("node")
+        self.ibft = kwargs.pop("ibft")
+        self.initiator = kwargs.pop("initiator")
+        DiskDevice.__init__(self, device, **kwargs)
+        NetworkStorageDevice.__init__(self, host_address=self.node.address)
+        log.debug("created new iscsi disk %s %s:%d" % (self.node.name, self.node.address, self.node.port))
+
+    def dracutSetupString(self):
+        if self.ibft:
+            return "iscsi_firmware"
+
+        netroot="netroot=iscsi:"
+        auth = self.node.getAuth()
+        if auth:
+            netroot += "%s:%s" % (auth.username, auth.password)
+            if len(auth.reverse_username) or len(auth.reverse_password):
+                netroot += ":%s:%s" % (auth.reverse_username,
+                                       auth.reverse_password)
+
+        netroot += "@%s::%d::%s" % (self.node.address, self.node.port,
+                                    self.node.name)
+
+        netroot += " iscsi_initiator=%s" % self.initiator
+
+        return netroot
+
+class FcoeDiskDevice(DiskDevice, NetworkStorageDevice):
+    """ An FCoE disk. """
+    _type = "fcoe"
+    _packages = ["fcoe-utils", "dracut-network"]
+
+    def __init__(self, device, **kwargs):
+        self.nic = kwargs.pop("nic")
+        self.identifier = kwargs.pop("identifier")
+        DiskDevice.__init__(self, device, **kwargs)
+        NetworkStorageDevice.__init__(self, nic=self.nic)
+        log.debug("created new fcoe disk %s @ %s" % (device, self.nic))
+
+    def dracutSetupString(self):
+        dcb = True
+
+        from .fcoe import fcoe
+        for nic, dcb in fcoe().nics:
+            if nic == self.nic:
+                break
+
+        if dcb:
+            dcbOpt = "dcb"
+        else:
+            dcbOpt = "nodcb"
+
+        return "netroot=fcoe:%s:%s" % (self.nic, dcbOpt)
+
+
+class OpticalDevice(StorageDevice):
+    """ An optical drive, eg: cdrom, dvd+r, &c.
+
+        XXX Is this useful?
+    """
+    _type = "cdrom"
+
+    def __init__(self, name, major=None, minor=None, exists=None,
+                 format=None, parents=None, sysfsPath='', vendor="",
+                 model=""):
+        StorageDevice.__init__(self, name, format=format,
+                               major=major, minor=minor, exists=True,
+                               parents=parents, sysfsPath=sysfsPath,
+                               vendor=vendor, model=model)
+
+    @property
+    def mediaPresent(self):
+        """ Return a boolean indicating whether or not the device contains
+            media.
+        """
+        log_method_call(self, self.name, status=self.status)
+        if not self.exists:
+            raise DeviceError("device has not been created", self.name)
+
+        try:
+            fd = os.open(self.path, os.O_RDONLY)
+        except OSError as e:
+            # errno 123 = No medium found
+            if e.errno == 123:
+                return False
+            else:
+                return True
+        else:
+            os.close(fd)
+            return True
+
+    def eject(self):
+        """ Eject the drawer. """
+        import _isys
+
+        log_method_call(self, self.name, status=self.status)
+        if not self.exists:
+            raise DeviceError("device has not been created", self.name)
+
+        #try to umount and close device before ejecting
+        self.teardown()
+
+        # Make a best effort attempt to do the eject.  If it fails, it's not
+        # critical.
+        fd = os.open(self.path, os.O_RDONLY | os.O_NONBLOCK)
+
+        try:
+            _isys.ejectcdrom(fd)
+        except SystemError as e:
+            log.warning("error ejecting cdrom %s: %s" % (self.name, e))
+
+        os.close(fd)
+
+
+class ZFCPDiskDevice(DiskDevice):
+    """ A mainframe ZFCP disk. """
+    _type = "zfcp"
+
+    def __init__(self, device, **kwargs):
+        self.hba_id = kwargs.pop("hba_id")
+        self.wwpn = kwargs.pop("wwpn")
+        self.fcp_lun = kwargs.pop("fcp_lun")
+        DiskDevice.__init__(self, device, **kwargs)
+
+    def __str__(self):
+        s = DiskDevice.__str__(self)
+        s += ("  hba_id = %(hba_id)s  wwpn = %(wwpn)s  fcp_lun = %(fcp_lun)s" %
+              {"hba_id": self.hba_id,
+               "wwpn": self.wwpn,
+               "fcp_lun": self.fcp_lun})
+        return s
+
+    def dracutSetupString(self):
+        return "rd_ZFCP=%s,%s,%s" % (self.hba_id, self.wwpn, self.fcp_lun,)
+
+
+class DASDDevice(DiskDevice):
+    """ A mainframe DASD. """
+    _type = "dasd"
+
+    def __init__(self, device, **kwargs):
+        self.busid = kwargs.pop('busid')
+        self.opts = kwargs.pop('opts')
+        self.dasd = kwargs.pop('dasd')
+        DiskDevice.__init__(self, device, **kwargs)
+
+        if self.dasd:
+            self.dasd.addDASD(self)
+
+    def getOpts(self):
+        return map(lambda (k, v): "%s=%s" % (k, v,), self.opts.items())
+
+    def dracutSetupString(self):
+        args = ["rd_DASD=%s" % (self.busid,)] + self.getOpts()
+        return ",".join(args)
+
+
+class NFSDevice(StorageDevice, NetworkStorageDevice):
+    """ An NFS device """
+    _type = "nfs"
+    _packages = ["dracut-network"]
+
+    def __init__(self, device, format=None, parents=None):
+        # we could make host/ip, path, &c but will anything use it?
+        StorageDevice.__init__(self, device, format=format, parents=parents)
+        NetworkStorageDevice.__init__(self, device.split(":")[0])
+
+    @property
+    def path(self):
+        """ Device node representing this device. """
+        return self.name
+
+    def setup(self, intf=None, orig=False):
+        """ Open, or set up, a device. """
+        log_method_call(self, self.name, orig=orig, status=self.status)
+
+    def teardown(self, recursive=None):
+        """ Close, or tear down, a device. """
+        log_method_call(self, self.name, status=self.status)
+
+    def create(self, intf=None):
+        """ Create the device. """
+        log_method_call(self, self.name, status=self.status)
+        self.createParents()
+        self.setupParents()
+
+    def destroy(self):
+        """ Destroy the device. """
+        log_method_call(self, self.name, status=self.status)
diff --git a/pyanaconda/storage/devicetree.py b/pyanaconda/storage/devicetree.py
new file mode 100644
index 0000000..5c4df8e
--- /dev/null
+++ b/pyanaconda/storage/devicetree.py
@@ -0,0 +1,2278 @@
+# devicetree.py
+# Device management for anaconda's storage configuration module.
+#
+# Copyright (C) 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, or (at your option) any later version.
+# 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.
+#
+# Red Hat Author(s): Dave Lehman <dlehman@xxxxxxxxxx>
+#
+
+import os
+import stat
+import block
+import re
+
+from errors import *
+from devices import *
+from deviceaction import *
+from partitioning import shouldClear
+from pykickstart.constants import *
+import formats
+import devicelibs.mdraid
+import devicelibs.dm
+import devicelibs.lvm
+import devicelibs.mpath
+from udev import *
+from .storage_log import log_method_call
+import iutil
+
+import gettext
+_ = lambda x: gettext.ldgettext("anaconda", x)
+
+import logging
+log = logging.getLogger("storage")
+
+def getLUKSPassphrase(intf, device, globalPassphrase):
+    """ Obtain a passphrase for a LUKS encrypted block device.
+
+        The format's mapping name must already be set and the backing
+        device must already be set up before calling this function.
+
+        If successful, this function leaves the device mapped.
+
+        Return value is a two-tuple: (passphrase, isglobal)
+
+        passphrase is the passphrase string, if obtained
+        isglobal is a boolean indicating whether the passphrase is global
+
+        Either or both can be None, depending on the outcome.
+    """
+    if device.format.type != "luks":
+        # this function only works on luks devices
+        raise ValueError("not a luks device")
+
+    if not device.status:
+        # the device should have already been set up
+        raise RuntimeError("device is not set up")
+
+    if device.format.status:
+        # the device is already mapped
+        raise RuntimeError("device is already mapped")
+
+    if not device.format.configured and globalPassphrase:
+        # try the given passphrase first
+        device.format.passphrase =  globalPassphrase
+    
+        try:
+            device.format.setup()
+        except CryptoError as e:
+            device.format.passphrase = None
+        else:
+            # we've opened the device so we're done.
+            return (globalPassphrase, False)
+
+    if not intf:
+        return (None, None)
+    
+    buttons = [_("Back"), _("Continue")]
+    passphrase_incorrect = False
+    while True:
+        if passphrase_incorrect:
+            # TODO: add a flag to passphraseEntryWindow to say the last
+            #       passphrase was incorrect so try again
+            passphrase_incorrect = False
+        (passphrase, isglobal) = intf.passphraseEntryWindow(device.name)
+        if not passphrase:
+            rc = intf.messageWindow(_("Confirm"),
+                                    _("Are you sure you want to skip "
+                                      "entering a passphrase for device "
+                                      "%s?\n\n"
+                                      "If you skip this step the "
+                                      "device's contents will not "
+                                      "be available during "
+                                      "installation.") % device.name,
+                                    type = "custom",
+                                    default = 0,
+                                    custom_buttons = buttons)
+            if rc == 0:
+                continue
+            else:
+                passphrase = None
+                isglobal = None
+                log.info("skipping passphrase for %s" % (device.name,))
+                break
+
+        device.format.passphrase = passphrase
+
+        try:
+            device.format.setup()
+        except CryptoError as e:
+            device.format.passphrase = None
+            passphrase_incorrect = True
+        else:
+            # we've opened the device so we're done.
+            break
+
+    return (passphrase, isglobal)
+
+
+class DeviceTree(object):
+    """ A quasi-tree that represents the devices in the system.
+
+        The tree contains a list of device instances, which does not
+        necessarily reflect the actual state of the system's devices.
+        DeviceActions are used to perform modifications to the tree,
+        except when initially populating the tree.
+
+        DeviceAction instances are registered, possibly causing the
+        addition or removal of Device instances to/from the tree. The
+        DeviceActions are all reversible up to the time their execute
+        method has been called.
+
+        Only one action of any given type/object pair should exist for
+        any given device at any given time.
+
+        DeviceAction instances can only be registered for leaf devices,
+        except for resize actions.
+    """
+
+    def __init__(self, intf=None, ignored=[], exclusive=[], type=CLEARPART_TYPE_NONE,
+                 clear=[], zeroMbr=None, reinitializeDisks=None, protected=[],
+                 passphrase=None, luksDict=None, iscsi=None, dasd=None):
+        # internal data members
+        self._devices = []
+        self._actions = []
+
+        # indicates whether or not the tree has been fully populated
+        self.populated = False
+
+        self.intf = intf
+        self.exclusiveDisks = exclusive
+        self.clearPartType = type
+        self.clearPartDisks = clear
+        self.zeroMbr = zeroMbr
+        self.reinitializeDisks = reinitializeDisks
+        self.iscsi = iscsi
+        self.dasd = dasd
+
+        # protected device specs as provided by the user
+        self.protectedDevSpecs = protected
+
+        # names of protected devices at the time of tree population
+        self.protectedDevNames = []
+
+        self.unusedRaidMembers = []
+
+        self.__multipaths = {}
+        self.__multipathConfigWriter = devicelibs.mpath.MultipathConfigWriter()
+
+        self.__passphrase = passphrase
+        self.__luksDevs = {}
+        if luksDict and isinstance(luksDict, dict):
+            self.__luksDevs = luksDict
+        self._ignoredDisks = []
+        for disk in ignored:
+            self.addIgnoredDisk(disk)
+        self.immutableDevices = []
+        lvm.lvm_cc_resetFilter()
+
+    def addIgnoredDisk(self, disk):
+        self._ignoredDisks.append(disk)
+        lvm.lvm_cc_addFilterRejectRegexp(disk)
+
+    def pruneActions(self):
+        """ Prune loops and redundant actions from the queue. """
+        # handle device destroy actions
+        actions = self.findActions(type="destroy", object="device")
+        for a in actions:
+            if a not in self._actions:
+                # we may have removed some of the actions in a previous
+                # iteration of this loop
+                continue
+
+            log.debug("action '%s' (%s)" % (a, id(a)))
+            destroys = self.findActions(devid=a.device.id,
+                                        type="destroy",
+                                        object="device")
+
+            creates = self.findActions(devid=a.device.id,
+                                       type="create",
+                                       object="device")
+            log.debug("found %d create and %d destroy actions for device id %d"
+                        % (len(creates), len(destroys), a.device.id))
+
+            # If the device is not preexisting, we remove all actions up
+            # to and including the last destroy action.
+            # If the device is preexisting, we remove all actions from
+            # after the first destroy action up to and including the last
+            # destroy action.
+            # If the device is preexisting and there is only one device
+            # destroy action we remove all resize and format create/migrate
+            # actions on that device that precede the destroy action.
+            loops = []
+            first_destroy_idx = None
+            first_create_idx = None
+            stop_action = None
+            start = None
+            if len(destroys) > 1:
+                # there are multiple destroy actions for this device
+                loops = destroys
+                first_destroy_idx = self._actions.index(loops[0])
+                start = self._actions.index(a) + 1
+                stop_action = destroys[-1]
+
+            if creates:
+                first_create_idx = self._actions.index(creates[0])
+                if not loops or first_destroy_idx > first_create_idx:
+                    # this device is not preexisting
+                    start = first_create_idx
+                    stop_action = destroys[-1]
+
+            dev_actions = self.findActions(devid=a.device.id)
+            if start is None:
+                # only one device destroy, so prune preceding resizes and
+                # format creates and migrates
+                for _a in dev_actions[:]:
+                    if _a.isResize() or (_a.isFormat() and not _a.isDestroy()):
+                        continue
+
+                    dev_actions.remove(_a)
+
+                if not dev_actions:
+                    # nothing to prune
+                    continue
+
+                start = self._actions.index(dev_actions[0])
+                stop_action = dev_actions[-1]
+
+            # now we remove all actions on this device between the start
+            # index (into self._actions) and stop_action.
+            for rem in dev_actions:
+                end = self._actions.index(stop_action)
+                if start <= self._actions.index(rem) <= end:
+                    log.debug(" removing action '%s' (%s)" % (rem, id(rem)))
+                    self._actions.remove(rem)
+
+                if rem == stop_action:
+                    break
+
+        # device create actions
+        actions = self.findActions(type="create", object="device")
+        for a in actions:
+            if a not in self._actions:
+                # we may have removed some of the actions in a previous
+                # iteration of this loop
+                continue
+
+            log.debug("action '%s' (%s)" % (a, id(a)))
+            creates = self.findActions(devid=a.device.id,
+                                       type="create",
+                                       object="device")
+
+            destroys = self.findActions(devid=a.device.id,
+                                        type="destroy",
+                                        object="device")
+
+            # If the device is preexisting, we remove everything between
+            # the first destroy and the last create.
+            # If the device is not preexisting, we remove everything up to
+            # the last create.
+            loops = []
+            first_destroy_idx = None
+            first_create_idx = None
+            stop_action = None
+            start = None
+            if len(creates) > 1:
+                # there are multiple create actions for this device
+                loops = creates
+                first_create_idx = self._actions.index(loops[0])
+                start = 0
+                stop_action = creates[-1]
+
+            if destroys:
+                first_destroy_idx = self._actions.index(destroys[0])
+                if not loops or first_create_idx > first_destroy_idx:
+                    # this device is preexisting
+                    start = first_destroy_idx + 1
+                    stop_action = creates[-1]
+
+            if start is None:
+                continue
+
+            # remove all actions on this from after the first destroy up
+            # to the last create
+            dev_actions = self.findActions(devid=a.device.id)
+            for rem in dev_actions:
+                if rem == stop_action:
+                    break
+
+                end = self._actions.index(stop_action)
+                if start <= self._actions.index(rem) < end:
+                    log.debug(" removing action '%s' (%s)" % (rem, id(rem)))
+                    self._actions.remove(rem)
+
+        # device resize actions
+        actions = self.findActions(type="resize", object="device")
+        for a in actions:
+            if a not in self._actions:
+                # we may have removed some of the actions in a previous
+                # iteration of this loop
+                continue
+
+            log.debug("action '%s' (%s)" % (a, id(a)))
+            loops = self.findActions(devid=a.device.id,
+                                     type="resize",
+                                     object="device")
+
+            if len(loops) == 1:
+                continue
+
+            # remove all but the last resize action on this device
+            for rem in loops[:-1]:
+                log.debug(" removing action '%s' (%s)" % (rem, id(rem)))
+                self._actions.remove(rem)
+
+        # format destroy
+        # XXX I don't think there's a way for these loops to happen
+        actions = self.findActions(type="destroy", object="format")
+        for a in actions:
+            if a not in self._actions:
+                # we may have removed some of the actions in a previous
+                # iteration of this loop
+                continue
+
+            log.debug("action '%s' (%s)" % (a, id(a)))
+            destroys = self.findActions(devid=a.device.id,
+                                        type="destroy",
+                                        object="format")
+
+            creates = self.findActions(devid=a.device.id,
+                                       type="create",
+                                       object="format")
+
+            # If the format is not preexisting, we remove all actions up
+            # to and including the last destroy action.
+            # If the format is preexisting, we remove all actions from
+            # after the first destroy action up to and including the last
+            # destroy action.
+            loops = []
+            first_destroy_idx = None
+            first_create_idx = None
+            stop_action = None
+            start = None
+            if len(destroys) > 1:
+                # there are multiple destroy actions for this format
+                loops = destroys
+                first_destroy_idx = self._actions.index(loops[0])
+                start = self._actions.index(a) + 1
+                stop_action = destroys[-1]
+
+            if creates:
+                first_create_idx = self._actions.index(creates[0])
+                if not loops or first_destroy_idx > first_create_idx:
+                    # this format is not preexisting
+                    start = first_create_idx
+                    stop_action = destroys[-1]
+
+            if start is None:
+                continue
+
+            # now we remove all actions on this device's format between
+            # the start index (into self._actions) and stop_action.
+            dev_actions = self.findActions(devid=a.device.id,
+                                           object="format")
+            for rem in dev_actions:
+                end = self._actions.index(stop_action)
+                if start <= self._actions.index(rem) <= end:
+                    log.debug(" removing action '%s' (%s)" % (rem, id(rem)))
+                    self._actions.remove(rem)
+
+                if rem == stop_action:
+                    break
+
+        # format create
+        # XXX I don't think there's a way for these loops to happen
+        actions = self.findActions(type="create", object="format")
+        for a in actions:
+            if a not in self._actions:
+                # we may have removed some of the actions in a previous
+                # iteration of this loop
+                continue
+
+            log.debug("action '%s' (%s)" % (a, id(a)))
+            creates = self.findActions(devid=a.device.id,
+                                       type="create",
+                                       object="format")
+
+            destroys = self.findActions(devid=a.device.id,
+                                        type="destroy",
+                                        object="format")
+
+            # If the format is preexisting, we remove everything between
+            # the first destroy and the last create.
+            # If the format is not preexisting, we remove everything up to
+            # the last create.
+            loops = []
+            first_destroy_idx = None
+            first_create_idx = None
+            stop_action = None
+            start = None
+            if len(creates) > 1:
+                # there are multiple create actions for this format
+                loops = creates
+                first_create_idx = self._actions.index(loops[0])
+                start = 0
+                stop_action = creates[-1]
+
+            if destroys:
+                first_destroy_idx = self._actions.index(destroys[0])
+                if not loops or first_create_idx > first_destroy_idx:
+                    # this format is preexisting
+                    start = first_destroy_idx + 1
+                    stop_action = creates[-1]
+
+            if start is None:
+                continue
+
+            # remove all actions on this from after the first destroy up
+            # to the last create
+            dev_actions = self.findActions(devid=a.device.id,
+                                           object="format")
+            for rem in dev_actions:
+                if rem == stop_action:
+                    break
+
+                end = self._actions.index(stop_action)
+                if start <= self._actions.index(rem) < end:
+                    log.debug(" removing action '%s' (%s)" % (rem, id(rem)))
+                    self._actions.remove(rem)
+
+        # format resize
+        actions = self.findActions(type="resize", object="format")
+        for a in actions:
+            if a not in self._actions:
+                # we may have removed some of the actions in a previous
+                # iteration of this loop
+                continue
+
+            log.debug("action '%s' (%s)" % (a, id(a)))
+            loops = self.findActions(devid=a.device.id,
+                                     type="resize",
+                                     object="format")
+
+            if len(loops) == 1:
+                continue
+
+            # remove all but the last resize action on this format
+            for rem in loops[:-1]:
+                log.debug(" removing action '%s' (%s)" % (rem, id(rem)))
+                self._actions.remove(rem)
+
+        # format migrate
+        # XXX I don't think there's away for these loops to occur
+        actions = self.findActions(type="migrate", object="format")
+        for a in actions:
+            if a not in self._actions:
+                # we may have removed some of the actions in a previous
+                # iteration of this loop
+                continue
+
+            log.debug("action '%s' (%s)" % (a, id(a)))
+            loops = self.findActions(devid=a.device.id,
+                                     type="migrate",
+                                     object="format")
+
+            if len(loops) == 1:
+                continue
+
+            # remove all but the last migrate action on this format
+            for rem in loops[:-1]:
+                log.debug(" removing action '%s' (%s)" % (rem, id(rem)))
+                self._actions.remove(rem)
+
+    def processActions(self, dryRun=None):
+        """ Execute all registered actions. """
+        # in most cases the actions will already be sorted because of the
+        # rules for registration, but let's not rely on that
+        def cmpActions(a1, a2):
+            ret = 0
+            if a1.isDestroy() and a2.isDestroy():
+                if a1.device.path == a2.device.path:
+                    # if it's the same device, destroy the format first
+                    if a1.isFormat() and a2.isFormat():
+                        ret = 0
+                    elif a1.isFormat() and not a2.isFormat():
+                        ret = -1
+                    elif not a1.isFormat() and a2.isFormat():
+                        ret = 1
+                elif a1.device.dependsOn(a2.device):
+                    ret = -1
+                elif a2.device.dependsOn(a1.device):
+                    ret = 1
+                # generally destroy partitions after lvs, vgs, &c
+                elif isinstance(a1.device, PartitionDevice) and \
+                     isinstance(a2.device, PartitionDevice):
+                    if a1.device.disk == a2.device.disk:
+                        ret = cmp(a2.device.partedPartition.number,
+                                  a1.device.partedPartition.number)
+                    else:
+                        ret = cmp(a2.device.name, a1.device.name)
+                elif isinstance(a1.device, PartitionDevice) and \
+                     a2.device.partitioned:
+                    ret = -1
+                elif isinstance(a2.device, PartitionDevice) and \
+                     a1.device.partitioned:
+                    ret = 1
+                # remove partitions before unpartitioned non-partition
+                # devices
+                elif isinstance(a1.device, PartitionDevice) and \
+                     not isinstance(a2.device, PartitionDevice):
+                    ret = 1
+                elif isinstance(a2.device, PartitionDevice) and \
+                     not isinstance(a1.device, PartitionDevice):
+                    ret = -1
+                else:
+                    ret = 0
+            elif a1.isDestroy():
+                ret = -1
+            elif a2.isDestroy():
+                ret = 1
+            elif a1.isResize() and a2.isResize():
+                if a1.device.path == a2.device.path:
+                    if a1.obj == a2.obj:
+                        ret = 0
+                    elif a1.isFormat() and not a2.isFormat():
+                        # same path, one device, one format
+                        if a1.isGrow():
+                            ret = 1
+                        else:
+                            ret = -1
+                    elif not a1.isFormat() and a2.isFormat():
+                        # same path, one device, one format
+                        if a1.isGrow():
+                            ret = -1
+                        else:
+                            ret = 1
+                    else:
+                        ret = cmp(a1.device.name, a2.device.name)
+                elif a1.device.dependsOn(a2.device):
+                    if a1.isGrow():
+                        ret = 1
+                    else:
+                        ret = -1
+                elif a2.device.dependsOn(a1.device):
+                    if a1.isGrow():
+                        ret = -1
+                    else:
+                        ret = 1
+                elif isinstance(a1.device, PartitionDevice) and \
+                     isinstance(a2.device, PartitionDevice):
+                    ret = cmp(a1.device.name, a2.device.name)
+                else:
+                    ret = 0
+            elif a1.isResize():
+                ret = -1
+            elif a2.isResize():
+                ret = 1
+            elif a1.isCreate() and a2.isCreate():
+                if a1.device.path == a2.device.path:
+                    if a1.obj == a2.obj:
+                        ret = 0
+                    if a1.isFormat():
+                        ret = 1
+                    elif a2.isFormat():
+                        ret = -1
+                    else:
+                        ret = 0
+                elif a1.device.dependsOn(a2.device):
+                    ret = 1
+                elif a2.device.dependsOn(a1.device):
+                    ret = -1
+                # generally create partitions before other device types
+                elif isinstance(a1.device, PartitionDevice) and \
+                     isinstance(a2.device, PartitionDevice):
+                    if a1.device.disk == a2.device.disk:
+                        ret = cmp(a1.device.partedPartition.number,
+                                  a2.device.partedPartition.number)
+                    else:
+                        ret = cmp(a1.device.name, a2.device.name)
+                elif isinstance(a1.device, PartitionDevice) and \
+                     a2.device.partitioned:
+                    ret = 1
+                elif isinstance(a2.device, PartitionDevice) and \
+                     a1.device.partitioned:
+                    ret = -1
+                elif isinstance(a1.device, PartitionDevice) and \
+                     not isinstance(a2.device, PartitionDevice):
+                    ret = -1
+                elif isinstance(a2.device, PartitionDevice) and \
+                     not isinstance(a1.device, PartitionDevice):
+                    ret = 1
+                else:
+                    ret = 0
+            elif a1.isCreate():
+                ret = -1
+            elif a2.isCreate():
+                ret = 1
+            elif a1.isMigrate() and a2.isMigrate():
+                if a1.device.path == a2.device.path:
+                    ret = 0
+                elif a1.device.dependsOn(a2.device):
+                    ret = 1
+                elif a2.device.dependsOn(a1.device):
+                    ret = -1
+                elif isinstance(a1.device, PartitionDevice) and \
+                     isinstance(a2.device, PartitionDevice):
+                    if a1.device.disk == a2.device.disk:
+                        ret = cmp(a1.device.partedPartition.number,
+                                  a2.device.partedPartition.number)
+                    else:
+                        ret = cmp(a1.device.name, a2.device.name)
+                else:
+                    ret = 0
+            else:
+                ret = 0
+
+            log.debug("cmp: %d -- %s | %s" % (ret, a1, a2))
+            return ret
+
+        log.debug("resetting parted disks...")
+        for device in self.devices:
+            if device.partitioned:
+                device.format.resetPartedDisk()
+                if device.originalFormat.type == "disklabel" and \
+                   device.originalFormat != device.format:
+                    device.originalFormat.resetPartedDisk()
+
+        # Call preCommitFixup on all devices
+        mpoints = [getattr(d.format, 'mountpoint', "") for d in self.devices]
+        for device in self.devices:
+            device.preCommitFixup(mountpoints=mpoints)
+
+        # Also call preCommitFixup on any devices we're going to
+        # destroy (these are already removed from the tree)
+        for action in self._actions:
+            if isinstance(action, ActionDestroyDevice):
+                action.device.preCommitFixup(mountpoints=mpoints)
+
+        # setup actions to create any extended partitions we added
+        #
+        # XXX At this point there can be duplicate partition paths in the
+        #     tree (eg: non-existent sda6 and previous sda6 that will become
+        #     sda5 in the course of partitioning), so we access the list
+        #     directly here.
+        for device in self._devices:
+            if isinstance(device, PartitionDevice) and \
+               device.isExtended and not device.exists:
+                # don't properly register the action since the device is
+                # already in the tree
+                self._actions.append(ActionCreateDevice(device))
+
+        for action in self._actions:
+            log.debug("action: %s" % action)
+
+        log.debug("pruning action queue...")
+        self.pruneActions()
+        for action in self._actions:
+            log.debug("action: %s" % action)
+
+        log.debug("sorting actions...")
+        self._actions.sort(cmp=cmpActions)
+        for action in self._actions:
+            log.debug("action: %s" % action)
+
+        for action in self._actions:
+            log.info("executing action: %s" % action)
+            if not dryRun:
+                try:
+                    action.execute(intf=self.intf)
+                except DiskLabelCommitError:
+                    # it's likely that a previous format destroy action
+                    # triggered setup of an lvm or md device.
+                    self.teardownAll()
+                    action.execute(intf=self.intf)
+
+                udev_settle()
+                for device in self._devices:
+                    # make sure we catch any renumbering parted does
+                    if device.exists and isinstance(device, PartitionDevice):
+                        device.updateName()
+                        device.format.device = device.path
+
+    def _addDevice(self, newdev):
+        """ Add a device to the tree.
+
+            Raise ValueError if the device's identifier is already
+            in the list.
+        """
+        if newdev.path in [d.path for d in self._devices] and \
+           not isinstance(newdev, NoDevice):
+            raise ValueError("device is already in tree")
+
+        # make sure this device's parent devices are in the tree already
+        for parent in newdev.parents:
+            if parent not in self._devices:
+                raise DeviceTreeError("parent device not in tree")
+
+        self._devices.append(newdev)
+        log.debug("added %s %s (id %d) to device tree" % (newdev.type,
+                                                          newdev.name,
+                                                          newdev.id))
+
+    def _removeDevice(self, dev, force=None, moddisk=True):
+        """ Remove a device from the tree.
+
+            Only leaves may be removed.
+        """
+        if dev not in self._devices:
+            raise ValueError("Device '%s' not in tree" % dev.name)
+
+        if not dev.isleaf and not force:
+            log.debug("%s has %d kids" % (dev.name, dev.kids))
+            raise ValueError("Cannot remove non-leaf device '%s'" % dev.name)
+
+        # if this is a partition we need to remove it from the parted.Disk
+        if moddisk and isinstance(dev, PartitionDevice) and \
+                dev.disk is not None:
+            # if this partition hasn't been allocated it could not have
+            # a disk attribute
+            if dev.partedPartition.type == parted.PARTITION_EXTENDED and \
+                    len(dev.disk.format.logicalPartitions) > 0:
+                raise ValueError("Cannot remove extended partition %s.  "
+                        "Logical partitions present." % dev.name)
+
+            dev.disk.format.removePartition(dev.partedPartition)
+
+            # adjust all other PartitionDevice instances belonging to the
+            # same disk so the device name matches the potentially altered
+            # name of the parted.Partition
+            for device in self._devices:
+                if isinstance(device, PartitionDevice) and \
+                   device.disk == dev.disk:
+                    device.updateName()
+
+        self._devices.remove(dev)
+        log.debug("removed %s %s (id %d) from device tree" % (dev.type,
+                                                              dev.name,
+                                                              dev.id))
+
+        for parent in dev.parents:
+            # Will this cause issues with garbage collection?
+            #   Do we care about garbage collection? At all?
+            parent.removeChild()
+
+    def registerAction(self, action):
+        """ Register an action to be performed at a later time.
+
+            Modifications to the Device instance are handled before we
+            get here.
+        """
+        if (action.isDestroy() or action.isResize() or \
+            (action.isCreate() and action.isFormat())) and \
+           action.device not in self._devices:
+            raise DeviceTreeError("device is not in the tree")
+        elif (action.isCreate() and action.isDevice()):
+            # this allows multiple create actions w/o destroy in between;
+            # we will clean it up before processing actions
+            #raise DeviceTreeError("device is already in the tree")
+            if action.device in self._devices:
+                self._removeDevice(action.device)
+            for d in self._devices:
+                if d.path == action.device.path:
+                    self._removeDevice(d)
+
+        if action.isCreate() and action.isDevice():
+            self._addDevice(action.device)
+        elif action.isDestroy() and action.isDevice():
+            self._removeDevice(action.device)
+        elif action.isCreate() and action.isFormat():
+            if isinstance(action.device.format, formats.fs.FS) and \
+               action.device.format.mountpoint in self.filesystems:
+                raise DeviceTreeError("mountpoint already in use")
+
+        log.debug("registered action: %s" % action)
+        self._actions.append(action)
+
+    def cancelAction(self, action):
+        """ Cancel a registered action.
+
+            This will unregister the action and do any required
+            modifications to the device list.
+
+            Actions all operate on a Device, so we can use the devices
+            to determine dependencies.
+        """
+        if action.isCreate() and action.isDevice():
+            # remove the device from the tree
+            self._removeDevice(action.device)
+        elif action.isDestroy() and action.isDevice():
+            # add the device back into the tree
+            self._addDevice(action.device)
+        elif action.isFormat() and \
+             (action.isCreate() or action.isMigrate() or action.isResize()):
+            action.cancel()
+
+        self._actions.remove(action)
+
+    def findActions(self, device=None, type=None, object=None, path=None,
+                    devid=None):
+        """ Find all actions that match all specified parameters.
+
+            Keyword arguments:
+
+                device -- device to match (Device, or None to match any)
+                type -- action type to match (string, or None to match any)
+                object -- operand type to match (string, or None to match any)
+                path -- device path to match (string, or None to match any)
+
+        """
+        if device is None and type is None and object is None and \
+           path is None and devid is None:
+            return self._actions[:]
+
+        # convert the string arguments to the types used in actions
+        _type = action_type_from_string(type)
+        _object = action_object_from_string(object)
+
+        actions = []
+        for action in self._actions:
+            if device is not None and action.device != device:
+                continue
+
+            if _type is not None and action.type != _type:
+                continue
+
+            if _object is not None and action.obj != _object:
+                continue
+
+            if path is not None and action.device.path != path:
+                continue
+
+            if devid is not None and action.device.id != devid:
+                continue
+                
+            actions.append(action)
+
+        return actions
+
+    def getDependentDevices(self, dep):
+        """ Return a list of devices that depend on dep.
+
+            The list includes both direct and indirect dependents.
+        """
+        dependents = []
+
+        # special handling for extended partitions since the logical
+        # partitions and their deps effectively depend on the extended
+        logicals = []
+        if isinstance(dep, PartitionDevice) and dep.partType and \
+           dep.isExtended:
+            # collect all of the logicals on the same disk
+            for part in self.getDevicesByInstance(PartitionDevice):
+                if part.partType and part.isLogical and part.disk == dep.disk:
+                    logicals.append(part)
+
+        for device in self.devices:
+            if device.dependsOn(dep):
+                dependents.append(device)
+            else:
+                for logical in logicals:
+                    if device.dependsOn(logical):
+                        dependents.append(device)
+                        break
+
+        return dependents
+
+    def isIgnored(self, info):
+        """ Return True if info is a device we should ignore.
+
+            Arguments:
+
+                info -- a dict representing a udev db entry
+
+            TODO:
+
+                - filtering of SAN/FC devices
+                - filtering by driver?
+
+        """
+        sysfs_path = udev_device_get_sysfs_path(info)
+        name = udev_device_get_name(info)
+        if not sysfs_path:
+            return None
+
+        if name in self._ignoredDisks:
+            return True
+
+        # Special handling for mdraid external metadata sets (mdraid BIOSRAID):
+        # 1) The containers are intermediate devices which will never be
+        # in exclusiveDisks
+        # 2) Sets get added to exclusive disks with their dmraid set name by
+        # the filter ui.  Note that making the ui use md names instead is not
+        # possible as the md names are simpy md# and we cannot predict the #
+        if udev_device_get_md_level(info) == "container":
+            return False
+
+        if udev_device_get_md_container(info) and \
+               udev_device_get_md_name(info):
+            md_name = udev_device_get_md_name(info)
+            for i in range(0, len(self.exclusiveDisks)):
+                if re.match("isw_[a-z]*_%s" % md_name, self.exclusiveDisks[i]):
+                    self.exclusiveDisks[i] = name
+                    return False
+
+        if udev_device_is_disk(info) and \
+                not udev_device_is_md(info) and \
+                not udev_device_is_dm(info) and \
+                not udev_device_is_biosraid(info) and \
+                not udev_device_is_multipath_member(info):
+            if self.exclusiveDisks and name not in self.exclusiveDisks:
+                self.addIgnoredDisk(name)
+                return True
+
+        # Ignore loop and ram devices, we normally already skip these in
+        # udev.py: enumerate_block_devices(), but we can still end up trying
+        # to add them to the tree when they are slaves of other devices, this
+        # happens for example with the livecd
+        if name.startswith("loop") or name.startswith("ram"):
+            return True
+
+        # FIXME: check for virtual devices whose slaves are on the ignore list
+
+    def addUdevDMDevice(self, info):
+        name = udev_device_get_name(info)
+        log_method_call(self, name=name)
+        uuid = udev_device_get_uuid(info)
+        sysfs_path = udev_device_get_sysfs_path(info)
+        device = None
+
+        for dmdev in self.devices:
+            if not isinstance(dmdev, DMDevice):
+                continue
+
+            try:
+                # there is a device in the tree already with the same
+                # major/minor as this one but with a different name
+                # XXX this is kind of racy
+                if dmdev.getDMNode() == os.path.basename(sysfs_path):
+                    # XXX should we take the name already in use?
+                    device = dmdev
+                    break
+            except DMError:
+                # This is a little lame, but the VG device is a DMDevice
+                # and it won't have a dm node. At any rate, this is not
+                # important enough to crash the install.
+                log.debug("failed to find dm node for %s" % dmdev.name)
+                continue
+
+        if device is None:
+            # we couldn't find it, so create it
+            # first, get a list of the slave devs and look them up
+            slaves = []
+            dir = os.path.normpath("/sys/%s/slaves" % sysfs_path)
+            slave_names = os.listdir(dir)
+            for slave_name in slave_names:
+                # if it's a dm-X name, resolve it to a map name first
+                if slave_name.startswith("dm-"):
+                    dev_name = dm.name_from_dm_node(slave_name)
+                else:
+                    dev_name = slave_name
+                slave_dev = self.getDeviceByName(dev_name)
+                if slave_dev:
+                    slaves.append(slave_dev)
+                else:
+                    # we haven't scanned the slave yet, so do it now
+                    path = os.path.normpath("%s/%s" % (dir, slave_name))
+                    new_info = udev_get_block_device(os.path.realpath(path)[4:])
+                    if new_info:
+                        self.addUdevDevice(new_info)
+                        if self.getDeviceByName(dev_name) is None:
+                            # if the current slave is still not in
+                            # the tree, something has gone wrong
+                            log.error("failure scanning device %s: could not add slave %s" % (name, dev_name))
+                            return
+
+            # try to get the device again now that we've got all the slaves
+            device = self.getDeviceByName(name)
+
+            if device is None:
+                if udev_device_is_multipath_partition(info, self):
+                    diskname = udev_device_get_multipath_partition_disk(info)
+                    disk = self.getDeviceByName(diskname)
+                    return self.addUdevPartitionDevice(info, disk=disk)
+                elif udev_device_is_dmraid_partition(info, self):
+                    diskname = udev_device_get_dmraid_partition_disk(info)
+                    disk = self.getDeviceByName(diskname)
+                    return self.addUdevPartitionDevice(info, disk=disk)
+
+            # if we get here, we found all of the slave devices and
+            # something must be wrong -- if all of the slaves are in
+            # the tree, this device should be as well
+            if device is None:
+                log.warning("ignoring dm device %s" % name)
+
+        return device
+
+    def addUdevMDDevice(self, info):
+        name = udev_device_get_name(info)
+        log_method_call(self, name=name)
+        uuid = udev_device_get_uuid(info)
+        sysfs_path = udev_device_get_sysfs_path(info)
+        device = None
+
+        slaves = []
+        dir = os.path.normpath("/sys/%s/slaves" % sysfs_path)
+        slave_names = os.listdir(dir)
+        for slave_name in slave_names:
+            # if it's a dm-X name, resolve it to a map name
+            if slave_name.startswith("dm-"):
+                dev_name = dm.name_from_dm_node(slave_name)
+            else:
+                dev_name = slave_name
+            slave_dev = self.getDeviceByName(dev_name)
+            if slave_dev:
+                slaves.append(slave_dev)
+            else:
+                # we haven't scanned the slave yet, so do it now
+                path = os.path.normpath("%s/%s" % (dir, slave_name))
+                new_info = udev_get_block_device(os.path.realpath(path)[4:])
+                if new_info:
+                    self.addUdevDevice(new_info)
+                    if self.getDeviceByName(dev_name) is None:
+                        # if the current slave is still not in
+                        # the tree, something has gone wrong
+                        log.error("failure scanning device %s: could not add slave %s" % (name, dev_name))
+                        return
+
+        # try to get the device again now that we've got all the slaves
+        device = self.getDeviceByName(name)
+
+        # if we get here, we found all of the slave devices and
+        # something must be wrong -- if all of the slaves we in
+        # the tree, this device should be as well
+        if device is None:
+            log.warning("using MD RAID device for %s" % name)
+            try:
+                # level is reported as, eg: "raid1"
+                md_level = udev_device_get_md_level(info)
+                md_devices = int(udev_device_get_md_devices(info))
+                md_uuid = udev_device_get_md_uuid(info)
+            except (KeyError, IndexError, ValueError) as e:
+                log.warning("invalid data for %s: %s" % (name, e))
+                return
+
+            device = MDRaidArrayDevice(name,
+                                       level=md_level,
+                                       memberDevices=md_devices,
+                                       uuid=md_uuid,
+                                       exists=True,
+                                       parents=slaves)
+            self._addDevice(device)
+
+        return device
+
+    def addUdevPartitionDevice(self, info, disk=None):
+        name = udev_device_get_name(info)
+        log_method_call(self, name=name)
+        uuid = udev_device_get_uuid(info)
+        sysfs_path = udev_device_get_sysfs_path(info)
+        device = None
+
+        if disk is None:
+            disk_name = os.path.basename(os.path.dirname(sysfs_path))
+            disk_name = disk_name.replace('!','/')
+            disk = self.getDeviceByName(disk_name)
+
+        if disk is None:
+            # create a device instance for the disk
+            new_info = udev_get_block_device(os.path.dirname(sysfs_path))
+            if new_info:
+                self.addUdevDevice(new_info)
+                disk = self.getDeviceByName(disk_name)
+
+            if disk is None:
+                # if the current device is still not in
+                # the tree, something has gone wrong
+                log.error("failure scanning device %s" % disk_name)
+                lvm.lvm_cc_addFilterRejectRegexp(name)
+                return
+
+        # Check that the disk has partitions. If it does not, we must have
+        # reinitialized the disklabel.
+        #
+        # Also ignore partitions on devices we do not support partitioning
+        # of, like logical volumes.
+        if not getattr(disk.format, "partitions", None) or \
+           not disk.partitionable:
+            # When we got here because the disk does not have a disklabel
+            # format (ie a biosraid member), or because it is not
+            # partitionable we want LVM to ignore this partition too
+            if disk.format.type != "disklabel" or not disk.partitionable:
+                lvm.lvm_cc_addFilterRejectRegexp(name)
+            log.debug("ignoring partition %s" % name)
+            return
+
+        try:
+            device = PartitionDevice(name, sysfsPath=sysfs_path,
+                                     major=udev_device_get_major(info),
+                                     minor=udev_device_get_minor(info),
+                                     exists=True, parents=[disk])
+        except DeviceError:
+            # corner case sometime the kernel accepts a partition table
+            # which gets rejected by parted, in this case we will
+            # prompt to re-initialize the disk, so simply skip the
+            # faulty partitions.
+            return
+
+        self._addDevice(device)
+        return device
+
+    def addUdevDiskDevice(self, info):
+        name = udev_device_get_name(info)
+        log_method_call(self, name=name)
+        uuid = udev_device_get_uuid(info)
+        sysfs_path = udev_device_get_sysfs_path(info)
+        serial = udev_device_get_serial(info)
+        bus = udev_device_get_bus(info)
+
+        # udev doesn't always provide a vendor.
+        vendor = udev_device_get_vendor(info)
+        if not vendor:
+            vendor = ""
+
+        device = None
+
+        kwargs = { "serial": serial, "vendor": vendor, "bus": bus }
+        if udev_device_is_iscsi(info):
+            diskType = iScsiDiskDevice
+            kwargs["node"] = self.iscsi.getNode(
+                                   udev_device_get_iscsi_name(info),
+                                   udev_device_get_iscsi_address(info),
+                                   udev_device_get_iscsi_port(info))
+            kwargs["ibft"] = kwargs["node"] in self.iscsi.ibftNodes
+            kwargs["initiator"] = self.iscsi.initiator
+            log.debug("%s is an iscsi disk" % name)
+        elif udev_device_is_fcoe(info):
+            diskType = FcoeDiskDevice
+            kwargs["nic"]        = udev_device_get_fcoe_nic(info)
+            kwargs["identifier"] = udev_device_get_fcoe_identifier(info)
+            log.debug("%s is an fcoe disk" % name)
+        elif udev_device_get_md_container(info):
+            diskType = MDRaidArrayDevice
+            parentName = devicePathToName(udev_device_get_md_container(info))
+            kwargs["parents"] = [ self.getDeviceByName(parentName) ]
+            kwargs["level"]  = udev_device_get_md_level(info)
+            kwargs["memberDevices"] = int(udev_device_get_md_devices(info))
+            kwargs["uuid"] = udev_device_get_md_uuid(info)
+            kwargs["exists"]  = True
+            del kwargs["serial"]
+            del kwargs["vendor"]
+            del kwargs["bus"]
+        elif udev_device_is_dasd(info):
+            diskType = DASDDevice
+            kwargs["dasd"] = self.dasd
+            kwargs["busid"] = udev_device_get_dasd_bus_id(info)
+            kwargs["opts"] = {}
+
+            for attr in ['readonly', 'use_diag', 'erplog', 'failfast']:
+                kwargs["opts"][attr] = udev_device_get_dasd_flag(info, attr)
+
+            log.debug("%s is a dasd device" % name)
+        elif udev_device_is_zfcp(info):
+            diskType = ZFCPDiskDevice
+
+            for attr in ['hba_id', 'wwpn', 'fcp_lun']:
+                kwargs[attr] = udev_device_get_zfcp_attribute(info, attr=attr)
+
+            log.debug("%s is a zfcp device" % name)
+        else:
+            diskType = DiskDevice
+            log.debug("%s is a disk" % name)
+
+        device = diskType(name,
+                          major=udev_device_get_major(info),
+                          minor=udev_device_get_minor(info),
+                          sysfsPath=sysfs_path, **kwargs)
+        self._addDevice(device)
+        return device
+
+    def addUdevOpticalDevice(self, info):
+        log_method_call(self)
+        # XXX should this be RemovableDevice instead?
+        #
+        # Looks like if it has ID_INSTANCE=0:1 we can ignore it.
+        device = OpticalDevice(udev_device_get_name(info),
+                               major=udev_device_get_major(info),
+                               minor=udev_device_get_minor(info),
+                               sysfsPath=udev_device_get_sysfs_path(info),
+                               vendor=udev_device_get_vendor(info),
+                               model=udev_device_get_model(info))
+        self._addDevice(device)
+        return device
+
+    def addUdevDevice(self, info):
+        name = udev_device_get_name(info)
+        log_method_call(self, name=name, info=info)
+        uuid = udev_device_get_uuid(info)
+        sysfs_path = udev_device_get_sysfs_path(info)
+
+        if self.isIgnored(info):
+            log.debug("ignoring %s (%s)" % (name, sysfs_path))
+            return
+
+        log.debug("scanning %s (%s)..." % (name, sysfs_path))
+        device = self.getDeviceByName(name)
+
+        #
+        # The first step is to either look up or create the device
+        #
+        if udev_device_is_multipath_member(info):
+            device = DiskDevice(name,
+                            major=udev_device_get_major(info),
+                            minor=udev_device_get_minor(info),
+                            sysfsPath=sysfs_path, exists=True,
+                            serial=udev_device_get_serial(info),
+                            vendor=udev_device_get_vendor(info),
+                            model=udev_device_get_model(info))
+            self._addDevice(device)
+        elif udev_device_is_dm(info) and \
+               devicelibs.dm.dm_is_multipath(info):
+            log.debug("%s is a multipath device" % name)
+            self.addUdevDMDevice(info)
+        elif udev_device_is_dm(info):
+            log.debug("%s is a device-mapper device" % name)
+            # try to look up the device
+            if device is None and uuid:
+                # try to find the device by uuid
+                device = self.getDeviceByUuid(uuid)
+
+            if device is None:
+                device = self.addUdevDMDevice(info)
+        elif udev_device_is_md(info):
+            log.debug("%s is an md device" % name)
+            if device is None and uuid:
+                # try to find the device by uuid
+                device = self.getDeviceByUuid(uuid)
+
+            if device is None:
+                device = self.addUdevMDDevice(info)
+        elif udev_device_is_cdrom(info):
+            log.debug("%s is a cdrom" % name)
+            if device is None:
+                device = self.addUdevOpticalDevice(info)
+        elif udev_device_is_biosraid(info) and udev_device_is_disk(info):
+            log.debug("%s is part of a biosraid" % name)
+            if device is None:
+                device = DiskDevice(name,
+                                major=udev_device_get_major(info),
+                                minor=udev_device_get_minor(info),
+                                sysfsPath=sysfs_path, exists=True)
+                self._addDevice(device)
+        elif udev_device_is_disk(info):
+            if device is None:
+                device = self.addUdevDiskDevice(info)
+        elif udev_device_is_partition(info):
+            log.debug("%s is a partition" % name)
+            if device is None:
+                device = self.addUdevPartitionDevice(info)
+        else:
+            log.error("Unknown block device type for: %s" % name)
+            return
+
+        # If this device is protected, mark it as such now. Once the tree
+        # has been populated, devices' protected attribute is how we will
+        # identify protected devices.
+        if device and device.name in self.protectedDevNames:
+            device.protected = True
+
+        # Don't try to do format handling on drives without media or
+        # if we didn't end up with a device somehow.
+        if not device or not device.mediaPresent:
+            return
+
+        # now handle the device's formatting
+        self.handleUdevDeviceFormat(info, device)
+        log.debug("got device: %s" % device)
+        if device.format.type:
+            log.debug("got format: %s" % device.format)
+        device.originalFormat = device.format
+
+    def handleUdevDiskLabelFormat(self, info, device):
+        log_method_call(self, device=device.name)
+        if device.partitioned:
+            # this device is already set up
+            log.debug("disklabel format on %s already set up" % device.name)
+            return
+
+        try:
+            device.setup()
+        except Exception as e:
+            log.debug("setup of %s failed: %s" % (device.name, e))
+            log.warning("aborting disklabel handler for %s" % device.name)
+            return
+
+        # special handling for unsupported partitioned devices
+        if not device.partitionable:
+            try:
+                format = getFormat("disklabel",
+                                   device=device.path,
+                                   exists=True)
+            except InvalidDiskLabelError:
+                pass
+            else:
+                if format.partitions:
+                    # parted's checks for disklabel presence are less than
+                    # rigorous, so we will assume that detected disklabels
+                    # with no partitions are spurious
+                    device.format = format
+            return
+
+        # if the disk contains protected partitions we will not wipe the
+        # disklabel even if clearpart --initlabel was specified
+        if not self.clearPartDisks or device.name in self.clearPartDisks:
+            initlabel = self.reinitializeDisks
+            sysfs_path = udev_device_get_sysfs_path(info)
+            for protected in self.protectedDevNames:
+                # check for protected partition
+                _p = "/sys/%s/%s" % (sysfs_path, protected)
+                if os.path.exists(os.path.normpath(_p)):
+                    initlabel = False
+                    break
+
+                # check for protected partition on a device-mapper disk
+                disk_name = re.sub(r'p\d+$', '', protected)
+                if disk_name != protected and disk_name == device.name:
+                    initlabel = False
+                    break
+        else:
+            initlabel = False
+
+
+        if self.zeroMbr:
+            initcb = lambda: True
+        else:
+            description = device.description or device.model
+            bypath = deviceNameToDiskByPath(device.name)
+            if bypath:
+                bypath = os.path.basename(bypath)
+                details = "\n\nDevice details:\n%s" % (bypath,)
+            else:
+                bypath = device.name
+                details = ""
+
+            initcb = lambda: self.intf.questionInitializeDisk(bypath,
+                                                              description,
+                                                              device.size,
+                                                              details)
+
+        try:
+            format = getFormat("disklabel",
+                               device=device.path,
+                               exists=not initlabel)
+        except InvalidDiskLabelError:
+            # if there is preexisting formatting on the device we will
+            # use it instead of ignoring the device
+            if not self.zeroMbr and \
+               getFormat(udev_device_get_format(info)).type is not None:
+                return
+            # if we have a cb function use it. else we ignore the device.
+            if initcb is not None and initcb():
+                format = getFormat("disklabel",
+                                   device=device.path,
+                                   exists=False)
+            else:
+                self._removeDevice(device)
+                self.addIgnoredDisk(device.name)
+                return
+
+        if not format.exists:
+            # if we just initialized a disklabel we should schedule
+            # actions for destruction of the previous format and creation
+            # of the new one
+            self.registerAction(ActionDestroyFormat(device))
+            self.registerAction(ActionCreateFormat(device, format))
+
+            # If this is a mac-formatted disk we just initialized, make
+            # sure the partition table partition gets added to the device
+            # tree.
+            if device.format.partedDisk.type == "mac" and \
+               len(device.format.partitions) == 1:
+                name = device.format.partitions[0].getDeviceNodeName()
+                if not self.getDeviceByName(name):
+                    partDevice = PartitionDevice(name, exists=True,
+                                                 parents=[device])
+                    self._addDevice(partDevice)
+
+        else:
+            device.format = format
+
+    def handleUdevLUKSFormat(self, info, device):
+        log_method_call(self, name=device.name, type=device.format.type)
+        if not device.format.uuid:
+            log.info("luks device %s has no uuid" % device.path)
+            return
+
+        # look up or create the mapped device
+        if not self.getDeviceByName(device.format.mapName):
+            passphrase = self.__luksDevs.get(device.format.uuid)
+            if passphrase:
+                device.format.passphrase = passphrase
+            else:
+                (passphrase, isglobal) = getLUKSPassphrase(self.intf,
+                                                    device,
+                                                    self.__passphrase)
+                if isglobal and device.format.status:
+                    self.__passphrase = passphrase
+
+            luks_device = LUKSDevice(device.format.mapName,
+                                     parents=[device],
+                                     exists=True)
+            try:
+                luks_device.setup()
+            except (LUKSError, CryptoError, DeviceError) as e:
+                log.info("setup of %s failed: %s" % (device.format.mapName,
+                                                     e))
+                device.removeChild()
+            else:
+                self._addDevice(luks_device)
+        else:
+            log.warning("luks device %s already in the tree"
+                        % device.format.mapName)
+
+    def handleUdevLVMPVFormat(self, info, device):
+        log_method_call(self, name=device.name, type=device.format.type)
+        # lookup/create the VG and LVs
+        try:
+            vg_name = udev_device_get_vg_name(info)
+        except KeyError:
+            # no vg name means no vg -- we're done with this pv
+            return
+
+        vg_device = self.getDeviceByName(vg_name)
+        if vg_device:
+            vg_device._addDevice(device)
+            for lv in vg_device.lvs:
+                try:
+                    lv.setup()
+                except DeviceError as (msg, name):
+                    log.info("setup of %s failed: %s" % (lv.name, msg))
+        else:
+            try:
+                vg_uuid = udev_device_get_vg_uuid(info)
+                vg_size = udev_device_get_vg_size(info)
+                vg_free = udev_device_get_vg_free(info)
+                pe_size = udev_device_get_vg_extent_size(info)
+                pe_count = udev_device_get_vg_extent_count(info)
+                pe_free = udev_device_get_vg_free_extents(info)
+                pv_count = udev_device_get_vg_pv_count(info)
+            except (KeyError, ValueError) as e:
+                log.warning("invalid data for %s: %s" % (device.name, e))
+                return
+
+            vg_device = LVMVolumeGroupDevice(vg_name,
+                                             device,
+                                             uuid=vg_uuid,
+                                             size=vg_size,
+                                             free=vg_free,
+                                             peSize=pe_size,
+                                             peCount=pe_count,
+                                             peFree=pe_free,
+                                             pvCount=pv_count,
+                                             exists=True)
+            self._addDevice(vg_device)
+
+            try:
+                lv_names = udev_device_get_lv_names(info)
+                lv_uuids = udev_device_get_lv_uuids(info)
+                lv_sizes = udev_device_get_lv_sizes(info)
+                lv_attr = udev_device_get_lv_attr(info)
+            except KeyError as e:
+                log.warning("invalid data for %s: %s" % (device.name, e))
+                return
+
+            if not lv_names:
+                log.debug("no LVs listed for VG %s" % device.name)
+                return
+
+            # make a list of indices with snapshots at the end
+            indices = range(len(lv_names))
+            indices.sort(key=lambda i: lv_attr[i][0] in 'Ss')
+            for index in indices:
+                lv_name = lv_names[index]
+                name = "%s-%s" % (vg_name, lv_name)
+                if lv_attr[index][0] in 'Ss':
+                    log.debug("found lvm snapshot volume '%s'" % name)
+                    origin_name = devicelibs.lvm.lvorigin(vg_name, lv_name)
+                    if not origin_name:
+                        log.error("lvm snapshot '%s-%s' has unknown origin"
+                                    % (vg_name, lv_name))
+                        continue
+
+                    origin = self.getDeviceByName("%s-%s" % (vg_name,
+                                                             origin_name))
+                    if not origin:
+                        log.warning("snapshot lv '%s' origin lv '%s-%s' "
+                                    "not found" % (name,
+                                                   vg_name, origin_name))
+                        continue
+
+                    log.debug("adding %dMB to %s snapshot total"
+                                % (lv_sizes[index], origin.name))
+                    origin.snapshotSpace += lv_sizes[index]
+                    continue
+                elif lv_attr[index][0] in 'Iil':
+                    # skip mirror images and log volumes
+                    continue
+
+                log_size = 0
+                if lv_attr[index][0] in 'Mm':
+                    stripes = 0
+                    # identify mirror stripes/copies and mirror logs
+                    for (j, _lvname) in enumerate(lv_names):
+                        if lv_attr[j][0] not in 'Iil':
+                            continue
+
+                        if _lvname == "[%s_mlog]" % lv_name:
+                            log_size = lv_sizes[j]
+                        elif _lvname.startswith("[%s_mimage_" % lv_name):
+                            stripes += 1
+                else:
+                    stripes = 1
+
+                lv_dev = self.getDeviceByName(name)
+                if lv_dev is None:
+                    lv_uuid = lv_uuids[index]
+                    lv_size = lv_sizes[index]
+                    lv_device = LVMLogicalVolumeDevice(lv_name,
+                                                       vg_device,
+                                                       uuid=lv_uuid,
+                                                       size=lv_size,
+                                                       stripes=stripes,
+                                                       logSize=log_size,
+                                                       exists=True)
+                    self._addDevice(lv_device)
+
+                    try:
+                        lv_device.setup()
+                    except DeviceError as (msg, name):
+                        log.info("setup of %s failed: %s"
+                                            % (lv_device.name, msg))
+
+    def handleUdevMDMemberFormat(self, info, device):
+        log_method_call(self, name=device.name, type=device.format.type)
+        # either look up or create the array device
+        name = udev_device_get_name(info)
+        sysfs_path = udev_device_get_sysfs_path(info)
+
+        if udev_device_is_biosraid(info):
+            # this will prevent display of the member devices in the UI
+            device.format.biosraid = True
+
+        md_array = self.getDeviceByUuid(device.format.mdUuid)
+        if device.format.mdUuid and md_array:
+            md_array._addDevice(device)
+        else:
+            # create the array with just this one member
+            # FIXME: why does this exact block appear twice?
+            try:
+                # level is reported as, eg: "raid1"
+                md_level = udev_device_get_md_level(info)
+                md_devices = int(udev_device_get_md_devices(info))
+                md_uuid = udev_device_get_md_uuid(info)
+            except (KeyError, ValueError) as e:
+                log.warning("invalid data for %s: %s" % (name, e))
+                return
+
+            # try to name the array based on the preferred minor
+            md_info = devicelibs.mdraid.mdexamine(device.path)
+            md_path = md_info.get("device", "")
+            md_name = devicePathToName(md_info.get("device", ""))
+            if md_name:
+                try:
+                    minor = int(md_name[2:])     # strip off leading "md"
+                except (IndexError, ValueError):
+                    minor = None
+                    md_name = None
+                else:
+                    array = self.getDeviceByName(md_name)
+                    if array and array.uuid != md_uuid:
+                        md_name = None
+
+            if not md_name:
+                # if we don't have a name yet, find the first unused minor
+                minor = 0
+                while True:
+                    if self.getDeviceByName("md%d" % minor):
+                        minor += 1
+                    else:
+                        break
+
+                md_name = "md%d" % minor
+
+            log.debug("using name %s for md array containing member %s"
+                        % (md_name, device.name))
+            md_array = MDRaidArrayDevice(md_name,
+                                         level=md_level,
+                                         minor=minor,
+                                         memberDevices=md_devices,
+                                         uuid=md_uuid,
+                                         sysfsPath=sysfs_path,
+                                         exists=True)
+            md_array._addDevice(device)
+            self._addDevice(md_array)
+
+    def handleMultipathMemberFormat(self, info, device):
+        log_method_call(self, name=device.name, type=device.format.type)
+
+        name = udev_device_get_multipath_name(info)
+        if self.__multipaths.has_key(name):
+            mp = self.__multipaths[name]
+            mp.addParent(device)
+        else:
+            mp = MultipathDevice(name, info, parents=[device])
+            self.__multipaths[name] = mp
+
+    def handleUdevDMRaidMemberFormat(self, info, device):
+        log_method_call(self, name=device.name, type=device.format.type)
+        name = udev_device_get_name(info)
+        sysfs_path = udev_device_get_sysfs_path(info)
+        uuid = udev_device_get_uuid(info)
+        major = udev_device_get_major(info)
+        minor = udev_device_get_minor(info)
+
+        def _all_ignored(rss):
+            retval = True
+            for rs in rss:
+                if rs.name not in self._ignoredDisks:
+                    retval = False
+                    break
+            return retval
+
+        # Have we already created the DMRaidArrayDevice?
+        rss = block.getRaidSetFromRelatedMem(uuid=uuid, name=name,
+                                            major=major, minor=minor)
+        if len(rss) == 0:
+            # we ignore the device in the hope that all the devices
+            # from this set will be ignored.
+            self.unusedRaidMembers.append(device.name)
+            self.addIgnoredDisk(device.name)
+            return
+
+        # We ignore the device if all the rss are in self._ignoredDisks
+        if _all_ignored(rss):
+            self.addIgnoredDisk(device.name)
+            return
+
+        for rs in rss:
+            dm_array = self.getDeviceByName(rs.name)
+            if dm_array is not None:
+                # We add the new device.
+                dm_array._addDevice(device)
+            else:
+                # Activate the Raid set.
+                rs.activate(mknod=True)
+                dm_array = DMRaidArrayDevice(rs.name,
+                                             raidSet=rs,
+                                             parents=[device])
+
+                self._addDevice(dm_array)
+
+                # Wait for udev to scan the just created nodes, to avoid a race
+                # with the udev_get_block_device() call below.
+                udev_settle()
+
+                # Get the DMRaidArrayDevice a DiskLabel format *now*, in case
+                # its partitions get scanned before it does.
+                dm_array.updateSysfsPath()
+                dm_array_info = udev_get_block_device(dm_array.sysfsPath)
+                self.handleUdevDiskLabelFormat(dm_array_info, dm_array)
+
+                # Use the rs's object on the device.
+                # pyblock can return the memebers of a set and the
+                # device has the attribute to hold it.  But ATM we
+                # are not really using it. Commenting this out until
+                # we really need it.
+                #device.format.raidmem = block.getMemFromRaidSet(dm_array,
+                #        major=major, minor=minor, uuid=uuid, name=name)
+
+    def handleUdevDeviceFormat(self, info, device):
+        log_method_call(self, name=getattr(device, "name", None))
+        name = udev_device_get_name(info)
+        sysfs_path = udev_device_get_sysfs_path(info)
+        uuid = udev_device_get_uuid(info)
+        label = udev_device_get_label(info)
+        format_type = udev_device_get_format(info)
+        serial = udev_device_get_serial(info)
+
+        # Now, if the device is a disk, see if there is a usable disklabel.
+        # If not, see if the user would like to create one.
+        # XXX ignore disklabels on multipath or biosraid member disks
+        if not udev_device_is_biosraid(info) and \
+           not udev_device_is_multipath_member(info):
+            self.handleUdevDiskLabelFormat(info, device)
+            if device.partitioned or self.isIgnored(info) or \
+               (not device.partitionable and
+                device.format.type == "disklabel"):
+                # If the device has a disklabel, or the user chose not to
+                # create one, we are finished with this device. Otherwise
+                # it must have some non-disklabel formatting, in which case
+                # we fall through to handle that.
+                return
+
+        format = None
+        if (not device) or (not format_type) or device.format.type:
+            # this device has no formatting or it has already been set up
+            # FIXME: this probably needs something special for disklabels
+            log.debug("no type or existing type for %s, bailing" % (name,))
+            return
+
+        # set up the common arguments for the format constructor
+        args = [format_type]
+        kwargs = {"uuid": uuid,
+                  "label": label,
+                  "device": device.path,
+                  "serial": serial,
+                  "exists": True}
+
+        # set up type-specific arguments for the format constructor
+        if format_type == "multipath_member":
+            kwargs["multipath_members"] = self.getDevicesBySerial(serial)
+        elif format_type == "crypto_LUKS":
+            # luks/dmcrypt
+            kwargs["name"] = "luks-%s" % uuid
+        elif format_type in formats.mdraid.MDRaidMember._udevTypes:
+            # mdraid
+            try:
+                kwargs["mdUuid"] = udev_device_get_md_uuid(info)
+            except KeyError:
+                log.debug("mdraid member %s has no md uuid" % name)
+        elif format_type == "LVM2_member":
+            # lvm
+            try:
+                kwargs["vgName"] = udev_device_get_vg_name(info)
+            except KeyError as e:
+                log.debug("PV %s has no vg_name" % name)
+            try:
+                kwargs["vgUuid"] = udev_device_get_vg_uuid(info)
+            except KeyError:
+                log.debug("PV %s has no vg_uuid" % name)
+            try:
+                kwargs["peStart"] = udev_device_get_pv_pe_start(info)
+            except KeyError:
+                log.debug("PV %s has no pe_start" % name)
+        elif format_type == "vfat":
+            # efi magic
+            if isinstance(device, PartitionDevice) and device.bootable:
+                efi = formats.getFormat("efi")
+                if efi.minSize <= device.size <= efi.maxSize:
+                    args[0] = "efi"
+        elif format_type == "hfs":
+            # apple bootstrap magic
+            if isinstance(device, PartitionDevice) and device.bootable:
+                apple = formats.getFormat("appleboot")
+                if apple.minSize <= device.size <= apple.maxSize:
+                    args[0] = "appleboot"
+
+        try:
+            log.debug("type detected on '%s' is '%s'" % (name, format_type,))
+            device.format = formats.getFormat(*args, **kwargs)
+        except FSError:
+            log.debug("type '%s' on '%s' invalid, assuming no format" %
+                      (format_type, name,))
+            device.format = formats.DeviceFormat()
+            return
+
+        if shouldClear(device, self.clearPartType,
+                       clearPartDisks=self.clearPartDisks):
+            # if this is a device that will be cleared by clearpart,
+            # don't bother with format-specific processing
+            return
+
+        #
+        # now do any special handling required for the device's format
+        #
+        if device.format.type == "luks":
+            self.handleUdevLUKSFormat(info, device)
+        elif device.format.type == "mdmember":
+            self.handleUdevMDMemberFormat(info, device)
+        elif device.format.type == "dmraidmember":
+            self.handleUdevDMRaidMemberFormat(info, device)
+        elif device.format.type == "lvmpv":
+            self.handleUdevLVMPVFormat(info, device)
+        elif device.format.type == "multipath_member":
+            self.handleMultipathMemberFormat(info, device)
+
+    def updateDeviceFormat(self, device):
+        log.debug("updating format of device: %s" % device)
+        iutil.notify_kernel("/sys%s" % device.sysfsPath)
+        udev_settle()
+        info = udev_get_device(device.sysfsPath)
+        self.handleUdevDeviceFormat(info, device)
+        if device.format.type:
+            log.debug("got format: %s" % device.format)
+
+    def _handleInconsistencies(self):
+        def reinitializeVG(vg):
+            # First we remove VG data
+            try:
+                vg.destroy()
+            except DeviceError:
+                # the pvremoves will finish the job.
+                log.debug("There was an error destroying the VG %s." % vg.name)
+
+            # remove VG device from list.
+            self._removeDevice(vg)
+
+            for parent in vg.parents:
+                parent.format.destroy()
+
+                # Give the vg the a default format
+                kwargs = {"device": parent.path,
+                          "exists": parent.exists}
+                parent.format = formats.getFormat(*[""], **kwargs)
+
+        def leafInconsistencies(device):
+            if device.type == "lvmvg":
+                if device.complete:
+                    return
+
+                paths = []
+                for parent in device.parents:
+                    paths.append(parent.path)
+
+                # if zeroMbr is true don't ask.
+                if (self.zeroMbr or
+                    self.intf.questionReinitInconsistentLVM(pv_names=paths,
+                                                            vg_name=device.name)):
+                    reinitializeVG(device)
+                else:
+                    # The user chose not to reinitialize.
+                    # hopefully this will ignore the vg components too.
+                    self._removeDevice(device)
+                    lvm.lvm_cc_addFilterRejectRegexp(device.name)
+                    lvm.blacklistVG(device.name)
+                    for parent in device.parents:
+                        if parent.type == "partition":
+                            self.immutableDevices.append([parent.name,
+                                _("This partition is part of an inconsistent LVM Volume Group.")])
+                        else:
+                            self._removeDevice(parent, moddisk=False)
+                            self.addIgnoredDisk(parent.name)
+                        lvm.lvm_cc_addFilterRejectRegexp(parent.name)
+
+            elif device.type == "lvmlv":
+                # we might have already fixed this.
+                if device not in self._devices or \
+                        device.name in self._ignoredDisks:
+                    return
+                if device.complete:
+                    return
+
+                paths = []
+                for parent in device.vg.parents:
+                    paths.append(parent.path)
+
+                if (self.zeroMbr or
+                    self.intf.questionReinitInconsistentLVM(pv_names=paths,
+                                                            lv_name=device.name)):
+
+                    # destroy all lvs.
+                    for lv in device.vg.lvs:
+                        try:
+                            # reinitializeVG should clean up if necessary
+                            lv.destroy()
+                        except StorageError as e:
+                            log.info("error removing lv %s from "
+                                     "inconsistent/incomplete vg %s"
+                                     % (lv.lvname, device.vg.name))
+                        device.vg._removeLogVol(lv)
+                        self._removeDevice(lv)
+
+                    reinitializeVG(device.vg)
+                else:
+                    # ignore all the lvs.
+                    for lv in device.vg.lvs:
+                        self._removeDevice(lv)
+                        lvm.lvm_cc_addFilterRejectRegexp(lv.name)
+                    # ignore the vg
+                    self._removeDevice(device.vg)
+                    lvm.lvm_cc_addFilterRejectRegexp(device.vg.name)
+                    lvm.blacklistVG(device.vg.name)
+                    # ignore all the pvs
+                    for parent in device.vg.parents:
+                        if parent.type == "partition":
+                            self.immutableDevices.append([parent.name,
+                                _("This partition is part of an inconsistent LVM Volume Group.")])
+                        else:
+                            self._removeDevice(parent, moddisk=False)
+                            self.addIgnoredDisk(parent.name)
+                        lvm.lvm_cc_addFilterRejectRegexp(parent.name)
+
+        # Address the inconsistencies present in the tree leaves.
+        for leaf in self.leaves:
+            leafInconsistencies(leaf)
+
+        # Check for unused BIOS raid members, unused dmraid members are added
+        # to self.unusedRaidMembers as they are processed, extend this list
+        # with unused mdraid BIOS raid members
+        for c in self.getDevicesByType("mdcontainer"):
+            if c.kids == 0:
+                self.unusedRaidMembers.extend(map(lambda m: m.name, c.devices))
+
+        self.intf.unusedRaidMembersWarning(self.unusedRaidMembers)
+
+    def populate(self):
+        """ Locate all storage devices. """
+
+        # mark the tree as unpopulated so exception handlers can tell the
+        # exception originated while finding storage devices
+        self.populated = False
+
+        # resolve the protected device specs to device names
+        for spec in self.protectedDevSpecs:
+            name = udev_resolve_devspec(spec)
+            if name:
+                self.protectedDevNames.append(name)
+
+        # FIXME: the backing dev for the live image can't be used as an
+        # install target.  note that this is a little bit of a hack
+        # since we're assuming that /dev/live will exist
+        if os.path.exists("/dev/live") and \
+           stat.S_ISBLK(os.stat("/dev/live")[stat.ST_MODE]):
+            livetarget = devicePathToName(os.path.realpath("/dev/live"))
+            log.info("%s looks to be the live device; marking as protected"
+                     % (livetarget,))
+            self.protectedDevNames.append(livetarget)
+
+        # First iteration - let's just look for disks.
+        old_devices = {}
+
+        devices = udev_get_block_devices()
+        for dev in devices:
+            old_devices[dev['name']] = dev
+
+        cfg = self.__multipathConfigWriter.write()
+        open("/etc/multipath.conf", "w+").write(cfg)
+        del cfg
+
+        (singles, mpaths, partitions) = devicelibs.mpath.identifyMultipaths(devices)
+        devices = singles + reduce(list.__add__, mpaths, []) + partitions
+        log.info("devices to scan: %s" % [d['name'] for d in devices])
+        for dev in devices:
+            self.addUdevDevice(dev)
+
+        # Having found all the disks, we can now find all the multipaths built
+        # upon them.
+        whitelist = []
+        mpaths = self.__multipaths.values()
+        mpaths.sort(key=lambda d: d.name)
+        for mp in mpaths:
+            log.info("adding mpath device %s" % mp.name)
+            mp.setup()
+            whitelist.append(mp.name)
+            for p in mp.parents:
+                whitelist.append(p.name)
+            self.__multipathConfigWriter.addMultipathDevice(mp)
+            self._addDevice(mp)
+        for d in self.devices:
+            if not d.name in whitelist:
+                self.__multipathConfigWriter.addBlacklistDevice(d)
+        cfg = self.__multipathConfigWriter.write()
+        open("/etc/multipath.conf", "w+").write(cfg)
+        del cfg
+
+        # Now, loop and scan for devices that have appeared since the two above
+        # blocks or since previous iterations.
+        while True:
+            devices = []
+            new_devices = udev_get_block_devices()
+
+            for new_device in new_devices:
+                if not old_devices.has_key(new_device['name']):
+                    old_devices[new_device['name']] = new_device
+                    devices.append(new_device)
+
+            if len(devices) == 0:
+                # nothing is changing -- we are finished building devices
+                break
+
+            log.info("devices to scan: %s" % [d['name'] for d in devices])
+            for dev in devices:
+                self.addUdevDevice(dev)
+
+        self.populated = True
+
+        # After having the complete tree we make sure that the system
+        # inconsistencies are ignored or resolved.
+        self._handleInconsistencies()
+
+        self.teardownAll()
+        try:
+            os.unlink("/etc/mdadm.conf")
+        except OSError:
+            log.info("failed to unlink /etc/mdadm.conf")
+
+    def teardownAll(self):
+        """ Run teardown methods on all devices. """
+        for device in self.leaves:
+            try:
+                device.teardown(recursive=True)
+            except StorageError as e:
+                log.info("teardown of %s failed: %s" % (device.name, e))
+
+    def setupAll(self):
+        """ Run setup methods on all devices. """
+        for device in self.leaves:
+            try:
+                device.setup()
+            except DeviceError as (msg, name):
+                log.debug("setup of %s failed: %s" % (device.name, msg))
+
+    def getDeviceBySysfsPath(self, path):
+        if not path:
+            return None
+
+        found = None
+        for device in self._devices:
+            if device.sysfsPath == path:
+                found = device
+                break
+
+        return found
+
+    def getDeviceByUuid(self, uuid):
+        if not uuid:
+            return None
+
+        found = None
+        for device in self._devices:
+            if device.uuid == uuid:
+                found = device
+                break
+            elif device.format.uuid == uuid:
+                found = device
+                break
+
+        return found
+
+    def getDevicesBySerial(self, serial):
+        devices = []
+        for device in self._devices:
+            if not hasattr(device, "serial"):
+                log.warning("device %s has no serial attr" % device.name)
+                continue
+            if device.serial == serial:
+                devices.append(device)
+        return devices
+
+    def getDeviceByLabel(self, label):
+        if not label:
+            return None
+
+        found = None
+        for device in self._devices:
+            _label = getattr(device.format, "label", None)
+            if not _label:
+                continue
+
+            if _label == label:
+                found = device
+                break
+
+        return found
+
+    def getDeviceByName(self, name):
+        log.debug("looking for device '%s'..." % name)
+        if not name:
+            return None
+
+        found = None
+        for device in self._devices:
+            if device.name == name:
+                found = device
+                break
+            elif (device.type == "lvmlv" or device.type == "lvmvg") and \
+                    device.name == name.replace("--","-"):
+                found = device
+                break
+
+        log.debug("found %s" % found)
+        return found
+
+    def getDeviceByPath(self, path):
+        log.debug("looking for device '%s'..." % path)
+        if not path:
+            return None
+
+        found = None
+        for device in self._devices:
+            if device.path == path:
+                found = device
+                break
+            elif (device.type == "lvmlv" or device.type == "lvmvg") and \
+                    device.path == path.replace("--","-"):
+                found = device
+                break
+
+        log.debug("found %s" % found)
+        return found
+
+    def getDevicesByType(self, device_type):
+        # TODO: expand this to catch device format types
+        return [d for d in self._devices if d.type == device_type]
+
+    def getDevicesByInstance(self, device_class):
+        return [d for d in self._devices if isinstance(d, device_class)]
+
+    @property
+    def devices(self):
+        """ List of device instances """
+        devices = []
+        for device in self._devices:
+            if device.path in [d.path for d in devices] and \
+               not isinstance(device, NoDevice):
+                raise DeviceTreeError("duplicate paths in device tree")
+
+            devices.append(device)
+
+        return devices
+
+    @property
+    def filesystems(self):
+        """ List of filesystems. """
+        #""" Dict with mountpoint keys and filesystem values. """
+        filesystems = []
+        for dev in self.leaves:
+            if dev.format and getattr(dev.format, 'mountpoint', None):
+                filesystems.append(dev.format)
+
+        return filesystems
+
+    @property
+    def uuids(self):
+        """ Dict with uuid keys and Device values. """
+        uuids = {}
+        for dev in self._devices:
+            try:
+                uuid = dev.uuid
+            except AttributeError:
+                uuid = None
+
+            if uuid:
+                uuids[uuid] = dev
+
+            try:
+                uuid = dev.format.uuid
+            except AttributeError:
+                uuid = None
+
+            if uuid:
+                uuids[uuid] = dev
+
+        return uuids
+
+    @property
+    def labels(self):
+        """ Dict with label keys and Device values.
+
+            FIXME: duplicate labels are a possibility
+        """
+        labels = {}
+        for dev in self._devices:
+            if dev.format and getattr(dev.format, "label", None):
+                labels[dev.format.label] = dev
+
+        return labels
+
+    @property
+    def leaves(self):
+        """ List of all devices upon which no other devices exist. """
+        leaves = [d for d in self._devices if d.isleaf]
+        return leaves
+
+    def getChildren(self, device):
+        """ Return a list of a device's children. """
+        return [c for c in self._devices if device in c.parents]
+
+    def resolveDevice(self, devspec, blkidTab=None, cryptTab=None):
+        # find device in the tree
+        device = None
+        if devspec.startswith("UUID="):
+            # device-by-uuid
+            uuid = devspec.partition("=")[2]
+            device = self.uuids.get(uuid)
+            if device is None:
+                log.error("failed to resolve device %s" % devspec)
+        elif devspec.startswith("LABEL="):
+            # device-by-label
+            label = devspec.partition("=")[2]
+            device = self.labels.get(label)
+            if device is None:
+                log.error("failed to resolve device %s" % devspec)
+        elif devspec.startswith("/dev/"):
+            # device path
+            device = self.getDeviceByPath(devspec)
+            if device is None:
+                if blkidTab:
+                    # try to use the blkid.tab to correlate the device
+                    # path with a UUID
+                    blkidTabEnt = blkidTab.get(devspec)
+                    if blkidTabEnt:
+                        log.debug("found blkid.tab entry for '%s'" % devspec)
+                        uuid = blkidTabEnt.get("UUID")
+                        if uuid:
+                            device = self.getDeviceByUuid(uuid)
+                            if device:
+                                devstr = device.name
+                            else:
+                                devstr = "None"
+                            log.debug("found device '%s' in tree" % devstr)
+                        if device and device.format and \
+                           device.format.type == "luks":
+                            map_name = device.format.mapName
+                            log.debug("luks device; map name is '%s'" % map_name)
+                            mapped_dev = self.getDeviceByName(map_name)
+                            if mapped_dev:
+                                device = mapped_dev
+
+                if device is None and cryptTab and \
+                   devspec.startswith("/dev/mapper/"):
+                    # try to use a dm-crypt mapping name to 
+                    # obtain the underlying device, possibly
+                    # using blkid.tab
+                    cryptTabEnt = cryptTab.get(devspec.split("/")[-1])
+                    if cryptTabEnt:
+                        luks_dev = cryptTabEnt['device']
+                        try:
+                            device = self.getChildren(luks_dev)[0]
+                        except IndexError as e:
+                            pass
+                elif device is None:
+                    # dear lvm: can we please have a few more device nodes
+                    #           for each logical volume?
+                    #           three just doesn't seem like enough.
+                    name = devspec[5:]      # strip off leading "/dev/"
+                    (vg_name, slash, lv_name) = name.partition("/")
+                    if lv_name and not "/" in lv_name:
+                        # looks like we may have one
+                        lv = "%s-%s" % (vg_name, lv_name)
+                        device = self.getDeviceByName(lv)
+
+        if device:
+            log.debug("resolved '%s' to '%s' (%s)" % (devspec, device.name, device.type))
+        else:
+            log.debug("failed to resolve '%s'" % devspec)
+        return device
diff --git a/pyanaconda/storage/errors.py b/pyanaconda/storage/errors.py
new file mode 100644
index 0000000..c4d4313
--- /dev/null
+++ b/pyanaconda/storage/errors.py
@@ -0,0 +1,153 @@
+# errors.py
+# Exception classes for anaconda's storage configuration module.
+#
+# Copyright (C) 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, or (at your option) any later version.
+# 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.
+#
+# Red Hat Author(s): Dave Lehman <dlehman@xxxxxxxxxx>
+#
+
+class StorageError(Exception):
+    pass
+
+# Device
+class DeviceError(StorageError):
+    pass
+
+class DeviceCreateError(DeviceError):
+    pass
+
+class DeviceDestroyError(DeviceError):
+    pass
+
+class DeviceResizeError(DeviceError):
+    pass
+
+class DeviceSetupError(DeviceError):
+    pass
+
+class DeviceTeardownError(DeviceError):
+    pass
+
+class DeviceUserDeniedFormatError(DeviceError):
+    pass
+
+# DeviceFormat
+class DeviceFormatError(StorageError):
+    pass
+
+class FormatCreateError(DeviceFormatError):
+    pass
+
+class FormatDestroyError(DeviceFormatError):
+    pass
+
+class FormatSetupError(DeviceFormatError):
+    pass
+
+class FormatTeardownError(DeviceFormatError):
+    pass
+
+class DMRaidMemberError(DeviceFormatError):
+    pass
+
+class MultipathMemberError(DeviceFormatError):
+    pass
+
+class FSError(DeviceFormatError):
+    pass
+
+class FSResizeError(FSError):
+    pass
+
+class FSMigrateError(FSError):
+    pass
+
+class LUKSError(DeviceFormatError):
+    pass
+
+class MDMemberError(DeviceFormatError):
+    pass
+
+class PhysicalVolumeError(DeviceFormatError):
+    pass
+
+class SwapSpaceError(DeviceFormatError):
+    pass
+
+class DiskLabelError(DeviceFormatError):
+    pass
+
+class InvalidDiskLabelError(DiskLabelError):
+    pass
+
+class DiskLabelCommitError(DiskLabelError):
+    pass
+
+# devicelibs
+class SwapError(StorageError):
+    pass
+
+class SuspendError(SwapError):
+    pass
+
+class OldSwapError(SwapError):
+    pass
+
+class UnknownSwapError(SwapError):
+    pass
+
+class MDRaidError(StorageError):
+    pass
+
+class DMError(StorageError):
+    pass
+
+class LVMError(StorageError):
+    pass
+
+class CryptoError(StorageError):
+    pass
+
+class MPathError(StorageError):
+    pass
+
+# DeviceTree
+class DeviceTreeError(StorageError):
+    pass
+
+# DeviceAction
+class DeviceActionError(StorageError):
+    pass
+
+# partitioning
+class PartitioningError(StorageError):
+    pass
+
+class PartitioningWarning(StorageError):
+    pass
+
+# udev
+class UdevError(StorageError):
+    pass
+
+# fstab
+class UnrecognizedFSTabEntryError(StorageError):
+    pass
+
+# dasd
+class DasdFormatError(StorageError):
+    pass
diff --git a/pyanaconda/storage/fcoe.py b/pyanaconda/storage/fcoe.py
new file mode 100644
index 0000000..e77caba
--- /dev/null
+++ b/pyanaconda/storage/fcoe.py
@@ -0,0 +1,164 @@
+#
+# fcoe.py - fcoe class
+#
+# Copyright (C) 2009  Red Hat, Inc.  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 as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# 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, see <http://www.gnu.org/licenses/>.
+#
+
+import os
+import iutil
+import isys
+import logging
+import time
+from flags import flags
+log = logging.getLogger("anaconda")
+
+import gettext
+_ = lambda x: gettext.ldgettext("anaconda", x)
+
+_fcoe_module_loaded = False
+
+def has_fcoe():
+    global _fcoe_module_loaded
+    if not _fcoe_module_loaded:
+        iutil.execWithRedirect("modprobe", [ "fcoe" ],
+                               stdout = "/dev/tty5", stderr="/dev/tty5")
+        _fcoe_module_loaded = True
+
+    return os.access("/sys/module/fcoe", os.X_OK)
+
+class fcoe(object):
+    """ FCoE utility class.
+
+        This class will automatically discover and connect to EDD configured
+        FCoE SAN's when the startup() method gets called. It can also be
+        used to manually configure FCoE SAN's through the addSan() method.
+
+        As this class needs to make sure certain things like starting fcoe
+        daemons and connecting to firmware discovered SAN's only happens once
+        and as it keeps a global list of all FCoE devices it is
+        implemented as a Singleton.
+    """
+
+    def __init__(self):
+        self.started = False
+        self.lldpadStarted = False
+        self.nics = []
+
+    # So that users can write fcoe() to get the singleton instance
+    def __call__(self):
+        return self
+
+    def _stabilize(self, intf = None):
+        if intf:
+            w = intf.waitWindow(_("Connecting to FCoE SAN"),
+                                _("Connecting to FCoE SAN"))
+
+        # I have no clue how long we need to wait, this ought to do the trick
+        time.sleep(10)
+        iutil.execWithRedirect("udevadm", [ "settle" ],
+                               stdout = "/dev/tty5", stderr="/dev/tty5")
+        if intf:
+            w.pop()
+
+    def _startEDD(self, intf = None):
+        rc = iutil.execWithCapture("/usr/libexec/fcoe/fcoe_edd.sh", [ "-i" ],
+                                   stderr="/dev/tty5")
+        if not rc.startswith("NIC="):
+            log.info("No FCoE EDD info found: %s" % rc)
+            return
+
+        (key, val) = rc.split("=", 1)
+        if val not in isys.getDeviceProperties():
+            log.error("Unknown FCoE NIC found in EDD: %s, ignoring" % val)
+            return
+
+        log.info("FCoE NIC found in EDD: %s" % val)
+        self.addSan(val, dcb=True, intf=intf)
+
+    def startup(self, intf = None):
+        if self.started:
+            return
+
+        if not has_fcoe():
+            return
+
+        self._startEDD(intf)
+        self.started = True
+
+    def _startLldpad(self):
+        if self.lldpadStarted:
+            return
+
+        iutil.execWithRedirect("lldpad", [ "-d" ],
+                               stdout = "/dev/tty5", stderr="/dev/tty5")
+        self.lldpadStarted = True
+
+    def addSan(self, nic, dcb=False, intf=None):
+        if not has_fcoe():
+            raise IOError, _("FCoE not available")
+
+        log.info("Activating FCoE SAN attached to %s, dcb: %s" % (nic, dcb))
+
+        iutil.execWithRedirect("ip", [ "link", "set", nic, "up" ],
+                               stdout = "/dev/tty5", stderr="/dev/tty5")
+
+        if dcb:
+            self._startLldpad()
+            iutil.execWithRedirect("dcbtool", [ "sc", nic, "dcb", "on" ],
+                               stdout = "/dev/tty5", stderr="/dev/tty5")
+            iutil.execWithRedirect("dcbtool", [ "sc", nic, "app:fcoe",
+                               "e:1", "a:1", "w:1" ],
+                               stdout = "/dev/tty5", stderr="/dev/tty5")
+            iutil.execWithRedirect("fipvlan", [ nic, "-c", "-s" ],
+                               stdout = "/dev/tty5", stderr="/dev/tty5")
+        else:
+            f = open("/sys/module/fcoe/parameters/create", "w")
+            f.write(nic)
+            f.close()
+
+        self._stabilize(intf)
+        self.nics.append((nic, dcb))
+
+    def writeKS(self, f):
+        # fixme plenty (including add ks support for fcoe in general)
+        return
+
+    def write(self, instPath, anaconda):
+        if not self.nics:
+            return
+
+        if not os.path.isdir(instPath + "/etc/fcoe"):
+            os.makedirs(instPath + "/etc/fcoe", 0755)
+
+        for nic, dcb in self.nics:
+            fd = os.open(instPath + "/etc/fcoe/cfg-" + nic,
+                         os.O_RDWR | os.O_CREAT)
+            os.write(fd, '# Created by anaconda\n')
+            os.write(fd, '# Enable/Disable FCoE service at the Ethernet port\n')
+            os.write(fd, 'FCOE_ENABLE="yes"\n')
+            os.write(fd, '# Indicate if DCB service is required at the Ethernet port\n')
+            if dcb:
+                os.write(fd, 'DCB_REQUIRED="yes"\n')
+            else:
+                os.write(fd, 'DCB_REQUIRED="no"\n')
+            os.close(fd)
+
+        return
+
+# Create FCoE singleton
+fcoe = fcoe()
+
+# vim:tw=78:ts=4:et:sw=4
diff --git a/pyanaconda/storage/formats/Makefile.am b/pyanaconda/storage/formats/Makefile.am
new file mode 100644
index 0000000..7ecaf07
--- /dev/null
+++ b/pyanaconda/storage/formats/Makefile.am
@@ -0,0 +1,24 @@
+# storage/formats/Makefile.am for anaconda
+#
+# Copyright (C) 2009  Red Hat, Inc.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License as published
+# by the Free Software Foundation; either version 2.1 of the License, or
+# (at your option) any later version.
+#
+# 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 Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+#
+# Author: David Cantrell <dcantrell@xxxxxxxxxx>
+
+pkgpyexecdir = $(pyexecdir)/py$(PACKAGE_NAME)
+storageformatsdir = $(pkgpyexecdir)/storage/formats
+storageformats_PYTHON = *.py
+
+MAINTAINERCLEANFILES = Makefile.in
diff --git a/pyanaconda/storage/formats/__init__.py b/pyanaconda/storage/formats/__init__.py
new file mode 100644
index 0000000..2decf4c
--- /dev/null
+++ b/pyanaconda/storage/formats/__init__.py
@@ -0,0 +1,403 @@
+# __init__.py
+# Entry point for anaconda storage formats subpackage.
+#
+# Copyright (C) 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, or (at your option) any later version.
+# 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.
+#
+# Red Hat Author(s): Dave Lehman <dlehman@xxxxxxxxxx>
+#
+
+import os
+
+from iutil import notify_kernel, get_sysfs_path_by_name
+from ..storage_log import log_method_call
+from ..errors import *
+from ..devicelibs.dm import dm_node_from_name
+
+import gettext
+_ = lambda x: gettext.ldgettext("anaconda", x)
+
+import logging
+log = logging.getLogger("storage")
+
+
+device_formats = {}
+def register_device_format(fmt_class):
+    if not issubclass(fmt_class, DeviceFormat):
+        raise ValueError("arg1 must be a subclass of DeviceFormat")
+
+    device_formats[fmt_class._type] = fmt_class
+    log.debug("registered device format class %s as %s" % (fmt_class.__name__,
+                                                           fmt_class._type))
+
+default_fstypes = ("ext4", "ext3", "ext2")
+def get_default_filesystem_type(boot=None):
+    import platform
+
+    if boot:
+        fstypes = [platform.getPlatform(None).defaultBootFSType]
+    else:
+        fstypes = default_fstypes
+
+    for fstype in fstypes:
+        try:
+            supported = get_device_format_class(fstype).supported
+        except AttributeError:
+            supported = None
+
+        if supported:
+            return fstype
+
+    raise DeviceFormatError("None of %s is supported by your kernel" % ",".join(fstypes))
+
+def getFormat(fmt_type, *args, **kwargs):
+    """ Return a DeviceFormat instance based on fmt_type and args.
+
+        Given a device format type and a set of constructor arguments,
+        return a DeviceFormat instance.
+
+        Return None if no suitable format class is found.
+
+        Arguments:
+
+            fmt_type -- the name of the format type (eg: 'ext3', 'swap')
+
+        Keyword Arguments:
+
+            The keyword arguments may vary according to the format type,
+            but here is the common set:
+
+            device -- path to the device on which the format resides
+            uuid -- the UUID of the (preexisting) formatted device
+            exists -- whether or not the format exists on the device            
+            
+    """
+    fmt_class = get_device_format_class(fmt_type)
+    fmt = None
+    if fmt_class:
+        fmt = fmt_class(*args, **kwargs)
+    try:
+        className = fmt.__class__.__name__
+    except AttributeError:
+        className = None
+    log.debug("getFormat('%s') returning %s instance" % (fmt_type, className))
+    return fmt
+
+def collect_device_format_classes():
+    """ Pick up all device format classes from this directory.
+
+        Note: Modules must call register_device_format(FormatClass) in
+              order for the format class to be picked up.
+    """
+    dir = os.path.dirname(__file__)
+    for module_file in os.listdir(dir):
+        # make sure we're not importing this module
+        if module_file.endswith(".py") and module_file != __file__:
+            mod_name = module_file[:-3]
+            # imputil is deprecated in python 2.6
+            try:
+                globals()[mod_name] = __import__(mod_name, globals(), locals(), [], -1)
+            except ImportError, e:
+                log.debug("import of device format module '%s' failed" % mod_name)
+
+def get_device_format_class(fmt_type):
+    """ Return an appropriate format class based on fmt_type. """
+    if not device_formats:
+        collect_device_format_classes()
+
+    fmt = device_formats.get(fmt_type)
+    if not fmt:
+        for fmt_class in device_formats.values():
+            if fmt_type and fmt_type == fmt_class._name:
+                fmt = fmt_class
+                break
+            elif fmt_type in fmt_class._udevTypes:
+                fmt = fmt_class
+                break
+
+    # default to no formatting, AKA "Unknown"
+    if not fmt:
+        fmt = DeviceFormat
+
+    return fmt
+
+class DeviceFormat(object):
+    """ Generic device format. """
+    _type = None
+    _name = "Unknown"
+    _udevTypes = []
+    partedFlag = None
+    partedSystem = None
+    _formattable = False                # can be formatted
+    _supported = False                  # is supported
+    _linuxNative = False                # for clearpart
+    _packages = []                      # required packages
+    _resizable = False                  # can be resized
+    _bootable = False                   # can be used as boot
+    _migratable = False                 # can be migrated
+    _maxSize = 0                        # maximum size in MB
+    _minSize = 0                        # minimum size in MB
+    _dump = False
+    _check = False
+    _hidden = False                     # hide devices with this formatting?
+
+    def __init__(self, *args, **kwargs):
+        """ Create a DeviceFormat instance.
+
+            Keyword Arguments:
+
+                device -- path to the underlying device
+                uuid -- this format's UUID
+                exists -- indicates whether this is an existing format
+
+        """
+        self.device = kwargs.get("device")
+        self.uuid = kwargs.get("uuid")
+        self.exists = kwargs.get("exists")
+        self.options = kwargs.get("options")
+        self._migrate = False
+
+        # don't worry about existence if this is a DeviceFormat instance
+        #if self.__class__ is DeviceFormat:
+        #    self.exists = True
+
+    def __str__(self):
+        s = ("%(classname)s instance (%(id)s) --\n"
+             "  type = %(type)s  name = %(name)s  status = %(status)s\n"
+             "  device = %(device)s  uuid = %(uuid)s  exists = %(exists)s\n"
+             "  options = %(options)s  supported = %(supported)s"
+             "  formattable = %(format)s  resizable = %(resize)s\n" %
+             {"classname": self.__class__.__name__, "id": "%#x" % id(self),
+              "type": self.type, "name": self.name, "status": self.status,
+              "device": self.device, "uuid": self.uuid, "exists": self.exists,
+              "options": self.options, "supported": self.supported,
+              "format": self.formattable, "resize": self.resizable})
+        return s
+
+    @property
+    def dict(self):
+        d = {"type": self.type, "name": self.name, "device": self.device,
+             "uuid": self.uuid, "exists": self.exists,
+             "options": self.options, "supported": self.supported,
+             "resizable": self.resizable}
+        return d
+
+    def _setOptions(self, options):
+        self._options = options
+
+    def _getOptions(self):
+        return self._options
+
+    options = property(_getOptions, _setOptions)
+
+    def _setDevice(self, devspec):
+        if devspec and not devspec.startswith("/"):
+            raise ValueError("device must be a fully qualified path")
+        self._device = devspec
+
+    def _getDevice(self):
+        return self._device
+
+    device = property(lambda f: f._getDevice(),
+                      lambda f,d: f._setDevice(d),
+                      doc="Full path the device this format occupies")
+
+    @property
+    def name(self):
+        if self._name:
+            name = self._name
+        else:
+            name = self.type
+        return name
+
+    @property
+    def type(self):
+        return self._type
+
+    def probe(self):
+        log_method_call(self, device=self.device,
+                        type=self.type, status=self.status)
+
+    def notifyKernel(self):
+        log_method_call(self, device=self.device,
+                        type=self.type)
+        if not self.device:
+            return
+
+        if self.device.startswith("/dev/mapper/"):
+            try:
+                name = dm_node_from_name(os.path.basename(self.device))
+            except Exception, e:
+                log.warning("failed to get dm node for %s" % self.device)
+                return
+        elif self.device:
+            name = os.path.basename(self.device)
+
+        path = get_sysfs_path_by_name(name)
+        try:
+            notify_kernel(path, action="change")
+        except Exception, e:
+            log.warning("failed to notify kernel of change: %s" % e)
+
+
+    def create(self, *args, **kwargs):
+        log_method_call(self, device=self.device,
+                        type=self.type, status=self.status)
+        # allow late specification of device path
+        device = kwargs.get("device")
+        if device:
+            self.device = device
+
+        if not os.path.exists(self.device):
+            raise FormatCreateError("invalid device specification", self.device)
+
+    def destroy(self, *args, **kwargs):
+        log_method_call(self, device=self.device,
+                        type=self.type, status=self.status)
+        # zero out the 1MB at the beginning and end of the device in the
+        # hope that it will wipe any metadata from filesystems that
+        # previously occupied this device
+        log.debug("zeroing out beginning and end of %s..." % self.device)
+        fd = None
+
+        try:
+            fd = os.open(self.device, os.O_RDWR)
+            buf = '\0' * 1024 * 1024
+            os.write(fd, buf)
+            os.lseek(fd, -1024 * 1024, 2)
+            os.write(fd, buf)
+            os.close(fd)
+        except OSError as e:
+            if getattr(e, "errno", None) == 28: # No space left in device
+                pass
+            else:
+                log.error("error zeroing out %s: %s" % (self.device, e))
+
+            if fd:
+                os.close(fd)
+        except Exception as e:
+            log.error("error zeroing out %s: %s" % (self.device, e))
+            if fd:
+                os.close(fd)
+
+        self.exists = False
+
+    def setup(self, *args, **kwargs):
+        log_method_call(self, device=self.device,
+                        type=self.type, status=self.status)
+
+        if not self.exists:
+            raise FormatSetupError("format has not been created")
+
+        if self.status:
+            return
+
+        # allow late specification of device path
+        device = kwargs.get("device")
+        if device:
+            self.device = device
+
+        if not self.device or not os.path.exists(self.device):
+            raise FormatSetupError("invalid device specification")
+
+    def teardown(self, *args, **kwargs):
+        log_method_call(self, device=self.device,
+                        type=self.type, status=self.status)
+
+    @property
+    def status(self):
+        return (self.exists and
+                self.__class__ is not DeviceFormat and
+                isinstance(self.device, str) and
+                self.device and 
+                os.path.exists(self.device))
+
+    @property
+    def formattable(self):
+        """ Can we create formats of this type? """
+        return self._formattable
+
+    @property
+    def supported(self):
+        """ Is this format a supported type? """
+        return self._supported
+
+    @property
+    def packages(self):
+        """ Packages required to manage formats of this type. """
+        return self._packages
+
+    @property
+    def resizable(self):
+        """ Can formats of this type be resized? """
+        return self._resizable and self.exists
+
+    @property
+    def bootable(self):
+        """ Is this format type suitable for a boot partition? """
+        return self._bootable
+
+    @property
+    def migratable(self):
+        """ Can formats of this type be migrated? """
+        return self._migratable
+
+    @property
+    def migrate(self):
+        return self._migrate
+
+    @property
+    def linuxNative(self):
+        """ Is this format type native to linux? """
+        return self._linuxNative
+
+    @property
+    def mountable(self):
+        """ Is this something we can mount? """
+        return False
+
+    @property
+    def dump(self):
+        """ Whether or not this format will be dumped by dump(8). """
+        return self._dump
+
+    @property
+    def check(self):
+        """ Whether or not this format is checked on boot. """
+        return self._check
+
+    @property
+    def maxSize(self):
+        """ Maximum size (in MB) for this format type. """
+        return self._maxSize
+
+    @property
+    def minSize(self):
+        """ Minimum size (in MB) for this format type. """
+        return self._minSize
+
+    @property
+    def hidden(self):
+        """ Whether devices with this formatting should be hidden in UIs. """
+        return self._hidden
+
+    def writeKS(self, f):
+        return
+
+
+collect_device_format_classes()
+
+
diff --git a/pyanaconda/storage/formats/disklabel.py b/pyanaconda/storage/formats/disklabel.py
new file mode 100644
index 0000000..a76e452
--- /dev/null
+++ b/pyanaconda/storage/formats/disklabel.py
@@ -0,0 +1,356 @@
+# disklabel.py
+# Device format classes for anaconda's storage configuration module.
+#
+# Copyright (C) 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, or (at your option) any later version.
+# 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.
+#
+# Red Hat Author(s): Dave Lehman <dlehman@xxxxxxxxxx>
+#
+
+import os
+import copy
+
+from ..storage_log import log_method_call
+import parted
+import _ped
+import platform
+from ..errors import *
+from ..udev import udev_settle
+from . import DeviceFormat, register_device_format
+
+import gettext
+_ = lambda x: gettext.ldgettext("anaconda", x)
+
+import logging
+log = logging.getLogger("storage")
+
+
+class DiskLabel(DeviceFormat):
+    """ Disklabel """
+    _type = "disklabel"
+    _name = "partition table"
+    _formattable = True                # can be formatted
+    _supported = False                 # is supported
+
+    def __init__(self, *args, **kwargs):
+        """ Create a DiskLabel instance.
+
+            Keyword Arguments:
+
+                device -- path to the underlying device
+                exists -- indicates whether this is an existing format
+
+        """
+        log_method_call(self, *args, **kwargs)
+        DeviceFormat.__init__(self, *args, **kwargs)
+
+        self._size = None
+
+        self._partedDevice = None
+        self._partedDisk = None
+        self._origPartedDisk = None
+        self._alignment = None
+        self._endAlignment = None
+
+        if self.partedDevice:
+            # set up the parted objects and raise exception on failure
+            self._origPartedDisk = self.partedDisk.duplicate()
+
+    def __deepcopy__(self, memo):
+        """ Create a deep copy of a Disklabel instance.
+
+            We can't do copy.deepcopy on parted objects, which is okay.
+            For these parted objects, we just do a shallow copy.
+        """
+        new = self.__class__.__new__(self.__class__)
+        memo[id(self)] = new
+        shallow_copy_attrs = ('_partedDevice', '_partedDisk', '_origPartedDisk')
+        for (attr, value) in self.__dict__.items():
+            if attr in shallow_copy_attrs:
+                setattr(new, attr, copy.copy(value))
+            else:
+                setattr(new, attr, copy.deepcopy(value, memo))
+
+        return new
+
+    def __str__(self):
+        s = DeviceFormat.__str__(self)
+        s += ("  type = %(type)s  partition count = %(count)s"
+              "  sectorSize = %(sectorSize)s\n"
+              "  align_offset = %(offset)s  align_grain = %(grain)s\n"
+              "  partedDisk = %(disk)r\n"
+              "  origPartedDisk = %(orig_disk)r\n"
+              "  partedDevice = %(dev)r\n" %
+              {"type": self.labelType, "count": len(self.partitions),
+               "sectorSize": self.partedDevice.sectorSize,
+               "offset": self.alignment.offset,
+               "grain": self.alignment.grainSize,
+               "disk": self.partedDisk, "orig_disk": self._origPartedDisk,
+               "dev": self.partedDevice})
+        return s
+
+    @property
+    def dict(self):
+        d = super(DiskLabel, self).dict
+        d.update({"labelType": self.labelType,
+                  "partitionCount": len(self.partitions),
+                  "sectorSize": self.partedDevice.sectorSize,
+                  "offset": self.alignment.offset,
+                  "grainSize": self.alignment.grainSize})
+        return d
+
+    def resetPartedDisk(self):
+        """ Set this instance's partedDisk to reflect the disk's contents. """
+        log_method_call(self, device=self.device)
+        self._partedDisk = self._origPartedDisk
+
+    def freshPartedDisk(self):
+        """ Return a new, empty parted.Disk instance for this device. """
+        log_method_call(self, device=self.device)
+        platf = platform.getPlatform(None)
+        labelType = platf.diskLabelType(self.partedDevice.type)
+        return parted.freshDisk(device=self.partedDevice, ty=labelType)
+
+    @property
+    def partedDisk(self):
+        if not self._partedDisk:
+            if self.exists:
+                try:
+                    self._partedDisk = parted.Disk(device=self.partedDevice)
+                except (_ped.DiskLabelException, _ped.IOException,
+                        NotImplementedError) as e:
+                    raise InvalidDiskLabelError()
+
+                if self._partedDisk.type == "loop":
+                    # When the device has no partition table but it has a FS,
+                    # it will be created with label type loop.  Treat the
+                    # same as if the device had no label (cause it really
+                    # doesn't).
+                    raise InvalidDiskLabelError()
+            else:
+                self._partedDisk = self.freshPartedDisk()
+
+            # turn off cylinder alignment
+            if self._partedDisk.isFlagAvailable(parted.DISK_CYLINDER_ALIGNMENT):
+                self._partedDisk.unsetFlag(parted.DISK_CYLINDER_ALIGNMENT)
+
+        return self._partedDisk
+
+    @property
+    def partedDevice(self):
+        if not self._partedDevice and self.device and \
+           os.path.exists(self.device):
+            # We aren't guaranteed to be able to get a device.  In
+            # particular, built-in USB flash readers show up as devices but
+            # do not always have any media present, so parted won't be able
+            # to find a device.
+            try:
+                 self._partedDevice = parted.Device(path=self.device)
+            except (_ped.IOException, _ped.DeviceException):
+                 pass
+
+        return self._partedDevice
+
+    @property
+    def labelType(self):
+        """ The disklabel type (eg: 'gpt', 'msdos') """
+        return self.partedDisk.type
+
+    @property
+    def name(self):
+        return "%s (%s)" % (self._name, self.labelType.upper())
+
+    @property
+    def size(self):
+        size = self._size
+        if not size:
+            try:
+                size = self.partedDevice.getSize(unit="MB")
+            except Exception:
+                size = 0
+
+        return size
+
+    @property
+    def status(self):
+        """ Device status. """
+        return False
+
+    def setup(self, *args, **kwargs):
+        """ Open, or set up, a device. """
+        log_method_call(self, device=self.device,
+                        type=self.type, status=self.status)
+        if not self.exists:
+            raise DeviceFormatError("format has not been created")
+
+        if self.status:
+            return
+
+        DeviceFormat.setup(self, *args, **kwargs)
+
+    def teardown(self, *args, **kwargs):
+        """ Close, or tear down, a device. """
+        log_method_call(self, device=self.device,
+                        type=self.type, status=self.status)
+        if not self.exists:
+            raise DeviceFormatError("format has not been created")
+
+    def create(self, *args, **kwargs):
+        """ Create the device. """
+        log_method_call(self, device=self.device,
+                        type=self.type, status=self.status)
+        if self.exists:
+            raise DeviceFormatError("format already exists")
+
+        if self.status:
+            raise DeviceFormatError("device exists and is active")
+
+        DeviceFormat.create(self, *args, **kwargs)
+
+        # We're relying on someone having called resetPartedDisk -- we
+        # could ensure a fresh disklabel by setting self._partedDisk to
+        # None right before calling self.commit(), but that might hide
+        # other problems.
+        self.commit()
+        self.exists = True
+
+    def destroy(self, *args, **kwargs):
+        """ Wipe the disklabel from the device. """
+        log_method_call(self, device=self.device,
+                        type=self.type, status=self.status)
+        if not self.exists:
+            raise DeviceFormatError("format does not exist")
+
+        if not os.access(self.device, os.W_OK):
+            raise DeviceFormatError("device path does not exist")
+
+        self.partedDevice.clobber()
+        self.exists = False
+
+    def commit(self):
+        """ Commit the current partition table to disk and notify the OS. """
+        log_method_call(self, device=self.device,
+                        numparts=len(self.partitions))
+        try:
+            self.partedDisk.commit()
+        except parted.DiskException as msg:
+            raise DiskLabelCommitError(msg)
+        else:
+            udev_settle()
+
+    def commitToDisk(self):
+        """ Commit the current partition table to disk. """
+        log_method_call(self, device=self.device,
+                        numparts=len(self.partitions))
+        try:
+            self.partedDisk.commitToDevice()
+        except parted.DiskException as msg:
+            raise DiskLabelCommitError(msg)
+
+    def addPartition(self, *args, **kwargs):
+        partition = kwargs.get("partition", None)
+        if not partition:
+            partition = args[0]
+        geometry = partition.geometry
+        constraint = kwargs.get("constraint", None)
+        if not constraint and len(args) > 1:
+            constraint = args[1]
+        elif not constraint:
+            constraint = parted.Constraint(exactGeom=geometry)
+
+        new_partition = parted.Partition(disk=self.partedDisk,
+                                         type=partition.type,
+                                         geometry=geometry)
+        self.partedDisk.addPartition(partition=new_partition,
+                                     constraint=constraint)
+
+    def removePartition(self, partition):
+        self.partedDisk.removePartition(partition)
+
+    @property
+    def extendedPartition(self):
+        try:
+            extended = self.partedDisk.getExtendedPartition()
+        except Exception:
+            extended = None
+        return extended
+
+    @property
+    def logicalPartitions(self):
+        try:
+            logicals = self.partedDisk.getLogicalPartitions()
+        except Exception:
+            logicals = []
+        return logicals
+
+    @property
+    def firstPartition(self):
+        try:
+            part = self.partedDisk.getFirstPartition()
+        except Exception:
+            part = None
+        return part
+
+    @property
+    def partitions(self):
+        try:
+            parts = self.partedDisk.partitions
+        except Exception:
+            parts = []
+        return parts
+
+    @property
+    def alignment(self):
+        """ Alignment requirements for this device. """
+        if not self._alignment:
+            try:
+                disklabel_alignment = self.partedDisk.partitionAlignment
+            except _ped.CreateException:
+                disklabel_alignment = parted.Alignment(offset=0, grainSize=1)
+
+            try:
+                optimum_device_alignment = self.partedDevice.optimumAlignment
+            except _ped.CreateException:
+                optimum_device_alignment = None
+
+            try:
+                minimum_device_alignment = self.partedDevice.minimumAlignment
+            except _ped.CreateException:
+                minimum_device_alignment = None
+
+            try:
+                a = optimum_device_alignment.intersect(disklabel_alignment)
+            except (ArithmeticError, AttributeError):
+                try:
+                    a = minimum_device_alignment.intersect(disklabel_alignment)
+                except (ArithmeticError, AttributeError):
+                    a = disklabel_alignment
+
+            self._alignment = a
+
+        return self._alignment
+
+    @property
+    def endAlignment(self):
+        if not self._endAlignment:
+            self._endAlignment = parted.Alignment(
+                                        offset = self.alignment.offset - 1,
+                                        grainSize = self.alignment.grainSize)
+
+        return self._endAlignment
+
+register_device_format(DiskLabel)
+
diff --git a/pyanaconda/storage/formats/dmraid.py b/pyanaconda/storage/formats/dmraid.py
new file mode 100644
index 0000000..3d2ee86
--- /dev/null
+++ b/pyanaconda/storage/formats/dmraid.py
@@ -0,0 +1,114 @@
+# dmraid.py
+# dmraid device formats
+#
+# Copyright (C) 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, or (at your option) any later version.
+# 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.
+#
+# Red Hat Author(s): Dave Lehman <dlehman@xxxxxxxxxx>
+#
+
+from ..storage_log import log_method_call
+from flags import flags
+from ..errors import *
+from . import DeviceFormat, register_device_format
+
+import gettext
+_ = lambda x: gettext.ldgettext("anaconda", x)
+
+import logging
+log = logging.getLogger("storage")
+
+
+class DMRaidMember(DeviceFormat):
+    """ A dmraid member disk. """
+    _type = "dmraidmember"
+    _name = "dm-raid member device"
+    # XXX This looks like trouble.
+    #
+    #     Maybe a better approach is a RaidMember format with subclass
+    #     for MDRaidMember, letting all *_raid_member types fall through
+    #     to the generic RaidMember format, which is basically read-only.
+    #
+    #     One problem that presents is the possibility of someone passing
+    #     a dmraid member to the MDRaidArrayDevice constructor.
+    _udevTypes = ["adaptec_raid_member", "ddf_raid_member",
+                 "highpoint_raid_member", "isw_raid_member",
+                 "jmicron_raid_member", "lsi_mega_raid_member",
+                 "nvidia_raid_member", "promise_fasttrack_raid_member",
+                 "silicon_medley_raid_member", "via_raid_member"]
+    _formattable = False                # can be formatted
+    _supported = True                   # is supported
+    _linuxNative = False                # for clearpart
+    _packages = ["dmraid"]              # required packages
+    _resizable = False                  # can be resized
+    _bootable = False                   # can be used as boot 
+    _maxSize = 0                        # maximum size in MB
+    _minSize = 0                        # minimum size in MB
+    _hidden = True                      # hide devices with this formatting?
+
+    def __init__(self, *args, **kwargs):
+        """ Create a DeviceFormat instance.
+
+            Keyword Arguments:
+
+                device -- path to the underlying device
+                uuid -- this format's UUID
+                exists -- indicates whether this is an existing format
+
+            On initialization this format is like DeviceFormat
+
+        """
+        log_method_call(self, *args, **kwargs)
+        DeviceFormat.__init__(self, *args, **kwargs)
+
+        # Initialize the attribute that will hold the block object.
+        self._raidmem = None
+
+    def __str__(self):
+        s = DeviceFormat.__str__(self)
+        s += ("  raidmem = %(raidmem)r" % {"raidmem": self.raidmem})
+        return s
+
+    def _getRaidmem(self):
+        return self._raidmem
+
+    def _setRaidmem(self, raidmem):
+        self._raidmem = raidmem
+
+    raidmem = property(lambda d: d._getRaidmem(),
+                       lambda d,r: d._setRaidmem(r))
+
+    def create(self, *args, **kwargs):
+        log_method_call(self, device=self.device,
+                        type=self.type, status=self.status)
+        raise DMRaidMemberError("creation of dmraid members is non-sense")
+
+    def destroy(self, *args, **kwargs):
+        log_method_call(self, device=self.device,
+                        type=self.type, status=self.status)
+        raise DMRaidMemberError("destruction of dmraid members is non-sense")
+
+
+if not flags.cmdline.has_key("noiswmd"):
+    DMRaidMember._udevTypes.remove("isw_raid_member")
+
+# The anaconda cmdline has not been parsed yet when we're first imported,
+# so we can not use flags.dmraid here
+if flags.cmdline.has_key("nodmraid"):
+    DMRaidMember._udevTypes = []
+
+register_device_format(DMRaidMember)
+
diff --git a/pyanaconda/storage/formats/fs.py b/pyanaconda/storage/formats/fs.py
new file mode 100644
index 0000000..7377471
--- /dev/null
+++ b/pyanaconda/storage/formats/fs.py
@@ -0,0 +1,1488 @@
+# filesystems.py
+# Filesystem classes for anaconda's storage configuration module.
+#
+# Copyright (C) 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, or (at your option) any later version.
+# 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.
+#
+# Red Hat Author(s): Dave Lehman <dlehman@xxxxxxxxxx>
+#                    David Cantrell <dcantrell@xxxxxxxxxx>
+#
+
+""" Filesystem classes for use by anaconda.
+
+    TODO:
+        - migration
+        - bug 472127: allow creation of tmpfs filesystems (/tmp, /var/tmp, &c)
+"""
+import math
+import os
+import sys
+import tempfile
+import selinux
+import isys
+
+from ..errors import *
+from . import DeviceFormat, register_device_format
+import iutil
+from flags import flags
+from parted import fileSystemType
+from ..storage_log import log_method_call
+
+import logging
+log = logging.getLogger("storage")
+
+import gettext
+_ = lambda x: gettext.ldgettext("anaconda", x)
+
+try:
+    lost_and_found_context = selinux.matchpathcon("/lost+found", 0)[1]
+except OSError:
+    lost_and_found_context = None
+
+fs_configs = {}
+
+def get_kernel_filesystems():
+    fs_list = []
+    for line in open("/proc/filesystems").readlines():
+        fs_list.append(line.split()[-1])
+    return fs_list
+
+global kernel_filesystems
+kernel_filesystems = get_kernel_filesystems()
+
+def fsConfigFromFile(config_file):
+    """ Generate a set of attribute name/value pairs with which a
+        filesystem type can be defined.
+
+        The following config file would define a filesystem identical to
+        the static Ext3FS class definition:
+
+            type = ext3
+            mkfs = "mke2fs"
+            resizefs = "resize2fs"
+            labelfs = "e2label"
+            fsck = "e2fsck"
+            packages = ["e2fsprogs"]
+            formattable = True
+            supported = True
+            resizable = True
+            bootable = True
+            linuxNative = True
+            maxSize = 8 * 1024 * 1024
+            minSize = 0
+            defaultFormatOptions = "-t ext3"
+            defaultMountOptions = "defaults"
+
+    """
+    # XXX NOTUSED
+    lines = open(config_file).readlines()
+    fs_attrs = {}
+    for line in lines:
+        (key, value) = [t.strip() for t in line.split("=")]
+        if not hasattr(FS, "_" + key):
+            print "invalid key: %s" % key
+            continue
+
+        fs_attrs[key] = value
+
+    if not fs_attrs.has_key("type"):
+        raise ValueError, _("filesystem configuration missing a type")
+
+    # XXX what's the policy about multiple configs for a given type?
+    fs_configs[fs_attrs['type']] = fs_attrs
+
+class FS(DeviceFormat):
+    """ Filesystem class. """
+    _type = "Abstract Filesystem Class"  # fs type name
+    _mountType = None                    # like _type but for passing to mount
+    _name = None
+    _mkfs = ""                           # mkfs utility
+    _modules = []                        # kernel modules required for support
+    _resizefs = ""                       # resize utility
+    _labelfs = ""                        # labeling utility
+    _fsck = ""                           # fs check utility
+    _fsckErrors = {}                     # fs check command error codes & msgs
+    _migratefs = ""                      # fs migration utility
+    _infofs = ""                         # fs info utility
+    _defaultFormatOptions = []           # default options passed to mkfs
+    _defaultMountOptions = ["defaults"]  # default options passed to mount
+    _defaultLabelOptions = []
+    _defaultCheckOptions = []
+    _defaultMigrateOptions = []
+    _defaultInfoOptions = []
+    _migrationTarget = None
+    _existingSizeFields = []
+    _fsProfileSpecifier = None           # mkfs option specifying fsprofile
+
+    def __init__(self, *args, **kwargs):
+        """ Create a FS instance.
+
+            Keyword Args:
+
+                device -- path to the device containing the filesystem
+                mountpoint -- the filesystem's mountpoint
+                label -- the filesystem label
+                uuid -- the filesystem UUID
+                mountopts -- mount options for the filesystem
+                size -- the filesystem's size in MiB
+                exists -- indicates whether this is an existing filesystem
+                
+        """
+        if self.__class__ is FS:
+            raise TypeError("FS is an abstract class.")
+
+        DeviceFormat.__init__(self, *args, **kwargs)
+        self.mountpoint = kwargs.get("mountpoint")
+        self.mountopts = kwargs.get("mountopts")
+        self.label = kwargs.get("label")
+        self.fsprofile = kwargs.get("fsprofile")
+
+        # filesystem size does not necessarily equal device size
+        self._size = kwargs.get("size", 0)
+        self._minInstanceSize = None    # min size of this FS instance
+        self._mountpoint = None     # the current mountpoint when mounted
+        if self.exists and self.supported:
+            self._size = self._getExistingSize()
+            foo = self.minSize      # force calculation of minimum size
+
+        self._targetSize = self._size
+
+        if self.supported:
+            self.loadModule()
+
+    def __str__(self):
+        s = DeviceFormat.__str__(self)
+        s += ("  mountpoint = %(mountpoint)s  mountopts = %(mountopts)s\n"
+              "  label = %(label)s  size = %(size)s"
+              "  targetSize = %(targetSize)s\n" %
+              {"mountpoint": self.mountpoint, "mountopts": self.mountopts,
+               "label": self.label, "size": self._size,
+               "targetSize": self.targetSize})
+        return s
+
+    @property
+    def dict(self):
+        d = super(FS, self).dict
+        d.update({"mountpoint": self.mountpoint, "size": self._size,
+                  "label": self.label, "targetSize": self.targetSize,
+                  "mountable": self.mountable,
+                  "migratable": self.migratable})
+        return d
+
+    def _setTargetSize(self, newsize):
+        """ Set a target size for this filesystem. """
+        if not self.exists:
+            raise FSError("filesystem has not been created")
+
+        if newsize is None:
+            # unset any outstanding resize request
+            self._targetSize = self._size
+            return
+
+        if not self.minSize <= newsize < self.maxSize:
+            raise ValueError("invalid target size request")
+
+        self._targetSize = newsize
+
+    def _getTargetSize(self):
+        """ Get this filesystem's target size. """
+        return self._targetSize
+
+    targetSize = property(_getTargetSize, _setTargetSize,
+                          doc="Target size for this filesystem")
+
+    def _getSize(self):
+        """ Get this filesystem's size. """
+        size = self._size
+        if self.resizable and self.targetSize != size:
+            size = self.targetSize
+        return size
+
+    size = property(_getSize, doc="This filesystem's size, accounting "
+                                  "for pending changes")
+
+    def _getExistingSize(self):
+        """ Determine the size of this filesystem.  Filesystem must
+            exist.  Each filesystem varies, but the general procedure
+            is to run the filesystem dump or info utility and read
+            the block size and number of blocks for the filesystem
+            and compute megabytes from that.
+
+            The loop that reads the output from the infofsProg is meant
+            to be simple, but take in to account variations in output.
+            The general procedure:
+                1) Capture output from infofsProg.
+                2) Iterate over each line of the output:
+                       a) Trim leading and trailing whitespace.
+                       b) Break line into fields split on ' '
+                       c) If line begins with any of the strings in
+                          _existingSizeFields, start at the end of
+                          fields and take the first one that converts
+                          to a long.  Store this in the values list.
+                       d) Repeat until the values list length equals
+                          the _existingSizeFields length.
+                3) If the length of the values list equals the length
+                   of _existingSizeFields, compute the size of this
+                   filesystem by multiplying all of the values together
+                   to get bytes, then convert to megabytes.  Return
+                   this value.
+                4) If we were unable to capture all fields, return 0.
+
+            The caller should catch exceptions from this method.  Any
+            exception raised indicates a need to change the fields we
+            are looking for, the command to run and arguments, or
+            something else.  If you catch an exception from this method,
+            assume the filesystem cannot be resized.
+        """
+        size = self._size
+
+        if self.infofsProg and self.mountable and self.exists and not size:
+            try:
+                values = []
+                argv = self._defaultInfoOptions + [ self.device ]
+
+                buf = iutil.execWithCapture(self.infofsProg, argv,
+                                            stderr="/dev/tty5")
+
+                for line in buf.splitlines():
+                    found = False
+
+                    line = line.strip()
+                    tmp = line.split(' ')
+                    tmp.reverse()
+
+                    for field in self._existingSizeFields:
+                        if line.startswith(field):
+                            for subfield in tmp:
+                                try:
+                                    values.append(long(subfield))
+                                    found = True
+                                    break
+                                except ValueError:
+                                    continue
+
+                        if found:
+                            break
+
+                    if len(values) == len(self._existingSizeFields):
+                        break
+
+                if len(values) != len(self._existingSizeFields):
+                    return 0
+
+                size = 1
+                for value in values:
+                    size *= value
+
+                # report current size as megabytes
+                size = math.floor(size / 1024.0 / 1024.0)
+            except Exception as e:
+                log.error("failed to obtain size of filesystem on %s: %s"
+                          % (self.device, e))
+
+        return size
+
+    @property
+    def currentSize(self):
+        """ The filesystem's current actual size. """
+        size = 0
+        if self.exists:
+            size = self._size
+        return float(size)
+
+    def _getFormatOptions(self, options=None):
+        argv = []
+        if options and isinstance(options, list):
+            argv.extend(options)
+        argv.extend(self.defaultFormatOptions)
+        if self._fsProfileSpecifier and self.fsprofile:
+            argv.extend([self._fsProfileSpecifier, self.fsprofile])
+        argv.append(self.device)
+        return argv
+    
+    def doFormat(self, *args, **kwargs):
+        """ Create the filesystem.
+
+            Arguments:
+
+                None
+
+            Keyword Arguments:
+
+                intf -- InstallInterface instance
+                options -- list of options to pass to mkfs
+
+        """
+        log_method_call(self, type=self.mountType, device=self.device,
+                        mountpoint=self.mountpoint)
+
+        intf = kwargs.get("intf")
+        options = kwargs.get("options")
+
+        if self.exists:
+            raise FormatCreateError("filesystem already exists", self.device)
+
+        if not self.formattable:
+            return
+
+        if not self.mkfsProg:
+            return
+
+        if self.exists:
+            return
+
+        if not os.path.exists(self.device):
+            raise FormatCreateError("device does not exist", self.device)
+
+        argv = self._getFormatOptions(options=options)
+
+        w = None
+        if intf:
+            w = intf.progressWindow(_("Formatting"),
+                                    _("Creating %s filesystem on %s")
+                                    % (self.type, self.device),
+                                    100, pulse = True)
+
+        try:
+            rc = iutil.execWithPulseProgress(self.mkfsProg,
+                                             argv,
+                                             stdout="/dev/tty5",
+                                             stderr="/dev/tty5",
+                                             progress=w)
+        except Exception as e:
+            raise FormatCreateError(e, self.device)
+        finally:
+            if w:
+                w.pop()
+
+        if rc:
+            raise FormatCreateError("format failed: %s" % rc, self.device)
+
+        self.exists = True
+        self.notifyKernel()
+
+        if self.label:
+            self.writeLabel(self.label)
+
+    def doMigrate(self, intf=None):
+        if not self.exists:
+            raise FSError("filesystem has not been created")
+
+        if not self.migratable or not self.migrate:
+            return
+
+        if not os.path.exists(self.device):
+            raise FSError("device does not exist")
+
+        # if journal already exists skip
+        if isys.ext2HasJournal(self.device):
+            log.info("Skipping migration of %s, has a journal already."
+                     % self.device)
+            return
+
+        argv = self._defaultMigrateOptions[:]
+        argv.append(self.device)
+        try:
+            rc = iutil.execWithRedirect(self.migratefsProg,
+                                        argv,
+                                        stdout = "/dev/tty5",
+                                        stderr = "/dev/tty5")
+        except Exception as e:
+            raise FSMigrateError("filesystem migration failed: %s" % e,
+                                 self.device)
+
+        if rc:
+            raise FSMigrateError("filesystem migration failed: %s" % rc,
+                                 self.device)
+
+        # the other option is to actually replace this instance with an
+        # instance of the new filesystem type.
+        self._type = self.migrationTarget
+
+    @property
+    def resizeArgs(self):
+        argv = [self.device, "%d" % (self.targetSize,)]
+        return argv
+
+    def doResize(self, *args, **kwargs):
+        """ Resize this filesystem to new size @newsize.
+
+            Arguments:
+
+                None
+
+            Keyword Arguments:
+
+                intf -- InstallInterface instance
+
+        """
+        intf = kwargs.get("intf")
+
+        if not self.exists:
+            raise FSResizeError("filesystem does not exist", self.device)
+
+        if not self.resizable:
+            raise FSResizeError("filesystem not resizable", self.device)
+
+        if self.targetSize == self.currentSize:
+            return
+
+        if not self.resizefsProg:
+            return
+
+        if not os.path.exists(self.device):
+            raise FSResizeError("device does not exist", self.device)
+
+        self.doCheck(intf=intf)
+
+        # The first minimum size can be incorrect if the fs was not
+        # properly unmounted. After doCheck the minimum size will be correct
+        # so run the check one last time and bump up the size if it was too
+        # small.
+        self._minInstanceSize = None
+        if self.targetSize < self.minSize:
+            self.targetSize = self.minSize
+            log.info("Minimum size changed, setting targetSize on %s to %s" \
+                     % (self.device, self.targetSize))
+
+        w = None
+        if intf:
+            w = intf.progressWindow(_("Resizing"),
+                                    _("Resizing filesystem on %s")
+                                    % (self.device,),
+                                    100, pulse = True)
+
+        try:
+            rc = iutil.execWithPulseProgress(self.resizefsProg,
+                                             self.resizeArgs,
+                                             stdout="/dev/tty5",
+                                             stderr="/dev/tty5",
+                                             progress=w)
+        except Exception as e:
+            raise FSResizeError(e, self.device)
+        finally:
+            if w:
+                w.pop()
+
+        if rc:
+            raise FSResizeError("resize failed: %s" % rc, self.device)
+
+        self.doCheck(intf=intf)
+
+        # XXX must be a smarter way to do this
+        self._size = self.targetSize
+        self.notifyKernel()
+
+    def _getCheckArgs(self):
+        argv = []
+        argv.extend(self.defaultCheckOptions)
+        argv.append(self.device)
+        return argv
+
+    def _fsckFailed(self, rc):
+        return False
+
+    def _fsckErrorMessage(self, rc):
+        return _("Unknown return code: %d.") % (rc,)
+
+    def doCheck(self, intf=None):
+        if not self.exists:
+            raise FSError("filesystem has not been created")
+
+        if not self.fsckProg:
+            return
+
+        if not os.path.exists(self.device):
+            raise FSError("device does not exist")
+
+        w = None
+        if intf:
+            w = intf.progressWindow(_("Checking"),
+                                    _("Checking filesystem on %s")
+                                    % (self.device),
+                                    100, pulse = True)
+
+        try:
+            rc = iutil.execWithPulseProgress(self.fsckProg,
+                                             self._getCheckArgs(),
+                                             stdout="/dev/tty5",
+                                             stderr="/dev/tty5",
+                                             progress = w)
+        except Exception as e:
+            raise FSError("filesystem check failed: %s" % e)
+        finally:
+            if w:
+                w.pop()
+
+        if self._fsckFailed(rc):
+            hdr = _("%(type)s filesystem check failure on %(device)s: ") % \
+                    {"type": self.type, "device": self.device}
+
+            msg = self._fsckErrorMessage(rc)
+
+            if intf:
+                help = _("Errors like this usually mean there is a problem "
+                         "with the filesystem that will require user "
+                         "interaction to repair.  Before restarting "
+                         "installation, reboot to rescue mode or another "
+                         "system that allows you to repair the filesystem "
+                         "interactively.  Restart installation after you "
+                         "have corrected the problems on the filesystem.")
+
+                intf.messageWindow(_("Unrecoverable Error"),
+                                   hdr + "\n\n" + msg + "\n\n" + help,
+                                   custom_icon='error')
+                sys.exit(0)
+            else:
+                raise FSError(hdr + msg)
+
+    def loadModule(self):
+        """Load whatever kernel module is required to support this filesystem."""
+        global kernel_filesystems
+
+        if not self._modules or self.mountType in kernel_filesystems:
+            return
+
+        for module in self._modules:
+            try:
+                rc = iutil.execWithRedirect("modprobe", [module],
+                                            stdout="/dev/tty5",
+                                            stderr="/dev/tty5")
+            except Exception as e:
+                log.error("Could not load kernel module %s: %s" % (module, e))
+                self._supported = False
+                return
+
+            if rc:
+                log.error("Could not load kernel module %s" % module)
+                self._supported = False
+                return
+
+        # If we successfully loaded a kernel module, for this filesystem, we
+        # also need to update the list of supported filesystems.
+        kernel_filesystems = get_kernel_filesystems()
+
+    def mount(self, *args, **kwargs):
+        """ Mount this filesystem.
+
+            Arguments:
+
+                None
+
+            Keyword Arguments:
+
+                options -- mount options (overrides all other option strings)
+                chroot -- prefix to apply to mountpoint
+                mountpoint -- mountpoint (overrides self.mountpoint)
+        """
+        options = kwargs.get("options", "")
+        chroot = kwargs.get("chroot", "/")
+        mountpoint = kwargs.get("mountpoint")
+
+        if not self.exists:
+            raise FSError("filesystem has not been created")
+
+        if not mountpoint:
+            mountpoint = self.mountpoint
+
+        if not mountpoint:
+            raise FSError("no mountpoint given")
+
+        if self.status:
+            return
+
+        if not isinstance(self, NoDevFS) and not os.path.exists(self.device):
+            raise FSError("device %s does not exist" % self.device)
+
+        # XXX os.path.join is FUBAR:
+        #
+        #         os.path.join("/mnt/foo", "/") -> "/"
+        #
+        #mountpoint = os.path.join(chroot, mountpoint)
+        chrootedMountpoint = os.path.normpath("%s/%s" % (chroot, mountpoint))
+        iutil.mkdirChain(chrootedMountpoint)
+        if flags.selinux:
+            ret = isys.resetFileContext(mountpoint, chroot)
+            log.info("set SELinux context for mountpoint %s to %s" \
+                     % (mountpoint, ret))
+
+        # passed in options override default options
+        if not options or not isinstance(options, str):
+            options = self.options
+
+        try: 
+            rc = isys.mount(self.device, chrootedMountpoint, 
+                            fstype=self.mountType,
+                            options=options,
+                            bindMount=isinstance(self, BindFS))
+        except Exception as e:
+            raise FSError("mount failed: %s" % e)
+
+        if rc:
+            raise FSError("mount failed: %s" % rc)
+
+        if flags.selinux and "ro" not in options.split(","):
+            ret = isys.resetFileContext(mountpoint, chroot)
+            log.info("set SELinux context for newly mounted filesystem "
+                     "root at %s to %s" %(mountpoint, ret))
+            isys.setFileContext("%s/lost+found" % mountpoint,
+                                lost_and_found_context, chroot)
+
+        self._mountpoint = chrootedMountpoint
+
+    def unmount(self):
+        """ Unmount this filesystem. """
+        if not self.exists:
+            raise FSError("filesystem has not been created")
+
+        if not self._mountpoint:
+            # not mounted
+            return
+
+        if not os.path.exists(self._mountpoint):
+            raise FSError("mountpoint does not exist")
+
+        rc = isys.umount(self._mountpoint, removeDir = False)
+        if rc:
+            raise FSError("umount failed")
+
+        self._mountpoint = None
+
+    def _getLabelArgs(self, label):
+        argv = []
+        argv.extend(self.defaultLabelOptions)
+        argv.extend([self.device, label])
+        return argv 
+
+    def writeLabel(self, label):
+        """ Create a label for this filesystem. """
+        if not self.exists:
+            raise FSError("filesystem has not been created")
+
+        if not self.labelfsProg:
+            return
+
+        if not os.path.exists(self.device):
+            raise FSError("device does not exist")
+
+        argv = self._getLabelArgs(label)
+        rc = iutil.execWithRedirect(self.labelfsProg,
+                                    argv,
+                                    stderr="/dev/tty5")
+        if rc:
+            raise FSError("label failed")
+
+        self.label = label
+        self.notifyKernel()
+
+    @property
+    def isDirty(self):
+        return False
+
+    @property
+    def mkfsProg(self):
+        """ Program used to create filesystems of this type. """
+        return self._mkfs
+
+    @property
+    def fsckProg(self):
+        """ Program used to check filesystems of this type. """
+        return self._fsck
+
+    @property
+    def resizefsProg(self):
+        """ Program used to resize filesystems of this type. """
+        return self._resizefs
+
+    @property
+    def labelfsProg(self):
+        """ Program used to manage labels for this filesystem type. """
+        return self._labelfs
+
+    @property
+    def migratefsProg(self):
+        """ Program used to migrate filesystems of this type. """
+        return self._migratefs
+
+    @property
+    def infofsProg(self):
+        """ Program used to get information for this filesystem type. """
+        return self._infofs
+
+    @property
+    def migrationTarget(self):
+        return self._migrationTarget
+
+    @property
+    def utilsAvailable(self):
+        # we aren't checking for fsck because we shouldn't need it
+        for prog in [self.mkfsProg, self.resizefsProg, self.labelfsProg,
+                     self.infofsProg]:
+            if not prog:
+                continue
+
+            if not filter(lambda d: os.access("%s/%s" % (d, prog), os.X_OK),
+                          os.environ["PATH"].split(":")):
+                return False
+
+        return True
+
+    @property
+    def supported(self):
+        log_method_call(self, supported=self._supported)
+        return self._supported and self.utilsAvailable
+
+    @property
+    def mountable(self):
+        canmount = (self.mountType in kernel_filesystems) or \
+                   (os.access("/sbin/mount.%s" % (self.mountType,), os.X_OK))
+        modpath = os.path.realpath(os.path.join("/lib/modules", os.uname()[2]))
+        modname = "%s.ko" % self.mountType
+
+        if not canmount and os.path.isdir(modpath):
+            for root, dirs, files in os.walk(modpath):
+                have = filter(lambda x: x.startswith(modname), files)
+                if len(have) == 1 and have[0].startswith(modname):
+                    return True
+
+        return canmount
+
+    @property
+    def resizable(self):
+        """ Can formats of this filesystem type be resized? """
+        return super(FS, self).resizable and self.utilsAvailable
+
+    @property
+    def defaultFormatOptions(self):
+        """ Default options passed to mkfs for this filesystem type. """
+        # return a copy to prevent modification
+        return self._defaultFormatOptions[:]
+
+    @property
+    def defaultMountOptions(self):
+        """ Default options passed to mount for this filesystem type. """
+        # return a copy to prevent modification
+        return self._defaultMountOptions[:]
+
+    @property
+    def defaultLabelOptions(self):
+        """ Default options passed to labeler for this filesystem type. """
+        # return a copy to prevent modification
+        return self._defaultLabelOptions[:]
+
+    @property
+    def defaultCheckOptions(self):
+        """ Default options passed to checker for this filesystem type. """
+        # return a copy to prevent modification
+        return self._defaultCheckOptions[:]
+
+    def _getOptions(self):
+        options = ",".join(self.defaultMountOptions)
+        if self.mountopts:
+            # XXX should we clobber or append?
+            options = self.mountopts
+        return options
+
+    def _setOptions(self, options):
+        self.mountopts = options
+
+    options = property(_getOptions, _setOptions)
+
+    def _isMigratable(self):
+        """ Can filesystems of this type be migrated? """
+        return bool(self._migratable and self.migratefsProg and
+                    filter(lambda d: os.access("%s/%s"
+                                               % (d, self.migratefsProg,),
+                                               os.X_OK),
+                           os.environ["PATH"].split(":")) and
+                    self.migrationTarget)
+
+    migratable = property(_isMigratable)
+
+    def _setMigrate(self, migrate):
+        if not migrate:
+            self._migrate = migrate
+            return
+
+        if self.migratable and self.exists:
+            self._migrate = migrate
+        else:
+            raise ValueError("cannot set migrate on non-migratable filesystem")
+
+    migrate = property(lambda f: f._migrate, lambda f,m: f._setMigrate(m))
+
+    @property
+    def type(self):
+        _type = self._type
+        if self.migrate:
+            _type = self.migrationTarget
+
+        return _type
+
+    @property
+    def mountType(self):
+        if not self._mountType:
+            self._mountType = self._type
+
+        return self._mountType
+
+    # These methods just wrap filesystem-specific methods in more
+    # generically named methods so filesystems and formatted devices
+    # like swap and LVM physical volumes can have a common API.
+    def create(self, *args, **kwargs):
+        if self.exists:
+            raise FSError("filesystem already exists")
+
+        DeviceFormat.create(self, *args, **kwargs)
+
+        return self.doFormat(*args, **kwargs)
+
+    def setup(self, *args, **kwargs):
+        """ Mount the filesystem.
+
+            The filesystem will be mounted at the directory indicated by
+            self.mountpoint.
+        """
+        return self.mount(**kwargs)
+
+    def teardown(self, *args, **kwargs):
+        return self.unmount(*args, **kwargs)
+
+    @property
+    def status(self):
+        # FIXME check /proc/mounts or similar
+        if not self.exists:
+            return False
+        return self._mountpoint is not None
+
+    def writeKS(self, f):
+        f.write("%s --fstype=%s" % (self.mountpoint, self.type))
+
+        if self.label:
+            f.write(" --label=\"%s\"" % self.label)
+
+
+class Ext2FS(FS):
+    """ ext2 filesystem. """
+    _type = "ext2"
+    _mkfs = "mke2fs"
+    _modules = ["ext2"]
+    _resizefs = "resize2fs"
+    _labelfs = "e2label"
+    _fsck = "e2fsck"
+    _fsckErrors = {4: _("File system errors left uncorrected."),
+                   8: _("Operational error."),
+                   16: _("Usage or syntax error."),
+                   32: _("e2fsck cancelled by user request."),
+                   128: _("Shared library error.")}
+    _packages = ["e2fsprogs"]
+    _formattable = True
+    _supported = True
+    _resizable = True
+    _bootable = True
+    _linuxNative = True
+    _maxSize = 8 * 1024 * 1024
+    _minSize = 0
+    _defaultFormatOptions = []
+    _defaultMountOptions = ["defaults"]
+    _defaultCheckOptions = ["-f", "-p", "-C", "0"]
+    _dump = True
+    _check = True
+    _migratable = True
+    _migrationTarget = "ext3"
+    _migratefs = "tune2fs"
+    _defaultMigrateOptions = ["-j"]
+    _infofs = "dumpe2fs"
+    _defaultInfoOptions = ["-h"]
+    _existingSizeFields = ["Block count:", "Block size:"]
+    _fsProfileSpecifier = "-T"
+    partedSystem = fileSystemType["ext2"]
+
+    def _fsckFailed(self, rc):
+        for errorCode in self._fsckErrors.keys():
+            if rc & errorCode:
+                return True
+        return False
+
+    def _fsckErrorMessage(self, rc):
+        msg = ''
+
+        for errorCode in self._fsckErrors.keys():
+            if rc & errorCode:
+                msg += "\n" + self._fsckErrors[errorCode]
+
+        return msg.strip()
+
+    def doMigrate(self, intf=None):
+        FS.doMigrate(self, intf=intf)
+        self.tuneFS()
+
+    def doFormat(self, *args, **kwargs):
+        FS.doFormat(self, *args, **kwargs)
+        self.tuneFS()
+
+    def tuneFS(self):
+        if not isys.ext2HasJournal(self.device):
+            # only do this if there's a journal
+            return
+
+        try:
+            rc = iutil.execWithRedirect("tune2fs",
+                                        ["-c0", "-i0",
+                                         "-ouser_xattr,acl", self.device],
+                                        stdout = "/dev/tty5",
+                                        stderr = "/dev/tty5")
+        except Exception as e:
+            log.error("failed to run tune2fs on %s: %s" % (self.device, e))
+
+    @property
+    def minSize(self):
+        """ Minimum size for this filesystem in MB. """
+        if self._minInstanceSize is None:
+            # try once in the beginning to get the minimum size for an
+            # existing filesystem.
+            size = self._minSize
+            blockSize = None
+
+            if self.exists and os.path.exists(self.device):
+                # get block size
+                buf = iutil.execWithCapture(self.infofsProg,
+                                            ["-h", self.device],
+                                            stderr="/dev/tty5")
+                for line in buf.splitlines():
+                    if line.startswith("Block size:"):
+                        blockSize = int(line.split(" ")[-1])
+                        break
+
+                if blockSize is None:
+                    raise FSError("failed to get block size for %s filesystem "
+                                  "on %s" % (self.mountType, self.device))
+
+                # get minimum size according to resize2fs
+                buf = iutil.execWithCapture(self.resizefsProg,
+                                            ["-P", self.device],
+                                            stderr="/dev/tty5")
+                for line in buf.splitlines():
+                    if "minimum size of the filesystem:" not in line:
+                        continue
+
+                    # line will look like:
+                    # Estimated minimum size of the filesystem: 1148649
+                    #
+                    # NOTE: The minimum size reported is in blocks.  Convert
+                    # to bytes, then megabytes, and finally round up.
+                    (text, sep, minSize) = line.partition(": ")
+                    size = long(minSize) * blockSize
+                    size = math.ceil(size / 1024.0 / 1024.0)
+                    break
+
+                if size is None:
+                    log.warning("failed to get minimum size for %s filesystem "
+                                "on %s" % (self.mountType, self.device))
+
+            self._minInstanceSize = size
+
+        return self._minInstanceSize
+
+    @property
+    def isDirty(self):
+        return isys.ext2IsDirty(self.device)
+
+    @property
+    def resizeArgs(self):
+        argv = ["-p", self.device, "%dM" % (self.targetSize,)]
+        return argv
+
+register_device_format(Ext2FS)
+
+
+class Ext3FS(Ext2FS):
+    """ ext3 filesystem. """
+    _type = "ext3"
+    _defaultFormatOptions = ["-t", "ext3"]
+    _migrationTarget = "ext4"
+    _modules = ["ext3"]
+    _defaultMigrateOptions = ["-O", "extents"]
+    partedSystem = fileSystemType["ext3"]
+
+    def _isMigratable(self):
+        """ Can filesystems of this type be migrated? """
+        return (flags.cmdline.has_key("ext4migrate") and
+                Ext2FS._isMigratable(self))
+
+    migratable = property(_isMigratable)
+
+register_device_format(Ext3FS)
+
+
+class Ext4FS(Ext3FS):
+    """ ext4 filesystem. """
+    _type = "ext4"
+    _defaultFormatOptions = ["-t", "ext4"]
+    _migratable = False
+    _modules = ["ext4"]
+    partedSystem = fileSystemType["ext4"]
+
+register_device_format(Ext4FS)
+
+
+class FATFS(FS):
+    """ FAT filesystem. """
+    _type = "vfat"
+    _mkfs = "mkdosfs"
+    _modules = ["vfat"]
+    _labelfs = "dosfslabel"
+    _fsck = "dosfsck"
+    _fsckErrors = {1: _("Recoverable errors have been detected or dosfsck has "
+                        "discovered an internal inconsistency."),
+                   2: _("Usage error.")}
+    _supported = True
+    _formattable = True
+    _maxSize = 1024 * 1024
+    _packages = [ "dosfstools" ]
+    _defaultMountOptions = ["umask=0077", "shortname=winnt"]
+    # FIXME this should be fat32 in some cases
+    partedSystem = fileSystemType["fat16"]
+
+    def _fsckFailed(self, rc):
+        if rc >= 1:
+            return True
+        return False
+
+    def _fsckErrorMessage(self, rc):
+        return self._fsckErrors[rc]
+
+register_device_format(FATFS)
+
+
+class EFIFS(FATFS):
+    _type = "efi"
+    _mountType = "vfat"
+    _modules = ["vfat"]
+    _name = "EFI System Partition"
+    _minSize = 50
+    _maxSize = 256
+    _bootable = True
+
+    @property
+    def supported(self):
+        import platform
+        p = platform.getPlatform(None)
+        return (isinstance(p, platform.EFI) and
+                p.isEfi and
+                self.utilsAvailable)
+
+register_device_format(EFIFS)
+
+
+class BTRFS(FS):
+    """ btrfs filesystem """
+    _type = "btrfs"
+    _mkfs = "mkfs.btrfs"
+    _modules = ["btrfs"]
+    _resizefs = "btrfsctl"
+    _formattable = True
+    _linuxNative = True
+    _bootable = False
+    _maxLabelChars = 256
+    _supported = False
+    _dump = True
+    _check = True
+    _packages = ["btrfs-progs"]
+    _maxSize = 16 * 1024 * 1024
+    # FIXME parted needs to be thaught about btrfs so that we can set the
+    # partition table type correctly for btrfs partitions
+    # partedSystem = fileSystemType["btrfs"]
+
+    def _getFormatOptions(self, options=None):
+        argv = []
+        if options and isinstance(options, list):
+            argv.extend(options)
+        argv.extend(self.defaultFormatOptions)
+        if self.label:
+            argv.extend(["-L", self.label])
+        argv.append(self.device)
+        return argv
+
+    @property
+    def resizeArgs(self):
+        argv = ["-r", "%dm" % (self.targetSize,), self.device]
+        return argv
+
+    @property
+    def supported(self):
+        """ Is this filesystem a supported type? """
+        supported = self._supported
+        if flags.cmdline.has_key("btrfs"):
+            supported = self.utilsAvailable
+
+        return supported
+
+register_device_format(BTRFS)
+
+
+class GFS2(FS):
+    """ gfs2 filesystem. """
+    _type = "gfs2"
+    _mkfs = "mkfs.gfs2"
+    _modules = ["dlm", "gfs2"]
+    _formattable = True
+    _defaultFormatOptions = ["-j", "1", "-p", "lock_nolock", "-O"]
+    _linuxNative = True
+    _supported = False
+    _dump = True
+    _check = True
+    _packages = ["gfs2-utils"]
+    # FIXME parted needs to be thaught about btrfs so that we can set the
+    # partition table type correctly for btrfs partitions
+    # partedSystem = fileSystemType["gfs2"]
+
+    @property
+    def supported(self):
+        """ Is this filesystem a supported type? """
+        supported = self._supported
+        if flags.cmdline.has_key("gfs2"):
+            supported = self.utilsAvailable
+
+        return supported
+
+register_device_format(GFS2)
+
+
+class JFS(FS):
+    """ JFS filesystem """
+    _type = "jfs"
+    _mkfs = "mkfs.jfs"
+    _modules = ["jfs"]
+    _labelfs = "jfs_tune"
+    _defaultFormatOptions = ["-q"]
+    _defaultLabelOptions = ["-L"]
+    _maxLabelChars = 16
+    _maxSize = 8 * 1024 * 1024
+    _formattable = True
+    _linuxNative = True
+    _supported = False
+    _dump = True
+    _check = True
+    _infofs = "jfs_tune"
+    _defaultInfoOptions = ["-l"]
+    _existingSizeFields = ["Aggregate block size:", "Aggregate size:"]
+    partedSystem = fileSystemType["jfs"]
+
+    @property
+    def supported(self):
+        """ Is this filesystem a supported type? """
+        supported = self._supported
+        if flags.cmdline.has_key("jfs"):
+            supported = self.utilsAvailable
+
+        return supported
+
+register_device_format(JFS)
+
+
+class ReiserFS(FS):
+    """ reiserfs filesystem """
+    _type = "reiserfs"
+    _mkfs = "mkreiserfs"
+    _resizefs = "resize_reiserfs"
+    _labelfs = "reiserfstune"
+    _modules = ["reiserfs"]
+    _defaultFormatOptions = ["-f", "-f"]
+    _defaultLabelOptions = ["-l"]
+    _maxLabelChars = 16
+    _maxSize = 16 * 1024 * 1024
+    _formattable = True
+    _linuxNative = True
+    _supported = False
+    _dump = True
+    _check = True
+    _packages = ["reiserfs-utils"]
+    _infofs = "debugreiserfs"
+    _defaultInfoOptions = []
+    _existingSizeFields = ["Count of blocks on the device:", "Blocksize:"]
+    partedSystem = fileSystemType["reiserfs"]
+
+    @property
+    def supported(self):
+        """ Is this filesystem a supported type? """
+        supported = self._supported
+        if flags.cmdline.has_key("reiserfs"):
+            supported = self.utilsAvailable
+
+        return supported
+
+    @property
+    def resizeArgs(self):
+        argv = ["-s", "%dM" % (self.targetSize,), self.device]
+        return argv
+
+register_device_format(ReiserFS)
+
+
+class XFS(FS):
+    """ XFS filesystem """
+    _type = "xfs"
+    _mkfs = "mkfs.xfs"
+    _modules = ["xfs"]
+    _labelfs = "xfs_admin"
+    _defaultFormatOptions = ["-f"]
+    _defaultLabelOptions = ["-L"]
+    _maxLabelChars = 16
+    _maxSize = 16 * 1024 * 1024
+    _formattable = True
+    _linuxNative = True
+    _supported = True
+    _dump = True
+    _check = True
+    _packages = ["xfsprogs"]
+    _infofs = "xfs_db"
+    _defaultInfoOptions = ["-c", "\"sb 0\"", "-c", "\"p dblocks\"",
+                           "-c", "\"p blocksize\""]
+    _existingSizeFields = ["dblocks =", "blocksize ="]
+    partedSystem = fileSystemType["xfs"]
+
+    def _getLabelArgs(self, label):
+        argv = []
+        argv.extend(self.defaultLabelOptions)
+        argv.extend([label, self.device])
+        return argv
+
+register_device_format(XFS)
+
+
+class HFS(FS):
+    _type = "hfs"
+    _mkfs = "hformat"
+    _modules = ["hfs"]
+    _formattable = True
+    partedSystem = fileSystemType["hfs"]
+
+register_device_format(HFS)
+
+
+class AppleBootstrapFS(HFS):
+    _type = "appleboot"
+    _mountType = "hfs"
+    _name = "Apple Bootstrap"
+    _bootable = True
+    _minSize = 800.00 / 1024.00
+    _maxSize = 1
+
+    @property
+    def supported(self):
+        import platform
+        return (isinstance(platform.getPlatform(None), platform.NewWorldPPC)
+                and self.utilsAvailable)
+
+    def writeKS(self, f):
+        f.write("appleboot --fstype=%s" % self.type)
+
+register_device_format(AppleBootstrapFS)
+
+
+# this doesn't need to be here
+class HFSPlus(FS):
+    _type = "hfs+"
+    _modules = ["hfsplus"]
+    _udevTypes = ["hfsplus"]
+    partedSystem = fileSystemType["hfs+"]
+
+register_device_format(HFSPlus)
+
+
+class NTFS(FS):
+    """ ntfs filesystem. """
+    _type = "ntfs"
+    _resizefs = "ntfsresize"
+    _fsck = "ntfsresize"
+    _resizable = True
+    _minSize = 1
+    _maxSize = 16 * 1024 * 1024
+    _defaultMountOptions = ["defaults", "ro"]
+    _defaultCheckOptions = ["-c"]
+    _packages = ["ntfsprogs"]
+    _infofs = "ntfsinfo"
+    _defaultInfoOptions = ["-m"]
+    _existingSizeFields = ["Cluster Size:", "Volume Size in Clusters:"]
+    partedSystem = fileSystemType["ntfs"]
+
+    def _fsckFailed(self, rc):
+        if rc != 0:
+            return True
+        return False
+
+    @property
+    def minSize(self):
+        """ The minimum filesystem size in megabytes. """
+        if self._minInstanceSize is None:
+            # we try one time to determine the minimum size.
+            size = self._minSize
+            if self.exists and os.path.exists(self.device):
+                minSize = None
+                buf = iutil.execWithCapture(self.resizefsProg,
+                                            ["-m", self.device],
+                                            stderr = "/dev/tty5")
+                for l in buf.split("\n"):
+                    if not l.startswith("Minsize"):
+                        continue
+                    try:
+                        min = l.split(":")[1].strip()
+                        minSize = int(min) + 250
+                    except Exception, e:
+                        minSize = None
+                        log.warning("Unable to parse output for minimum size on %s: %s" %(self.device, e))
+
+                if minSize is None:
+                    log.warning("Unable to discover minimum size of filesystem "
+                                "on %s" %(self.device,))
+                else:
+                    size = minSize
+
+            self._minInstanceSize = size
+
+        return self._minInstanceSize
+
+    @property
+    def resizeArgs(self):
+        # You must supply at least two '-f' options to ntfsresize or
+        # the proceed question will be presented to you.
+        argv = ["-ff", "-s", "%dM" % (self.targetSize,), self.device]
+        return argv
+
+
+register_device_format(NTFS)
+
+
+# if this isn't going to be mountable it might as well not be here
+class NFS(FS):
+    """ NFS filesystem. """
+    _type = "nfs"
+    _modules = ["nfs"]
+
+    def _deviceCheck(self, devspec):
+        if devspec is not None and ":" not in devspec:
+            raise ValueError("device must be of the form <host>:<path>")
+
+    @property
+    def mountable(self):
+        return False
+
+    def _setDevice(self, devspec):
+        self._deviceCheck(devspec)
+        self._device = devspec
+
+    def _getDevice(self):
+        return self._device
+
+    device = property(lambda f: f._getDevice(),
+                      lambda f,d: f._setDevice(d),
+                      doc="Full path the device this format occupies")
+ 
+register_device_format(NFS)
+
+
+class NFSv4(NFS):
+    """ NFSv4 filesystem. """
+    _type = "nfs4"
+    _modules = ["nfs4"]
+
+register_device_format(NFSv4)
+
+
+class Iso9660FS(FS):
+    """ ISO9660 filesystem. """
+    _type = "iso9660"
+    _formattable = False
+    _supported = True
+    _resizable = False
+    _bootable = False
+    _linuxNative = False
+    _dump = False
+    _check = False
+    _migratable = False
+    _defaultMountOptions = ["ro"]
+
+    def writeKS(self, f):
+        return
+
+register_device_format(Iso9660FS)
+
+
+class NoDevFS(FS):
+    """ nodev filesystem base class """
+    _type = "nodev"
+
+    def __init__(self, *args, **kwargs):
+        FS.__init__(self, *args, **kwargs)
+        self.exists = True
+        self.device = self.type
+
+    def _setDevice(self, devspec):
+        self._device = devspec
+
+    def _getExistingSize(self):
+        pass
+
+    def writeKS(self, f):
+        return
+
+register_device_format(NoDevFS)
+
+
+class DevPtsFS(NoDevFS):
+    """ devpts filesystem. """
+    _type = "devpts"
+    _defaultMountOptions = ["gid=5", "mode=620"]
+
+register_device_format(DevPtsFS)
+
+
+# these don't really need to be here
+class ProcFS(NoDevFS):
+    _type = "proc"
+
+register_device_format(ProcFS)
+
+
+class SysFS(NoDevFS):
+    _type = "sysfs"
+
+register_device_format(SysFS)
+
+
+class TmpFS(NoDevFS):
+    _type = "tmpfs"
+
+register_device_format(TmpFS)
+
+
+class BindFS(FS):
+    _type = "bind"
+
+    @property
+    def mountable(self):
+        return True
+
+    def _getExistingSize(self):
+        pass
+
+    def writeKS(self, f):
+        return
+
+register_device_format(BindFS)
+
+
diff --git a/pyanaconda/storage/formats/luks.py b/pyanaconda/storage/formats/luks.py
new file mode 100644
index 0000000..b164f14
--- /dev/null
+++ b/pyanaconda/storage/formats/luks.py
@@ -0,0 +1,352 @@
+# luks.py
+# Device format classes for anaconda's storage configuration module.
+#
+# Copyright (C) 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, or (at your option) any later version.
+# 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.
+#
+# Red Hat Author(s): Dave Lehman <dlehman@xxxxxxxxxx>
+#
+
+
+
+import os
+
+try:
+    import volume_key
+except ImportError:
+    volume_key = None
+
+from ..storage_log import log_method_call
+from ..errors import *
+from ..devicelibs import crypto
+from . import DeviceFormat, register_device_format
+
+import gettext
+_ = lambda x: gettext.ldgettext("anaconda", x)
+
+import logging
+log = logging.getLogger("storage")
+
+
+class LUKS(DeviceFormat):
+    """ A LUKS device. """
+    _type = "luks"
+    _name = "LUKS"
+    _lockedName = _("Encrypted")
+    _udevTypes = ["crypto_LUKS"]
+    _formattable = True                 # can be formatted
+    _supported = False                  # is supported
+    _linuxNative = True                 # for clearpart
+    _packages = ["cryptsetup-luks"]     # required packages
+
+    def __init__(self, *args, **kwargs):
+        """ Create a LUKS instance.
+
+            Keyword Arguments:
+
+                device -- the path to the underlying device
+                name -- the name of the mapped device
+                uuid -- this device's UUID
+                passphrase -- device passphrase (string)
+                key_file -- path to a file containing a key (string)
+                cipher -- cipher mode string
+                key_size -- key size in bits
+                exists -- indicates whether this is an existing format
+                escrow_cert -- certificate to use for key escrow
+                add_backup_passphrase -- generate a backup passphrase?
+        """
+        log_method_call(self, *args, **kwargs)
+        DeviceFormat.__init__(self, *args, **kwargs)
+        self.cipher = kwargs.get("cipher")
+        self.key_size = kwargs.get("key_size")
+        self.mapName = kwargs.get("name")
+
+        if not self.exists and not self.cipher:
+            self.cipher = "aes-xts-plain"
+            if not self.key_size:
+                # default to the max (512 bits) for aes-xts
+                self.key_size = 512
+
+        # FIXME: these should both be lists, but managing them will be a pain
+        self.__passphrase = kwargs.get("passphrase")
+        self._key_file = kwargs.get("key_file")
+        self.escrow_cert = kwargs.get("escrow_cert")
+        self.add_backup_passphrase = kwargs.get("add_backup_passphrase", False)
+
+        if not self.mapName and self.exists and self.uuid:
+            self.mapName = "luks-%s" % self.uuid
+        elif not self.mapName and self.device:
+            self.mapName = "luks-%s" % os.path.basename(self.device)
+
+    def __str__(self):
+        s = DeviceFormat.__str__(self)
+        if self.__passphrase:
+            passphrase = "(set)"
+        else:
+            passphrase = "(not set)"
+        s += ("  cipher = %(cipher)s  keySize = %(keySize)s"
+              "  mapName = %(mapName)s\n"
+              "  keyFile = %(keyFile)s  passphrase = %(passphrase)s\n"
+              "  escrowCert = %(escrowCert)s  addBackup = %(backup)s" %
+              {"cipher": self.cipher, "keySize": self.key_size,
+               "mapName": self.mapName, "keyFile": self._key_file,
+               "passphrase": passphrase, "escrowCert": self.escrow_cert,
+               "backup": self.add_backup_passphrase})
+        return s
+
+    @property
+    def dict(self):
+        d = super(LUKS, self).dict
+        d.update({"cipher": self.cipher, "keySize": self.key_size,
+                  "mapName": self.mapName, "hasKey": self.hasKey,
+                  "escrowCert": self.escrow_cert,
+                  "backup": self.add_backup_passphrase})
+        return d
+
+    @property
+    def name(self):
+        name = self._name
+        # for existing locked devices, show "Encrypted" instead of LUKS
+        if self.hasKey or not self.exists:
+            name = self._name
+        else:
+            name = "%s (%s)" % (self._lockedName, self._name)
+        return name
+
+    def _setPassphrase(self, passphrase):
+        """ Set the passphrase used to access this device. """
+        self.__passphrase = passphrase
+
+    passphrase = property(fset=_setPassphrase)
+
+    @property
+    def hasKey(self):
+        return ((self.__passphrase not in ["", None]) or
+                (self._key_file and os.access(self._key_file, os.R_OK)))
+
+    @property
+    def configured(self):
+        """ To be ready we need a key or passphrase and a map name. """
+        return self.hasKey and self.mapName
+
+    @property
+    def status(self):
+        if not self.exists or not self.mapName:
+            return False
+        return os.path.exists("/dev/mapper/%s" % self.mapName)
+
+    def probe(self):
+        """ Probe for any missing information about this format.
+
+            cipher mode, key size
+        """
+        raise NotImplementedError("probe method not defined for LUKS")
+
+    def setup(self, *args, **kwargs):
+        """ Open, or set up, the format. """
+        log_method_call(self, device=self.device, mapName=self.mapName,
+                        type=self.type, status=self.status)
+        if not self.configured:
+            raise LUKSError("luks device not configured")
+
+        if self.status:
+            return
+
+        DeviceFormat.setup(self, *args, **kwargs)
+        crypto.luks_open(self.device, self.mapName,
+                       passphrase=self.__passphrase,
+                       key_file=self._key_file)
+
+    def teardown(self, *args, **kwargs):
+        """ Close, or tear down, the format. """
+        log_method_call(self, device=self.device,
+                        type=self.type, status=self.status)
+        if not self.exists:
+            raise LUKSError("format has not been created")
+
+        if self.status:
+            log.debug("unmapping %s" % self.mapName)
+            crypto.luks_close(self.mapName)
+
+    def create(self, *args, **kwargs):
+        """ Create the format. """
+        log_method_call(self, device=self.device,
+                        type=self.type, status=self.status)
+        if not self.hasKey:
+            raise LUKSError("luks device has no key/passphrase")
+
+        intf = kwargs.get("intf")
+        w = None
+        if intf:
+            w = intf.waitWindow(_("Formatting"),
+                                _("Encrypting %s") % kwargs.get("device",
+                                                                self.device))
+
+        try:
+            DeviceFormat.create(self, *args, **kwargs)
+            crypto.luks_format(self.device,
+                             passphrase=self.__passphrase,
+                             key_file=self._key_file,
+                             cipher=self.cipher,
+                             key_size=self.key_size)
+        except Exception:
+            raise
+        else:
+            self.uuid = crypto.luks_uuid(self.device)
+            self.exists = True
+            self.mapName = "luks-%s" % self.uuid
+            self.notifyKernel()
+        finally:
+            if w:
+                w.pop()
+
+    def destroy(self, *args, **kwargs):
+        """ Create the format. """
+        log_method_call(self, device=self.device,
+                        type=self.type, status=self.status)
+        self.teardown()
+        DeviceFormat.destroy(self, *args, **kwargs)
+
+    @property
+    def keyFile(self):
+        """ Path to key file to be used in /etc/crypttab """
+        return self._key_file
+
+    def addKeyFromFile(self, keyfile):
+        """ Add a new key from a file.
+
+            Add the contents of the specified key file to an available key
+            slot in the LUKS header.
+        """
+        log_method_call(self, device=self.device,
+                        type=self.type, status=self.status, file=keyfile)
+        if not self.exists:
+            raise LUKSError("format has not been created")
+
+        crypto.luks_add_key(self.device,
+                          passphrase=self.__passphrase,
+                          key_file=self._key_file,
+                          new_key_file=keyfile)
+
+    def addPassphrase(self, passphrase):
+        """ Add a new passphrase.
+
+            Add the specified passphrase to an available key slot in the
+            LUKS header.
+        """
+        log_method_call(self, device=self.device,
+                        type=self.type, status=self.status)
+        if not self.exists:
+            raise LUKSError("format has not been created")
+
+        crypto.luks_add_key(self.device,
+                          passphrase=self.__passphrase,
+                          key_file=self._key_file,
+                          new_passphrase=passphrase)
+
+    def removeKeyFromFile(self, keyfile):
+        """ Remove a key contained in a file.
+
+            Remove key contained in the specified key file from the LUKS
+            header.
+        """
+        log_method_call(self, device=self.device,
+                        type=self.type, status=self.status, file=keyfile)
+        if not self.exists:
+            raise LUKSError("format has not been created")
+
+        crypto.luks_remove_key(self.device,
+                             passphrase=self.__passphrase,
+                             key_file=self._key_file,
+                             del_key_file=keyfile)
+
+
+    def removePassphrase(self, passphrase):
+        """ Remove the specified passphrase from the LUKS header. """
+        log_method_call(self, device=self.device,
+                        type=self.type, status=self.status)
+        if not self.exists:
+            raise LUKSError("format has not been created")
+
+        crypto.luks_remove_key(self.device,
+                             passphrase=self.__passphrase,
+                             key_file=self._key_file,
+                             del_passphrase=passphrase)
+
+    def _escrowVolumeIdent(self, vol):
+        """ Return an escrow packet filename prefix for a volume_key.Volume. """
+        label = vol.label
+        if label is not None:
+            label = label.replace("/", "_")
+        uuid = vol.uuid
+        if uuid is not None:
+            uuid = uuid.replace("/", "_")
+        # uuid is never None on LUKS volumes
+        if label is not None and uuid is not None:
+            volume_ident = "%s-%s" % (label, uuid)
+        elif uuid is not None:
+            volume_ident = uuid
+        elif label is not None:
+            volume_ident = label
+        else:
+            volume_ident = "_unknown"
+        return volume_ident
+
+    def escrow(self, directory, backupPassphrase):
+        log.debug("escrow: escrowVolume start for %s" % self.device)
+        if volume_key is None:
+            raise LUKSError("Missing key escrow support libraries")
+
+        vol = volume_key.Volume.open(self.device)
+        volume_ident = self._escrowVolumeIdent(vol)
+
+        ui = volume_key.UI()
+        # This callback is not expected to be used, let it always fail
+        ui.generic_cb = lambda unused_prompt, unused_echo: None
+        def known_passphrase_cb(unused_prompt, failed_attempts):
+            if failed_attempts == 0:
+                return self.__passphrase
+            return None
+        ui.passphrase_cb = known_passphrase_cb
+
+        log.debug("escrow: getting secret")
+        vol.get_secret(volume_key.SECRET_DEFAULT, ui)
+        log.debug("escrow: creating packet")
+        default_packet = vol.create_packet_assymetric_from_cert_data \
+            (volume_key.SECRET_DEFAULT, self.escrow_cert, ui)
+        log.debug("escrow: packet created")
+        with open("%s/%s-escrow" % (directory, volume_ident), "wb") as f:
+            f.write(default_packet)
+        log.debug("escrow: packet written")
+
+        if self.add_backup_passphrase:
+            log.debug("escrow: adding backup passphrase")
+            vol.add_secret(volume_key.SECRET_PASSPHRASE, backupPassphrase)
+            log.debug("escrow: creating backup packet")
+            backup_passphrase_packet = \
+                vol.create_packet_assymetric_from_cert_data \
+                (volume_key.SECRET_PASSPHRASE, self.escrow_cert, ui)
+            log.debug("escrow: backup packet created")
+            with open("%s/%s-escrow-backup-passphrase" %
+                      (directory, volume_ident), "wb") as f:
+                f.write(backup_passphrase_packet)
+            log.debug("escrow: backup packet written")
+
+        log.debug("escrow: escrowVolume done for %s" % repr(self.device))
+
+
+register_device_format(LUKS)
+
diff --git a/pyanaconda/storage/formats/lvmpv.py b/pyanaconda/storage/formats/lvmpv.py
new file mode 100644
index 0000000..9fe9ba3
--- /dev/null
+++ b/pyanaconda/storage/formats/lvmpv.py
@@ -0,0 +1,156 @@
+# lvmpv.py
+# Device format classes for anaconda's storage configuration module.
+#
+# Copyright (C) 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, or (at your option) any later version.
+# 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.
+#
+# Red Hat Author(s): Dave Lehman <dlehman@xxxxxxxxxx>
+#
+
+import os
+
+from ..storage_log import log_method_call
+from parted import PARTITION_LVM
+from ..errors import *
+from ..devicelibs import lvm
+from . import DeviceFormat, register_device_format
+
+import gettext
+_ = lambda x: gettext.ldgettext("anaconda", x)
+
+import logging
+log = logging.getLogger("storage")
+
+
+class LVMPhysicalVolume(DeviceFormat):
+    """ An LVM physical volume. """
+    _type = "lvmpv"
+    _name = "physical volume (LVM)"
+    _udevTypes = ["LVM2_member"]
+    partedFlag = PARTITION_LVM
+    _formattable = True                 # can be formatted
+    _supported = True                   # is supported
+    _linuxNative = True                 # for clearpart
+    _packages = ["lvm2"]                # required packages
+
+    def __init__(self, *args, **kwargs):
+        """ Create an LVMPhysicalVolume instance.
+
+            Keyword Arguments:
+
+                device -- path to the underlying device
+                uuid -- this PV's uuid (not the VG uuid)
+                vgName -- the name of the VG this PV belongs to
+                vgUuid -- the UUID of the VG this PV belongs to
+                peStart -- offset of first physical extent
+                exists -- indicates whether this is an existing format
+
+        """
+        log_method_call(self, *args, **kwargs)
+        DeviceFormat.__init__(self, *args, **kwargs)
+        self.vgName = kwargs.get("vgName")
+        self.vgUuid = kwargs.get("vgUuid")
+        # liblvm may be able to tell us this at some point, even
+        # for not-yet-created devices
+        self.peStart = kwargs.get("peStart", 0.1875)    # in MB
+
+    def __str__(self):
+        s = DeviceFormat.__str__(self)
+        s += ("  vgName = %(vgName)s  vgUUID = %(vgUUID)s"
+              "  peStart = %(peStart)s" %
+              {"vgName": self.vgName, "vgUUID": self.vgUuid,
+               "peStart": self.peStart})
+        return s
+
+    @property
+    def dict(self):
+        d = super(LVMPhysicalVolume, self).dict
+        d.update({"vgName": self.vgName, "vgUUID": self.vgUuid,
+                  "peStart": self.peStart})
+        return d
+
+    def probe(self):
+        """ Probe for any missing information about this device. """
+        log_method_call(self, device=self.device,
+                        type=self.type, status=self.status)
+        if not self.exists:
+            raise PhysicalVolumeError("format has not been created")
+
+        #info = lvm.pvinfo(self.device)
+        #self.vgName = info['vg_name']
+        #self.vgUuid = info['vg_uuid']
+
+    def create(self, *args, **kwargs):
+        """ Create the format. """
+        log_method_call(self, device=self.device,
+                        type=self.type, status=self.status)
+        intf = kwargs.get("intf")
+        w = None
+        if intf:
+            w = intf.progressWindow(_("Formatting"),
+                                    _("Creating %s on %s")
+                                    % (self.name, self.device),
+                                    100, pulse = True)
+
+        try:
+            DeviceFormat.create(self, *args, **kwargs)
+            # Consider use of -Z|--zero
+            # -f|--force or -y|--yes may be required
+
+            # lvm has issues with persistence of metadata, so here comes the
+            # hammer...
+            DeviceFormat.destroy(self, *args, **kwargs)
+
+            lvm.pvcreate(self.device, progress=w)
+        except Exception:
+            raise
+        else:
+            self.exists = True
+            self.notifyKernel()
+        finally:
+            if w:
+                w.pop()
+
+    def destroy(self, *args, **kwargs):
+        """ Destroy the format. """
+        log_method_call(self, device=self.device,
+                        type=self.type, status=self.status)
+        if not self.exists:
+            raise PhysicalVolumeError("format has not been created")
+
+        if self.status:
+            raise PhysicalVolumeError("device is active")
+
+        # FIXME: verify path exists?
+        try:
+            lvm.pvremove(self.device)
+        except LVMError:
+            DeviceFormat.destroy(self, *args, **kwargs)
+
+        self.exists = False
+        self.notifyKernel()
+
+    @property
+    def status(self):
+        # XXX hack
+        return (self.exists and self.vgName and
+                os.path.isdir("/dev/mapper/%s" % self.vgName))
+
+    def writeKS(self, f):
+        f.write("pv.%s" % self.uuid)
+
+register_device_format(LVMPhysicalVolume)
+
diff --git a/pyanaconda/storage/formats/mdraid.py b/pyanaconda/storage/formats/mdraid.py
new file mode 100644
index 0000000..d153807
--- /dev/null
+++ b/pyanaconda/storage/formats/mdraid.py
@@ -0,0 +1,124 @@
+# mdraid.py
+# Device format classes for anaconda's storage configuration module.
+#
+# Copyright (C) 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, or (at your option) any later version.
+# 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.
+#
+# Red Hat Author(s): Dave Lehman <dlehman@xxxxxxxxxx>
+#
+
+import os
+
+from ..storage_log import log_method_call
+from flags import flags
+from parted import PARTITION_RAID
+from ..errors import *
+from ..devicelibs import mdraid
+from . import DeviceFormat, register_device_format
+
+import gettext
+_ = lambda x: gettext.ldgettext("anaconda", x)
+
+import logging
+log = logging.getLogger("storage")
+
+
+class MDRaidMember(DeviceFormat):
+    """ An mdraid member disk. """
+    _type = "mdmember"
+    _name = "software RAID"
+    _udevTypes = ["linux_raid_member"]
+    partedFlag = PARTITION_RAID
+    _formattable = True                 # can be formatted
+    _supported = True                   # is supported
+    _linuxNative = True                 # for clearpart
+    _packages = ["mdadm"]               # required packages
+    
+    def __init__(self, *args, **kwargs):
+        """ Create a MDRaidMember instance.
+
+            Keyword Arguments:
+
+                device -- path to underlying device
+                uuid -- this member device's uuid
+                mdUuid -- the uuid of the array this device belongs to
+                exists -- indicates whether this is an existing format
+
+        """
+        log_method_call(self, *args, **kwargs)
+        DeviceFormat.__init__(self, *args, **kwargs)
+        self.mdUuid = kwargs.get("mdUuid")
+        self.raidMinor = None
+
+        #self.probe()
+        self.biosraid = False
+
+    def __str__(self):
+        s = DeviceFormat.__str__(self)
+        s += ("  mdUUID = %(mdUUID)s  biosraid = %(biosraid)s" %
+              {"mdUUID": self.mdUuid, "biosraid": self.biosraid})
+        return s
+
+    @property
+    def dict(self):
+        d = super(MDRaidMember, self).dict
+        d.update({"mdUUID": self.mdUuid, "biosraid": self.biosraid})
+        return d
+
+    def probe(self):
+        """ Probe for any missing information about this format. """
+        log_method_call(self, device=self.device,
+                        type=self.type, status=self.status)
+        if not self.exists:
+            raise MDMemberError("format does not exist")
+
+        info = mdraid.mdexamine(self.device)
+        if self.uuid is None:
+            self.uuid = info['uuid']
+        if self.raidMinor is None:
+            self.raidMinor = info['mdMinor']
+
+    def destroy(self, *args, **kwargs):
+        if not self.exists:
+            raise MDMemberError("format does not exist")
+
+        if not os.access(self.device, os.W_OK):
+            raise MDMemberError("device path does not exist")
+
+        mdraid.mddestroy(self.device)
+        self.exists = False
+
+    @property
+    def status(self):
+        # XXX hack -- we don't have a nice way to see if the array is active
+        return False
+
+    @property
+    def hidden(self):
+        return (self._hidden or self.biosraid)
+
+    def writeKS(self, f):
+        f.write("raid.%s" % self.mdUuid)
+
+# nodmraid -> Wether to use BIOS RAID or not
+# Note the anaconda cmdline has not been parsed yet when we're first imported,
+# so we can not use flags.dmraid here
+if not flags.cmdline.has_key("noiswmd") and \
+   not flags.cmdline.has_key("nodmraid"):
+    MDRaidMember._udevTypes.append("isw_raid_member")
+
+register_device_format(MDRaidMember)
+
diff --git a/pyanaconda/storage/formats/multipath.py b/pyanaconda/storage/formats/multipath.py
new file mode 100644
index 0000000..86c05d6
--- /dev/null
+++ b/pyanaconda/storage/formats/multipath.py
@@ -0,0 +1,95 @@
+# multipath.py
+# multipath device formats
+#
+# Copyright (C) 2009  Red Hat, 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; either version 2 of the License, or
+# (at your option) any later version.
+#
+# 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, see <http://www.gnu.org/licenses/>.
+#
+# 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.
+#
+# Red Hat Author(s): Peter Jones <pjones@xxxxxxxxxx>
+#
+
+from ..storage_log import log_method_call
+from ..errors import *
+from . import DeviceFormat, register_device_format
+
+import gettext
+_ = lambda x: gettext.ldgettext("anaconda", x)
+
+import logging
+log = logging.getLogger("storage")
+
+class MultipathMember(DeviceFormat):
+    """ A multipath member disk. """
+    _type = "multipath_member"
+    _name = "multipath member device"
+    _udev_types = ["multipath_member"]
+    _formattable = False                # can be formatted
+    _supported = True                   # is supported
+    _linuxNative = False                # for clearpart
+    _packages = ["device-mapper-multipath"] # required packages
+    _resizable = False                  # can be resized
+    _bootable = False                   # can be used as boot
+    _maxSize = 0                        # maximum size in MB
+    _minSize = 0                        # minimum size in MB
+    _hidden = True                      # hide devices with this formatting?
+
+    def __init__(self, *args, **kwargs):
+        """ Create a DeviceFormat instance.
+
+            Keyword Arguments:
+
+                device -- path to the underlying device
+                uuid -- this format's UUID
+                exists -- indicates whether this is an existing format
+
+            On initialization this format is like DeviceFormat
+
+        """
+        log_method_call(self, *args, **kwargs)
+        DeviceFormat.__init__(self, *args, **kwargs)
+
+        # Initialize the attribute that will hold the block object.
+        self._member = None
+
+    def __str__(self):
+        s = DeviceFormat.__str__(self)
+        s += ("  member = %(member)r" % {"member": self.member})
+        return s
+
+    def _getMember(self):
+        return self._member
+
+    def _setMember(self, member):
+        self._member = member
+
+    member = property(lambda s: s._getMember(),
+                      lambda s,m: s._setMember(m))
+
+    def create(self, *args, **kwargs):
+        log_method_call(self, device=self.device,
+                        type=self.type, status=self.status)
+        raise MultipathMemberError("creation of multipath members is non-sense")
+
+    def destroy(self, *args, **kwargs):
+        log_method_call(self, device=self.device,
+                        type=self.type, status=self.status)
+        raise MultipathMemberError("destruction of multipath members is non-sense")
+
+register_device_format(MultipathMember)
+
diff --git a/pyanaconda/storage/formats/prepboot.py b/pyanaconda/storage/formats/prepboot.py
new file mode 100644
index 0000000..2191b81
--- /dev/null
+++ b/pyanaconda/storage/formats/prepboot.py
@@ -0,0 +1,64 @@
+# prepboot.py
+# Format class for PPC PReP Boot.
+#
+# Copyright (C) 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, or (at your option) any later version.
+# 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.
+#
+# Red Hat Author(s): Dave Lehman <dlehman@xxxxxxxxxx>
+#
+
+from ..errors import *
+from . import DeviceFormat, register_device_format
+from parted import PARTITION_PREP
+
+class PPCPRePBoot(DeviceFormat):
+    """ Generic device format. """
+    _type = "prepboot"
+    _name = "PPC PReP Boot"
+    _udevTypes = []
+    partedFlag = PARTITION_PREP
+    _formattable = True                 # can be formatted
+    _linuxNative = True                 # for clearpart
+    _bootable = True                    # can be used as boot
+    _maxSize = 4                        # maximum size in MB
+    _minSize = 10                       # minimum size in MB
+
+    def __init__(self, *args, **kwargs):
+        """ Create a PRePBoot instance.
+
+            Keyword Arguments:
+
+                device -- path to the underlying device
+                exists -- indicates whether this is an existing format
+
+        """
+        DeviceFormat.__init__(self, *args, **kwargs)
+
+    @property
+    def status(self):
+        return False
+
+    @property
+    def supported(self):
+        import platform
+        return isinstance(platform.getPlatform(None), platform.IPSeriesPPC)
+
+    def writeKS(self, f):
+        f.write("prepboot --fstype=%s" % self.type)
+
+
+register_device_format(PPCPRePBoot)
+
diff --git a/pyanaconda/storage/formats/swap.py b/pyanaconda/storage/formats/swap.py
new file mode 100644
index 0000000..362f6d5
--- /dev/null
+++ b/pyanaconda/storage/formats/swap.py
@@ -0,0 +1,186 @@
+# swap.py
+# Device format classes for anaconda's storage configuration module.
+#
+# Copyright (C) 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, or (at your option) any later version.
+# 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.
+#
+# Red Hat Author(s): Dave Lehman <dlehman@xxxxxxxxxx>
+#
+
+from iutil import numeric_type
+from parted import PARTITION_SWAP, fileSystemType
+from ..storage_log import log_method_call
+from ..errors import *
+from ..devicelibs import swap
+from . import DeviceFormat, register_device_format
+
+import gettext
+_ = lambda x: gettext.ldgettext("anaconda", x)
+
+import logging
+log = logging.getLogger("storage")
+
+
+class SwapSpace(DeviceFormat):
+    """ Swap space """
+    _type = "swap"
+    _name = None
+    _udevTypes = ["swap"]
+    partedFlag = PARTITION_SWAP
+    partedSystem = fileSystemType["linux-swap(v1)"]
+    _formattable = True                # can be formatted
+    _supported = True                  # is supported
+    _linuxNative = True                # for clearpart
+
+    def __init__(self, *args, **kwargs):
+        """ Create a SwapSpace instance.
+
+            Keyword Arguments:
+
+                device -- path to the underlying device
+                uuid -- this swap space's uuid
+                label -- this swap space's label
+                priority -- this swap space's priority
+                exists -- indicates whether this is an existing format
+
+        """
+        log_method_call(self, *args, **kwargs)
+        DeviceFormat.__init__(self, *args, **kwargs)
+
+        self.priority = kwargs.get("priority")
+        self.label = kwargs.get("label")
+
+    def __str__(self):
+        s = DeviceFormat.__str__(self)
+        s += ("  priority = %(priority)s  label = %(label)s" %
+              {"priority": self.priority, "label": self.label})
+        return s
+
+    @property
+    def dict(self):
+        d = super(SwapSpace, self).dict
+        d.update({"priority": self.priority, "label": self.label})
+        return d
+
+    def _setPriority(self, priority):
+        if priority is None:
+            self._priority = None
+            return
+
+        if not isinstance(priority, int) or not 0 <= priority <= 32767:
+            raise ValueError("swap priority must be an integer between 0 and 32767")
+
+        self._priority = priority
+
+    def _getPriority(self):
+        return self._priority
+
+    priority = property(_getPriority, _setPriority,
+                        doc="The priority of the swap device")
+
+    def _getOptions(self):
+        opts = ""
+        if self.priority is not None:
+            opts += "pri=%d" % self.priority
+
+        return opts
+
+    def _setOptions(self, opts):
+        if not opts:
+            self.priority = None
+            return
+
+        for option in opts.split(","):
+            (opt, equals, arg) = option.partition("=")
+            if equals and opt == "pri":
+                try:
+                    self.priority = int(arg)
+                except ValueError:
+                    log.info("invalid value for swap priority: %s" % arg)
+
+    options = property(_getOptions, _setOptions,
+                       doc="The swap device's fstab options string")
+
+    @property
+    def status(self):
+        """ Device status. """
+        return self.exists and swap.swapstatus(self.device)
+
+    def setup(self, *args, **kwargs):
+        """ Open, or set up, a device. """
+        log_method_call(self, device=self.device,
+                        type=self.type, status=self.status)
+        if not self.exists:
+            raise SwapSpaceError("format has not been created")
+
+        if self.status:
+            return
+
+        DeviceFormat.setup(self, *args, **kwargs)
+        swap.swapon(self.device, priority=self.priority)
+
+    def teardown(self, *args, **kwargs):
+        """ Close, or tear down, a device. """
+        log_method_call(self, device=self.device,
+                        type=self.type, status=self.status)
+        if not self.exists:
+            raise SwapSpaceError("format has not been created")
+
+        if self.status:
+            swap.swapoff(self.device)
+
+    def create(self, *args, **kwargs):
+        """ Create the device. """
+        log_method_call(self, device=self.device,
+                        type=self.type, status=self.status)
+        intf = kwargs.get("intf")
+        force = kwargs.get("force")
+        if not force and self.exists:
+            raise SwapSpaceError("format already exists")
+
+        if force:
+            self.teardown()
+        elif self.status:
+            raise SwapSpaceError("device exists and is active")
+
+        w = None
+        if intf:
+            w = intf.progressWindow(_("Formatting"),
+                                    _("Creating %s on %s")
+                                    % (self.type,
+                                       kwargs.get("device", self.device)),
+                                    100, pulse = True)
+
+        try:
+            DeviceFormat.create(self, *args, **kwargs)
+            swap.mkswap(self.device, label=self.label, progress=w)
+        except Exception:
+            raise
+        else:
+            self.exists = True
+        finally:
+            if w:
+                w.pop()
+
+    def writeKS(self, f):
+        f.write("swap")
+
+        if self.label:
+            f.write(" --label=\"%s\"" % self.label)
+
+
+register_device_format(SwapSpace)
+
diff --git a/pyanaconda/storage/iscsi.py b/pyanaconda/storage/iscsi.py
new file mode 100644
index 0000000..55caa17
--- /dev/null
+++ b/pyanaconda/storage/iscsi.py
@@ -0,0 +1,333 @@
+#
+# iscsi.py - iscsi class
+#
+# Copyright (C) 2005, 2006  IBM, Inc.  All rights reserved.
+# Copyright (C) 2006  Red Hat, Inc.  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 as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# 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, see <http://www.gnu.org/licenses/>.
+#
+
+from constants import *
+from udev import *
+import os
+import iutil
+from flags import flags
+import logging
+import shutil
+import time
+import hashlib
+import random
+log = logging.getLogger("anaconda")
+
+import gettext
+_ = lambda x: gettext.ldgettext("anaconda", x)
+
+has_libiscsi = True
+try:
+    import libiscsi
+except ImportError:
+    has_libiscsi = False
+
+# Note that stage2 copies all files under /sbin to /usr/sbin
+ISCSID=""
+INITIATOR_FILE="/etc/iscsi/initiatorname.iscsi"
+
+def find_iscsi_files():
+    global ISCSID
+    if ISCSID == "":
+        for dir in ("/usr/sbin", "/tmp/updates", "/mnt/source/RHupdates"):
+            path="%s/iscsid" % (dir,)
+            if os.access(path, os.X_OK):
+                ISCSID=path
+
+def has_iscsi():
+    find_iscsi_files()
+    if ISCSID == "" or not has_libiscsi:
+        return False
+
+    log.info("ISCSID is %s" % (ISCSID,))
+
+    # make sure the module is loaded
+    if not os.access("/sys/module/iscsi_tcp", os.X_OK):
+        return False
+    return True
+
+def randomIname():
+    """Generate a random initiator name the same way as iscsi-iname"""
+    
+    s = "iqn.1994-05.com.fedora:01."
+    m = hashlib.md5()
+    u = os.uname()
+    for i in u:
+        m.update(i)
+    dig = m.hexdigest()
+    
+    for i in range(0, 6):
+        s += dig[random.randrange(0, 32)]
+    return s
+
+def stabilize(intf = None):
+    # Wait for udev to create the devices for the just added disks
+    if intf:
+        w = intf.waitWindow(_("Scanning iSCSI nodes"),
+                            _("Scanning iSCSI nodes"))
+    # It is possible when we get here the events for the new devices
+    # are not send yet, so sleep to make sure the events are fired
+    time.sleep(2)
+    udev_settle()
+    if intf:
+        w.pop()
+
+class iscsi(object):
+    """ iSCSI utility class.
+
+        This class will automatically discover and login to iBFT (or
+        other firmware) configured iscsi devices when the startup() method
+        gets called. It can also be used to manually configure iscsi devices
+        through the addTarget() method.
+
+        As this class needs to make sure certain things like starting iscsid
+        and logging in to firmware discovered disks only happens once 
+        and as it keeps a global list of all iSCSI devices it is implemented as
+        a Singleton.
+    """
+
+    def __init__(self):
+        # This list contains all nodes
+        self.nodes = []
+        # This list contains nodes discovered through iBFT (or other firmware)
+        self.ibftNodes = []
+        self._initiator = ""
+        self.initiatorSet = False
+        self.started = False
+
+        if flags.ibft:
+            try:
+                initiatorname = libiscsi.get_firmware_initiator_name()
+                self._initiator = initiatorname
+                self.initiatorSet = True
+            except:
+                pass
+
+    # So that users can write iscsi() to get the singleton instance
+    def __call__(self):
+        return self
+
+    def _getInitiator(self):
+        if self._initiator != "":
+            return self._initiator
+
+        return randomIname()
+
+    def _setInitiator(self, val):
+        if self.initiatorSet and val != self._initiator:
+            raise ValueError, "Unable to change iSCSI initiator name once set"
+        if len(val) == 0:
+            raise ValueError, "Must provide a non-zero length string"
+        self._initiator = val
+
+    initiator = property(_getInitiator, _setInitiator)
+
+    def _startIBFT(self, intf = None):
+        if not flags.ibft:
+            return
+
+        try:
+            found_nodes = libiscsi.discover_firmware()
+        except:
+            # an exception here means there is no ibft firmware, just return
+            return
+
+        for node in found_nodes:
+            try:
+                node.login()
+                log.info("iscsi._startIBFT logged in to %s %s %s" % (node.name, node.address, node.port))
+                self.nodes.append(node)
+                self.ibftNodes.append(node)
+            except IOError, e:
+                log.error("Could not log into ibft iscsi target %s: %s" %
+                          (node.name, str(e)))
+                pass
+
+        stabilize(intf)
+
+    def startup(self, intf = None):
+        if self.started:
+            return
+
+        if not has_iscsi():
+            return
+
+        if self._initiator == "":
+            log.info("no initiator set")
+            return
+
+        if intf:
+            w = intf.waitWindow(_("Initializing iSCSI initiator"),
+                                _("Initializing iSCSI initiator"))
+
+        log.debug("Setting up %s" % (INITIATOR_FILE, ))
+        log.info("iSCSI initiator name %s", self.initiator)
+        if os.path.exists(INITIATOR_FILE):
+            os.unlink(INITIATOR_FILE)
+        if not os.path.isdir("/etc/iscsi"):
+            os.makedirs("/etc/iscsi", 0755)
+        fd = os.open(INITIATOR_FILE, os.O_RDWR | os.O_CREAT)
+        os.write(fd, "InitiatorName=%s\n" %(self.initiator))
+        os.close(fd)
+        self.initiatorSet = True
+
+        for dir in ['ifaces','isns','nodes','send_targets','slp','static']:
+            fulldir = "/var/lib/iscsi/%s" % (dir,)
+            if not os.path.isdir(fulldir):
+                os.makedirs(fulldir, 0755)
+
+        log.info("iSCSI startup")
+        iutil.execWithRedirect(ISCSID, [],
+                               stdout="/dev/tty5", stderr="/dev/tty5")
+        time.sleep(1)
+
+        if intf:
+            w.pop()
+
+        self._startIBFT(intf)
+        self.started = True
+
+    def addTarget(self, ipaddr, port="3260", user=None, pw=None,
+                  user_in=None, pw_in=None, intf=None):
+        authinfo = None
+        found = 0
+        logged_in = 0
+
+        if not has_iscsi():
+            raise IOError, _("iSCSI not available")
+        if self._initiator == "":
+            raise ValueError, _("No initiator name set")
+
+        if user or pw or user_in or pw_in:
+            # Note may raise a ValueError
+            authinfo = libiscsi.chapAuthInfo(username=user, password=pw,
+                                             reverse_username=user_in,
+                                             reverse_password=pw_in)
+        self.startup(intf)
+
+        # Note may raise an IOError
+        found_nodes = libiscsi.discover_sendtargets(address=ipaddr,
+                                                    port=int(port),
+                                                    authinfo=authinfo)
+        if found_nodes == None:
+            raise IOError, _("No iSCSI nodes discovered")
+
+        if intf:
+            w = intf.waitWindow(_("Logging in to iSCSI nodes"),
+                                _("Logging in to iSCSI nodes"))
+
+        for node in found_nodes:
+            # skip nodes we already have
+            if node in self.nodes:
+                continue
+
+            found = found + 1
+            try:
+                if (authinfo):
+                    node.setAuth(authinfo)
+                node.login()
+                log.info("iscsi.addTarget logged in to %s %s %s" % (node.name, node.address, node.port))
+                self.nodes.append(node)
+                logged_in = logged_in + 1
+            except IOError, e:
+                log.warning(
+                    "Could not log into discovered iscsi target %s: %s" %
+                    (node.name, str(e)))
+                # some nodes may require different credentials
+                pass
+
+        if intf:
+            w.pop()
+
+        if found == 0:
+            raise IOError, _("No new iSCSI nodes discovered")
+
+        if logged_in == 0:
+            raise IOError, _("Could not log in to any of the discovered nodes")
+
+        stabilize(intf)
+
+    def writeKS(self, f):
+        if not self.initiatorSet:
+            return
+        f.write("iscsiname %s\n" %(self.initiator,))
+        for n in self.nodes:
+            f.write("iscsi --ipaddr %s --port %s" %(n.address, n.port))
+            auth = n.getAuth()
+            if auth:
+                f.write(" --user %s" % auth.username)
+                f.write(" --password %s" % auth.password)
+                if len(auth.reverse_username):
+                    f.write(" --reverse-user %s" % auth.reverse_username)
+                if len(auth.reverse_password):
+                    f.write(" --reverse-password %s" % auth.reverse_password)
+            f.write("\n")
+
+    def write(self, instPath, anaconda):
+        if not self.initiatorSet:
+            return
+
+        # set iscsi nodes to autostart
+        root = anaconda.storage.rootDevice
+        for node in self.nodes:
+            autostart = True
+            disks = self.getNodeDisks(node, anaconda.storage)
+            for disk in disks:
+                # nodes used for root get started by the initrd
+                if root.dependsOn(disk):
+                    autostart = False
+
+            if autostart:
+                node.setParameter("node.startup", "automatic")
+
+        if not os.path.isdir(instPath + "/etc/iscsi"):
+            os.makedirs(instPath + "/etc/iscsi", 0755)
+        fd = os.open(instPath + INITIATOR_FILE, os.O_RDWR | os.O_CREAT)
+        os.write(fd, "InitiatorName=%s\n" %(self.initiator))
+        os.close(fd)
+
+        # copy "db" files.  *sigh*
+        if os.path.isdir(instPath + "/var/lib/iscsi"):
+            shutil.rmtree(instPath + "/var/lib/iscsi")
+        if os.path.isdir("/var/lib/iscsi"):
+            shutil.copytree("/var/lib/iscsi", instPath + "/var/lib/iscsi",
+                            symlinks=True)
+
+    def getNode(self, name, address, port):
+        for node in self.nodes:
+            if node.name == name and node.address == address and \
+               node.port == int(port):
+                return node
+
+        return None
+
+    def getNodeDisks(self, node, storage):
+        nodeDisks = []
+        iscsiDisks = storage.devicetree.getDevicesByType("iscsi")
+        for disk in iscsiDisks:
+            if disk.node == node:
+                nodeDisks.append(disk)
+
+        return nodeDisks
+
+# Create iscsi singleton
+iscsi = iscsi()
+
+# vim:tw=78:ts=4:et:sw=4
diff --git a/pyanaconda/storage/miscutils.py b/pyanaconda/storage/miscutils.py
new file mode 100644
index 0000000..e577497
--- /dev/null
+++ b/pyanaconda/storage/miscutils.py
@@ -0,0 +1,57 @@
+# iutil.py stubs
+import os
+
+import logging
+log = logging.getLogger("storage")
+
+def notify_kernel(path, action="change"):
+    """ Signal the kernel that the specified device has changed. """
+    log.debug("notifying kernel of '%s' event on device %s" % (action, path))
+    path = os.path.join(path, "uevent")
+    if not path.startswith("/sys/") or not os.access(path, os.W_OK):
+        log.debug("sysfs path '%s' invalid" % path)
+        raise ValueError("invalid sysfs path")
+
+    f = open(path, "a")
+    f.write("%s\n" % action)
+    f.close()
+
+def get_sysfs_path_by_name(dev_name, class_name="block"):
+    dev_name = os.path.basename(dev_name)
+    sysfs_class_dir = "/sys/class/%s" % class_name
+    dev_path = os.path.join(sysfs_class_dir, dev_name)
+    if os.path.exists(dev_path):
+        return dev_path
+
+import inspect
+def log_method_call(d, *args, **kwargs):
+    classname = d.__class__.__name__
+    methodname = inspect.stack()[1][3]
+    fmt = "%s.%s:"
+    fmt_args = [classname, methodname]
+    for arg in args:
+        fmt += " %s ;"
+        fmt_args.append(arg)
+
+    for k, v in kwargs.items():
+        fmt += " %s: %s ;"
+        fmt_args.extend([k, v])
+
+    log.debug(fmt % tuple(fmt_args))
+
+def numeric_type(num):
+    """ Verify that a value is given as a numeric data type.
+
+        Return the number if the type is sensible or raise ValueError
+        if not.
+    """
+    if num is None:
+        num = 0
+    elif not (isinstance(num, int) or \
+              isinstance(num, long) or \
+              isinstance(num, float)):
+        raise ValueError("value (%s) must be either a number or None" % num)
+
+    return num
+
+
diff --git a/pyanaconda/storage/partitioning.py b/pyanaconda/storage/partitioning.py
new file mode 100644
index 0000000..00c1986
--- /dev/null
+++ b/pyanaconda/storage/partitioning.py
@@ -0,0 +1,1707 @@
+# partitioning.py
+# Disk partitioning functions.
+#
+# Copyright (C) 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, or (at your option) any later version.
+# 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.
+#
+# Red Hat Author(s): Dave Lehman <dlehman@xxxxxxxxxx>
+#
+
+import sys
+import os
+from operator import add, sub, gt, lt
+
+import parted
+from pykickstart.constants import *
+
+from constants import *
+
+from errors import *
+from deviceaction import *
+from devices import PartitionDevice, LUKSDevice, devicePathToName
+from formats import getFormat
+
+import gettext
+_ = lambda x: gettext.ldgettext("anaconda", x)
+
+import logging
+log = logging.getLogger("storage")
+
+def _createFreeSpacePartitions(anaconda):
+    # get a list of disks that have at least one free space region of at
+    # least 100MB
+    disks = []
+    for disk in anaconda.storage.partitioned:
+        if anaconda.storage.clearPartDisks and \
+           (disk.name not in anaconda.storage.clearPartDisks):
+            continue
+
+        part = disk.format.firstPartition
+        while part:
+            if not part.type & parted.PARTITION_FREESPACE:
+                part = part.nextPartition()
+                continue
+
+            if part.getSize(unit="MB") > 100:
+                disks.append(disk)
+                break
+
+            part = part.nextPartition()
+
+    # create a separate pv partition for each disk with free space
+    devs = []
+    for disk in disks:
+        if anaconda.storage.encryptedAutoPart:
+            fmt_type = "luks"
+            fmt_args = {"escrow_cert": anaconda.storage.autoPartEscrowCert,
+                        "add_backup_passphrase": anaconda.storage.autoPartAddBackupPassphrase}
+        else:
+            fmt_type = "lvmpv"
+            fmt_args = {}
+        part = anaconda.storage.newPartition(fmt_type=fmt_type,
+                                                fmt_args=fmt_args,
+                                                grow=True,
+                                                disks=[disk])
+        anaconda.storage.createDevice(part)
+        devs.append(part)
+
+    return (disks, devs)
+
+def _schedulePartitions(anaconda, disks):
+    #
+    # Convert storage.autoPartitionRequests into Device instances and
+    # schedule them for creation
+    #
+    # First pass is for partitions only. We'll do LVs later.
+    #
+    for request in anaconda.storage.autoPartitionRequests:
+        if request.asVol:
+            continue
+
+        if request.fstype is None:
+            request.fstype = anaconda.storage.defaultFSType
+        # This is a little unfortunate but let the backend dictate the rootfstype
+        # so that things like live installs can do the right thing
+        if request.mountpoint == "/" and anaconda.backend.rootFsType != None:
+            request.fstype = anaconda.backend.rootFsType
+
+        dev = anaconda.storage.newPartition(fmt_type=request.fstype,
+                                            size=request.size,
+                                            grow=request.grow,
+                                            maxsize=request.maxSize,
+                                            mountpoint=request.mountpoint,
+                                            disks=disks,
+                                            weight=request.weight)
+
+        # schedule the device for creation
+        anaconda.storage.createDevice(dev)
+
+    # make sure preexisting broken lvm/raid configs get out of the way
+    return
+
+def _scheduleLVs(anaconda, devs):
+    if anaconda.storage.encryptedAutoPart:
+        pvs = []
+        for dev in devs:
+            pv = LUKSDevice("luks-%s" % dev.name,
+                            format=getFormat("lvmpv", device=dev.path),
+                            size=dev.size,
+                            parents=dev)
+            pvs.append(pv)
+            anaconda.storage.createDevice(pv)
+    else:
+        pvs = devs
+
+    # create a vg containing all of the autopart pvs
+    vg = anaconda.storage.newVG(pvs=pvs)
+    anaconda.storage.createDevice(vg)
+
+    initialVGSize = vg.size
+
+    #
+    # Convert storage.autoPartitionRequests into Device instances and
+    # schedule them for creation.
+    #
+    # Second pass, for LVs only.
+    for request in anaconda.storage.autoPartitionRequests:
+        if not request.asVol:
+            continue
+
+        if request.requiredSpace and request.requiredSpace > initialVGSize:
+            continue
+
+        if request.fstype is None:
+            request.fstype = anaconda.storage.defaultFSType
+
+        # This is a little unfortunate but let the backend dictate the rootfstype
+        # so that things like live installs can do the right thing
+        if request.mountpoint == "/" and anaconda.backend.rootFsType != None:
+            request.fstype = anaconda.backend.rootFsType
+
+        # FIXME: move this to a function and handle exceptions
+        dev = anaconda.storage.newLV(vg=vg,
+                                     fmt_type=request.fstype,
+                                     mountpoint=request.mountpoint,
+                                     grow=request.grow,
+                                     maxsize=request.maxSize,
+                                     size=request.size)
+
+        # schedule the device for creation
+        anaconda.storage.createDevice(dev)
+
+
+def doAutoPartition(anaconda):
+    log.debug("doAutoPartition(%s)" % anaconda)
+    log.debug("doAutoPart: %s" % anaconda.storage.doAutoPart)
+    log.debug("clearPartType: %s" % anaconda.storage.clearPartType)
+    log.debug("clearPartDisks: %s" % anaconda.storage.clearPartDisks)
+    log.debug("autoPartitionRequests: %s" % anaconda.storage.autoPartitionRequests)
+    log.debug("storage.disks: %s" % [d.name for d in anaconda.storage.disks])
+    log.debug("storage.partitioned: %s" % [d.name for d in anaconda.storage.partitioned])
+    log.debug("all names: %s" % [d.name for d in anaconda.storage.devices])
+    if anaconda.dir == DISPATCH_BACK:
+        anaconda.storage.reset()
+        return
+
+    disks = []
+    devs = []
+
+    if anaconda.storage.doAutoPart:
+        clearPartitions(anaconda.storage)
+
+    if anaconda.storage.doAutoPart:
+        (disks, devs) = _createFreeSpacePartitions(anaconda)
+
+        if disks == []:
+            if anaconda.ksdata:
+                msg = _("Could not find enough free space for automatic "
+                        "partitioning.  Press 'OK' to exit the installer.")
+            else:
+                msg = _("Could not find enough free space for automatic "
+                        "partitioning, please use another partitioning method.")
+
+            anaconda.intf.messageWindow(_("Error Partitioning"), msg,
+                                        custom_icon='error')
+
+            if anaconda.ksdata:
+                sys.exit(0)
+
+            anaconda.storage.reset()
+            return DISPATCH_BACK
+
+        _schedulePartitions(anaconda, disks)
+
+    # sanity check the individual devices
+    log.warning("not sanity checking devices because I don't know how yet")
+
+    # run the autopart function to allocate and grow partitions
+    try:
+        doPartitioning(anaconda.storage,
+                       exclusiveDisks=anaconda.storage.clearPartDisks)
+
+        if anaconda.storage.doAutoPart:
+            _scheduleLVs(anaconda, devs)
+
+        # grow LVs
+        growLVM(anaconda.storage)
+    except PartitioningWarning as msg:
+        if not anaconda.ksdata:
+            anaconda.intf.messageWindow(_("Warnings During Automatic "
+                                          "Partitioning"),
+                           _("Following warnings occurred during automatic "
+                           "partitioning:\n\n%s") % (msg,),
+                           custom_icon='warning')
+        else:
+            log.warning(msg)
+    except PartitioningError as msg:
+        # restore drives to original state
+        anaconda.storage.reset()
+        if not anaconda.ksdata:
+            extra = ""
+
+            if anaconda.displayMode != "t":
+                anaconda.dispatch.skipStep("partition", skip = 0)
+        else:
+            extra = _("\n\nPress 'OK' to exit the installer.")
+        anaconda.intf.messageWindow(_("Error Partitioning"),
+               _("Could not allocate requested partitions: \n\n"
+                 "%(msg)s.%(extra)s") % {'msg': msg, 'extra': extra},
+               custom_icon='error')
+
+        if anaconda.ksdata:
+            sys.exit(0)
+        else:
+            return
+
+    # sanity check the collection of devices
+    log.warning("not sanity checking storage config because I don't know how yet")
+    # now do a full check of the requests
+    (errors, warnings) = anaconda.storage.sanityCheck()
+    if warnings:
+        for warning in warnings:
+            log.warning(warning)
+    if errors:
+        errortxt = "\n".join(errors)
+        if anaconda.ksdata:
+            extra = _("\n\nPress 'OK' to exit the installer.")
+        else:
+            extra = _("\n\nPress 'OK' to choose a different partitioning option.")
+
+        anaconda.intf.messageWindow(_("Automatic Partitioning Errors"),
+                           _("The following errors occurred with your "
+                             "partitioning:\n\n%(errortxt)s\n\n"
+                             "This can happen if there is not enough "
+                             "space on your hard drive(s) for the "
+                             "installation. %(extra)s")
+                           % {'errortxt': errortxt, 'extra': extra},
+                           custom_icon='error')
+        #
+        # XXX if in kickstart we reboot
+        #
+        if anaconda.ksdata:
+            anaconda.intf.messageWindow(_("Unrecoverable Error"),
+                               _("The system will now reboot."))
+            sys.exit(0)
+        anaconda.storage.reset()
+        return DISPATCH_BACK
+
+def shouldClear(device, clearPartType, clearPartDisks=None):
+    if clearPartType not in [CLEARPART_TYPE_LINUX, CLEARPART_TYPE_ALL]:
+        return False
+
+    if isinstance(device, PartitionDevice):
+        # Never clear the special first partition on a Mac disk label, as that
+        # holds the partition table itself.
+        if device.disk.format.partedDisk.type == "mac" and \
+           device.partedPartition.number == 1 and \
+           device.partedPartition.name == "Apple":
+            return False
+
+        # If we got a list of disks to clear, make sure this one's on it
+        if clearPartDisks and device.disk.name not in clearPartDisks:
+            return False
+
+        # We don't want to fool with extended partitions, freespace, &c
+        if device.partType not in [parted.PARTITION_NORMAL,
+                                   parted.PARTITION_LOGICAL]:
+            return False
+
+        if clearPartType == CLEARPART_TYPE_LINUX and \
+           not device.format.linuxNative and \
+           not device.getFlag(parted.PARTITION_LVM) and \
+           not device.getFlag(parted.PARTITION_RAID) and \
+           not device.getFlag(parted.PARTITION_SWAP):
+            return False
+    elif device.isDisk and not device.partitioned:
+        # If we got a list of disks to clear, make sure this one's on it
+        if clearPartDisks and device.name not in clearPartDisks:
+            return False
+
+        # Never clear disks with hidden formats
+        if device.format.hidden:
+            return False
+
+        if clearPartType == CLEARPART_TYPE_LINUX and \
+           not device.format.linuxNative:
+            return False
+
+    # Don't clear devices holding install media.
+    if device.protected:
+        return False
+
+    # TODO: do platform-specific checks on ia64, pSeries, iSeries, mac
+
+    return True
+
+def clearPartitions(storage):
+    """ Clear partitions and dependent devices from disks.
+
+        Arguments:
+
+            storage -- a storage.Storage instance
+
+        Keyword arguments:
+
+            None
+
+        NOTES:
+
+            - Needs some error handling, especially for the parted bits.
+
+    """
+    if storage.clearPartType is None or storage.clearPartType == CLEARPART_TYPE_NONE:
+        # not much to do
+        return
+
+    # we are only interested in partitions that physically exist
+    partitions = [p for p in storage.partitions if p.exists]
+    # Sort partitions by descending partition number to minimize confusing
+    # things like multiple "destroy sda5" actions due to parted renumbering
+    # partitions. This can still happen through the UI but it makes sense to
+    # avoid it where possible.
+    partitions.sort(key=lambda p: p.partedPartition.number, reverse=True)
+    for part in partitions:
+        log.debug("clearpart: looking at %s" % part.name)
+        if not shouldClear(part, storage.clearPartType, storage.clearPartDisks):
+            continue
+
+        log.debug("clearing %s" % part.name)
+
+        # XXX is there any argument for not removing incomplete devices?
+        #       -- maybe some RAID devices
+        devices = storage.deviceDeps(part)
+        while devices:
+            log.debug("devices to remove: %s" % ([d.name for d in devices],))
+            leaves = [d for d in devices if d.isleaf]
+            log.debug("leaves to remove: %s" % ([d.name for d in leaves],))
+            for leaf in leaves:
+                storage.destroyDevice(leaf)
+                devices.remove(leaf)
+
+        log.debug("partitions: %s" % [p.getDeviceNodeName() for p in part.partedPartition.disk.partitions])
+        storage.destroyDevice(part)
+
+    # now remove any empty extended partitions
+    removeEmptyExtendedPartitions(storage)
+
+    _platform = storage.anaconda.platform
+
+    # make sure that the the boot device has the correct disklabel type if
+    # we're going to completely clear it.
+    for disk in storage.partitioned:
+        if not storage.anaconda.bootloader.drivelist:
+            break
+
+        if disk.name != storage.anaconda.bootloader.drivelist[0]:
+            continue
+
+        if storage.clearPartType != CLEARPART_TYPE_ALL or \
+           (storage.clearPartDisks and disk.name not in storage.clearPartDisks):
+            continue
+
+        # don't reinitialize the disklabel if the disk contains install media
+        if filter(lambda p: p.dependsOn(disk), storage.protectedDevices):
+            continue
+
+        nativeLabelType = _platform.diskLabelType(disk.partedDevice.type)
+        if disk.format.labelType == nativeLabelType:
+            continue
+
+        if disk.format.labelType == "mac":
+            # remove the magic apple partition
+            for part in storage.partitions:
+                if part.disk == disk and part.partedPartition.number == 1:
+                    log.debug("clearing %s" % part.name)
+                    # We can't schedule the apple map partition for removal
+                    # because parted will not allow us to remove it from the
+                    # disk. Still, we need it out of the devicetree.
+                    storage.devicetree._removeDevice(part, moddisk=False)
+
+        destroy_action = ActionDestroyFormat(disk)
+        newLabel = getFormat("disklabel", device=disk.path)
+        create_action = ActionCreateFormat(disk, format=newLabel)
+        storage.devicetree.registerAction(destroy_action)
+        storage.devicetree.registerAction(create_action)
+
+def removeEmptyExtendedPartitions(storage):
+    for disk in storage.partitioned:
+        log.debug("checking whether disk %s has an empty extended" % disk.name)
+        extended = disk.format.extendedPartition
+        logical_parts = disk.format.logicalPartitions
+        log.debug("extended is %s ; logicals is %s" % (extended, [p.getDeviceNodeName() for p in logical_parts]))
+        if extended and not logical_parts:
+            log.debug("removing empty extended partition from %s" % disk.name)
+            extended_name = devicePathToName(extended.getDeviceNodeName())
+            extended = storage.devicetree.getDeviceByName(extended_name)
+            storage.destroyDevice(extended)
+            #disk.partedDisk.removePartition(extended.partedPartition)
+
+    for disk in [d for d in storage.disks if d not in storage.partitioned]:
+        # clear any whole-disk formats that need clearing
+        if shouldClear(disk, storage.clearPartType, storage.clearPartDisks):
+            log.debug("clearing %s" % disk.name)
+            devices = storage.deviceDeps(disk)
+            while devices:
+                log.debug("devices to remove: %s" % ([d.name for d in devices],))
+                leaves = [d for d in devices if d.isleaf]
+                log.debug("leaves to remove: %s" % ([d.name for d in leaves],))
+                for leaf in leaves:
+                    storage.destroyDevice(leaf)
+                    devices.remove(leaf)
+
+            destroy_action = ActionDestroyFormat(disk)
+            newLabel = getFormat("disklabel", device=disk.path)
+            create_action = ActionCreateFormat(disk, format=newLabel)
+            storage.devicetree.registerAction(destroy_action)
+            storage.devicetree.registerAction(create_action)
+
+def partitionCompare(part1, part2):
+    """ More specifically defined partitions come first.
+
+        < 1 => x < y
+          0 => x == y
+        > 1 => x > y
+    """
+    ret = 0
+
+    if part1.req_base_weight:
+        ret -= part1.req_base_weight
+
+    if part2.req_base_weight:
+        ret += part2.req_base_weight
+
+    # bootable partitions to the front
+    ret -= cmp(part1.req_bootable, part2.req_bootable) * 1000
+
+    # more specific disk specs to the front of the list
+    # req_disks being empty is equivalent to it being an infinitely long list
+    if part1.req_disks and not part2.req_disks:
+        ret -= 500
+    elif not part1.req_disks and part2.req_disks:
+        ret += 500
+    else:
+        ret += cmp(len(part1.req_disks), len(part2.req_disks)) * 500
+
+    # primary-only to the front of the list
+    ret -= cmp(part1.req_primary, part2.req_primary) * 200
+
+    # fixed size requests to the front
+    ret += cmp(part1.req_grow, part2.req_grow) * 100
+
+    # larger requests go to the front of the list
+    ret -= cmp(part1.req_base_size, part2.req_base_size) * 50
+
+    # potentially larger growable requests go to the front
+    if part1.req_grow and part2.req_grow:
+        if not part1.req_max_size and part2.req_max_size:
+            ret -= 25
+        elif part1.req_max_size and not part2.req_max_size:
+            ret += 25
+        else:
+            ret -= cmp(part1.req_max_size, part2.req_max_size) * 25
+
+    # give a little bump based on mountpoint
+    if hasattr(part1.format, "mountpoint") and \
+       hasattr(part2.format, "mountpoint"):
+        ret += cmp(part1.format.mountpoint, part2.format.mountpoint) * 10
+
+    if ret > 0:
+        ret = 1
+    elif ret < 0:
+        ret = -1
+
+    return ret
+
+def getNextPartitionType(disk, no_primary=None):
+    """ Find the type of partition to create next on a disk.
+
+        Return a parted partition type value representing the type of the
+        next partition we will create on this disk.
+
+        If there is only one free primary partition and we can create an
+        extended partition, we do that.
+
+        If there are free primary slots and an extended partition we will
+        recommend creating a primary partition. This can be overridden
+        with the keyword argument no_primary.
+
+        Arguments:
+
+            disk -- a parted.Disk instance representing the disk
+
+        Keyword arguments:
+
+            no_primary -- given a choice between primary and logical
+                          partitions, prefer logical
+
+    """
+    part_type = None
+    extended = disk.getExtendedPartition()
+    supports_extended = disk.supportsFeature(parted.DISK_TYPE_EXTENDED)
+    logical_count = len(disk.getLogicalPartitions())
+    max_logicals = disk.getMaxLogicalPartitions()
+    primary_count = disk.primaryPartitionCount
+
+    if primary_count < disk.maxPrimaryPartitionCount:
+        if primary_count == disk.maxPrimaryPartitionCount - 1:
+            # can we make an extended partition? now's our chance.
+            if not extended and supports_extended:
+                part_type = parted.PARTITION_EXTENDED
+            elif not extended:
+                # extended partitions not supported. primary or nothing.
+                if not no_primary:
+                    part_type = parted.PARTITION_NORMAL
+            else:
+                # there is an extended and a free primary
+                if not no_primary:
+                    part_type = parted.PARTITION_NORMAL
+                elif logical_count < max_logicals:
+                    # we have an extended with logical slots, so use one.
+                    part_type = parted.PARTITION_LOGICAL
+        else:
+            # there are two or more primary slots left. use one unless we're
+            # not supposed to make primaries.
+            if not no_primary:
+                part_type = parted.PARTITION_NORMAL
+            elif extended and logical_count < max_logicals:
+                part_type = parted.PARTITION_LOGICAL
+    elif extended and logical_count < max_logicals:
+        part_type = parted.PARTITION_LOGICAL
+
+    return part_type
+
+def getBestFreeSpaceRegion(disk, part_type, req_size,
+                           boot=None, best_free=None, grow=None):
+    """ Return the "best" free region on the specified disk.
+
+        For non-boot partitions, we return the largest free region on the
+        disk. For boot partitions, we return the first region that is
+        large enough to hold the partition.
+
+        Partition type (parted's PARTITION_NORMAL, PARTITION_LOGICAL) is
+        taken into account when locating a suitable free region.
+
+        For locating the best region from among several disks, the keyword
+        argument best_free allows the specification of a current "best"
+        free region with which to compare the best from this disk. The
+        overall best region is returned.
+
+        Arguments:
+
+            disk -- the disk (a parted.Disk instance)
+            part_type -- the type of partition we want to allocate
+                         (one of parted's partition type constants)
+            req_size -- the requested size of the partition (in MB)
+
+        Keyword arguments:
+
+            boot -- indicates whether this will be a bootable partition
+                    (boolean)
+            best_free -- current best free region for this partition
+            grow -- indicates whether this is a growable request
+
+    """
+    log.debug("getBestFreeSpaceRegion: disk=%s part_type=%d req_size=%dMB "
+              "boot=%s best=%s grow=%s" %
+              (disk.device.path, part_type, req_size, boot, best_free, grow))
+    extended = disk.getExtendedPartition()
+
+    for _range in disk.getFreeSpaceRegions():
+        if extended:
+            # find out if there is any overlap between this region and the
+            # extended partition
+            log.debug("looking for intersection between extended (%d-%d) and free (%d-%d)" %
+                    (extended.geometry.start, extended.geometry.end, _range.start, _range.end))
+
+            # parted.Geometry.overlapsWith can handle this
+            try:
+                free_geom = extended.geometry.intersect(_range)
+            except ArithmeticError, e:
+                # this freespace region does not lie within the extended
+                # partition's geometry
+                free_geom = None
+
+            if (free_geom and part_type == parted.PARTITION_NORMAL) or \
+               (not free_geom and part_type == parted.PARTITION_LOGICAL):
+                log.debug("free region not suitable for request")
+                continue
+
+            if part_type == parted.PARTITION_NORMAL:
+                # we're allocating a primary and the region is not within
+                # the extended, so we use the original region
+                free_geom = _range
+        else:
+            free_geom = _range
+
+        log.debug("current free range is %d-%d (%dMB)" % (free_geom.start,
+                                                          free_geom.end,
+                                                          free_geom.getSize()))
+        free_size = free_geom.getSize()
+
+        # For boot partitions, we want the first suitable region we find.
+        # For growable or extended partitions, we want the largest possible
+        # free region.
+        # For all others, we want the smallest suitable free region.
+        if grow or part_type == parted.PARTITION_EXTENDED:
+            op = gt
+        else:
+            op = lt
+        if req_size <= free_size:
+            if not best_free or op(free_geom.length, best_free.length):
+                best_free = free_geom
+
+                if boot:
+                    # if this is a bootable partition we want to
+                    # use the first freespace region large enough
+                    # to satisfy the request
+                    break
+
+    return best_free
+
+def sectorsToSize(sectors, sectorSize):
+    """ Convert length in sectors to size in MB.
+
+        Arguments:
+
+            sectors     -   sector count
+            sectorSize  -   sector size for the device, in bytes
+    """
+    return (sectors * sectorSize) / (1024.0 * 1024.0)
+
+def sizeToSectors(size, sectorSize):
+    """ Convert size in MB to length in sectors.
+
+        Arguments:
+
+            size        -   size in MB
+            sectorSize  -   sector size for the device, in bytes
+    """
+    return (size * 1024.0 * 1024.0) / sectorSize
+
+def removeNewPartitions(disks, partitions):
+    """ Remove newly added input partitions from input disks.
+
+        Arguments:
+
+            disks -- list of StorageDevice instances with DiskLabel format
+            partitions -- list of PartitionDevice instances
+
+    """
+    log.debug("removing all non-preexisting partitions %s from disk(s) %s"
+                % (["%s(id %d)" % (p.name, p.id) for p in partitions
+                                                    if not p.exists],
+                   [d.name for d in disks]))
+    for part in partitions:
+        if part.partedPartition and part.disk in disks:
+            if part.exists:
+                # we're only removing partitions that don't physically exist
+                continue
+
+            if part.isExtended:
+                # these get removed last
+                continue
+
+            part.disk.format.partedDisk.removePartition(part.partedPartition)
+            part.partedPartition = None
+            part.disk = None
+
+    for disk in disks:
+        # remove empty extended so it doesn't interfere
+        extended = disk.format.extendedPartition
+        if extended and not disk.format.logicalPartitions:
+            log.debug("removing empty extended partition from %s" % disk.name)
+            disk.format.partedDisk.removePartition(extended)
+
+def addPartition(disklabel, free, part_type, size):
+    """ Return new partition after adding it to the specified disk.
+
+        Arguments:
+
+            disklabel -- disklabel instance to add partition to
+            free -- where to add the partition (parted.Geometry instance)
+            part_type -- partition type (parted.PARTITION_* constant)
+            size -- size (in MB) of the new partition
+
+        The new partition will be aligned.
+
+        Return value is a parted.Partition instance.
+
+    """
+    start = free.start
+    if not disklabel.alignment.isAligned(free, start):
+        start = disklabel.alignment.alignNearest(free, start)
+
+    if part_type == parted.PARTITION_LOGICAL:
+        # make room for logical partition's metadata
+        start += disklabel.alignment.grainSize
+
+    if start != free.start:
+        log.debug("adjusted start sector from %d to %d" % (free.start, start))
+
+    if part_type == parted.PARTITION_EXTENDED:
+        end = free.end
+        length = end - start + 1
+    else:
+        # size is in MB
+        length = sizeToSectors(size, disklabel.partedDevice.sectorSize)
+        end = start + length - 1
+
+    if not disklabel.endAlignment.isAligned(free, end):
+        end = disklabel.endAlignment.alignNearest(free, end)
+        log.debug("adjusted length from %d to %d" % (length, end - start + 1))
+
+    new_geom = parted.Geometry(device=disklabel.partedDevice,
+                               start=start,
+                               end=end)
+
+    max_length = disklabel.partedDisk.maxPartitionLength
+    if max_length and new_geom.length > max_length:
+        raise PartitioningError("requested size exceeds maximum allowed")
+
+    # create the partition and add it to the disk
+    partition = parted.Partition(disk=disklabel.partedDisk,
+                                 type=part_type,
+                                 geometry=new_geom)
+    constraint = parted.Constraint(exactGeom=new_geom)
+    disklabel.partedDisk.addPartition(partition=partition,
+                                      constraint=constraint)
+    return partition
+
+def getFreeRegions(disks):
+    """ Return a list of free regions on the specified disks.
+
+        Arguments:
+
+            disks -- list of parted.Disk instances
+
+        Return value is a list of unaligned parted.Geometry instances.
+
+    """
+    free = []
+    for disk in disks:
+        for f in disk.format.partedDisk.getFreeSpaceRegions():
+            if f.length > 0:
+                free.append(f)
+
+    return free
+
+def doPartitioning(storage, exclusiveDisks=None):
+    """ Allocate and grow partitions.
+
+        When this function returns without error, all PartitionDevice
+        instances must have their parents set to the disk they are
+        allocated on, and their partedPartition attribute set to the
+        appropriate parted.Partition instance from their containing
+        disk. All req_xxxx attributes must be unchanged.
+
+        Arguments:
+
+            storage - Main anaconda Storage instance
+
+        Keyword arguments:
+
+            exclusiveDisks -- list of names of disks to use
+
+    """
+    anaconda = storage.anaconda
+    disks = storage.partitioned
+    if exclusiveDisks:
+        disks = [d for d in disks if d.name in exclusiveDisks]
+
+    for disk in disks:
+        disk.setup()
+
+    partitions = storage.partitions[:]
+    for part in storage.partitions:
+        part.req_bootable = False
+
+        if part.exists or \
+           (storage.deviceImmutable(part) and part.partedPartition):
+            # if the partition is preexisting or part of a complex device
+            # then we shouldn't modify it
+            partitions.remove(part)
+            continue
+
+        if not part.exists:
+            # start over with flexible-size requests
+            part.req_size = part.req_base_size
+
+    # FIXME: isn't there a better place for this to happen?
+    try:
+        bootDev = anaconda.platform.bootDevice()
+    except DeviceError:
+        bootDev = None
+
+    if bootDev:
+        bootDev.req_bootable = True
+
+    removeNewPartitions(disks, partitions)
+    free = getFreeRegions(disks)
+    allocatePartitions(storage, disks, partitions, free)
+    growPartitions(disks, partitions, free)
+
+    # The number and thus the name of partitions may have changed now,
+    # allocatePartitions() takes care of this for new partitions, but not
+    # for pre-existing ones, so we update the name of all partitions here
+    for part in storage.partitions:
+        # needed because of XXX hack below
+        if part.isExtended:
+            continue
+        part.updateName()
+
+    # XXX hack -- if we created any extended partitions we need to add
+    #             them to the tree now
+    for disk in disks:
+        extended = disk.format.extendedPartition
+        if not extended:
+            # remove any obsolete extended partitions
+            for part in storage.partitions:
+                if part.disk == disk and part.isExtended:
+                    if part.exists:
+                        storage.destroyDevice(part)
+                    else:
+                        storage.devicetree._removeDevice(part, moddisk=False)
+            continue
+
+        extendedName = devicePathToName(extended.getDeviceNodeName())
+        # remove any obsolete extended partitions
+        for part in storage.partitions:
+            if part.disk == disk and part.isExtended and \
+               part.partedPartition not in disk.format.partitions:
+                if part.exists:
+                    storage.destroyDevice(part)
+                else:
+                    storage.devicetree._removeDevice(part, moddisk=False)
+
+        device = storage.devicetree.getDeviceByName(extendedName)
+        if device:
+            if not device.exists:
+                # created by us, update partedPartition
+                device.partedPartition = extended
+            continue
+
+        # This is a little odd because normally instantiating a partition
+        # that does not exist means leaving self.parents empty and instead
+        # populating self.req_disks. In this case, we need to skip past
+        # that since this partition is already defined.
+        device = PartitionDevice(extendedName, parents=disk)
+        device.parents = [disk]
+        device.partedPartition = extended
+        # just add the device for now -- we'll handle actions at the last
+        # moment to simplify things
+        storage.devicetree._addDevice(device)
+
+def allocatePartitions(storage, disks, partitions, freespace):
+    """ Allocate partitions based on requested features.
+
+        Non-existing partitions are sorted according to their requested
+        attributes, and then allocated.
+
+        The basic approach to sorting is that the more specifically-
+        defined a request is, the earlier it will be allocated. See
+        the function partitionCompare for details on the sorting
+        criteria.
+
+        The PartitionDevice instances will have their name and parents
+        attributes set once they have been allocated.
+    """
+    log.debug("allocatePartitions: disks=%s ; partitions=%s" %
+                ([d.name for d in disks],
+                 ["%s(id %d)" % (p.name, p.id) for p in partitions]))
+
+    new_partitions = [p for p in partitions if not p.exists]
+    new_partitions.sort(cmp=partitionCompare)
+
+    # the following dicts all use device path strings as keys
+    disklabels = {}     # DiskLabel instances for each disk
+    all_disks = {}      # StorageDevice for each disk
+    for disk in disks:
+        if disk.path not in disklabels.keys():
+            disklabels[disk.path] = disk.format
+            all_disks[disk.path] = disk
+
+    removeNewPartitions(disks, new_partitions)
+
+    for _part in new_partitions:
+        if _part.partedPartition and _part.isExtended:
+            # ignore new extendeds as they are implicit requests
+            continue
+
+        # obtain the set of candidate disks
+        req_disks = []
+        if _part.disk:
+            # we have a already selected a disk for this request
+            req_disks = [_part.disk]
+        elif _part.req_disks:
+            # use the requested disk set
+            req_disks = _part.req_disks
+        else:
+            # no disks specified means any disk will do
+            req_disks = disks
+
+        # sort the disks, making sure the boot disk is first
+        req_disks.sort(key=lambda d: d.name, cmp=storage.compareDisks)
+        boot_index = None
+        for disk in req_disks:
+            if disk.name == storage.anaconda.bootloader.drivelist[0]:
+                boot_index = req_disks.index(disk)
+
+        if boot_index is not None and len(req_disks) > 1:
+            boot_disk = req_disks.pop(boot_index)
+            req_disks.insert(0, boot_disk)
+
+        log.debug("allocating partition: %s ; id: %d ; disks: %s ;\n"
+                  "boot: %s ; primary: %s ; size: %dMB ; grow: %s ; "
+                  "max_size: %s" % (_part.name, _part.id,
+                                    [d.name for d in req_disks],
+                                    _part.req_bootable, _part.req_primary,
+                                    _part.req_size, _part.req_grow,
+                                    _part.req_max_size))
+        free = None
+        use_disk = None
+        part_type = None
+        growth = 0
+        # loop through disks
+        for _disk in req_disks:
+            disklabel = disklabels[_disk.path]
+            sectorSize = disklabel.partedDevice.sectorSize
+            best = None
+            current_free = free
+
+            # for growable requests, we don't want to pass the current free
+            # geometry to getBestFreeRegion -- this allows us to try the
+            # best region from each disk and choose one based on the total
+            # growth it allows
+            if _part.req_grow:
+                current_free = None
+
+            log.debug("checking freespace on %s" % _disk.name)
+
+            new_part_type = getNextPartitionType(disklabel.partedDisk)
+            if new_part_type is None:
+                # can't allocate any more partitions on this disk
+                log.debug("no free partition slots on %s" % _disk.name)
+                continue
+
+            if _part.req_primary and new_part_type != parted.PARTITION_NORMAL:
+                if (disklabel.partedDisk.primaryPartitionCount <
+                    disklabel.partedDisk.maxPrimaryPartitionCount):
+                    # don't fail to create a primary if there are only three
+                    # primary partitions on the disk (#505269)
+                    new_part_type = parted.PARTITION_NORMAL
+                else:
+                    # we need a primary slot and none are free on this disk
+                    log.debug("no primary slots available on %s" % _disk.name)
+                    continue
+
+            best = getBestFreeSpaceRegion(disklabel.partedDisk,
+                                          new_part_type,
+                                          _part.req_size,
+                                          best_free=current_free,
+                                          boot=_part.req_bootable,
+                                          grow=_part.req_grow)
+
+            if best == free and not _part.req_primary and \
+               new_part_type == parted.PARTITION_NORMAL:
+                # see if we can do better with a logical partition
+                log.debug("not enough free space for primary -- trying logical")
+                new_part_type = getNextPartitionType(disklabel.partedDisk,
+                                                     no_primary=True)
+                if new_part_type:
+                    best = getBestFreeSpaceRegion(disklabel.partedDisk,
+                                                  new_part_type,
+                                                  _part.req_size,
+                                                  best_free=current_free,
+                                                  boot=_part.req_bootable,
+                                                  grow=_part.req_grow)
+
+            if best and free != best:
+                update = True
+                if _part.req_grow:
+                    log.debug("evaluating growth potential for new layout")
+                    new_growth = 0
+                    for disk_path in disklabels.keys():
+                        log.debug("calculating growth for disk %s" % disk_path)
+                        # Now we check, for growable requests, which of the two
+                        # free regions will allow for more growth.
+
+                        # set up chunks representing the disks' layouts
+                        temp_parts = []
+                        for _p in new_partitions[:new_partitions.index(_part)]:
+                            if _p.disk.path == disk_path:
+                                temp_parts.append(_p)
+
+                        # add the current request to the temp disk to set up
+                        # its partedPartition attribute with a base geometry
+                        if disk_path == _disk.path:
+                            temp_part = addPartition(disklabel,
+                                                     best,
+                                                     new_part_type,
+                                                     _part.req_size)
+                            _part.partedPartition = temp_part
+                            _part.disk = _disk
+                            temp_parts.append(_part)
+
+                        chunks = getDiskChunks(all_disks[disk_path],
+                                               temp_parts, freespace)
+
+                        # grow all growable requests
+                        disk_growth = 0
+                        disk_sector_size = disklabels[disk_path].partedDevice.sectorSize
+                        for chunk in chunks:
+                            chunk.growRequests()
+                            # record the growth for this layout
+                            new_growth += chunk.growth
+                            disk_growth += chunk.growth
+                            for req in chunk.requests:
+                                log.debug("request %d (%s) growth: %d (%dMB) "
+                                          "size: %dMB" %
+                                          (req.partition.id,
+                                           req.partition.name,
+                                           req.growth,
+                                           sectorsToSize(req.growth,
+                                                         disk_sector_size),
+                                           sectorsToSize(req.growth + req.base,
+                                                         disk_sector_size)))
+                        log.debug("disk %s growth: %d (%dMB)" %
+                                        (disk_path, disk_growth,
+                                         sectorsToSize(disk_growth,
+                                                       disk_sector_size)))
+
+                    disklabel.partedDisk.removePartition(temp_part)
+                    _part.partedPartition = None
+                    _part.disk = None
+
+                    log.debug("total growth: %d sectors" % new_growth)
+
+                    # update the chosen free region unless the previous
+                    # choice yielded greater total growth
+                    if new_growth < growth:
+                        log.debug("keeping old free: %d < %d" % (new_growth,
+                                                                 growth))
+                        update = False
+                    else:
+                        growth = new_growth
+
+                if update:
+                    # now we know we are choosing a new free space,
+                    # so update the disk and part type
+                    log.debug("updating use_disk to %s (%s), type: %s"
+                                % (_disk, _disk.name, new_part_type))
+                    part_type = new_part_type
+                    use_disk = _disk
+                    log.debug("new free: %s (%d-%d / %dMB)" % (best,
+                                                               best.start,
+                                                               best.end,
+                                                               best.getSize()))
+                    log.debug("new free allows for %d sectors of growth" %
+                                growth)
+                    free = best
+
+            # For platforms with a fake boot partition (like Apple Bootstrap or
+            # PReP) and multiple disks, we need to ensure the /boot partition
+            # ends up on the same disk as the fake one.
+            mountpoint = getattr(_part.format, "mountpoint", "")
+            if not mountpoint:
+                mountpoint = ""
+
+            if free and (_part.req_bootable or mountpoint.startswith("/boot")):
+                # if this is a bootable partition we want to
+                # use the first freespace region large enough
+                # to satisfy the request
+                log.debug("found free space for bootable request")
+                break
+
+        if free is None:
+            raise PartitioningError("not enough free space on disks")
+
+        _disk = use_disk
+        disklabel = _disk.format
+
+        # create the extended partition if needed
+        if part_type == parted.PARTITION_EXTENDED:
+            log.debug("creating extended partition")
+            addPartition(disklabel, free, part_type, None)
+
+            # now the extended partition exists, so set type to logical
+            part_type = parted.PARTITION_LOGICAL
+
+            # recalculate freespace
+            log.debug("recalculating free space")
+            free = getBestFreeSpaceRegion(disklabel.partedDisk,
+                                          part_type,
+                                          _part.req_size,
+                                          boot=_part.req_bootable,
+                                          grow=_part.req_grow)
+            if not free:
+                raise PartitioningError("not enough free space after "
+                                        "creating extended partition")
+
+        partition = addPartition(disklabel, free, part_type, _part.req_size)
+        log.debug("created partition %s of %dMB and added it to %s" %
+                (partition.getDeviceNodeName(), partition.getSize(),
+                 disklabel.device))
+
+        # this one sets the name
+        _part.partedPartition = partition
+        _part.disk = _disk
+
+        # parted modifies the partition in the process of adding it to
+        # the disk, so we need to grab the latest version...
+        _part.partedPartition = disklabel.partedDisk.getPartitionByPath(_part.path)
+
+
+class Request(object):
+    """ A partition request.
+
+        Request instances are used for calculating how much to grow
+        partitions.
+    """
+    def __init__(self, partition):
+        """ Create a Request instance.
+
+            Arguments:
+
+                partition -- a PartitionDevice instance
+
+        """
+        self.partition = partition          # storage.devices.PartitionDevice
+        self.growth = 0                     # growth in sectors
+        self.max_growth = 0                 # max growth in sectors
+        self.done = not partition.req_grow  # can we grow this request more?
+        self.base = partition.partedPartition.geometry.length   # base sectors
+
+        sector_size = partition.partedPartition.disk.device.sectorSize
+
+        if partition.req_grow:
+            limits = filter(lambda l: l > 0,
+                        [sizeToSectors(partition.req_max_size, sector_size),
+                         sizeToSectors(partition.format.maxSize, sector_size),
+                         partition.partedPartition.disk.maxPartitionLength])
+
+            if limits:
+                max_sectors = min(limits)
+                self.max_growth = max_sectors - self.base
+
+    @property
+    def growable(self):
+        """ True if this request is growable. """
+        return self.partition.req_grow
+
+    @property
+    def id(self):
+        """ The id of the PartitionDevice this request corresponds to. """
+        return self.partition.id
+
+    def __str__(self):
+        s = ("%(type)s instance --\n"
+             "id = %(id)s  name = %(name)s  growable = %(growable)s\n"
+             "base = %(base)d  growth = %(growth)d  max_grow = %(max_grow)d\n"
+             "done = %(done)s" %
+             {"type": self.__class__.__name__, "id": self.id,
+              "name": self.partition.name, "growable": self.growable,
+              "base": self.base, "growth": self.growth,
+              "max_grow": self.max_growth, "done": self.done})
+        return s
+
+
+class Chunk(object):
+    """ A free region on disk from which partitions will be allocated """
+    def __init__(self, geometry, requests=None):
+        """ Create a Chunk instance.
+
+            Arguments:
+
+                geometry -- parted.Geometry instance describing the free space
+
+
+            Keyword Arguments:
+
+                requests -- list of Request instances allocated from this chunk
+
+        """
+        self.geometry = geometry            # parted.Geometry
+        self.pool = self.geometry.length    # free sector count
+        self.sectorSize = self.geometry.device.sectorSize
+        self.base = 0                       # sum of growable requests' base
+                                            # sizes, in sectors
+        self.requests = []                  # list of Request instances
+        if isinstance(requests, list):
+            for req in requests:
+                self.addRequest(req)
+
+    def __str__(self):
+        s = ("%(type)s instance --\n"
+             "device = %(device)s  start = %(start)d  end = %(end)d\n"
+             "length = %(length)d  size = %(size)d pool = %(pool)d\n"
+             "remaining = %(rem)d  sectorSize = %(sectorSize)d" %
+             {"type": self.__class__.__name__,
+              "device": self.geometry.device.path,
+              "start": self.geometry.start, "end": self.geometry.end,
+              "length": self.geometry.length, "size": self.geometry.getSize(),
+              "pool": self.pool, "rem": self.remaining,
+              "sectorSize": self.sectorSize})
+
+        return s
+
+    def addRequest(self, req):
+        """ Add a Request to this chunk. """
+        log.debug("adding request %d to chunk %s" % (req.partition.id, self))
+        self.requests.append(req)
+        self.pool -= req.base
+
+        if not req.done:
+            self.base += req.base
+
+    def getRequestByID(self, id):
+        """ Retrieve a request from this chunk based on its id. """
+        for request in self.requests:
+            if request.id == id:
+                return request
+
+    @property
+    def growth(self):
+        """ Sum of growth in sectors for all requests in this chunk. """
+        return sum(r.growth for r in self.requests)
+
+    @property
+    def hasGrowable(self):
+        """ True if this chunk contains at least one growable request. """
+        for req in self.requests:
+            if req.growable:
+                return True
+        return False
+
+    @property
+    def remaining(self):
+        """ Number of requests still being grown in this chunk. """
+        return len([d for d in self.requests if not d.done])
+
+    @property
+    def done(self):
+        """ True if we are finished growing all requests in this chunk. """
+        return self.remaining == 0
+
+    def trimOverGrownRequest(self, req, base=None):
+        """ Enforce max growth and return extra sectors to the pool. """
+        if req.max_growth and req.growth >= req.max_growth:
+            if req.growth > req.max_growth:
+                # we've grown beyond the maximum. put some back.
+                extra = req.growth - req.max_growth
+                log.debug("taking back %d (%dMB) from %d (%s)" %
+                            (extra,
+                             sectorsToSize(extra, self.sectorSize),
+                             req.partition.id, req.partition.name))
+                self.pool += extra
+                req.growth = req.max_growth
+
+            # We're done growing this partition, so it no longer
+            # factors into the growable base used to determine
+            # what fraction of the pool each request gets.
+            if base is not None:
+                base -= req.base
+            req.done = True
+
+        return base
+
+    def growRequests(self):
+        """ Calculate growth amounts for requests in this chunk. """
+        log.debug("Chunk.growRequests: %s" % self)
+
+        # sort the partitions by start sector
+        self.requests.sort(key=lambda r: r.partition.partedPartition.geometry.start)
+
+        # we use this to hold the base for the next loop through the
+        # chunk's requests since we want the base to be the same for
+        # all requests in any given growth iteration
+        new_base = self.base
+        last_pool = 0 # used to track changes to the pool across iterations
+        while not self.done and self.pool and last_pool != self.pool:
+            last_pool = self.pool    # to keep from getting stuck
+            self.base = new_base
+            log.debug("%d partitions and %d (%dMB) left in chunk" %
+                        (self.remaining, self.pool,
+                         sectorsToSize(self.pool, self.sectorSize)))
+            for p in self.requests:
+                if p.done:
+                    continue
+
+                # Each partition is allocated free sectors from the pool
+                # based on the relative _base_ sizes of the remaining
+                # growable partitions.
+                share = p.base / float(self.base)
+                growth = int(share * last_pool) # truncate, don't round
+                p.growth += growth
+                self.pool -= growth
+                log.debug("adding %d (%dMB) to %d (%s)" %
+                            (growth,
+                             sectorsToSize(growth, self.sectorSize),
+                             p.partition.id, p.partition.name))
+
+                new_base = self.trimOverGrownRequest(p, base=new_base)
+                log.debug("new grow amount for partition %d (%s) is %d "
+                          "sectors, or %dMB" %
+                            (p.partition.id, p.partition.name, p.growth,
+                             sectorsToSize(p.growth, self.sectorSize)))
+
+        if self.pool:
+            # allocate any leftovers in pool to the first partition
+            # that can still grow
+            for p in self.requests:
+                if p.done:
+                    continue
+
+                p.growth += self.pool
+                self.pool = 0
+
+                self.trimOverGrownRequest(p)
+                if self.pool == 0:
+                    break
+
+
+def getDiskChunks(disk, partitions, free):
+    """ Return a list of Chunk instances representing a disk.
+
+        Arguments:
+
+            disk -- a StorageDevice with a DiskLabel format
+            partitions -- list of PartitionDevice instances
+            free -- list of parted.Geometry instances representing free space
+
+        Partitions and free regions not on the specified disk are ignored.
+
+    """
+    # list of all new partitions on this disk
+    disk_parts = [p for p in partitions if p.disk == disk and not p.exists]
+    disk_free = [f for f in free if f.device.path == disk.path]
+
+
+    chunks = [Chunk(f) for f in disk_free]
+
+    for p in disk_parts:
+        if p.isExtended:
+            # handle extended partitions specially since they are
+            # indeed very special
+            continue
+
+        for i, f in enumerate(disk_free):
+            if f.contains(p.partedPartition.geometry):
+                chunks[i].addRequest(Request(p))
+                break
+
+    return chunks
+
+def growPartitions(disks, partitions, free):
+    """ Grow all growable partition requests.
+
+        Partitions have already been allocated from chunks of free space on
+        the disks. This function does not modify the ordering of partitions
+        or the free chunks from which they are allocated.
+
+        Free space within a given chunk is allocated to each growable
+        partition allocated from that chunk in an amount corresponding to
+        the ratio of that partition's base size to the sum of the base sizes
+        of all growable partitions allocated from the chunk.
+
+        Arguments:
+
+            disks -- a list of all usable disks (DiskDevice instances)
+            partitions -- a list of all partitions (PartitionDevice instances)
+            free -- a list of all free regions (parted.Geometry instances)
+    """
+    log.debug("growPartitions: disks=%s, partitions=%s" %
+            ([d.name for d in disks],
+             ["%s(id %d)" % (p.name, p.id) for p in partitions]))
+    all_growable = [p for p in partitions if p.req_grow]
+    if not all_growable:
+        log.debug("no growable partitions")
+        return
+
+    log.debug("growable partitions are %s" % [p.name for p in all_growable])
+
+    for disk in disks:
+        log.debug("growing partitions on %s" % disk.name)
+        sector_size = disk.format.partedDevice.sectorSize
+
+        # find any extended partition on this disk
+        extended_geometry = getattr(disk.format.extendedPartition,
+                                    "geometry",
+                                    None)  # parted.Geometry
+
+        # list of free space regions on this disk prior to partition allocation
+        disk_free = [f for f in free if f.device.path == disk.path]
+        if not disk_free:
+            log.debug("no free space on %s" % disk.name)
+            continue
+
+        chunks = getDiskChunks(disk, partitions, disk_free)
+        log.debug("disk %s has %d chunks" % (disk.name, len(chunks)))
+        # grow the partitions in each chunk as a group
+        for chunk in chunks:
+            if not chunk.hasGrowable:
+                # no growable partitions in this chunk
+                continue
+
+            chunk.growRequests()
+
+            # recalculate partition geometries
+            disklabel = disk.format
+            start = chunk.geometry.start
+            # align start sector as needed
+            if not disklabel.alignment.isAligned(chunk.geometry, start):
+                start = disklabel.alignment.alignUp(chunk.geometry, start)
+            new_partitions = []
+            for p in chunk.requests:
+                ptype = p.partition.partedPartition.type
+                log.debug("partition %s (%d): %s" % (p.partition.name,
+                                                     p.partition.id, ptype))
+                if ptype == parted.PARTITION_EXTENDED:
+                    continue
+
+                # XXX since we need one metadata sector before each
+                #     logical partition we burn one logical block to
+                #     safely align the start of each logical partition
+                if ptype == parted.PARTITION_LOGICAL:
+                    start += disklabel.alignment.grainSize
+
+                old_geometry = p.partition.partedPartition.geometry
+                new_length = p.base + p.growth
+                end = start + new_length - 1
+                # align end sector as needed
+                if not disklabel.endAlignment.isAligned(chunk.geometry, end):
+                    end = disklabel.endAlignment.alignDown(chunk.geometry, end)
+                new_geometry = parted.Geometry(device=disklabel.partedDevice,
+                                               start=start,
+                                               end=end)
+                log.debug("new geometry for %s: %s" % (p.partition.name,
+                                                       new_geometry))
+                start = end + 1
+                new_partition = parted.Partition(disk=disklabel.partedDisk,
+                                                 type=ptype,
+                                                 geometry=new_geometry)
+                new_partitions.append((new_partition, p.partition))
+
+            # remove all new partitions from this chunk
+            removeNewPartitions([disk], [r.partition for r in chunk.requests])
+            log.debug("back from removeNewPartitions")
+
+            # adjust the extended partition as needed
+            # we will ony resize an extended partition that we created
+            log.debug("extended: %s" % extended_geometry)
+            if extended_geometry and \
+               chunk.geometry.contains(extended_geometry):
+                log.debug("setting up new geometry for extended on %s" % disk.name)
+                ext_start = 0
+                ext_end = 0
+                for (partition, device) in new_partitions:
+                    if partition.type != parted.PARTITION_LOGICAL:
+                        continue
+
+                    if not ext_start or partition.geometry.start < ext_start:
+                        # account for the logical block difference in start
+                        # sector for the extended -v- first logical
+                        # (partition.geometry.start is already aligned)
+                        ext_start = partition.geometry.start - disklabel.alignment.grainSize
+
+                    if not ext_end or partition.geometry.end > ext_end:
+                        ext_end = partition.geometry.end
+
+                new_geometry = parted.Geometry(device=disklabel.partedDevice,
+                                               start=ext_start,
+                                               end=ext_end)
+                log.debug("new geometry for extended: %s" % new_geometry)
+                new_extended = parted.Partition(disk=disklabel.partedDisk,
+                                                type=parted.PARTITION_EXTENDED,
+                                                geometry=new_geometry)
+                ptypes = [p.type for (p, d) in new_partitions]
+                for pt_idx, ptype in enumerate(ptypes):
+                    if ptype == parted.PARTITION_LOGICAL:
+                        new_partitions.insert(pt_idx, (new_extended, None))
+                        break
+
+            # add the partitions with their new geometries to the disk
+            for (partition, device) in new_partitions:
+                if device:
+                    name = device.name
+                else:
+                    # If there was no extended partition on this disk when
+                    # doPartitioning was called we won't have a
+                    # PartitionDevice instance for it.
+                    name = partition.getDeviceNodeName()
+
+                log.debug("setting %s new geometry: %s" % (name,
+                                                           partition.geometry))
+                constraint = parted.Constraint(exactGeom=partition.geometry)
+                disklabel.partedDisk.addPartition(partition=partition,
+                                                  constraint=constraint)
+                path = partition.path
+                if device:
+                    # set the device's name
+                    device.partedPartition = partition
+                    # without this, the path attr will be a basename. eek.
+                    device.disk = disk
+
+                    # make sure we store the disk's version of the partition
+                    newpart = disklabel.partedDisk.getPartitionByPath(path)
+                    device.partedPartition = newpart
+
+
+def hasFreeDiskSpace(storage, exclusiveDisks=None):
+    """Returns True if there is at least 100Mb of free usable space in any of
+       the disks.  False otherwise.
+
+    """
+    # FIXME: This function needs to be implemented.  It is used, at least, by
+    # iw/partition_gui.py.  It should be implemented after the new
+    # doPartitioning code is commited for fedora 13.  Since it returns True
+    # the user will always be able to access the create partition screen. If
+    # no partition can be created, the user will go back to the previous
+    # storage state after seeing a warning message.
+    return True
+
+
+def lvCompare(lv1, lv2):
+    """ More specifically defined lvs come first.
+
+        < 1 => x < y
+          0 => x == y
+        > 1 => x > y
+    """
+    ret = 0
+
+    # larger requests go to the front of the list
+    ret -= cmp(lv1.size, lv2.size) * 100
+
+    # fixed size requests to the front
+    ret += cmp(lv1.req_grow, lv2.req_grow) * 50
+
+    # potentially larger growable requests go to the front
+    if lv1.req_grow and lv2.req_grow:
+        if not lv1.req_max_size and lv2.req_max_size:
+            ret -= 25
+        elif lv1.req_max_size and not lv2.req_max_size:
+            ret += 25
+        else:
+            ret -= cmp(lv1.req_max_size, lv2.req_max_size) * 25
+
+    if ret > 0:
+        ret = 1
+    elif ret < 0:
+        ret = -1
+
+    return ret
+
+def growLVM(storage):
+    """ Grow LVs according to the sizes of the PVs. """
+    for vg in storage.vgs:
+        total_free = vg.freeSpace
+        if total_free < 0:
+            # by now we have allocated the PVs so if there isn't enough
+            # space in the VG we have a real problem
+            raise PartitioningError("not enough space for LVM requests")
+        elif not total_free:
+            log.debug("vg %s has no free space" % vg.name)
+            continue
+
+        log.debug("vg %s: %dMB free ; lvs: %s" % (vg.name, vg.freeSpace,
+                                                  [l.lvname for l in vg.lvs]))
+
+        # figure out how much to grow each LV
+        grow_amounts = {}
+        lv_total = vg.size - total_free
+        log.debug("used: %dMB ; vg.size: %dMB" % (lv_total, vg.size))
+
+        # This first loop is to calculate percentage-based growth
+        # amounts. These are based on total free space.
+        lvs = vg.lvs
+        lvs.sort(cmp=lvCompare)
+        for lv in lvs:
+            if not lv.req_grow or not lv.req_percent:
+                continue
+
+            portion = (lv.req_percent * 0.01)
+            grow = portion * vg.vgFree
+            new_size = lv.req_size + grow
+            if lv.req_max_size and new_size > lv.req_max_size:
+                grow -= (new_size - lv.req_max_size)
+
+            if lv.format.maxSize and lv.format.maxSize < new_size:
+                grow -= (new_size - lv.format.maxSize)
+
+            # clamp growth amount to a multiple of vg extent size
+            grow_amounts[lv.name] = vg.align(grow)
+            total_free -= grow
+            lv_total += grow
+
+        # This second loop is to calculate non-percentage-based growth
+        # amounts. These are based on free space remaining after
+        # calculating percentage-based growth amounts.
+
+        # keep a tab on space not allocated due to format or requested
+        # maximums -- we'll dole it out to subsequent requests
+        leftover = 0
+        for lv in lvs:
+            log.debug("checking lv %s: req_grow: %s ; req_percent: %s"
+                      % (lv.name, lv.req_grow, lv.req_percent))
+            if not lv.req_grow or lv.req_percent:
+                continue
+
+            portion = float(lv.req_size) / float(lv_total)
+            grow = portion * total_free
+            log.debug("grow is %dMB" % grow)
+
+            todo = lvs[lvs.index(lv):]
+            unallocated = reduce(lambda x,y: x+y,
+                                 [l.req_size for l in todo
+                                  if l.req_grow and not l.req_percent])
+            extra_portion = float(lv.req_size) / float(unallocated)
+            extra = extra_portion * leftover
+            log.debug("%s getting %dMB (%d%%) of %dMB leftover space"
+                      % (lv.name, extra, extra_portion * 100, leftover))
+            leftover -= extra
+            grow += extra
+            log.debug("grow is now %dMB" % grow)
+            max_size = lv.req_size + grow
+            if lv.req_max_size and max_size > lv.req_max_size:
+                max_size = lv.req_max_size
+
+            if lv.format.maxSize and max_size > lv.format.maxSize:
+                max_size = lv.format.maxSize
+
+            log.debug("max size is %dMB" % max_size)
+            max_size = max_size
+            leftover += (lv.req_size + grow) - max_size
+            grow = max_size - lv.req_size
+            log.debug("lv %s gets %dMB" % (lv.name, vg.align(grow)))
+            grow_amounts[lv.name] = vg.align(grow)
+
+        if not grow_amounts:
+            log.debug("no growable lvs in vg %s" % vg.name)
+            continue
+
+        # now grow the lvs by the amounts we've calculated above
+        for lv in lvs:
+            if lv.name not in grow_amounts.keys():
+                continue
+            lv.size += grow_amounts[lv.name]
+
+        # now there shouldn't be any free space left, but if there is we
+        # should allocate it to one of the LVs
+        vg_free = vg.freeSpace
+        log.debug("vg %s has %dMB free" % (vg.name, vg_free))
+        if vg_free:
+            for lv in lvs:
+                if not lv.req_grow:
+                    continue
+
+                if lv.req_max_size and lv.size == lv.req_max_size:
+                    continue
+
+                if lv.format.maxSize and lv.size == lv.format.maxSize:
+                    continue
+
+                # first come, first served
+                projected = lv.size + vg.freeSpace
+                if lv.req_max_size and projected > lv.req_max_size:
+                    projected = lv.req_max_size
+
+                if lv.format.maxSize and projected > lv.format.maxSize:
+                    projected = lv.format.maxSize
+
+                log.debug("giving leftover %dMB to %s" % (projected - lv.size,
+                                                          lv.name))
+                lv.size = projected
+
diff --git a/pyanaconda/storage/partspec.py b/pyanaconda/storage/partspec.py
new file mode 100644
index 0000000..8ad81ca
--- /dev/null
+++ b/pyanaconda/storage/partspec.py
@@ -0,0 +1,66 @@
+# partspec.py
+#
+# Copyright (C) 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, or (at your option) any later version.
+# 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.
+#
+# Red Hat Author(s): Chris Lumens <clumens@xxxxxxxxxx>
+#
+
+class PartSpec(object):
+    def __init__(self, mountpoint=None, fstype=None, size=None, maxSize=None,
+                 grow=False, asVol=False, weight=0, requiredSpace=0):
+        """ Create a new storage specification.  These are used to specify
+            the default partitioning layout as an object before we have the
+            storage system up and running.  The attributes are obvious
+            except for the following:
+
+            asVol -- Should this be allocated as a logical volume?  If not,
+                     it will be allocated as a partition.
+            weight -- An integer that modifies the sort algorithm for partition
+                      requests.  A larger value means the partition will end up
+                      closer to the front of the disk.  This is mainly used to
+                      make sure /boot ends up in front, and any special (PReP,
+                      appleboot, etc.) partitions end up in front of /boot.
+                      This value means nothing if asVol=False.
+            requiredSpace -- This value is only taken into account if
+                             asVol=True, and specifies the size in MB that the
+                             containing VG must be for this PartSpec to even
+                             get used.  The VG's size is calculated before any
+                             other LVs are created inside it.  If not enough
+                             space exists, this PartSpec will never get turned
+                             into an LV.
+        """
+
+        self.mountpoint = mountpoint
+        self.fstype = fstype
+        self.size = size
+        self.maxSize = maxSize
+        self.grow = grow
+        self.asVol = asVol
+        self.weight = weight
+        self.requiredSpace = requiredSpace
+
+    def __str__(self):
+        s = ("%(type)s instance (%(id)s) -- \n"
+             "  mountpoint = %(mountpoint)s  asVol = %(asVol)s\n"
+             "  weight = %(weight)s  fstype = %(fstype)s\n"
+             "  size = %(size)s  maxSize = %(maxSize)s  grow = %(grow)s\n" %
+             {"type": self.__class__.__name__, "id": "%#x" % id(self),
+              "mountpoint": self.mountpoint, "asVol": self.asVol,
+              "weight": self.weight, "fstype": self.fstype, "size": self.size,
+              "maxSize": self.maxSize, "grow": self.grow})
+
+        return s
diff --git a/pyanaconda/storage/storage_log.py b/pyanaconda/storage/storage_log.py
new file mode 100644
index 0000000..a52513d
--- /dev/null
+++ b/pyanaconda/storage/storage_log.py
@@ -0,0 +1,32 @@
+import logging
+import anaconda_log
+import inspect
+
+def log_method_call(d, *args, **kwargs):
+    classname = d.__class__.__name__
+    stack = inspect.stack()
+    methodname = stack[1][3]
+
+    spaces = len(stack) * ' '
+    fmt = "%s%s.%s:"
+    fmt_args = [spaces, classname, methodname]
+
+    for arg in args:
+        fmt += " %s ;"
+        fmt_args.append(arg)
+
+    for k, v in kwargs.items():
+        fmt += " %s: %s ;"
+        fmt_args.extend([k, v])
+
+    logger.debug(fmt % tuple(fmt_args))
+
+
+logger = logging.getLogger("storage")
+logger.setLevel(logging.DEBUG)
+anaconda_log.logger.addFileHandler("/tmp/storage.log", logger, logging.DEBUG)
+anaconda_log.logger.addFileHandler("/dev/tty3", logger,
+                                   anaconda_log.DEFAULT_TTY_LEVEL,
+                                   anaconda_log.TTY_FORMAT,
+                                   autoLevel=True)
+anaconda_log.logger.forwardToSyslog(logger)
diff --git a/pyanaconda/storage/udev.py b/pyanaconda/storage/udev.py
new file mode 100644
index 0000000..c8ccfbf
--- /dev/null
+++ b/pyanaconda/storage/udev.py
@@ -0,0 +1,523 @@
+# udev.py
+# Python module for querying the udev database for device information.
+#
+# Copyright (C) 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, or (at your option) any later version.
+# 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.
+#
+# Red Hat Author(s): Dave Lehman <dlehman@xxxxxxxxxx>
+#
+
+import os
+
+import iutil
+from errors import *
+from baseudev import *
+
+import logging
+log = logging.getLogger("storage")
+
+def udev_resolve_devspec(devspec):
+    if not devspec:
+        return None
+
+    import devices as _devices
+    ret = None
+    for dev in udev_get_block_devices():
+        if devspec.startswith("LABEL="):
+            if udev_device_get_label(dev) == devspec[6:]:
+                ret = dev
+                break
+        elif devspec.startswith("UUID="):
+            if udev_device_get_uuid(dev) == devspec[5:]:
+                ret = dev
+                break
+        elif udev_device_get_name(dev) == _devices.devicePathToName(devspec):
+            ret = dev
+            break
+        else:
+            for link in dev["symlinks"]:
+                if devspec == link:
+                    ret = dev
+                    break
+
+    del _devices
+    if ret:
+        return udev_device_get_name(ret)
+
+def udev_resolve_glob(glob):
+    import fnmatch
+    ret = []
+
+    if not glob:
+        return ret
+
+    for dev in udev_get_block_devices():
+        name = udev_device_get_name(dev)
+
+        if fnmatch.fnmatch(name, glob):
+            ret.append(name)
+        else:
+            for link in dev["symlinks"]:
+                if fnmatch.fnmatch(link, glob):
+                    ret.append(name)
+
+    return ret
+
+def udev_get_block_devices():
+    # Wait for scsi adapters to be done with scanning their busses (#583143)
+    iutil.execWithRedirect("modprobe", [ "scsi_wait_scan" ],
+                               stdout = "/dev/tty5", stderr="/dev/tty5")
+    iutil.execWithRedirect("rmmod", [ "scsi_wait_scan" ],
+                               stdout = "/dev/tty5", stderr="/dev/tty5")
+    udev_settle()
+    entries = []
+    for path in udev_enumerate_block_devices():
+        entry = udev_get_block_device(path)
+        if entry:
+            if entry["name"].startswith("md"):
+                # mdraid is really braindead, when a device is stopped
+                # it is no longer usefull in anyway (and we should not
+                # probe it) yet it still sticks around, see bug rh523387
+                state = None
+                state_file = "/sys/%s/md/array_state" % entry["sysfs_path"]
+                if os.access(state_file, os.R_OK):
+                    state = open(state_file).read().strip()
+                if state == "clear":
+                    continue
+            entries.append(entry)
+    return entries
+
+def __is_blacklisted_blockdev(dev_name):
+    """Is this a blockdev we never want for an install?"""
+    if dev_name.startswith("loop") or dev_name.startswith("ram") or dev_name.startswith("fd"):
+        return True
+
+    if os.path.exists("/sys/class/block/%s/device/model" %(dev_name,)):
+        model = open("/sys/class/block/%s/device/model" %(dev_name,)).read()
+        for bad in ("IBM *STMF KERNEL", "SCEI Flash-5", "DGC LUNZ"):
+            if model.find(bad) != -1:
+                log.info("ignoring %s with model %s" %(dev_name, model))
+                return True
+
+    return False
+
+def udev_enumerate_block_devices():
+    import os.path
+
+    return filter(lambda d: not __is_blacklisted_blockdev(os.path.basename(d)),
+                  udev_enumerate_devices(deviceClass="block"))
+
+def udev_get_block_device(sysfs_path):
+    dev = udev_get_device(sysfs_path)
+    if not dev or not dev.has_key("name"):
+        return None
+    else:
+        return dev
+
+
+# These are functions for retrieving specific pieces of information from
+# udev database entries.
+def udev_device_get_name(udev_info):
+    """ Return the best name for a device based on the udev db data. """
+    return udev_info.get("DM_NAME", udev_info["name"])
+
+def udev_device_get_format(udev_info):
+    """ Return a device's format type as reported by udev. """
+    return udev_info.get("ID_FS_TYPE")
+
+def udev_device_get_uuid(udev_info):
+    """ Get the UUID from the device's format as reported by udev. """
+    md_uuid = udev_info.get("MD_UUID")
+    uuid = udev_info.get("ID_FS_UUID")
+    # we don't want to return the array's uuid as a member's uuid
+    if uuid and not md_uuid == uuid:
+        return udev_info.get("ID_FS_UUID")
+
+def udev_device_get_label(udev_info):
+    """ Get the label from the device's format as reported by udev. """
+    return udev_info.get("ID_FS_LABEL")
+
+def udev_device_is_dm(info):
+    """ Return True if the device is a device-mapper device. """
+    return info.has_key("DM_NAME")
+
+def udev_device_is_md(info):
+    """ Return True if the device is a mdraid array device. """
+    # Don't identify partitions on mdraid arrays as raid arrays
+    if udev_device_is_partition(info):
+        return False
+    # isw raid set *members* have MD_METADATA set, but are not arrays!
+    return info.has_key("MD_METADATA") and \
+           info.get("ID_FS_TYPE") != "isw_raid_member"
+
+def udev_device_is_cciss(info):
+    """ Return True if the device is a CCISS device. """
+    return udev_device_get_name(info).startswith("cciss")
+
+def udev_device_is_dasd(info):
+    """ Return True if the device is a dasd device. """
+    devname = info.get("DEVNAME")
+    if devname:
+        return devname.startswith("dasd")
+    else:
+        return False
+
+def udev_device_is_zfcp(info):
+    """ Return True if the device is a zfcp device. """
+    if info.get("DEVTYPE") != "disk":
+        return False
+
+    subsystem = "/sys" + info.get("sysfs_path")
+
+    while True:
+        topdir = os.path.realpath(os.path.dirname(subsystem))
+        driver = "%s/driver" % (topdir,)
+
+        if os.path.islink(driver):
+            subsystemname = os.path.basename(os.readlink(subsystem))
+            drivername = os.path.basename(os.readlink(driver))
+
+            if subsystemname == 'ccw' and drivername == 'zfcp':
+                return True
+
+        newsubsystem = os.path.dirname(topdir)
+
+        if newsubsystem == topdir:
+            break
+
+        subsystem = newsubsystem + "/subsystem"
+
+    return False
+
+def udev_device_get_zfcp_attribute(info, attr=None):
+    """ Return the value of the specified attribute of the zfcp device. """
+    if not attr:
+        log.debug("udev_device_get_zfcp_attribute() called with attr=None")
+        return None
+
+    attribute = "/sys%s/device/%s" % (info.get("sysfs_path"), attr,)
+    attribute = os.path.realpath(attribute)
+
+    if not os.path.isfile(attribute):
+        log.warning("%s is not a valid zfcp attribute" % (attribute,))
+        return None
+
+    return open(attribute, "r").read().strip()
+
+def udev_device_get_dasd_bus_id(info):
+    """ Return the CCW bus ID of the dasd device. """
+    return info.get("sysfs_path").split("/")[-3]
+
+def udev_device_get_dasd_flag(info, flag=None):
+    """ Return the specified flag for the dasd device. """
+    if flag is None:
+        return None
+
+    path = "/sys" + info.get("sysfs_path") + "/device/" + flag
+    if not os.path.isfile(path):
+        return None
+
+    return open(path, 'r').read().strip()
+
+def udev_device_is_cdrom(info):
+    """ Return True if the device is an optical drive. """
+    # FIXME: how can we differentiate USB drives from CD-ROM drives?
+    #         -- USB drives also generate a sdX device.
+    return info.get("ID_CDROM") == "1"
+
+def udev_device_is_disk(info):
+    """ Return True is the device is a disk. """
+    if udev_device_is_cdrom(info):
+        return False
+    has_range = os.path.exists("/sys/%s/range" % info['sysfs_path'])
+    return info.get("DEVTYPE") == "disk" or has_range
+
+def udev_device_is_partition(info):
+    has_start = os.path.exists("/sys/%s/start" % info['sysfs_path'])
+    return info.get("DEVTYPE") == "partition" or has_start
+
+def udev_device_get_serial(udev_info):
+    """ Get the serial number/UUID from the device as reported by udev. """
+    return udev_info.get("ID_SERIAL_SHORT", udev_info.get("ID_SERIAL"))
+
+def udev_device_get_wwid(udev_info):
+    """ The WWID of a device is typically just its serial number, but with
+        colons in the name to make it more readable. """
+    serial = udev_device_get_serial(udev_info)
+
+    if serial and len(serial) == 32:
+        retval = ""
+        for i in range(0, 16):
+            retval += serial[i*2:i*2+2] + ":"
+
+        return retval[0:-1]
+
+    return ""
+
+def udev_device_get_vendor(udev_info):
+    """ Get the vendor of the device as reported by udev. """
+    return udev_info.get("ID_VENDOR_FROM_DATABASE", udev_info.get("ID_VENDOR"))
+
+def udev_device_get_model(udev_info):
+    """ Get the model of the device as reported by udev. """
+    return udev_info.get("ID_MODEL_FROM_DATABASE", udev_info.get("ID_MODEL"))
+
+def udev_device_get_bus(udev_info):
+    """ Get the bus a device is connected to the system by. """
+    return udev_info.get("ID_BUS", "").upper()
+
+def udev_device_get_path(info):
+    return info["ID_PATH"]
+
+def udev_device_get_by_path(info):
+    if info.has_key('symlinks'):
+        for link in info['symlinks']:
+            if link.startswith('/dev/disk/by-path/'):
+                return link
+
+    return None
+
+def udev_device_get_sysfs_path(info):
+    return info['sysfs_path']
+
+def udev_device_get_major(info):
+    return int(info["MAJOR"])
+
+def udev_device_get_minor(info):
+    return int(info["MINOR"])
+
+def udev_device_get_md_level(info):
+    return info.get("MD_LEVEL")
+
+def udev_device_get_md_devices(info):
+    return int(info["MD_DEVICES"])
+
+def udev_device_get_md_uuid(info):
+    return info["MD_UUID"]
+
+def udev_device_get_md_container(info):
+    return info.get("MD_CONTAINER")
+
+def udev_device_get_md_name(info):
+    return info.get("MD_DEVNAME")
+
+def udev_device_get_vg_name(info):
+    return info['LVM2_VG_NAME']
+
+def udev_device_get_vg_uuid(info):
+    return info['LVM2_VG_UUID']
+
+def udev_device_get_vg_size(info):
+    # lvm's decmial precision is not configurable, so we tell it to use
+    # KB and convert to MB here
+    return float(info['LVM2_VG_SIZE']) / 1024
+
+def udev_device_get_vg_free(info):
+    # lvm's decmial precision is not configurable, so we tell it to use
+    # KB and convert to MB here
+    return float(info['LVM2_VG_FREE']) / 1024
+
+def udev_device_get_vg_extent_size(info):
+    # lvm's decmial precision is not configurable, so we tell it to use
+    # KB and convert to MB here
+    return float(info['LVM2_VG_EXTENT_SIZE']) / 1024
+
+def udev_device_get_vg_extent_count(info):
+    return int(info['LVM2_VG_EXTENT_COUNT'])
+
+def udev_device_get_vg_free_extents(info):
+    return int(info['LVM2_VG_FREE_COUNT'])
+
+def udev_device_get_vg_pv_count(info):
+    return int(info['LVM2_PV_COUNT'])
+
+def udev_device_get_pv_pe_start(info):
+    # lvm's decmial precision is not configurable, so we tell it to use
+    # KB and convert to MB here
+    return float(info['LVM2_PE_START']) / 1024
+
+def udev_device_get_lv_names(info):
+    names = info['LVM2_LV_NAME']
+    if not names:
+        names = []
+    elif not isinstance(names, list):
+        names = [names]
+    return names
+
+def udev_device_get_lv_uuids(info):
+    uuids = info['LVM2_LV_UUID']
+    if not uuids:
+        uuids = []
+    elif not isinstance(uuids, list):
+        uuids = [uuids]
+    return uuids
+
+def udev_device_get_lv_sizes(info):
+    # lvm's decmial precision is not configurable, so we tell it to use
+    # KB and convert to MB here
+    sizes = info['LVM2_LV_SIZE']
+    if not sizes:
+        sizes = []
+    elif not isinstance(sizes, list):
+        sizes = [sizes]
+
+    return [float(s) / 1024 for s in sizes]
+
+def udev_device_get_lv_attr(info):
+    attr = info['LVM2_LV_ATTR']
+    if not attr:
+        attr = []
+    elif not isinstance(attr, list):
+        attr = [attr]
+    return attr
+
+def udev_device_is_biosraid(info):
+    # Note that this function does *not* identify raid sets.
+    # Tests to see if device is parto of a dmraid set.
+    # dmraid and mdraid have the same ID_FS_USAGE string, ID_FS_TYPE has a
+    # string that describes the type of dmraid (isw_raid_member...),  I don't
+    # want to maintain a list and mdraid's ID_FS_TYPE='linux_raid_member', so
+    # dmraid will be everything that is raid and not linux_raid_member
+    from formats.dmraid import DMRaidMember
+    from formats.mdraid import MDRaidMember
+    if info.has_key("ID_FS_TYPE") and \
+            (info["ID_FS_TYPE"] in DMRaidMember._udevTypes or \
+             info["ID_FS_TYPE"] in MDRaidMember._udevTypes) and \
+            info["ID_FS_TYPE"] != "linux_raid_member":
+        return True
+
+    return False
+
+def udev_device_get_dmraid_partition_disk(info):
+    try:
+        p_index = info["DM_NAME"].rindex("p")
+    except (KeyError, AttributeError, ValueError):
+        return None
+
+    if not info["DM_NAME"][p_index+1:].isdigit():
+        return None
+
+    return info["DM_NAME"][:p_index]
+
+def udev_device_is_dmraid_partition(info, devicetree):
+    diskname = udev_device_get_dmraid_partition_disk(info)
+    dmraid_devices = devicetree.getDevicesByType("dm-raid array")
+
+    for device in dmraid_devices:
+        if diskname == device.name:
+            return True
+
+    return False
+
+def udev_device_is_multipath_partition(info, devicetree):
+    """ Return True if the device is a partition of a multipath device. """
+    if not udev_device_is_dm(info):
+        return False
+    if not info["DM_NAME"].startswith("mpath"):
+        return False
+    diskname = udev_device_get_dmraid_partition_disk(info)
+    if diskname is None:
+        return False
+
+    # this is sort of a lame check, but basically, if diskname gave us "mpath0"
+    # and we start with "mpath" but we're not "mpath0", then we must be
+    # "mpath0" plus some non-numeric crap.
+    if diskname != info["DM_NAME"]:
+        return True
+
+    return False
+
+def udev_device_get_multipath_partition_disk(info):
+    """ Return True if the device is a partition of a multipath device. """
+    # XXX PJFIX This whole function is crap.
+    if not udev_device_is_dm(info):
+        return False
+    if not info["DM_NAME"].startswith("mpath"):
+        return False
+    diskname = udev_device_get_dmraid_partition_disk(info)
+    return diskname
+
+def udev_device_is_multipath_member(info):
+    """ Return True if the device is part of a multipath. """
+    return info.get("ID_FS_TYPE") == "multipath_member"
+
+def udev_device_get_multipath_name(info):
+    """ Return the name of the multipath that the device is a member of. """
+    if udev_device_is_multipath_member(info):
+        return info['ID_MPATH_NAME']
+    return None
+
+# iscsi disks have ID_PATH in the form of:
+# ip-${iscsi_address}:${iscsi_port}-iscsi-${iscsi_tgtname}-lun-${lun}
+# Note that in the case of IPV6 iscsi_address itself can contain :
+# too, but iscsi_port never contains :
+def udev_device_is_iscsi(info):
+    try:
+        path_components = udev_device_get_path(info).split("-")
+
+        if info["ID_BUS"] == "scsi" and len(path_components) >= 6 and \
+           path_components[0] == "ip" and path_components[2] == "iscsi":
+            return True
+    except KeyError:
+        pass
+
+    return False
+
+def udev_device_get_iscsi_name(info):
+    path_components = udev_device_get_path(info).split("-")
+
+    # Tricky, the name itself contains atleast 1 - char
+    return "-".join(path_components[3:len(path_components)-2])
+
+def udev_device_get_iscsi_address(info):
+    path_components = udev_device_get_path(info).split("-")
+
+    # IPV6 addresses contain : within the address, so take everything
+    # before the last : as address
+    return ":".join(path_components[1].split(":")[:-1])
+
+def udev_device_get_iscsi_port(info):
+    path_components = udev_device_get_path(info).split("-")
+
+    # IPV6 contains : within the address, the part after the last : is the port
+    return path_components[1].split(":")[-1]
+
+# fcoe disks have ID_PATH in the form of:
+# pci-eth#-fc-${id}
+# fcoe parts look like this:
+# pci-eth#-fc-${id}-part#
+def udev_device_is_fcoe(info):
+    try:
+        path_components = udev_device_get_path(info).split("-")
+
+        if info["ID_BUS"] == "scsi" and len(path_components) >= 4 and \
+           path_components[0] == "pci" and path_components[2] == "fc" and \
+           path_components[1][0:3] == "eth":
+            return True
+    except LookupError:
+        pass
+
+    return False
+
+def udev_device_get_fcoe_nic(info):
+    path_components = udev_device_get_path(info).split("-")
+
+    return path_components[1]
+
+def udev_device_get_fcoe_identifier(info):
+    path_components = udev_device_get_path(info).split("-")
+
+    return path_components[3]
diff --git a/pyanaconda/storage/zfcp.py b/pyanaconda/storage/zfcp.py
new file mode 100644
index 0000000..7692cad
--- /dev/null
+++ b/pyanaconda/storage/zfcp.py
@@ -0,0 +1,441 @@
+#
+# zfcp.py - mainframe zfcp configuration install data
+#
+# Copyright (C) 2001, 2002, 2003, 2004  Red Hat, Inc.  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 as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# 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, see <http://www.gnu.org/licenses/>.
+#
+# Author(s): Karsten Hopp <karsten@xxxxxxxxxx>
+#
+
+import string
+import os
+from constants import *
+from udev import udev_settle
+
+import gettext
+_ = lambda x: gettext.ldgettext("anaconda", x)
+
+import logging
+log = logging.getLogger("anaconda")
+import warnings
+
+def loggedWriteLineToFile(fn, value):
+    f = open(fn, "w")
+    log.debug("echo %s > %s" % (value, fn))
+    f.write("%s\n" % (value))
+    f.close()
+
+zfcpsysfs = "/sys/bus/ccw/drivers/zfcp"
+scsidevsysfs = "/sys/bus/scsi/devices"
+
+class ZFCPDevice:
+    def __init__(self, devnum, wwpn, fcplun):
+        self.devnum = self.sanitizeDeviceInput(devnum)
+        self.wwpn = self.sanitizeWWPNInput(wwpn)
+        self.fcplun = self.sanitizeFCPLInput(fcplun)
+
+        if not self.checkValidDevice(self.devnum):
+            raise ValueError, _("You have not specified a device number or the number is invalid")
+        if not self.checkValidWWPN(self.wwpn):
+            raise ValueError, _("You have not specified a worldwide port name or the name is invalid.")
+        if not self.checkValidFCPLun(self.fcplun):
+            raise ValueError, _("You have not specified a FCP LUN or the number is invalid.")
+
+    def __str__(self):
+        return "%s %s %s" %(self.devnum, self.wwpn, self.fcplun)
+
+    def sanitizeDeviceInput(self, dev):
+        if dev is None or dev == "":
+            return None
+        dev = dev.lower()
+        bus = dev[:string.rfind(dev, ".") + 1]
+        dev = dev[string.rfind(dev, ".") + 1:]
+        dev = "0" * (4 - len(dev)) + dev
+        if not len(bus):
+            return "0.0." + dev
+        else:
+            return bus + dev
+
+    def sanitizeWWPNInput(self, id):
+        if id is None or id == "":
+            return None
+        id = id.lower()
+        if id[:2] != "0x":
+            return "0x" + id
+        return id
+
+    # ZFCP LUNs are usually entered as 16 bit, sysfs accepts only 64 bit 
+    # (#125632), expand with zeroes if necessary
+    def sanitizeFCPLInput(self, lun):
+        if lun is None or lun == "":
+            return None
+        lun = lun.lower()
+        if lun[:2] == "0x":
+            lun = lun[2:]
+        lun = "0x" + "0" * (4 - len(lun)) + lun
+        lun = lun + "0" * (16 - len(lun) + 2)
+        return lun
+
+    def _hextest(self, hex):
+        try:
+            int(hex, 16)
+            return True
+        except TypeError:
+            return False
+
+    def checkValidDevice(self, id):
+        if id is None or id == "":
+            return False
+        if len(id) != 8:             # p.e. 0.0.0600
+            return False
+        if id[0] not in string.digits or id[2] not in string.digits:
+            return False
+        if id[1] != "." or id[3] != ".":
+            return False
+        return self._hextest(id[4:])
+
+    def checkValid64BitHex(self, hex):
+        if hex is None or hex == "":
+            return False
+        if len(hex) != 18:
+            return False
+        return self._hextest(hex)
+    checkValidWWPN = checkValidFCPLun = checkValid64BitHex
+
+    def onlineDevice(self):
+        online = "%s/%s/online" %(zfcpsysfs, self.devnum)
+        portadd = "%s/%s/port_add" %(zfcpsysfs, self.devnum)
+        portdir = "%s/%s/%s" %(zfcpsysfs, self.devnum, self.wwpn)
+        unitadd = "%s/unit_add" %(portdir)
+        unitdir = "%s/%s" %(portdir, self.fcplun)
+        failed = "%s/failed" %(unitdir)
+
+        try:
+            if not os.path.exists(online):
+                loggedWriteLineToFile("/proc/cio_ignore",
+                                      "free %s" %(self.devnum,))
+                udev_settle()
+        except IOError as e:
+            raise ValueError, _("Could not free zFCP device %(devnum)s from "
+                                "device ignore list (%(e)s).") \
+                              % {'devnum': self.devnum, 'e': e}
+
+        if not os.path.exists(online):
+            raise ValueError, _(
+                "zFCP device %s not found, not even in device ignore list."
+                %(self.devnum,))
+
+        try:
+            f = open(online, "r")
+            devonline = f.readline().strip()
+            f.close()
+            if devonline != "1":
+                loggedWriteLineToFile(online, "1")
+            else:
+                log.info("zFCP device %s already online." %(self.devnum,))
+        except IOError as e:
+            raise ValueError, _("Could not set zFCP device %(devnum)s "
+                                "online (%(e)s).") \
+                              % {'devnum': self.devnum, 'e': e}
+
+        if not os.path.exists(portdir):
+            if os.path.exists(portadd):
+                # older zfcp sysfs interface
+                try:
+                    loggedWriteLineToFile(portadd, self.wwpn)
+                    udev_settle()
+                except IOError as e:
+                    raise ValueError, _("Could not add WWPN %(wwpn)s to zFCP "
+                                        "device %(devnum)s (%(e)s).") \
+                                      % {'wwpn': self.wwpn,
+                                         'devnum': self.devnum,
+                                         'e': e}
+            else:
+                # newer zfcp sysfs interface with auto port scan
+                raise ValueError, _("WWPN %(wwpn)s not found at zFCP device "
+                                    "%(devnum)s.") % {'wwpn': self.wwpn,
+                                                      'devnum': self.devnum}
+        else:
+            if os.path.exists(portadd):
+                # older zfcp sysfs interface
+                log.info("WWPN %(wwpn)s at zFCP device %(devnum)s already "
+                         "there.") % {'wwpn': self.wwpn,
+                                      'devnum': self.devnum}
+
+        if not os.path.exists(unitdir):
+            try:
+                loggedWriteLineToFile(unitadd, self.fcplun)
+                udev_settle()
+            except IOError as e:
+                raise ValueError, _("Could not add LUN %(fcplun)s to WWPN "
+                                    "%(wwpn)s on zFCP device %(devnum)s "
+                                    "(%(e)s).") \
+                                  % {'fcplun': self.fcplun, 'wwpn': self.wwpn,
+                                     'devnum': self.devnum, 'e': e}
+        else:
+            raise ValueError, _("LUN %(fcplun)s at WWPN %(wwpn)s on zFCP "
+                                "device %(devnum)s already configured.") \
+                              % {'fcplun': self.fcplun,
+                                 'wwpn': self.wwpn,
+                                 'devnum': self.devnum}
+
+        fail = "0"
+        try:
+            f = open(failed, "r")
+            fail = f.readline().strip()
+            f.close()
+        except IOError as e:
+            raise ValueError, _("Could not read failed attribute of LUN "
+                                "%(fcplun)s at WWPN %(wwpn)s on zFCP device "
+                                "%(devnum)s (%(e)s).") \
+                              % {'fcplun': self.fcplun,
+                                 'wwpn': self.wwpn,
+                                 'devnum': self.devnum,
+                                 'e': e}
+        if fail != "0":
+            self.offlineDevice()
+            raise ValueError, _("Failed LUN %(fcplun)s at WWPN %(wwpn)s on "
+                                "zFCP device %(devnum)s removed again.") \
+                              % {'fcplun': self.fcplun,
+                                 'wwpn': self.wwpn,
+                                 'devnum': self.devnum}
+
+        return True
+
+    def offlineSCSIDevice(self):
+        f = open("/proc/scsi/scsi", "r")
+        lines = f.readlines()
+        f.close()
+        # alternatively iterate over /sys/bus/scsi/devices/*:0:*:*/
+
+        for line in lines:
+            if not line.startswith("Host"):
+                continue
+            scsihost = string.split(line)
+            host = scsihost[1]
+            channel = "0"
+            id = scsihost[5]
+            lun = scsihost[7]
+            scsidev = "%s:%s:%s:%s" % (host[4:], channel, id, lun)
+            fcpsysfs = "%s/%s" % (scsidevsysfs, scsidev)
+            scsidel = "%s/%s/delete" % (scsidevsysfs, scsidev)
+
+            f = open("%s/hba_id" %(fcpsysfs), "r")
+            fcphbasysfs = f.readline().strip()
+            f.close()
+            f = open("%s/wwpn" %(fcpsysfs), "r")
+            fcpwwpnsysfs = f.readline().strip()
+            f.close()
+            f = open("%s/fcp_lun" %(fcpsysfs), "r")
+            fcplunsysfs = f.readline().strip()
+            f.close()
+
+            if fcphbasysfs == self.devnum \
+                    and fcpwwpnsysfs == self.wwpn \
+                    and fcplunsysfs == self.fcplun:
+                loggedWriteLineToFile(scsidel, "1")
+                udev_settle()
+                return
+
+        log.warn("no scsi device found to delete for zfcp %s %s %s"
+                 %(self.devnum, self.wwpn, self.fcplun))
+
+    def offlineDevice(self):
+        offline = "%s/%s/online" %(zfcpsysfs, self.devnum)
+        portadd = "%s/%s/port_add" %(zfcpsysfs, self.devnum)
+        portremove = "%s/%s/port_remove" %(zfcpsysfs, self.devnum)
+        unitremove = "%s/%s/%s/unit_remove" %(zfcpsysfs, self.devnum, self.wwpn)
+        portdir = "%s/%s/%s" %(zfcpsysfs, self.devnum, self.wwpn)
+        devdir = "%s/%s" %(zfcpsysfs, self.devnum)
+
+        try:
+            self.offlineSCSIDevice()
+        except IOError as e:
+            raise ValueError, _("Could not correctly delete SCSI device of "
+                                "zFCP %(devnum)s %(wwpn)s %(fcplun)s "
+                                "(%(e)s).") \
+                              % {'devnum': self.devnum, 'wwpn': self.wwpn,
+                                 'fcplun': self.fcplun, 'e': e}
+
+        try:
+            loggedWriteLineToFile(unitremove, self.fcplun)
+        except IOError as e:
+            raise ValueError, _("Could not remove LUN %(fcplun)s at WWPN "
+                                "%(wwpn)s on zFCP device %(devnum)s "
+                                "(%(e)s).") \
+                              % {'fcplun': self.fcplun, 'wwpn': self.wwpn,
+                                 'devnum': self.devnum, 'e': e}
+
+        if os.path.exists(portadd):
+            # only try to remove ports with older zfcp sysfs interface
+            for lun in os.listdir(portdir):
+                if lun.startswith("0x") and \
+                        os.path.isdir(os.path.join(portdir, lun)):
+                    log.info("Not removing WWPN %s at zFCP device %s since port still has other LUNs, e.g. %s."
+                             %(self.wwpn, self.devnum, lun))
+                    return True
+
+            try:
+                loggedWriteLineToFile(portremove, self.wwpn)
+            except IOError as e:
+                raise ValueError, _("Could not remove WWPN %(wwpn)s on zFCP "
+                                    "device %(devnum)s (%(e)s).") \
+                                  % {'wwpn': self.wwpn,
+                                     'devnum': self.devnum, 'e': e}
+
+        if os.path.exists(portadd):
+            # older zfcp sysfs interface
+            for port in os.listdir(devdir):
+                if port.startswith("0x") and \
+                        os.path.isdir(os.path.join(devdir, port)):
+                    log.info("Not setting zFCP device %s offline since it still has other ports, e.g. %s."
+                             %(self.devnum, port))
+                    return True
+        else:
+            # newer zfcp sysfs interface with auto port scan
+            import glob
+            luns = glob.glob("%s/0x????????????????/0x????????????????"
+                          %(devdir,))
+            if len(luns) != 0:
+                log.info("Not setting zFCP device %s offline since it still has other LUNs, e.g. %s."
+                         %(self.devnum, luns[0]))
+                return True
+
+        try:
+            loggedWriteLineToFile(offline, "0")
+        except IOError as e:
+            raise ValueError, _("Could not set zFCP device %(devnum)s "
+                                "offline (%(e)s).") \
+                              % {'devnum': self.devnum, 'e': e}
+
+        return True
+
+class ZFCP:
+    """ ZFCP utility class.
+
+        This class will automatically online to ZFCP drives configured in
+        /tmp/fcpconfig when the startup() method gets called. It can also be
+        used to manually configure ZFCP devices through the addFCP() method.
+
+        As this class needs to make sure that /tmp/fcpconfig configured
+        drives are only onlined once and as it keeps a global list of all ZFCP
+        devices it is implemented as a Singleton.
+    """
+
+    def __init__(self):
+        self.fcpdevs = []
+        self.hasReadConfig = False
+        self.down = True
+
+    # So that users can write zfcp() to get the singleton instance
+    def __call__(self):
+        return self
+
+    def readConfig(self):
+        try:
+            f = open("/tmp/fcpconfig", "r")
+        except IOError:
+            log.info("no /tmp/fcpconfig; not configuring zfcp")
+            return
+
+        lines = f.readlines()
+        f.close()
+        for line in lines:
+            # each line is a string separated list of values to describe a dev
+            # there are two valid formats for the line:
+            #   devnum scsiid wwpn scsilun fcplun    (scsiid + scsilun ignored)
+            #   devnum wwpn fcplun
+            line = string.strip(line).lower()
+            if line.startswith("#"):
+                continue
+            fcpconf = string.split(line)
+            if len(fcpconf) == 3:
+                devnum = fcpconf[0]
+                wwpn = fcpconf[1]
+                fcplun = fcpconf[2]
+            elif len(fcpconf) == 5:
+                warnings.warn("SCSI ID and SCSI LUN values for ZFCP devices are ignored and deprecated.", DeprecationWarning)
+                devnum = fcpconf[0]
+                wwpn = fcpconf[2]
+                fcplun = fcpconf[4]
+            else:
+                log.warn("Invalid line found in /tmp/fcpconfig!")
+                continue
+
+            try:
+                self.addFCP(devnum, wwpn, fcplun)
+            except ValueError, e:
+                log.warn(str(e))
+                continue
+
+    def addFCP(self, devnum, wwpn, fcplun):
+        d = ZFCPDevice(devnum, wwpn, fcplun)
+        if d.onlineDevice():
+            self.fcpdevs.append(d)
+
+    def shutdown(self):
+        if self.down:
+            return
+        self.down = True
+        if len(self.fcpdevs) == 0:
+            return
+        for d in self.fcpdevs:
+            try:
+                d.offlineDevice()
+            except ValueError, e:
+                log.warn(str(e))
+
+    def startup(self):
+        if not self.down:
+            return
+        self.down = False
+        if not self.hasReadConfig:
+            self.readConfig()
+            self.hasReadConfig = True
+            # readConfig calls addFCP which calls onlineDevice already
+            return
+            
+        if len(self.fcpdevs) == 0:
+            return
+        for d in self.fcpdevs:
+            try:
+                d.onlineDevice()
+            except ValueError, e:
+                log.warn(str(e))
+
+    def writeKS(self, f):
+        if len(self.fcpdevs) == 0:
+            return
+        for d in self.fcpdevs:
+            f.write("zfcp --devnum %s --wwpn %s --fcplun %s\n" %(d.devnum,
+                                                                 d.wwpn,
+                                                                 d.fcplun))
+
+    def write(self, instPath):
+        if len(self.fcpdevs) == 0:
+            return
+        f = open(instPath + "/etc/zfcp.conf", "w")
+        for d in self.fcpdevs:
+            f.write("%s\n" %(d,))
+        f.close()
+        
+        f = open(instPath + "/etc/modprobe.conf", "a")
+        f.write("alias scsi_hostadapter zfcp\n")
+        f.close()
+
+# Create ZFCP singleton
+ZFCP = ZFCP()
+
+# vim:tw=78:ts=4:et:sw=4
diff --git a/pyanaconda/text.py b/pyanaconda/text.py
new file mode 100644
index 0000000..cb37467
--- /dev/null
+++ b/pyanaconda/text.py
@@ -0,0 +1,692 @@
+#
+# text.py - text mode frontend to anaconda
+#
+# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006  Red Hat, Inc.
+# 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 as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# 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, see <http://www.gnu.org/licenses/>.
+#
+# Author(s): Erik Troan <ewt@xxxxxxxxxx>
+#            Matt Wilson <msw@xxxxxxxxxx>
+#
+
+from snack import *
+import sys
+import os
+import isys
+import iutil
+import time
+import signal
+import parted
+import product
+import string
+from language import expandLangs
+from flags import flags
+from constants_text import *
+from constants import *
+from network import hasActiveNetDev
+from installinterfacebase import InstallInterfaceBase
+import imputil
+
+import gettext
+_ = lambda x: gettext.ldgettext("anaconda", x)
+P_ = lambda x, y, z: gettext.ldngettext("anaconda", x, y, z)
+
+import logging
+log = logging.getLogger("anaconda")
+
+stepToClasses = {
+    "language" : ("language_text", "LanguageWindow"),
+    "keyboard" : ("keyboard_text", "KeyboardWindow"),
+    "welcome" : ("welcome_text", "WelcomeWindow"),
+    "parttype" : ("partition_text", "PartitionTypeWindow"),
+    "addswap" : ("upgrade_text", "UpgradeSwapWindow"),
+    "upgrademigratefs" : ("upgrade_text", "UpgradeMigrateFSWindow"),
+    "zfcpconfig": ("zfcp_text", ("ZFCPWindow")),
+    "findinstall" : ("upgrade_text", ("UpgradeExamineWindow")),
+    "upgbootloader": ("upgrade_bootloader_text", "UpgradeBootloaderWindow"),
+    "network" : ("network_text", ("HostnameWindow")),
+    "timezone" : ("timezone_text", "TimezoneWindow"),
+    "accounts" : ("userauth_text", "RootPasswordWindow"),
+    "tasksel": ("task_text", "TaskWindow"),
+    "install" : ("progress_text", "setupForInstall"),
+    "complete" : ("complete_text", "FinishedWindow"),
+}
+
+if iutil.isS390():
+    stepToClasses["bootloader"] = ("zipl_text", ( "ZiplWindow"))
+
+class InstallWindow:
+    def __call__ (self, screen):
+        raise RuntimeError, "Unimplemented screen"
+
+class WaitWindow:
+    def pop(self):
+	self.screen.popWindow()
+	self.screen.refresh()
+
+    def refresh(self):
+        pass
+
+    def __init__(self, screen, title, text):
+	self.screen = screen
+	width = 40
+	if (len(text) < width): width = len(text)
+
+	t = TextboxReflowed(width, text)
+
+	g = GridForm(self.screen, title, 1, 1)
+	g.add(t, 0, 0)
+	g.draw()
+	self.screen.refresh()
+
+class OkCancelWindow:
+    def getrc(self):
+	return self.rc
+
+    def __init__(self, screen, title, text):
+	rc = ButtonChoiceWindow(screen, title, text,
+			        buttons=[TEXT_OK_BUTTON, _("Cancel")])
+	if rc == string.lower(_("Cancel")):
+	    self.rc = 1
+	else:
+	    self.rc = 0
+
+class ProgressWindow:
+    def pop(self):
+	self.screen.popWindow()
+	self.screen.refresh()
+        del self.scale
+        self.scale = None
+
+    def pulse(self):
+        pass
+
+    def set(self, amount):
+        self.scale.set(int(float(amount) * self.multiplier))
+        self.screen.refresh()
+
+    def refresh(self):
+        pass
+
+    def __init__(self, screen, title, text, total, updpct = 0.05, pulse = False):
+        self.multiplier = 1
+        if total == 1.0:
+            self.multiplier = 100
+	self.screen = screen
+	width = 55
+	if (len(text) > width): width = len(text)
+
+	t = TextboxReflowed(width, text)
+
+	g = GridForm(self.screen, title, 1, 2)
+	g.add(t, 0, 0, (0, 0, 0, 1), anchorLeft=1)
+
+        self.scale = Scale(int(width), int(float(total) * self.multiplier))
+        if not pulse:
+            g.add(self.scale, 0, 1)
+                
+	g.draw()
+	self.screen.refresh()
+
+class LuksPassphraseWindow:
+    def __init__(self, screen, passphrase = "", preexist = False):
+        self.screen = screen
+        self.passphrase = passphrase
+        self.minLength = 8
+        self.preexist = preexist
+        self.txt = _("Choose a passphrase for the encrypted devices. You "
+                     "will be prompted for this passphrase during system boot.")
+        self.rc = None
+
+    def run(self):
+        toplevel = GridForm(self.screen, _("Passphrase for encrypted device"),
+                            1, 5)
+
+        txt = TextboxReflowed(65, self.txt)
+        toplevel.add(txt, 0, 0)
+
+        passphraseentry = Entry(60, password = 1)
+        toplevel.add(passphraseentry, 0, 1, (0,0,0,1))
+
+        confirmentry = Entry(60, password = 1)
+        toplevel.add(confirmentry, 0, 2, (0,0,0,1))
+
+        if self.preexist:
+            globalcheckbox = Checkbox(_("Also add this passphrase to all existing encrypted devices"), isOn = True)
+            toplevel.add(globalcheckbox, 0, 3)
+
+        buttons = ButtonBar(self.screen, [TEXT_OK_BUTTON, TEXT_CANCEL_BUTTON])
+        toplevel.add(buttons, 0, 4, growx=1)
+
+        passphraseentry.set(self.passphrase)
+        confirmentry.set(self.passphrase)
+
+        while True:
+            rc = toplevel.run()
+            res = buttons.buttonPressed(rc)
+
+            passphrase = None
+            if res == TEXT_OK_CHECK or rc == "F12":
+                passphrase = passphraseentry.value()
+                confirm = confirmentry.value()
+
+                if passphrase != confirm:
+                    ButtonChoiceWindow(self.screen,
+                                       _("Error with passphrase"),
+                                       _("The passphrases you entered were "
+                                         "different.  Please try again."),
+                                       buttons=[TEXT_OK_BUTTON])
+                    passphraseentry.set("")
+                    confirmentry.set("")
+                    continue
+
+                if len(passphrase) < self.minLength:
+                    ButtonChoiceWindow(self.screen,
+                                       _("Error with passphrase"),
+                                       P_("The passphrase must be at least "
+                                          "%d character long.",
+                                          "The passphrase must be at least "
+                                          "%d characters long.",
+                                          self.minLength)
+                                         % (self.minLength,),
+                                       buttons=[TEXT_OK_BUTTON])
+                    passphraseentry.set("")
+                    confirmentry.set("")
+                    continue
+            else:
+                passphrase = self.passphrase
+                passphraseentry.set(self.passphrase)
+                confirmentry.set(self.passphrase)
+
+            retrofit = False
+            if self.preexist:
+                retrofit = globalcheckbox.selected()
+            self.rc = passphrase
+            return (self.rc, retrofit)
+
+    def pop(self):
+        self.screen.popWindow()
+
+class PassphraseEntryWindow:
+    def __init__(self, screen, device):
+        self.screen = screen
+        self.txt = _("Device %s is encrypted. In order to "
+                     "access the device's contents during "
+                     "installation you must enter the device's "
+                     "passphrase below.") % (device,)
+        self.rc = None
+
+    def run(self):
+        toplevel = GridForm(self.screen, _("Passphrase"), 1, 4)
+
+        txt = TextboxReflowed(65, self.txt)
+        toplevel.add(txt, 0, 0)
+
+        passphraseentry = Entry(60, password = 1)
+        toplevel.add(passphraseentry, 0, 1, (0,0,0,1))
+
+        globalcheckbox = Checkbox(_("This is a global passphrase"))
+        toplevel.add(globalcheckbox, 0, 2)
+
+        buttons = ButtonBar(self.screen, [TEXT_OK_BUTTON, TEXT_CANCEL_BUTTON])
+        toplevel.add(buttons, 0, 3, growx=1)
+
+        rc = toplevel.run()
+        res = buttons.buttonPressed(rc)
+
+        passphrase = None
+        isglobal = False
+        if res == TEXT_OK_CHECK:
+            passphrase = passphraseentry.value().strip()
+            isglobal = globalcheckbox.selected()
+
+        self.rc = (passphrase, isglobal)
+        return self.rc
+
+    def pop(self):
+        self.screen.popWindow()
+
+class InstallInterface(InstallInterfaceBase):
+    def progressWindow(self, title, text, total, updpct = 0.05, pulse = False):
+        return ProgressWindow(self.screen, title, text, total, updpct, pulse)
+
+    def setInstallProgressClass(self, c):
+        self.instProgress = c
+
+    def exitWindow(self, title, text):
+        return self.messageWindow(title, text, type="custom",
+                                  custom_buttons=[_("Exit installer")])
+
+    def messageWindow(self, title, text, type="ok", default = None,
+		      custom_icon=None, custom_buttons=[]):
+	if type == "ok":
+	    ButtonChoiceWindow(self.screen, title, text,
+			       buttons=[TEXT_OK_BUTTON])
+        elif type == "yesno":
+            if default and default == "no":
+                btnlist = [TEXT_NO_BUTTON, TEXT_YES_BUTTON]
+            else:
+                btnlist = [TEXT_YES_BUTTON, TEXT_NO_BUTTON]
+	    rc = ButtonChoiceWindow(self.screen, title, text,
+			       buttons=btnlist)
+            if rc == "yes":
+                return 1
+            else:
+                return 0
+	elif type == "custom":
+	    tmpbut = []
+	    for but in custom_buttons:
+		tmpbut.append(string.replace(but,"_",""))
+
+	    rc = ButtonChoiceWindow(self.screen, title, text, width=60,
+				    buttons=tmpbut)
+
+	    idx = 0
+	    for b in tmpbut:
+		if string.lower(b) == rc:
+		    return idx
+		idx = idx + 1
+	    return 0
+	else:
+	    return OkCancelWindow(self.screen, title, text)
+
+    def detailedMessageWindow(self, title, text, longText=None, type="ok",
+                              default=None, custom_icon=None,
+                              custom_buttons=[], expanded=False):
+        t = TextboxReflowed(60, text, maxHeight=8)
+        lt = Textbox(60, 6, longText, scroll=1, wrap=1)
+        g = GridFormHelp(self.screen, title, help, 1, 3)
+        g.add(t, 0, 0)
+        g.add(lt, 0, 1, padding = (0, 1, 0, 1))
+
+        if type == "ok":
+            bb = ButtonBar(self.screen, [TEXT_OK_BUTTON])
+            g.add(bb, 0, 2, growx = 1)
+            return bb.buttonPressed(g.runOnce(None, None))
+        elif type == "yesno":
+            if default and default == "no":
+                buttons = [TEXT_NO_BUTTON, TEXT_YES_BUTTON]
+            else:
+                buttons = [TEXT_YES_BUTTON, TEXT_NO_BUTTON]
+
+            bb = ButtonBar(self.screen, buttons)
+            g.add(bb, 0, 2, growx = 1)
+            rc = bb.buttonPressed(g.runOnce(None, None))
+
+            if rc == "yes":
+                return 1
+            else:
+                return 0
+        elif type == "custom":
+            buttons = []
+            idx = 0
+
+            for button in custom_buttons:
+                buttons.append(string.replace(button, "_", ""))
+
+            bb = ButtonBar(self.screen, buttons)
+            g.add(bb, 0, 2, growx = 1)
+            rc = bb.buttonPressed(g.runOnce(None, None))
+
+            for b in buttons:
+                if string.lower(b) == rc:
+                    return idx
+                idx += 1
+
+            return 0
+        else:
+            return self.messageWindow(title, text, type, default, custom_icon,
+                                      custom_buttons)
+
+    def createRepoWindow(self):
+        self.messageWindow(_("Error"),
+                           _("Repository editing is not available in text mode."))
+
+    def editRepoWindow(self, repoObj):
+        self.messageWindow(_("Error"),
+                           _("Repository editing is not available in text mode."))
+
+    def entryWindow(self, title, text, prompt, entrylength = None):
+        (res, value) = EntryWindow(self.screen, title, text, [prompt])
+        if res == "cancel":
+            return None
+        r = value[0]
+        r.strip()
+        return r
+
+    def getLuksPassphrase(self, passphrase = "", preexist = False):
+        w = LuksPassphraseWindow(self.screen, passphrase = passphrase,
+                                 preexist = preexist)
+        rc = w.run()
+        w.pop()
+        return rc
+
+    def passphraseEntryWindow(self, device):
+        w = PassphraseEntryWindow(self.screen, device)
+        (passphrase, isglobal) = w.run()
+        w.pop()
+        return (passphrase, isglobal)
+
+    def enableNetwork(self):
+        if len(self.anaconda.network.netdevices) == 0:
+            return False
+        from netconfig_text import NetworkConfiguratorText
+        w = NetworkConfiguratorText(self.screen, self.anaconda)
+        ret = w.run()
+        return ret != INSTALL_BACK
+
+    def kickstartErrorWindow(self, text):
+        s = _("The following error was found while parsing the "
+              "kickstart configuration file:\n\n%s") %(text,)
+        self.messageWindow(_("Error Parsing Kickstart Config"),
+                           s,
+                           type = "custom",
+                           custom_buttons = [("_Reboot")],
+                           custom_icon="error")
+                           
+    def mainExceptionWindow(self, shortText, longTextFile):
+        from meh.ui.text import MainExceptionWindow
+        log.critical(shortText)
+        exnWin = MainExceptionWindow(shortText, longTextFile, screen=self.screen)
+        return exnWin
+
+    def saveExceptionWindow(self, accountManager, signature, *args, **kwargs):
+        from meh.ui.text import SaveExceptionWindow
+        win = SaveExceptionWindow (accountManager, signature, screen=self.screen,
+                                   *args, **kwargs)
+        win.run()
+
+    def waitWindow(self, title, text):
+	return WaitWindow(self.screen, title, text)
+
+    def beep(self):
+        # no-op.  could call newtBell() if it was bound
+        pass
+
+    def drawFrame(self):
+        self.screen.drawRootText (0, 0, self.screen.width * " ")
+        if productArch:
+          self.screen.drawRootText (0, 0, _("Welcome to %(productName)s for %(productArch)s") % {'productName': productName, 'productArch': productArch})
+        else:
+          self.screen.drawRootText (0, 0, _("Welcome to %s") % productName)
+
+        self.screen.pushHelpLine(_("  <Tab>/<Alt-Tab> between elements   |  <Space> selects   |  <F12> next screen"))
+
+    def setScreen(self, screen):
+        self.screen = screen
+
+    def shutdown(self):
+	self.screen.finish()
+	self.screen = None
+
+    def suspend(self):
+        self.screen.suspend()
+
+    def resume(self):
+        self.screen.resume()
+
+    def __init__(self):
+	InstallInterfaceBase.__init__(self)
+	signal.signal(signal.SIGINT, signal.SIG_IGN)
+	signal.signal(signal.SIGTSTP, signal.SIG_IGN)
+	self.screen = SnackScreen()
+        self.instProgress = None
+        self._initLabelAnswers = {}
+        self._inconsistentLVMAnswers = {}
+
+    def __del__(self):
+	if self.screen:
+	    self.screen.finish()
+
+    def isRealConsole(self):
+        """Returns True if this is a _real_ console that can do things, False
+        for non-real consoles such as serial, i/p virtual consoles or xen."""
+        if flags.serial or flags.virtpconsole:
+            return False
+        if isys.isPseudoTTY(0):
+            return False
+        if isys.isVioConsole():
+            return False
+        return True
+
+    def resetInitializeDiskQuestion(self):
+        self._initLabelAnswers = {}
+
+    def questionInitializeDisk(self, path, description, size, details=""):
+
+        retVal = False # The less destructive default
+
+        if not path:
+            return retVal
+
+        # we are caching answers so that we don't
+        # ask in each storage.reset() again
+        if path in self._initLabelAnswers:
+            log.info("UI not asking about disk initialization, "
+                     "using cached answer: %s" % self._initLabelAnswers[path])
+            return self._initLabelAnswers[path]
+        elif "all" in self._initLabelAnswers:
+            log.info("UI not asking about disk initialization, "
+                     "using cached answer: %s" % self._initLabelAnswers["all"])
+            return self._initLabelAnswers["all"]
+
+        rc = self.messageWindow(_("Warning"),
+                _("Error processing drive:\n\n"
+                  "%(path)s\n%(size)-0.fMB\n%(description)s\n\n"
+                  "This device may need to be reinitialized.\n\n"
+                  "REINITIALIZING WILL CAUSE ALL DATA TO BE LOST!\n\n"
+                  "This action may also be applied to all other disks "
+                  "needing reinitialization.%(details)s")
+                % {'path': path, 'size': size,
+                   'description': description, 'details': details},
+                type="custom",
+                custom_buttons = [ _("_Ignore"),
+                                   _("Ignore _all"),
+                                   _("_Re-initialize"),
+                                   _("Re-ini_tialize all") ],
+                custom_icon="question")
+        if rc == 0:
+            retVal = False
+        elif rc == 1:
+            path = "all"
+            retVal = False
+        elif rc == 2:
+            retVal = True
+        elif rc == 3:
+            path = "all"
+            retVal = True
+
+        self._initLabelAnswers[path] = retVal
+        return retVal
+
+    def resetReinitInconsistentLVMQuestion(self):
+        self._inconsistentLVMAnswers = {}
+
+    def questionReinitInconsistentLVM(self, pv_names=None, lv_name=None, vg_name=None):
+
+        retVal = False # The less destructive default
+        allSet = frozenset(["all"])
+
+        if not pv_names or (lv_name is None and vg_name is None):
+            return retVal
+
+        # We are caching answers so that we don't ask for ignoring
+        # in each storage.reset() again (note that reinitialization is
+        # done right after confirmation in dialog, not as a planned
+        # action).
+        key = frozenset(pv_names)
+        if key in self._inconsistentLVMAnswers:
+            log.info("UI not asking about disk initialization, "
+                     "using cached answer: %s" % self._inconsistentLVMAnswers[key])
+            return self._inconsistentLVMAnswers[key]
+        elif allSet in self._inconsistentLVMAnswers:
+            log.info("UI not asking about disk initialization, "
+                     "using cached answer: %s" % self._inconsistentLVMAnswers[allSet])
+            return self._inconsistentLVMAnswers[allSet]
+
+        if vg_name is not None:
+            message = "Volume Group %s" % vg_name
+        elif lv_name is not None:
+            message = "Logical Volume %s" % lv_name
+
+        na = {'msg': message, 'pvs': ", ".join(pv_names)}
+        rc = self.messageWindow(_("Warning"),
+                  _("Error processing LVM.\n"
+                    "There is inconsistent LVM data on %(msg)s.  You can "
+                    "reinitialize all related PVs (%(pvs)s) which will erase "
+                    "the LVM metadata, or ignore which will preserve the "
+                    "contents.  This action may also be applied to all other "
+                    "PVs with inconsistent metadata.") % na,
+                type="custom",
+                custom_buttons = [ _("_Ignore"),
+                                   _("Ignore _all"),
+                                   _("_Re-initialize"),
+                                   _("Re-ini_tialize all") ],
+                custom_icon="question")
+        if rc == 0:
+            retVal = False
+        elif rc == 1:
+            key = allSet
+            retVal = False
+        elif rc == 2:
+            retVal = True
+        elif rc == 3:
+            key = allSet
+            retval = True
+
+        self._inconsistentLVMAnswers[key] = retVal
+        return retVal
+
+    def run(self, anaconda):
+        self.anaconda = anaconda
+        instLang = anaconda.instLanguage
+
+        if instLang.getFontFile(instLang.instLang) == "none":
+            if not anaconda.ksdata:
+                ButtonChoiceWindow(self.screen, "Language Unavailable",
+                                   "%s display is unavailable in text mode.  "
+                                   "The installation will continue in "
+                                   "English." % (instLang.instLang,),
+                                   buttons=[TEXT_OK_BUTTON])
+
+	if not self.isRealConsole():
+	    self.screen.suspendCallback(spawnShell, self.screen)
+
+        # drop into the python debugger on ctrl-z if we're running in test mode
+        if flags.debug:
+            self.screen.suspendCallback(debugSelf, self.screen)
+
+        # draw the frame after setting up the fallback
+        self.drawFrame()
+
+	lastrc = INSTALL_OK
+	(step, instance) = anaconda.dispatch.currentStep()
+	while step:
+	    (file, classNames) = stepToClasses[step]
+
+	    if type(classNames) != type(()):
+		classNames = (classNames,)
+
+	    if lastrc == INSTALL_OK:
+		step = 0
+	    else:
+		step = len(classNames) - 1
+
+	    while step >= 0 and step < len(classNames):
+                # reget the args.  they could change (especially direction)
+                (foo, args) = anaconda.dispatch.currentStep()
+                nextWindow = None
+
+                while 1:
+                    try:
+                        found = imputil.imp.find_module(file)
+                        loaded = imputil.imp.load_module(classNames[step],
+                                                         found[0], found[1],
+                                                         found[2])
+                        nextWindow = loaded.__dict__[classNames[step]]
+                        break
+                    except ImportError, e:
+                        rc = ButtonChoiceWindow(self.screen, _("Error!"),
+                                          _("An error occurred when attempting "
+                                            "to load an installer interface "
+                                            "component.\n\nclassName = %s")
+                                          % (classNames[step],),
+                                          buttons=[_("Exit"), _("Retry")])
+
+                        if rc == string.lower(_("Exit")):
+                            sys.exit(0)
+
+		win = nextWindow()
+
+		#log.info("TUI running step %s (class %s, file %s)" % 
+			 #(step, file, classNames))
+
+                rc = win(self.screen, instance)
+
+		if rc == INSTALL_NOOP:
+		    rc = lastrc
+
+		if rc == INSTALL_BACK:
+		    step = step - 1
+                    anaconda.dispatch.dir = DISPATCH_BACK
+		elif rc == INSTALL_OK:
+		    step = step + 1
+                    anaconda.dispatch.dir = DISPATCH_FORWARD
+
+		lastrc = rc
+
+	    if step == -1:
+                if not anaconda.dispatch.canGoBack():
+                    ButtonChoiceWindow(self.screen, _("Cancelled"),
+                                       _("I can't go to the previous step "
+                                         "from here. You will have to try "
+                                         "again."),
+                                       buttons=[_("OK")])
+		anaconda.dispatch.gotoPrev()
+	    else:
+		anaconda.dispatch.gotoNext()
+
+	    (step, args) = anaconda.dispatch.currentStep()
+
+        self.screen.finish()
+
+    def setSteps(self, anaconda):
+        anaconda.dispatch.skipStep("filtertype", permanent=1)
+        anaconda.dispatch.skipStep("filter", permanent=1)
+        anaconda.dispatch.skipStep("cleardiskssel", permanent=1)
+        anaconda.dispatch.skipStep("group-selection", permanent=1)
+
+def killSelf(screen):
+    screen.finish()
+    os._exit(0)
+
+def debugSelf(screen):
+    screen.suspend()
+    import pdb
+    try:
+        pdb.set_trace()
+    except:
+        sys.exit(-1)
+    screen.resume()
+
+def spawnShell(screen):
+    screen.suspend()
+    print("\n\nType <exit> to return to the install program.\n")
+    if os.path.exists("/bin/sh"):
+        iutil.execConsole()
+    else:
+        print("Unable to find /bin/sh to execute!  Not starting shell")
+    time.sleep(5)
+    screen.resume()
diff --git a/pyanaconda/textw/Makefile.am b/pyanaconda/textw/Makefile.am
new file mode 100644
index 0000000..2624967
--- /dev/null
+++ b/pyanaconda/textw/Makefile.am
@@ -0,0 +1,24 @@
+# textw/Makefile.am for anaconda
+#
+# Copyright (C) 2009  Red Hat, Inc.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License as published
+# by the Free Software Foundation; either version 2.1 of the License, or
+# (at your option) any later version.
+#
+# 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 Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+#
+# Author: David Cantrell <dcantrell@xxxxxxxxxx>
+
+pkgpyexecdir = $(pyexecdir)/py$(PACKAGE_NAME)
+textwdir = $(pkgpyexecdir)/textw
+textw_PYTHON = *.py
+
+MAINTAINERCLEANFILES = Makefile.in
diff --git a/pyanaconda/textw/add_drive_text.py b/pyanaconda/textw/add_drive_text.py
new file mode 100644
index 0000000..0fbd86c
--- /dev/null
+++ b/pyanaconda/textw/add_drive_text.py
@@ -0,0 +1,180 @@
+import iutil
+import network
+import storage.iscsi
+import storage.fcoe
+import storage.zfcp
+from snack import *
+from constants_text import *
+from constants import *
+
+import gettext
+_ = lambda x: gettext.ldgettext("anaconda", x)
+
+import logging
+log = logging.getLogger("anaconda")
+
+class addDriveDialog(object):
+    def __init__(self, anaconda):
+        self.anaconda = anaconda
+
+    def addDriveDialog(self, screen):
+        newdrv = []
+        if storage.iscsi.has_iscsi():
+            newdrv.append("Add iSCSI target")
+        if iutil.isS390():
+            newdrv.append( "Add zFCP LUN" )
+        if storage.fcoe.has_fcoe():
+            newdrv.append("Add FCoE SAN")
+
+        if len(newdrv) == 0:
+            return INSTALL_BACK
+
+        (button, choice) = ListboxChoiceWindow(screen,
+                                   _("Advanced Storage Options"),
+                                   _("How would you like to modify "
+                                     "your drive configuration?"),
+                                   newdrv,
+                                   [ TEXT_OK_BUTTON, TEXT_BACK_BUTTON],
+                                               width=55, height=3)
+        
+        if button == TEXT_BACK_CHECK:
+            return INSTALL_BACK
+        if newdrv[choice] == "Add zFCP LUN":
+            try:
+                return self.addZFCPDriveDialog(screen)
+            except ValueError, e:
+                ButtonChoiceWindow(screen, _("Error"), str(e))
+                return INSTALL_BACK
+        elif newdrv[choice] == "Add FCoE SAN":
+            try:
+                return self.addFcoeDriveDialog(screen)
+            except ValueError, e:
+                ButtonChoiceWindow(screen, _("Error"), str(e))
+                return INSTALL_BACK
+        else:
+            try:
+                return self.addIscsiDriveDialog(screen)
+            except (ValueError, IOError), e:
+                ButtonChoiceWindow(screen, _("Error"), str(e))
+                return INSTALL_BACK
+
+    def addZFCPDriveDialog(self, screen):
+        (button, entries) = EntryWindow(screen,
+                                        _("Add FCP Device"),
+                                        _("zSeries machines can access industry-standard SCSI devices via Fibre Channel (FCP). You need to provide a 16 bit device number, a 64 bit World Wide Port Name (WWPN), and a 64 bit FCP LUN for each device."),
+                                        prompts = [ "Device number",
+                                                    "WWPN",
+                                                    "FCP LUN" ] )
+        if button == TEXT_CANCEL_CHECK:
+            return INSTALL_BACK
+
+        devnum = entries[0].strip()
+        wwpn = entries[1].strip()
+        fcplun = entries[2].strip()
+
+        # This may throw a value error, which gets handled by addDriveDialog()
+        storage.zfcp.ZFCP().addFCP(devnum, wwpn, fcplun)
+
+        return INSTALL_OK
+
+    def addFcoeDriveDialog(self, screen):
+        netdevs = self.anaconda.network.available()
+        devs = netdevs.keys()
+        devs.sort()
+
+        if not devs:
+            ButtonChoiceWindow(screen, _("Error"),
+                               _("No network cards present."))
+            return INSTALL_BACK
+
+        grid = GridFormHelp(screen, _("Add FCoE SAN"), "fcoeconfig",
+                            1, 4)
+
+        tb = TextboxReflowed(60,
+                        _("Select which NIC is connected to the FCoE SAN."))
+        grid.add(tb, 0, 0, anchorLeft = 1, padding = (0, 0, 0, 1))
+
+        interfaceList = Listbox(height=len(devs), scroll=1)
+        for dev in devs:
+            hwaddr = netdevs[dev].get("HWADDR")
+            if hwaddr:
+                desc = "%s - %.50s" % (dev, hwaddr)
+            else:
+                desc = dev
+
+            interfaceList.append(desc, dev)
+
+        interfaceList.setCurrent(devs[0])
+        grid.add(interfaceList, 0, 1, padding = (0, 1, 0, 0))
+
+        dcbCheckbox = Checkbox(_("Use DCB"), 1)
+        grid.add(dcbCheckbox, 0, 2, anchorLeft = 1)
+
+        buttons = ButtonBar(screen, [TEXT_OK_BUTTON, TEXT_BACK_BUTTON] )
+        grid.add(buttons, 0, 3, anchorLeft = 1, growx = 1)
+
+        result = grid.run()
+        if buttons.buttonPressed(result) == TEXT_BACK_CHECK:
+            screen.popWindow()
+            return INSTALL_BACK
+
+        nic = interfaceList.current()
+        dcb = dcbCheckbox.selected()
+
+        storage.fcoe.fcoe().addSan(nic=nic, dcb=dcb,
+                                   intf=self.anaconda.intf)
+
+        screen.popWindow()
+        return INSTALL_OK
+
+    def addIscsiDriveDialog(self, screen):
+        if not network.hasActiveNetDev():
+            ButtonChoiceWindow(screen, _("Error"),
+                               "Must have a network configuration set up "
+                               "for iSCSI config.  Please boot with "
+                               "'linux asknetwork'")
+            return INSTALL_BACK
+        
+        (button, entries) = EntryWindow(screen,
+                                        _("Configure iSCSI Parameters"),
+                                        _("To use iSCSI disks, you must provide the address of your iSCSI target and the iSCSI initiator name you've configured for your host."),
+                                        prompts = [ _("Target IP Address"),
+                                                    _("iSCSI Initiator Name"),
+                                                    _("CHAP username"),
+                                                    _("CHAP password"),
+                                                    _("Reverse CHAP username"),
+                                                    _("Reverse CHAP password") ])
+        if button == TEXT_CANCEL_CHECK:
+            return INSTALL_BACK
+
+        (user, pw, user_in, pw_in) = entries[2:]
+
+        target = entries[0].strip()
+        try:
+            count = len(target.split(":"))
+            idx = target.rfind("]:")
+            # Check for IPV6 [IPV6-ip]:port
+            if idx != -1:
+                ip = target[1:idx]
+                port = target[idx+2:]
+            # Check for IPV4 aaa.bbb.ccc.ddd:port
+            elif count == 2:
+                idx = target.rfind(":")
+                ip = target[:idx]
+                port = target[idx+1:]
+            else:
+                ip = target
+                port = "3260"
+            network.sanityCheckIPString(ip)
+        except network.IPMissing, msg:
+            raise ValueError, msg
+        except network.IPError, msg:
+            raise ValueError, msg
+
+        iname = entries[1].strip()
+        if not storage.iscsi.iscsi().initiatorSet:
+            storage.iscsi.iscsi().initiator = iname
+        storage.iscsi.iscsi().addTarget(ip, port, user, pw, user_in, pw_in,
+                                        intf=self.anaconda.intf)
+
+        return INSTALL_OK
diff --git a/pyanaconda/textw/complete_text.py b/pyanaconda/textw/complete_text.py
new file mode 100644
index 0000000..fc4e5c1
--- /dev/null
+++ b/pyanaconda/textw/complete_text.py
@@ -0,0 +1,65 @@
+#
+# complete_text.py: text mode congratulations windows
+#
+# Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006  Red Hat, Inc.
+# 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 as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# 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, see <http://www.gnu.org/licenses/>.
+#
+
+from snack import *
+from constants_text import *
+from constants import *
+import gettext
+import platform
+_ = lambda x: gettext.ldgettext("anaconda", x)
+
+class FinishedWindow:
+  
+  def __call__ (self, screen, anaconda):
+        bootstr = ""
+        buttonstr = _("Reboot")
+
+        bottomstr = _("<Enter> to exit")
+
+        screen.pushHelpLine (string.center(bottomstr, screen.width))
+
+        if isinstance(anaconda.platform, platform.S390):
+            txt = _("Congratulations, your %s installation is complete.\n\n") % (productName,)
+
+            if not anaconda.canReIPL:
+                buttonstr = _("Shutdown")
+
+                txt = txt + _("Please shutdown to use the installed system.\n")
+            else:
+                txt = txt + _("Please reboot to use the installed system.\n")
+
+            if not anaconda.reIPLMessage is None:
+                txt = txt + "\n" + anaconda.reIPLMessage + "\n\n"
+
+            txt = txt + _("Note that updates may be available to ensure the proper "
+                          "functioning of your system and installation of these "
+                          "updates is recommended after the reboot.")
+        else:
+            txt = _("Congratulations, your %s installation is complete.\n\n"
+                    "Please reboot to use the installed system.  "
+                    "Note that updates may be available to ensure the proper "
+                    "functioning of your system and installation of these "
+                    "updates is recommended after the reboot.") %(productName,)
+
+
+        rc = ButtonChoiceWindow (screen, _("Complete"), txt,
+                                 [ buttonstr ], help = "finished", width=60)
+
+        return INSTALL_OK
diff --git a/pyanaconda/textw/constants_text.py b/pyanaconda/textw/constants_text.py
new file mode 100644
index 0000000..1561d5a
--- /dev/null
+++ b/pyanaconda/textw/constants_text.py
@@ -0,0 +1,68 @@
+#
+# constants_text.py: text mode constants
+#
+# Copyright (C) 2000, 2001, 2002  Red Hat, Inc.  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 as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# 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, see <http://www.gnu.org/licenses/>.
+#
+
+from constants import *
+import gettext
+_ = lambda x: gettext.ldgettext("anaconda", x)
+
+INSTALL_OK = 0
+INSTALL_BACK = -1
+INSTALL_NOOP = -2
+
+class Translator:
+    """A simple class to facilitate on-the-fly translation for newt buttons"""
+    def __init__(self, button, check):
+        self.button = button
+        self.check = check
+
+    def __getitem__(self, which):
+        if which == 0:
+            return _(self.button)
+        elif which == 1:
+            return self.check
+        raise IndexError
+
+    def __len__(self):
+        return 2
+
+TEXT_OK_STR = N_("OK")
+TEXT_OK_CHECK  = "ok"
+TEXT_OK_BUTTON = Translator(TEXT_OK_STR, TEXT_OK_CHECK)
+
+TEXT_CANCEL_STR = N_("Cancel")
+TEXT_CANCEL_CHECK  = "cancel"
+TEXT_CANCEL_BUTTON = Translator(TEXT_CANCEL_STR, TEXT_CANCEL_CHECK)
+
+TEXT_BACK_STR = N_("Back")
+TEXT_BACK_CHECK = "back"
+TEXT_BACK_BUTTON = Translator(TEXT_BACK_STR, TEXT_BACK_CHECK)
+
+TEXT_YES_STR = N_("Yes")
+TEXT_YES_CHECK = "yes"
+TEXT_YES_BUTTON = Translator(TEXT_YES_STR, TEXT_YES_CHECK)
+
+TEXT_NO_STR = N_("No")
+TEXT_NO_CHECK = "no"
+TEXT_NO_BUTTON = Translator(TEXT_NO_STR, TEXT_NO_CHECK)
+
+TEXT_EDIT_STR = N_("Edit")
+TEXT_EDIT_CHECK = "edit"
+TEXT_EDIT_BUTTON = Translator(TEXT_EDIT_STR, TEXT_EDIT_CHECK)
+
+TEXT_F12_CHECK = "F12"
diff --git a/pyanaconda/textw/keyboard_text.py b/pyanaconda/textw/keyboard_text.py
new file mode 100644
index 0000000..aa0201a
--- /dev/null
+++ b/pyanaconda/textw/keyboard_text.py
@@ -0,0 +1,67 @@
+#
+# keyboard_text: text mode keyboard setup dialogs
+#
+# Copyright (C) 2001, 2002  Red Hat, Inc.  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 as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# 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, see <http://www.gnu.org/licenses/>.
+#
+
+import isys
+from snack import *
+from constants_text import *
+from flags import flags
+
+from constants import *
+import gettext
+_ = lambda x: gettext.ldgettext("anaconda", x)
+
+import logging
+log = logging.getLogger("anaconda")
+
+class KeyboardWindow:
+    def __call__(self, screen, anaconda):
+        if flags.serial or flags.virtpconsole:
+	    return INSTALL_NOOP
+        keyboards = anaconda.keyboard.modelDict.keys()
+        keyboards.sort ()
+
+	if anaconda.keyboard.beenset:
+	    default = anaconda.keyboard.get ()
+	else:
+	    default = anaconda.instLanguage.getDefaultKeyboard(anaconda.rootPath)
+
+        if default not in keyboards:
+            default = 'us'
+
+        (button, choice) = \
+            ListboxChoiceWindow(screen, _("Keyboard Selection"),
+                                _("Which model keyboard is attached to this computer?"), keyboards, 
+                                buttons = [TEXT_OK_BUTTON, TEXT_BACK_BUTTON], width = 30, scroll = 1, height = 8,
+                                default = default, help = "kybd")
+        
+        if button == TEXT_BACK_CHECK:
+            return INSTALL_BACK
+
+        anaconda.keyboard.set (keyboards[choice])
+        anaconda.keyboard.beenset = 1
+
+        anaconda.keyboard.activate()
+
+        # FIXME: eventually, kbd.activate will do this
+	try:
+	    isys.loadKeymap(keyboards[choice])
+	except SystemError, (errno, msg):
+	    log.error("Could not install keymap %s: %s" % (keyboards[choice], msg))
+        return INSTALL_OK
+
diff --git a/pyanaconda/textw/language_text.py b/pyanaconda/textw/language_text.py
new file mode 100644
index 0000000..14c8503
--- /dev/null
+++ b/pyanaconda/textw/language_text.py
@@ -0,0 +1,70 @@
+#
+# language_text.py: text mode language selection dialog
+#
+# Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007  Red Hat, Inc.
+# 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 as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# 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, see <http://www.gnu.org/licenses/>.
+#
+
+from snack import *
+from constants_text import *
+
+from constants import *
+import gettext
+_ = lambda x: gettext.ldgettext("anaconda", x)
+
+import logging
+log = logging.getLogger("anaconda")
+
+class LanguageWindow:
+    def __call__(self, screen, anaconda):
+        languages = anaconda.instLanguage.available ()
+        languages.sort()
+
+        current = anaconda.instLanguage.instLang
+
+        height = min((8, len(languages)))
+	buttons = [TEXT_OK_BUTTON, TEXT_BACK_BUTTON]
+
+        translated = []
+        for lang in languages:
+            translated.append ((_(lang), anaconda.instLanguage.getLangByName(lang)))
+        (button, choice) = \
+            ListboxChoiceWindow(screen, _("Language Selection"),
+			_("What language would you like to use during the "
+			  "installation process?"), translated, 
+			buttons, width = 30, default = _(current), scroll = 1,
+                                height = height, help = "lang")
+
+        if button == TEXT_BACK_CHECK:
+            return INSTALL_BACK
+
+        if anaconda.instLanguage.getFontFile(choice) == "none":
+            ButtonChoiceWindow(screen, "Language Unavailable",
+                               "%s display is unavailable in text mode.  The "
+                               "installation will continue in English." % (choice,),
+                               buttons=[TEXT_OK_BUTTON])
+            anaconda.instLanguage.instLang = choice
+            anaconda.instLanguage.systemLang = choice
+            anaconda.timezone.setTimezoneInfo(anaconda.instLanguage.getDefaultTimeZone(anaconda.rootPath))
+            return INSTALL_OK
+
+        anaconda.instLanguage.instLang = choice
+        anaconda.instLanguage.systemLang = choice
+        anaconda.timezone.setTimezoneInfo(anaconda.instLanguage.getDefaultTimeZone(anaconda.rootPath))
+
+	anaconda.intf.drawFrame()
+
+        return INSTALL_OK
diff --git a/pyanaconda/textw/netconfig_text.py b/pyanaconda/textw/netconfig_text.py
new file mode 100644
index 0000000..4cea192
--- /dev/null
+++ b/pyanaconda/textw/netconfig_text.py
@@ -0,0 +1,285 @@
+#
+# netconfig_text.py: Configure a network interface now.
+#
+# Copyright (C) 2008  Red Hat, Inc.
+# 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 as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# 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, see <http://www.gnu.org/licenses/>.
+#
+# Author(s): Chris Lumens <clumens@xxxxxxxxxx>
+#            David Cantrell <dcantrell@xxxxxxxxxx>
+#
+
+
+import isys
+import network
+from snack import *
+from constants_text import *
+
+import gettext
+_ = lambda x: gettext.ldgettext("anaconda", x)
+
+class NetworkConfiguratorText:
+    def _handleIPError(self, field, errmsg):
+        self.anaconda.intf.messageWindow(_("Error With Data"),
+                                         _("An error occurred converting the "
+                                           "value entered for "
+                                           "\"%(field)s\":\n%(errmsg)s") \
+                                         % {'field': field, 'errmsg': errmsg})
+
+    def _handleIPMissing(self, field):
+        self.anaconda.intf.messageWindow(_("Error With Data"),
+                                         _("A value is required for the field %s") % field)
+
+    def _dhcpToggled(self, *args):
+        if self.dhcpCheckbox.selected():
+            self.ipv4Address.setFlags(FLAG_DISABLED, FLAGS_SET)
+            self.ipv4Netmask.setFlags(FLAG_DISABLED, FLAGS_SET)
+            #self.ipv6Address.setFlags(FLAG_DISABLED, FLAGS_SET)
+            #self.ipv6Netmask.setFlags(FLAG_DISABLED, FLAGS_SET)
+            self.gatewayEntry.setFlags(FLAG_DISABLED, FLAGS_SET)
+            self.nameserverEntry.setFlags(FLAG_DISABLED, FLAGS_SET)
+        else:
+            self.ipv4Address.setFlags(FLAG_DISABLED, int(self.ipv4Checkbox.selected()))
+            self.ipv4Netmask.setFlags(FLAG_DISABLED, int(self.ipv4Checkbox.selected()))
+            #self.ipv6Address.setFlags(FLAG_DISABLED, int(self.ipv6Checkbox.selected()))
+            #self.ipv6Netmask.setFlags(FLAG_DISABLED, int(self.ipv6Checkbox.selected()))
+            self.gatewayEntry.setFlags(FLAG_DISABLED, FLAGS_RESET)
+            self.nameserverEntry.setFlags(FLAG_DISABLED, FLAGS_RESET)
+
+    def _ipv4Toggled(self, *args):
+        if self.dhcpCheckbox.selected():
+            return
+
+        flag = FLAGS_RESET
+        if not self.ipv4Checkbox.selected():
+            flag = FLAGS_SET
+
+        self.ipv4Address.setFlags(FLAG_DISABLED, flag)
+        self.ipv4Netmask.setFlags(FLAG_DISABLED, flag)
+
+    #def _ipv6Toggled(self, *args):
+    #    if self.dhcpCheckbox.selected():
+    #        return
+    #
+    #    flag = FLAGS_RESET
+    #    if not self.ipv6Checkbox.selected():
+    #        flag = FLAGS_SET
+    #
+    #    self.ipv6Address.setFlags(FLAG_DISABLED, flag)
+    #    self.ipv6Netmask.setFlags(FLAG_DISABLED, flag)
+
+    def __init__(self, screen, anaconda):
+        self.screen = screen
+        self.anaconda = anaconda
+
+    def run(self):
+        grid = GridFormHelp(self.screen, _("Enable network interface"), "netconfig",
+                            1, 9)
+
+        tb = TextboxReflowed(60, _("This requires that you have an active "
+                                   "network connection during the installation "
+                                   "process.  Please configure a network "
+                                   "interface."))
+        grid.add(tb, 0, 0, anchorLeft = 1, padding = (0, 0, 0, 1))
+
+        self.interfaceList = CheckboxTree(height=3, scroll=1)
+
+        netdevs = self.anaconda.network.available()
+        devs = netdevs.keys()
+        devs.sort()
+        ksdevice = self.anaconda.network.getKSDevice()
+        if ksdevice:
+            ksdevice = ksdevice.get('DEVICE')
+        selected_interface = None
+
+        for dev in devs:
+            hwaddr = netdevs[dev].get("HWADDR")
+
+            if hwaddr:
+                desc = "%s - %.50s" % (dev, hwaddr)
+            else:
+                desc = dev
+
+            if selected_interface is None:
+                selected_interface = desc
+
+            if ksdevice and ksdevice == dev:
+                selected_interface = desc
+
+            self.interfaceList.append(desc)
+
+        if selected_interface:
+            self.interfaceList.setCurrent(selected_interface)
+        else:
+            self.interfaceList.setCurrent(0)
+
+        grid.add(self.interfaceList, 0, 1, padding = (0, 0, 0, 1))
+
+        self.dhcpCheckbox = Checkbox(_("Use dynamic IP configuration (DHCP)"), 1)
+        grid.add(self.dhcpCheckbox, 0, 2, anchorLeft = 1)
+
+        self.ipv4Checkbox = Checkbox(_("Enable IPv4 support"), 1)
+        grid.add(self.ipv4Checkbox, 0, 3, anchorLeft = 1)
+
+        #self.ipv6Checkbox = Checkbox(_("Enable IPv6 support"), 0)
+        #grid.add(self.ipv6Checkbox, 0, 4, anchorLeft = 1, padding = (0, 0, 0, 1))
+
+        ipv4Grid = Grid(4, 1)
+        ipv4Grid.setField(Label(_("IPv4 Address:")), 0, 0, padding = (0, 0, 1, 0))
+        self.ipv4Address = Entry(20, scroll=1)
+        ipv4Grid.setField(self.ipv4Address, 1, 0)
+        ipv4Grid.setField(Label("/"), 2, 0)
+        self.ipv4Netmask = Entry(20, scroll=0)
+        ipv4Grid.setField(self.ipv4Netmask, 3, 0)
+
+        grid.add(ipv4Grid, 0, 5, anchorLeft = 1)
+
+        #ipv6Grid = Grid(4, 1)
+        #ipv6Grid.setField(Label(_("IPv6 Address:")), 0, 0, padding = (0, 0, 1, 0))
+        #self.ipv6Address = Entry(20, scroll=1)
+        #ipv6Grid.setField(self.ipv6Address, 1, 0)
+        #ipv6Grid.setField(Label("/"), 2, 0)
+        #self.ipv6Netmask = Entry(20, scroll=0)
+        #ipv6Grid.setField(self.ipv6Netmask, 3, 0)
+
+        #grid.add(ipv6Grid, 0, 6, anchorLeft = 1)
+
+        extraGrid = Grid(4, 1)
+        extraGrid.setField(Label(_("Gateway:")), 0, 0, padding = (0, 0, 1, 0))
+        self.gatewayEntry = Entry(20, scroll=1)
+        extraGrid.setField(self.gatewayEntry, 1, 0, padding = (0, 0, 2, 0))
+        extraGrid.setField(Label(_("Nameserver:")), 2, 0, padding = (0, 0, 1, 0))
+        self.nameserverEntry = Entry(20, scroll=1)
+        extraGrid.setField(self.nameserverEntry, 3, 0)
+
+        grid.add(extraGrid, 0, 7, anchorLeft = 1)
+
+        buttons = ButtonBar(self.screen, [TEXT_OK_BUTTON, TEXT_BACK_BUTTON] )
+        grid.add(buttons, 0, 8, anchorLeft = 1, growx = 1)
+
+        self.dhcpCheckbox.setCallback(self._dhcpToggled)
+        self.ipv4Checkbox.setCallback(self._ipv4Toggled)
+        #self.ipv6Checkbox.setCallback(self._ipv6Toggled)
+
+        # Call these functions to set initial UI state.
+        self._ipv4Toggled()
+        #self._ipv6Toggled()
+        self._dhcpToggled()
+
+        netdevs = self.anaconda.network.available()
+
+        while True:
+            result = grid.run()
+            button = buttons.buttonPressed(result)
+
+            if button == TEXT_BACK_CHECK:
+                self.screen.popWindow()
+                return INSTALL_BACK
+
+            selected = map(lambda x: x.split()[0], self.interfaceList.getSelection())
+            if selected is None or selected == []:
+                self.anaconda.intf.messageWindow(_("Missing Device"),
+                                                 _("You must select a network device"))
+                continue
+
+            for name, dev in netdevs.items():
+                if name in selected:
+                    dev.set(('ONBOOT', 'yes'))
+                else:
+                    dev.set(('ONBOOT', 'no'))
+
+            selected_netdevs = []
+            for devname in selected:
+                if not netdevs.has_key(devname):
+                    continue
+
+                netdev = netdevs[devname]
+                selected_netdevs.append(netdev)
+                netdev.set(("ONBOOT", "yes"))
+
+                if self.dhcpCheckbox.selected():
+                    netdev.set(("BOOTPROTO", "dhcp"))
+                else:
+                    netdev.set(("BOOTPROTO", "static"))
+                    ipv4addr = self.ipv4Address.value()
+                    ipv4nm = self.ipv4Netmask.value()
+                    gateway = self.gatewayEntry.value()
+                    ns = self.nameserverEntry.value()
+
+                    try:
+                        network.sanityCheckIPString(ipv4addr)
+                        netdev.set(("IPADDR", ipv4addr))
+                    except network.IPMissing, msg:
+                        self._handleIPMissing(_("IP Address"))
+                        continue
+                    except network.IPError, msg:
+                        self._handleIPError(_("IP Address"), msg)
+                        continue
+
+                    if ipv4nm.find('.') == -1:
+                        # user provided a CIDR prefix
+                        try:
+                            if int(ipv4nm) > 32 or int(ipv4nm) < 0:
+                                msg = _("IPv4 CIDR prefix must be between 0 and 32.")
+                                self._handleIPError(_("IPv4 Network Mask"), msg)
+                                continue
+                            else:
+                                ipv4nm = isys.prefix2netmask(int(ipv4nm))
+                                netdev.set(("NETMASK", ipv4nm))
+                        except:
+                            self._handleIPMissing(_("IPv4 Network Mask"))
+                            continue
+                    else:
+                        # user provided a dotted-quad netmask
+                        try:
+                            network.sanityCheckIPString(ipv4nm)
+                            netdev.set(("NETMASK", ipv4nm))
+                        except network.IPMissing, msg:
+                            self._handleIPMissing(_("IPv4 Network Mask"))
+                            continue
+                        except network.IPError, msg:
+                            self._handleIPError(_("IPv4 Network Mask "), msg)
+                            continue
+
+                    try:
+                        if gateway:
+                            network.sanityCheckIPString(gateway)
+                            netdev.set(("GATEWAY", gateway))
+                    except network.IPMissing, msg:
+                        pass
+                    except network.IPError, msg:
+                        self._handleIPError(_("Gateway"), msg)
+                        continue
+
+                    try:
+                        if ns:
+                            network.sanityCheckIPString(ns)
+                            netdev.set(("DNS1", ns))
+                    except network.IPMissing, msg:
+                        pass
+                    except network.IPError, msg:
+                        self._handleIPError(_("Nameserver"), msg)
+                        continue
+
+            w = self.anaconda.intf.waitWindow(_("Configuring Network Interfaces"), _("Waiting for NetworkManager"))
+            result = self.anaconda.network.bringUp(devices=selected_netdevs)
+            w.pop()
+            if result:
+                break
+            else:
+                 self.anaconda.intf.messageWindow(_("Error"), _("Error configuring network device"), _("Error configuring network device %s") % netdev.get('DEVICE'))
+
+        self.screen.popWindow()
+        return INSTALL_OK
diff --git a/pyanaconda/textw/network_text.py b/pyanaconda/textw/network_text.py
new file mode 100644
index 0000000..26499b8
--- /dev/null
+++ b/pyanaconda/textw/network_text.py
@@ -0,0 +1,33 @@
+#
+# network_text.py: text mode network configuration dialogs
+#
+# Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006  Red Hat, Inc.
+# 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 as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# 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, see <http://www.gnu.org/licenses/>.
+#
+# Author(s): Jeremy Katz <katzj@xxxxxxxxxx>
+#            Michael Fulbright <msf@xxxxxxxxxx>
+#            David Cantrell <dcantrell@xxxxxxxxxx>
+#
+from constants_text import *
+import network
+
+class HostnameWindow:
+    def __call__(self, screen, anaconda):
+        hname = network.getDefaultHostname(anaconda)
+        anaconda.network.hostname = hname
+        return INSTALL_OK
+
+# vim:tw=78:ts=4:et:sw=4
diff --git a/pyanaconda/textw/partition_text.py b/pyanaconda/textw/partition_text.py
new file mode 100644
index 0000000..193ff21
--- /dev/null
+++ b/pyanaconda/textw/partition_text.py
@@ -0,0 +1,162 @@
+#
+# partition_text.py: allows the user to choose how to partition their disks
+# in text mode
+#
+# Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007  Red Hat, Inc.
+# 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 as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# 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, see <http://www.gnu.org/licenses/>.
+#
+# Author(s): Jeremy Katz <katzj@xxxxxxxxxx>
+#
+
+import os, sys
+import isys
+import string
+import copy
+import network
+import parted
+import storage.iscsi
+import storage.fcoe
+import storage.zfcp
+from partIntfHelpers import *
+from snack import *
+from constants_text import *
+from constants import *
+from add_drive_text import addDriveDialog
+
+import gettext
+_ = lambda x: gettext.ldgettext("anaconda", x)
+
+import logging
+log = logging.getLogger("anaconda")
+
+class PartitionTypeWindow:
+    def typeboxChange(self, (typebox, drivelist)):
+        flag = FLAGS_RESET
+        if typebox.current() == CLEARPART_TYPE_NONE:
+            flag = FLAGS_SET
+        # XXX need a way to disable the checkbox tree
+
+    def clearDrivelist(self):
+        # XXX remove parted object refs
+        #     need to put in clear() method for checkboxtree in snack
+        self.drivelist.key2item = {}
+        self.drivelist.item2key = {}
+
+    def __call__(self, screen, anaconda):
+        self.anaconda = anaconda
+
+        while 1:
+            g = GridFormHelp(screen, _("Partitioning Type"), "autopart", 1, 6)
+
+            txt = TextboxReflowed(65, _("Installation requires partitioning of your hard drive.  The default layout is suitable for most users.  Select what space to use and which drives to use as the install target."))
+            g.add(txt, 0, 0, (0, 0, 0, 0))
+
+            opts = ((_("Use entire drive"), CLEARPART_TYPE_ALL),
+                    (_("Replace existing Linux system"), CLEARPART_TYPE_LINUX),
+                    (_("Use free space"), CLEARPART_TYPE_NONE))
+            typebox = Listbox(height = len(opts), scroll = 0)
+            for (txt, val) in opts:
+                typebox.append(txt, val)
+
+            if anaconda.storage.clearPartType is None:
+                preselection = CLEARPART_TYPE_LINUX
+            else:
+                preselection = anaconda.storage.clearPartType
+            typebox.setCurrent(preselection)
+
+            g.add(typebox, 0, 1, (0, 1, 0, 0))
+
+            # list of drives to select which to clear
+            subgrid = Grid(1, 2)
+            subgrid.setField(TextboxReflowed(55, _("Which drive(s) do you want to "
+                                                   "use for this installation?")),
+                             0, 0)
+            drivelist = CheckboxTree(height=2, scroll=1)
+            subgrid.setField(drivelist, 0, 1)
+            g.add(subgrid, 0, 2, (0, 1, 0, 0))
+
+            bb = ButtonBar(screen, [ TEXT_OK_BUTTON, TEXT_BACK_BUTTON ])
+            g.add(bb, 0, 5, (0,1,0,0))
+
+
+            typebox.setCallback(self.typeboxChange, (typebox, drivelist))
+            self.drivelist = drivelist
+
+            g.addHotKey("F2")
+            screen.pushHelpLine (_("<Space>,<+>,<-> selection   |   <F2> Add drive   |   <F12> next screen"))
+
+            # restore the drive list each time
+            disks = anaconda.storage.partitioned
+            cleardrives = anaconda.storage.clearPartDisks
+
+            for disk in disks:
+                model = disk.model
+
+                if not cleardrives or len(cleardrives) < 1:
+                    selected = 1
+                else:
+                    if disk in cleardrives:
+                        selected = 1
+                    else:
+                        selected = 0
+
+                sizestr = "%8.0f MB" % (disk.size,)
+                diskdesc = "%6s %s (%s)" % (disk.name, sizestr, model[:23],)
+
+                drivelist.append(diskdesc, selected = selected)
+
+            rc = g.run()
+
+            if len(self.drivelist.getSelection()) > 0:
+                sel = map(lambda s: s.split()[0], self.drivelist.getSelection())
+            else:
+                sel = []
+            partmethod_ans = typebox.current()
+            res = bb.buttonPressed(rc)
+
+            self.clearDrivelist()
+            screen.popHelpLine()
+            screen.popWindow()
+
+            if rc == "F2":
+                addDialog = addDriveDialog(anaconda)
+                if addDialog.addDriveDialog(screen) != INSTALL_BACK:
+                    anaconda.storage.reset()
+                    anaconda.bootloader.updateDriveList()
+                continue
+
+            if res == TEXT_BACK_CHECK:
+                return INSTALL_BACK
+
+            if anaconda.storage.checkNoDisks():
+                continue
+
+            if len(sel) < 1:
+                mustHaveSelectedDrive(anaconda.intf)
+                continue
+
+            anaconda.dispatch.skipStep("autopartitionexecute", skip = 0)
+            anaconda.storage.doAutoPart = True
+            anaconda.storage.clearPartType = partmethod_ans
+            anaconda.storage.clearPartDisks = sel
+            break
+
+        # ask to review autopartition layout - but only if it's not custom partitioning
+        anaconda.dispatch.skipStep("partition", skip = 1)
+        anaconda.dispatch.skipStep("bootloader", skip = 1)
+
+        return INSTALL_OK
+
diff --git a/pyanaconda/textw/progress_text.py b/pyanaconda/textw/progress_text.py
new file mode 100644
index 0000000..579408a
--- /dev/null
+++ b/pyanaconda/textw/progress_text.py
@@ -0,0 +1,131 @@
+#
+# progress_text.py: text mode install/upgrade progress dialog
+#
+# Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007  Red Hat, Inc.
+# 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 as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# 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, see <http://www.gnu.org/licenses/>.
+#
+
+from constants import *
+from snack import *
+from constants_text import *
+from iutil import strip_markup
+
+import gettext
+_ = lambda x: gettext.ldgettext("anaconda", x)
+
+import logging
+log = logging.getLogger("anaconda")
+
+class InstallProgressWindow:
+    def __init__(self, screen):
+	self.screen = screen
+	self.drawn = False
+
+        self.pct = 0
+
+    def __del__ (self):
+	if self.drawn:
+            self.screen.popWindow ()
+
+    def _setupScreen(self):
+        screen = self.screen
+
+        self.grid = GridForm(self.screen, _("Package Installation"), 1, 6)
+
+        self.width = 65
+        self.progress = Scale(self.width, 100)
+        self.grid.add (self.progress, 0, 1, (0, 1, 0, 0))
+
+        self.label = Label("")
+        self.grid.add(self.label, 0, 2, (0, 1, 0, 0), anchorLeft = 1)
+
+        self.info = Textbox(self.width, 4, "", wrap = 1)
+        self.grid.add(self.info, 0, 3, (0, 1, 0, 0))
+
+        self.grid.draw()
+        screen.refresh()
+        self.drawn = True
+
+    def processEvents(self):
+        if not self.drawn:
+            return
+        self.grid.draw()
+        self.screen.refresh()
+
+    def setShowPercentage(self, val):
+        pass
+
+    def get_fraction(self):
+        return self.pct
+
+    def set_fraction(self, pct):
+        if not self.drawn:
+            self._setupScreen()
+
+        if pct > 1.0:
+            pct = 1.0
+
+        self.progress.set(int(pct * 100))
+        self.pct = pct
+        self.processEvents()
+
+    def set_label(self, txt):
+        if not self.drawn:
+            self._setupScreen()
+        
+        self.info.setText(strip_markup(txt))
+        self.processEvents()
+
+    def set_text(self, txt):
+        if not self.drawn:
+            self._setupScreen()
+        
+        if len(txt) > self.width:
+            txt = txt[:self.width]
+        else:
+            spaces = (self.width - len(txt)) / 2
+            txt = (" " * spaces) + txt
+        
+        self.label.setText(strip_markup(txt))
+        self.processEvents()
+
+class setupForInstall:
+
+    def __call__(self, screen, anaconda):
+	if anaconda.dir == DISPATCH_BACK:
+	    anaconda.intf.setInstallProgressClass(None)
+	    return INSTALL_BACK
+
+        anaconda.intf.setInstallProgressClass(InstallProgressWindow(screen))
+	return INSTALL_OK
+
+if __name__ == "__main__":
+    screen = SnackScreen()
+    ipw = InstallProgressWindow(screen)
+
+    import time
+    ipw._setupScreen()
+    time.sleep(2)
+
+    ipw.set_label("testing blah\n<b>blahblahb</b>lahbl ahalsdfkj")
+    ipw.set_text("blah blah blah")
+    ipw.set_fraction(0.25)
+    time.sleep(2)
+
+    p = ipw.get_fraction()
+
+    screen.finish()
+    print(p)
diff --git a/pyanaconda/textw/statusline_text.py b/pyanaconda/textw/statusline_text.py
new file mode 100644
index 0000000..4a4a3db
--- /dev/null
+++ b/pyanaconda/textw/statusline_text.py
@@ -0,0 +1,78 @@
+#
+# statusline_text.py: text mode status line management functions
+#
+# Copyright (C) 2000, 2001  Red Hat, Inc.  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 as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# 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, see <http://www.gnu.org/licenses/>.
+#
+
+# XXX this file appears to be unused.
+
+import string
+import copy
+
+class CleanStatusLine:
+
+    def centerLabel(self, str, space):
+        return string.center(str, space)
+
+    def formatStatusLine(self, args):
+        if len(args) == 1:
+            return self.centerLabel(args[0], self.width)
+
+        nonspaces = 0
+        for i in args:
+            nonspaces = nonspaces + len(i)
+
+        spaceEach = (self.width-nonspaces)/len(args)
+        outstr = ""
+
+        j = 0
+        for i in args:
+            str = self.centerLabel(i, len(i) + spaceEach)
+            outstr = outstr + str
+            j = j + 1
+            if j != len(args):
+                outstr = outstr + "|"
+
+        return outstr
+
+    def setdefaultStatusLine(self, rargs, largs):
+        self.rargs = rargs
+        self.largs = largs
+        
+
+#    def defaultStatusLine(self):
+#    def __str__(self):
+#        args = copy.deepcopy(self.largs)
+#        args.extend(self.rargs)
+#        return self.formatStatusLine(args)
+        
+#    def customStatusLine(self, optargs):
+    def __str__(self):
+        args = copy.deepcopy(self.largs)
+        if self.optargs != None:
+            args.extend(self.optargs)
+        args.extend(self.rargs)
+        return self.formatStatusLine(args)
+
+
+    def __init__(self, args, optargs=None):
+#        self.largs = ["<Tab>/<Alt-Tab> between elements"]
+#        self.rargs = ["<F12> next screen"]
+        (self.largs, self.rargs) = args
+        self.optargs = optargs
+            
+        self.width = 80
+        
diff --git a/pyanaconda/textw/task_text.py b/pyanaconda/textw/task_text.py
new file mode 100644
index 0000000..17d312b
--- /dev/null
+++ b/pyanaconda/textw/task_text.py
@@ -0,0 +1,28 @@
+#
+# task_gui.py: Choose tasks for installation
+#
+# Copyright (C) 2006  Red Hat, Inc.  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 as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# 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, see <http://www.gnu.org/licenses/>.
+#
+
+from constants_text import *
+from constants import *
+
+class TaskWindow:
+    def __call__(self, screen, anaconda):
+        anaconda.backend.resetPackageSelections()
+        anaconda.backend.selectGroup("Core")
+
+        return INSTALL_OK
diff --git a/pyanaconda/textw/timezone_text.py b/pyanaconda/textw/timezone_text.py
new file mode 100644
index 0000000..c78442a
--- /dev/null
+++ b/pyanaconda/textw/timezone_text.py
@@ -0,0 +1,131 @@
+#
+# timezone_text.py: text mode timezone selection dialog
+#
+# Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006  Red Hat, Inc.
+# 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 as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# 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, see <http://www.gnu.org/licenses/>.
+#
+
+import sys
+import string
+import iutil
+from time import *
+from snack import *
+from constants_text import *
+from bootloader import hasWindows
+from scdate.core import zonetab
+
+from constants import *
+import gettext
+_ = lambda x: gettext.ldgettext("anaconda", x)
+
+sys.path.append("/usr/share/system-config-date")
+
+class TimezoneWindow:
+
+    def getTimezoneList(self):
+        zt = zonetab.ZoneTab()
+        zoneList = [ x.tz for x in zt.getEntries() ]
+        zoneList.sort()
+        return zoneList
+
+    def updateSysClock(self):
+	args = ["--hctosys"]
+	if self.c.selected():
+	    args.append("--utc")
+
+	iutil.execWithRedirect("hwclock", args)
+	self.g.setTimer(500)
+	self.updateClock()
+
+    def updateClock(self):
+        # disable for now
+        return
+        
+#	if os.access("/usr/share/zoneinfo/" + self.l.current(), os.R_OK):
+#	    os.environ['TZ'] = self.l.current()
+#	    self.label.setText(self.currentTime())
+#	else:
+#	    self.label.setText("")
+
+    def currentTime(self):
+	return "Current time: " + strftime("%X %Z", localtime(time()))
+
+    def __call__(self, screen, anaconda):
+	timezones = self.getTimezoneList()
+	(default, asUtc) = anaconda.timezone.getTimezoneInfo()
+        if not default:
+	    default = anaconda.instLanguage.getDefaultTimeZone(anaconda.rootPath)
+
+	bb = ButtonBar(screen, [TEXT_OK_BUTTON, TEXT_BACK_BUTTON])
+	t = TextboxReflowed(30, 
+			_("In which time zone are you located?"))
+
+        if not anaconda.ksdata and not hasWindows(anaconda.bootloader):
+            asUtc = True
+
+#
+# disabling this for now
+# 
+#	self.label = Label(self.currentTime())
+		
+	self.l = Listbox(5, scroll = 1, returnExit = 0)
+
+        for tz in timezones:
+	    self.l.append(gettext.ldgettext("system-config-date", tz), tz)
+
+	self.l.setCurrent(default.replace("_", " "))
+#	self.l.setCallback(self.updateClock)
+        
+	self.c = Checkbox(_("System clock uses UTC"), isOn = asUtc)
+#	self.c.setCallback(self.updateSysClock)
+
+	self.g = GridFormHelp(screen, _("Time Zone Selection"), "timezone",
+			      1, 5)
+	self.g.add(t, 0, 0)
+#	self.g.add(self.label, 0, 1, padding = (0, 1, 0, 0), anchorLeft = 1)
+	self.g.add(self.c, 0, 2, padding = (0, 1, 0, 1), anchorLeft = 1)
+	self.g.add(self.l, 0, 3, padding = (0, 0, 0, 1))
+	self.g.add(bb, 0, 4, growx = 1)
+
+# disabling for now
+#	self.updateClock()
+#	self.updateSysClock()
+#
+#	self.g.setTimer(500)
+#
+#	result = "TIMER"
+#	while result == "TIMER":
+#	    result = self.g.run()
+#	    if result == "TIMER":
+#		self.updateClock()
+
+        result = ""
+        while 1:
+            result = self.g.run()
+            rc = bb.buttonPressed (result)
+            
+            if rc == TEXT_BACK_CHECK:
+                screen.popWindow()
+                return INSTALL_BACK
+            else:
+                break
+
+        screen.popWindow()
+	anaconda.timezone.setTimezoneInfo(self.l.current().replace(" ", "_"), asUtc = self.c.selected())
+
+	return INSTALL_OK
+
+
diff --git a/pyanaconda/textw/upgrade_bootloader_text.py b/pyanaconda/textw/upgrade_bootloader_text.py
new file mode 100644
index 0000000..db736f3
--- /dev/null
+++ b/pyanaconda/textw/upgrade_bootloader_text.py
@@ -0,0 +1,183 @@
+#
+# upgrade_bootloader_text.py: text bootloader dialog for upgrades
+#
+# Copyright (C) 2002  Red Hat, Inc.  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 as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# 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, see <http://www.gnu.org/licenses/>.
+#
+# Author(s): Jeremy Katz <katzj@xxxxxxxxxx>
+#
+
+from snack import *
+from constants_text import *
+from flags import flags
+import string
+from booty import checkbootloader
+from storage.devices import devicePathToName
+
+from constants import *
+import gettext
+_ = lambda x: gettext.ldgettext("anaconda", x)
+
+import logging
+log = logging.getLogger("anaconda")
+
+class UpgradeBootloaderWindow:
+    def _ideToLibata(self, rootPath):
+        try:
+            f = open("/proc/modules", "r")
+            buf = f.read()
+            if buf.find("libata") == -1:
+                return False
+        except:
+            log.debug("error reading /proc/modules")
+            pass
+
+        try:
+            f = open(rootPath + "/etc/modprobe.conf")
+        except:
+            log.debug("error reading /etc/modprobe.conf")
+            return False
+
+        modlines = f.readlines()
+        f.close()
+
+        try:
+            f = open("/tmp/scsidisks")
+        except:
+            log.debug("error reading /tmp/scsidisks")
+            return False
+        mods = []
+        for l in f.readlines():
+            (disk, mod) = l.split()
+            if mod.strip() not in mods:
+                mods.append(mod.strip())
+        f.close()
+
+        for l in modlines:
+            stripped = l.strip()
+
+            if stripped == "" or stripped[0] == "#":
+                continue
+
+            if stripped.find("scsi_hostadapter") != -1:
+                mod = stripped.split()[-1]
+                if mod in mods:
+                    mods.remove(mod)
+
+        if len(mods) > 0:
+            return True
+        return False
+
+    def __call__(self, screen, anaconda):
+        self.screen = screen
+        self.dispatch = anaconda.dispatch
+        self.bl = anaconda.bootloader
+
+        newToLibata = self._ideToLibata(anaconda.rootPath)
+        (self.type, self.bootDev) = \
+                    checkbootloader.getBootloaderTypeAndBoot(anaconda.rootPath, storage=anaconda.storage)
+
+        blradio = RadioGroup()
+
+        (update, newbl, nobl) = (0, 0, 0)
+        if not self.dispatch.stepInSkipList("bootloader"):
+            newbl = 1
+        elif self.dispatch.stepInSkipList("instbootloader"):
+            nobl = 1
+        else:
+            if newToLibata or self.type is None or self.bootDev is None:
+                newbl = 1
+            else:
+                update = 1
+
+        if newToLibata or self.type is None or self.bootDev is None:
+            if newToLibata:
+                t = TextboxReflowed(53,
+                    _("Due to system changes, your boot loader "
+                      "configuration can not be automatically updated."))
+            else:
+                t = TextboxReflowed(53,
+                  _("The installer is unable to detect the boot loader "
+                    "currently in use on your system."))
+            
+
+            self.update_radio = blradio.add(_("Update boot loader configuration"),
+                                            "update", update)
+            self.update_radio.w.checkboxSetFlags(FLAG_DISABLED, FLAGS_SET)
+        else:
+            t = TextboxReflowed(53,
+                                _("The installer has detected the %(type)s "
+                                  "boot loader currently installed on "
+                                  "%(bootDev)s.")
+                                % {'type': self.type, 'bootDev': self.bootDev})
+
+            self.update_radio = blradio.add(_("Update boot loader configuration"),
+                                            "update", update)
+
+        self.nobl_radio = blradio.add(_("Skip boot loader updating"),
+                                      "nobl", nobl)
+        self.newbl_radio = blradio.add(_("Create new boot loader "
+                                         "configuration"),
+                                       "newbl", newbl)
+
+        buttons = ButtonBar(screen, [TEXT_OK_BUTTON, TEXT_BACK_BUTTON])
+
+        grid = GridFormHelp(screen, _("Upgrade Boot Loader Configuration"),
+                            "bl-upgrade", 1, 5)
+
+        grid.add(t, 0, 0, (0,0,0,1))
+        grid.add(self.update_radio, 0, 1, (0,0,0,0))
+        grid.add(self.nobl_radio, 0, 2, (0,0,0,0))
+        grid.add(self.newbl_radio, 0, 3, (0,0,0,1))
+        grid.add(buttons, 0, 4, growx = 1)
+
+
+        while 1:
+            result = grid.run()
+
+            button = buttons.buttonPressed(result)
+
+            if button == TEXT_BACK_CHECK:
+                screen.popWindow()
+                return INSTALL_BACK        
+
+            if blradio.getSelection() == "nobl":                           
+                self.dispatch.skipStep("bootloadersetup", skip = 1)
+                self.dispatch.skipStep("bootloader", skip = 1)
+                self.dispatch.skipStep("bootloaderadvanced", skip = 1)
+                self.dispatch.skipStep("instbootloader", skip = 1)
+            elif blradio.getSelection() == "newbl":
+                self.dispatch.skipStep("bootloadersetup", skip = 0)
+                self.dispatch.skipStep("bootloader", skip = 0)
+                self.dispatch.skipStep("bootloaderadvanced", skip = 0)
+                self.dispatch.skipStep("instbootloader", skip = 0)
+                self.bl.doUpgradeOnly = 0
+            else:
+                self.dispatch.skipStep("bootloadersetup", skip = 0)
+                self.dispatch.skipStep("bootloader", skip = 1)
+                self.dispatch.skipStep("bootloaderadvanced", skip = 1)
+                self.dispatch.skipStep("instbootloader", skip = 0)
+                self.bl.doUpgradeOnly = 1
+
+                if self.type == "GRUB":
+                    self.bl.useGrubVal = 1
+                else:
+                    self.bl.useGrubVal = 0
+                self.bl.setDevice(devicePathToName(self.bootDev))
+
+
+
+            screen.popWindow()
+            return INSTALL_OK
diff --git a/pyanaconda/textw/upgrade_text.py b/pyanaconda/textw/upgrade_text.py
new file mode 100644
index 0000000..7fd7ebe
--- /dev/null
+++ b/pyanaconda/textw/upgrade_text.py
@@ -0,0 +1,258 @@
+#
+# upgrade_text.py: text mode upgrade dialogs
+#
+# Copyright (C) 2001  Red Hat, Inc.  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 as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# 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, see <http://www.gnu.org/licenses/>.
+#
+
+import isys
+import iutil
+import upgrade
+from constants_text import *
+from snack import *
+from flags import flags
+from constants import *
+from storage.formats import getFormat
+
+import gettext
+_ = lambda x: gettext.ldgettext("anaconda", x)
+
+import logging
+log = logging.getLogger("anaconda")
+
+seenExamineScreen = False
+
+class UpgradeMigrateFSWindow:
+    def __call__ (self, screen, anaconda):
+      
+        migent = anaconda.storage.migratableDevices
+
+	g = GridFormHelp(screen, _("Migrate File Systems"), "upmigfs", 1, 4)
+
+	text = (_("This release of %(productName)s supports "
+                 "an updated file system, which has several "
+                 "benefits over the file system traditionally shipped "
+                 "in %(productName)s.  This installation program can migrate "
+                 "formatted partitions without data loss.\n\n"
+                 "Which of these partitions would you like to migrate?") %
+                  {'productName': productName})
+
+	tb = TextboxReflowed(60, text)
+	g.add(tb, 0, 0, anchorLeft = 1, padding = (0, 0, 0, 1))
+
+        partlist = CheckboxTree(height=4, scroll=1)
+        for device in migent:
+            if not device.format.exists:
+                migrating = True
+            else:
+                migrating = False
+
+            # FIXME: the fstype at least will be wrong here
+            partlist.append("%s - %s - %s" % (device.path,
+                                              device.format.type,
+                                              device.format.mountpoint),
+                                              device, migrating)
+            
+	g.add(partlist, 0, 1, padding = (0, 0, 0, 1))
+        
+	buttons = ButtonBar(screen, [TEXT_OK_BUTTON, TEXT_BACK_BUTTON] )
+	g.add(buttons, 0, 3, anchorLeft = 1, growx = 1)
+
+	while 1:
+	    result = g.run()
+        
+	    if (buttons.buttonPressed(result)):
+		result = buttons.buttonPressed(result)
+
+	    if result == TEXT_BACK_CHECK:
+		screen.popWindow()
+		return INSTALL_BACK
+
+            # reset
+            # XXX the way to do this is by scheduling and cancelling actions
+            #for entry in migent:
+            #    entry.setFormat(0)
+            #    entry.setMigrate(0)
+            #    entry.fsystem = entry.origfsystem
+
+            for entry in partlist.getSelection():
+                try:
+                    newfs = getFormat(entry.format.migratetofs[0])
+                except Exception, e:
+                    log.info("failed to get new filesystem type, defaulting to ext3: %s" %(e,))
+                    newfs = getFormat("ext3")
+                    anaconda.storage.migrateFormat(entry, newfs)
+
+            screen.popWindow()
+            return INSTALL_OK
+
+class UpgradeSwapWindow:
+    def __call__ (self, screen, anaconda):
+	(fsList, suggSize, suggDev) = anaconda.upgradeSwapInfo
+
+        ramDetected = iutil.memInstalled()/1024
+
+	text = _("Recent kernels (2.4 or newer) need significantly more swap than older "
+		 "kernels, up to twice the amount of RAM on the "
+		 "system.  You currently have %dMB of swap configured, but "
+		 "you may create additional swap space on one of your "
+		 "file systems now.") % (iutil.swapAmount() / 1024)
+
+	tb = TextboxReflowed(60, text)
+	amount = Entry(10, scroll = 0)
+	amount.set(str(suggSize))
+
+	l = len(fsList)
+	scroll = 0
+	if l > 4:
+	    l = 4
+	    scroll = 1
+	listbox = Listbox(l, scroll = scroll)
+
+	liLabel = Label("%-25s %-15s %8s" % (_("Mount Point"), 
+			_("Partition"), _("Free Space")))
+
+	count = 0
+	for (device, size) in fsList:
+	    listbox.append("%-25s %-15s %6dMB" % (device.format.mountpoint,
+                                                  device.path,
+                                                  size),
+                                                  count)
+
+	    if (device == suggDev):
+		listbox.setCurrent(count)
+
+	    count = count + 1
+
+	buttons = ButtonBar(screen, [TEXT_OK_BUTTON, (_("Skip"), "skip"),  
+			    TEXT_BACK_BUTTON] )
+
+	amGrid = Grid(2, 3)
+	amGrid.setField(Label(_("RAM detected (MB):")), 0, 0, anchorLeft = 1,
+			padding = (0, 0, 1, 0))
+	amGrid.setField(Label(str(ramDetected)), 1, 0, anchorLeft = 1)
+	amGrid.setField(Label(_("Suggested size (MB):")), 0, 1, anchorLeft = 1,
+			padding = (0, 0, 1, 0))
+	amGrid.setField(Label(str(suggSize)), 1, 1, anchorLeft = 1)
+	amGrid.setField(Label(_("Swap file size (MB):")), 0, 2, anchorLeft = 1,
+			padding = (0, 0, 1, 0))
+	amGrid.setField(amount, 1, 2)
+	
+	liGrid = Grid(1, 2)
+	liGrid.setField(liLabel, 0, 0)
+	liGrid.setField(listbox, 0, 1)
+
+	g = GridFormHelp(screen, _("Add Swap"), "upgradeswap", 1, 4)
+	g.add(tb, 0, 0, anchorLeft = 1, padding = (0, 0, 0, 1))
+	g.add(amGrid, 0, 1, padding = (0, 0, 0, 1))
+	g.add(liGrid, 0, 2, padding = (0, 0, 0, 1))
+	g.add(buttons, 0, 3, anchorLeft = 1, growx = 1)
+
+	while 1:
+	    result = g.run()
+
+	    if (buttons.buttonPressed(result)):
+		result = buttons.buttonPressed(result)
+
+	    if result == TEXT_BACK_CHECK:
+		screen.popWindow()
+		return INSTALL_BACK
+	    elif result == "skip":
+		screen.popWindow()
+		return INSTALL_OK
+
+	    val = amount.value()
+            
+	    try:
+		val = int(val)
+	    except ValueError:
+		anaconda.intf.messageWindow(_("Error"),
+                                   _("The value you entered is not a "
+                                     "valid number."))
+
+	    if type(val) == type(1):
+		(dev, size) = fsList[listbox.current()]
+		if size < (val + 16):
+		    anaconda.intf.messageWindow(_("Error"),
+                                       _("There is not enough space on the "
+                                         "device you selected for the swap "
+                                         "partition."))
+                elif val > 2000 or val < 1:
+                    anaconda.intf.messageWindow(_("Warning"), 
+                                       _("The swap file must be between 1 "
+                                         "and 2000 MB in size."))
+		else:
+		    screen.popWindow()
+                    anaconda.storage.createSwapFile(dev, val)
+                    anaconda.dispatch.skipStep("addswap", 1)
+		    return INSTALL_OK
+
+	raise ValueError
+	
+class UpgradeExamineWindow:
+    def __call__ (self, screen, anaconda):
+        parts = anaconda.rootParts
+
+        height = min(len(parts), 11) + 1
+        if height == 12:
+            scroll = 1
+        else:
+            scroll = 0
+        partList = []
+        partList.append(_("Reinstall System"))
+
+        global seenExamineScreen
+
+	if (not seenExamineScreen and anaconda.dispatch.stepInSkipList("installtype")) or anaconda.upgrade:
+            default = 1
+        else:
+            default = 0
+
+        for (device, desc) in parts:
+            partList.append("%s (%s)" %(desc, device.path))
+
+        (button, choice) =  ListboxChoiceWindow(screen, _("System to Upgrade"),
+                            _("There seem to be one or more existing Linux installations "
+                              "on your system.\n\nPlease choose one to upgrade, "
+			      "or select 'Reinstall System' to freshly install "
+			      "your system."), partList,
+                                                [ TEXT_OK_BUTTON,
+                                                  TEXT_BACK_BUTTON ],
+                                                width = 55, scroll = scroll,
+                                                height = height,
+                                                default = default,
+                                                help = "upgraderoot")
+
+        if button == TEXT_BACK_CHECK:
+            return INSTALL_BACK
+        else:
+            if choice == 0:
+                root = None
+            else:
+                root = parts[choice - 1]
+
+        if root is not None:
+            upgrade.setSteps(anaconda)
+            anaconda.upgrade = True
+
+            anaconda.upgradeRoot = [(root[0], root[1])]
+            anaconda.rootParts = parts
+            anaconda.dispatch.skipStep("installtype", skip = 1)
+        else:
+            anaconda.dispatch.skipStep("installtype", skip = 0)
+            anaconda.upgradeRoot = None
+
+        seenExamineScreen = True
+        return INSTALL_OK
diff --git a/pyanaconda/textw/userauth_text.py b/pyanaconda/textw/userauth_text.py
new file mode 100644
index 0000000..111858c
--- /dev/null
+++ b/pyanaconda/textw/userauth_text.py
@@ -0,0 +1,107 @@
+#
+# userauth_text.py: text mode authentication setup dialogs
+#
+# Copyright (C) 2000, 2001, 2002, 2008  Red Hat, Inc.  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 as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# 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, see <http://www.gnu.org/licenses/>.
+#
+
+from snack import *
+from constants_text import *
+import cracklib
+
+from constants import *
+import gettext
+_ = lambda x: gettext.ldgettext("anaconda", x)
+
+class RootPasswordWindow:
+    def __call__ (self, screen, anaconda):
+        toplevel = GridFormHelp(screen, _("Root Password"), "rootpw", 1, 3)
+
+        toplevel.add(TextboxReflowed(37,
+                                     _("Pick a root password. You must "
+                                       "type it twice to ensure you know "
+                                       "it and do not make a typing "
+                                       "mistake. ")),
+                     0, 0, (0, 0, 0, 1))
+
+        if anaconda.users.rootPassword["isCrypted"]:
+            anaconda.users.rootPassword["password"] = ""
+
+        entry1 = Entry(24, password=1,
+                       text=anaconda.users.rootPassword["password"])
+        entry2 = Entry(24, password=1,
+                       text=anaconda.users.rootPassword["password"])
+        passgrid = Grid(2, 2)
+        passgrid.setField(Label(_("Password:")), 0, 0, (0, 0, 1, 0),
+                          anchorLeft=1)
+        passgrid.setField(Label(_("Password (confirm):")), 0, 1, (0, 0, 1, 0),
+                          anchorLeft=1)
+        passgrid.setField(entry1, 1, 0)
+        passgrid.setField(entry2, 1, 1)
+        toplevel.add(passgrid, 0, 1, (0, 0, 0, 1))
+
+        bb = ButtonBar(screen, (TEXT_OK_BUTTON, TEXT_BACK_BUTTON))
+        toplevel.add(bb, 0, 2, growx = 1)
+
+        while 1:
+            toplevel.setCurrent(entry1)
+            result = toplevel.run()
+            rc = bb.buttonPressed(result)
+            if rc == TEXT_BACK_CHECK:
+                screen.popWindow()
+                return INSTALL_BACK
+            if len(entry1.value()) < 6:
+                ButtonChoiceWindow(screen, _("Password Length"),
+                    _("The root password must be at least 6 characters long."),
+                    buttons = [ TEXT_OK_BUTTON ], width = 50)
+            elif entry1.value() != entry2.value():
+                ButtonChoiceWindow(screen, _("Password Mismatch"),
+                    _("The passwords you entered were different. Please "
+                      "try again."), buttons = [ TEXT_OK_BUTTON ], width = 50)
+            elif self.hasBadChars(entry1.value()):
+                ButtonChoiceWindow(screen, _("Error with Password"),
+                    _("Requested password contains non-ASCII characters, "
+                      "which are not allowed."),
+                    buttons = [ TEXT_OK_BUTTON ], width = 50)
+            else:
+                try:
+                    cracklib.FascistCheck(entry1.value())
+                except ValueError, e:
+                    msg = gettext.ldgettext("cracklib", e)
+                    ret = anaconda.intf.messageWindow(_("Weak Password"),
+                             _("You have provided a weak password: %s\n\n"
+                               "Would you like to continue with this password?"
+                               % (msg, )),
+                             type = "yesno", default="no")
+                    if ret == 1:
+                        break
+                else:
+                    break
+
+            entry1.set("")
+            entry2.set("")
+
+        screen.popWindow()
+        anaconda.users.rootPassword["password"] = entry1.value()
+        anaconda.users.rootPassword["isCrypted"] = False
+        return INSTALL_OK
+
+    def hasBadChars(self, pw):
+        allowed = string.digits + string.ascii_letters + \
+                  string.punctuation + " "
+        for letter in pw:
+            if letter not in allowed:
+                return True
+        return False
diff --git a/pyanaconda/textw/welcome_text.py b/pyanaconda/textw/welcome_text.py
new file mode 100644
index 0000000..bf58b58
--- /dev/null
+++ b/pyanaconda/textw/welcome_text.py
@@ -0,0 +1,47 @@
+#
+# welcome_text.py: text mode welcome window
+#
+# Copyright (C) 2001, 2002  Red Hat, Inc.  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 as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# 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, see <http://www.gnu.org/licenses/>.
+#
+
+from snack import *
+from constants_text import *
+from constants import *
+import sys
+import gettext
+_ = lambda x: gettext.ldgettext("anaconda", x)
+
+class WelcomeWindow:
+    def __call__(self, screen, anaconda):
+        rc = ButtonChoiceWindow(screen, _("%s") % (productName,),
+                                _("Welcome to %s!\n\n")
+                                % (productName, ),
+                                buttons = [TEXT_OK_BUTTON], width = 50,
+                                help = "welcome")
+
+        if anaconda.requiresNetworkInstall():
+            anaconda.intf.messageWindow(_("Network Install Required"),
+                                        _("Your installation source is set to "
+                                          "a network location, but no netork "
+                                          "devices were found on your "
+                                          "system.  To avoid a network "
+                                          "installation, boot with the full "
+                                          "DVD, full CD set, or do not pass "
+                                          "a repo= parameter that specifies "
+                                          "a network source."))
+            sys.exit(0)
+
+        return INSTALL_OK
diff --git a/pyanaconda/textw/zipl_text.py b/pyanaconda/textw/zipl_text.py
new file mode 100644
index 0000000..9a1b202
--- /dev/null
+++ b/pyanaconda/textw/zipl_text.py
@@ -0,0 +1,102 @@
+#
+# zipl_text.py: text mode z/IPL setup dialog
+#
+# Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006  Red Hat, Inc.
+# 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 as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# 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, see <http://www.gnu.org/licenses/>.
+#
+
+import string
+from snack import *
+from constants_text import *
+
+from constants import *
+from storage.dasd import getDasdPorts
+
+import gettext
+_ = lambda x: gettext.ldgettext("anaconda", x)
+
+class ZiplWindow:
+    def __call__(self, screen, anaconda):
+        self.bl = anaconda.bootloader
+
+        t = TextboxReflowed(53,
+                         _("The z/IPL Boot Loader will be installed "
+                           "on your system after installation is complete. "
+                           "You can now enter any additional kernel and "
+                           "chandev parameters which your machine or your "
+                           "setup require."))
+
+        kernelparms = ""
+        kernelentry = Entry(48, scroll = 1, returnExit = 1)
+        chandeventry1 = Entry(48, scroll = 1, returnExit = 1)
+        chandeventry2 = Entry(48, scroll = 1, returnExit = 1)
+
+        if self.bl.args and self.bl.args.get():
+            kernelparms = self.bl.args.get()
+        if getDasdPorts() and (kernelparms.find("dasd=") == -1):
+            if len(kernelparms) > 0:
+                kernelparms = "%s dasd=%s" %(kernelparms, getDasdPorts())
+            else:
+                kernelparms = "dasd=%s" %(getDasdPorts(),)
+        kernelentry.set(kernelparms)
+
+        if self.bl.args and self.bl.args.chandevget():
+            cdevs = self.bl.args.chandevget()
+            chandeventry1.set('')
+            chandeventry2.set('')
+            if len(cdevs) > 0:
+                chandeventry1.set(cdevs[0])
+            if len(cdevs) > 1:
+                chandeventry2.set(string.join(cdevs[1:],';'))
+
+        buttons = ButtonBar(screen, [TEXT_OK_BUTTON,
+                            TEXT_BACK_BUTTON ] )
+
+        grid = GridFormHelp(screen, _("z/IPL Configuration"), 
+                            "zipl-s390", 1, 5)
+        grid.add(t, 0, 0)
+        sg = Grid(2, 1)
+        sg.setField(Label(_("Kernel Parameters") + ": "), 0, 0, anchorLeft=1)
+        sg.setField(kernelentry, 1, 0, anchorLeft=1)
+        grid.add(sg, 0, 1, padding = (0, 1, 0, 1))
+        sg = Grid(2, 1)
+        sg.setField(Label(_("Chandev line ") + "1: "), 0, 0, anchorLeft=1)
+        sg.setField(chandeventry1, 1, 0, anchorLeft=1)
+        grid.add(sg, 0, 2, padding = (0, 1, 0, 1))
+        sg = Grid(2, 1)
+        sg.setField(Label(_("Chandev line ") + "2: "), 0, 0, anchorLeft=1)
+        sg.setField(chandeventry2, 1, 0, anchorLeft=1)
+        grid.add(sg, 0, 3, padding = (0, 1, 0, 1))
+        grid.add(buttons, 0, 4, growx = 1)
+
+        result = grid.runOnce ()
+        button = buttons.buttonPressed(result)
+        
+        if button == TEXT_BACK_CHECK:
+            return INSTALL_BACK
+
+        if kernelentry.value():
+            self.bl.args.set(string.strip(kernelentry.value()))
+        else:
+            self.bl.args.set("")
+
+        cdevs = []
+        if chandeventry1.value():
+            cdevs.append(string.strip(chandeventry1.value()))
+        if chandeventry2.value():
+            cdevs.append(string.strip(chandeventry2.value()))
+        self.bl.args.chandevset(cdevs)
+        return INSTALL_OK
diff --git a/pyanaconda/timezone.py b/pyanaconda/timezone.py
new file mode 100644
index 0000000..74d66db
--- /dev/null
+++ b/pyanaconda/timezone.py
@@ -0,0 +1,76 @@
+#
+# timezone.py - timezone install data
+#
+# Copyright (C) 2001  Red Hat, Inc.  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 as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# 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, see <http://www.gnu.org/licenses/>.
+#
+
+import shutil
+import iutil
+import os
+from flags import flags
+
+import logging
+log = logging.getLogger("anaconda")
+
+class Timezone:
+    def writeKS(self, f):
+        f.write("timezone")
+        if self.utc:
+            f.write(" --utc")
+        f.write(" %s\n" % self.tz)
+
+    def write(self, instPath):
+        fromFile = instPath + "/usr/share/zoneinfo/" + self.tz
+
+        if not os.access(fromFile, os.R_OK):
+            log.error("Timezone to be copied (%s) doesn't exist" % fromFile)
+        else:
+            try:
+                shutil.copyfile(fromFile, instPath + "/etc/localtime")
+            except OSError as e:
+                log.error("Error copying timezone (from %s): %s" % (fromFile, e.strerror))
+
+        f = open(instPath + "/etc/sysconfig/clock", "w")
+
+        f.write('ZONE="%s"\n' % self.tz)
+        f.close()
+
+        try:
+            f = open(instPath + "/etc/adjtime", "r")
+            lines = f.readlines()
+            f.close()
+        except:
+            lines = [ "0.0 0 0.0\n", "0\n" ]
+
+        f = open(instPath + "/etc/adjtime", "w")
+        f.write(lines[0])
+        f.write(lines[1])
+        if self.utc:
+            f.write("UTC\n")
+        else:
+            f.write("LOCAL\n")
+        f.close()
+
+    def getTimezoneInfo(self):
+        return (self.tz, self.utc)
+
+    def setTimezoneInfo(self, timezone, asUtc = 0):
+        self.tz = timezone
+        self.utc = asUtc
+
+    def __init__(self):
+        self.tz = "America/New_York"
+        self.utc = 0
diff --git a/pyanaconda/upgrade.py b/pyanaconda/upgrade.py
new file mode 100644
index 0000000..91e8911
--- /dev/null
+++ b/pyanaconda/upgrade.py
@@ -0,0 +1,344 @@
+#
+# upgrade.py - Existing install probe and upgrade procedure
+#
+# Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007  Red Hat, Inc.
+# 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 as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# 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, see <http://www.gnu.org/licenses/>.
+#
+# Author(s): Matt Wilson <msw@xxxxxxxxxx>
+#
+
+import isys
+import os
+import iutil
+import time
+import sys
+import os.path
+import shutil
+import string
+import selinux
+from flags import flags
+from constants import *
+from product import productName
+from storage import findExistingRootDevices, getReleaseString
+from storage import mountExistingSystem
+from storage.formats import getFormat
+
+import gettext
+_ = lambda x: gettext.ldgettext("anaconda", x)
+
+import rpm
+
+import logging
+log = logging.getLogger("anaconda")
+
+def queryUpgradeContinue(anaconda):
+    if anaconda.dir == DISPATCH_FORWARD:
+        return
+
+    rc = anaconda.intf.messageWindow(_("Proceed with upgrade?"),
+                       _("The file systems of the Linux installation "
+                         "you have chosen to upgrade have already been "
+                         "mounted. You cannot go back past this point. "
+                         "\n\n") + 
+                       _("Would you like to continue with the upgrade?"),
+                         type="custom", custom_icon=["error","error"],
+                         custom_buttons=[_("_Exit installer"), _("_Continue")])
+    if rc == 0:
+        sys.exit(0)
+    return DISPATCH_FORWARD
+
+def setUpgradeRoot(anaconda):
+    anaconda.upgradeRoot = []
+    root_device = None
+    # kickstart can pass device as device name or uuid. No quotes allowed.
+    if anaconda.ksdata and anaconda.ksdata.upgrade.root_device is not None:
+        root_device = anaconda.ksdata.upgrade.root_device
+    for (dev, label) in anaconda.rootParts:
+        if ((root_device is not None) and
+            (root_device == dev.name or root_device == "UUID=%s" % dev.format.uuid)):
+            anaconda.upgradeRoot.insert(0, (dev,label))
+        else:
+            anaconda.upgradeRoot.append((dev,label))
+
+def findRootParts(anaconda):
+    if anaconda.dir == DISPATCH_BACK:
+        return
+    if anaconda.rootParts is None:
+        anaconda.rootParts = findExistingRoots(anaconda,
+                                               flags.cmdline.has_key("upgradeany"))
+
+    setUpgradeRoot(anaconda)
+
+    if anaconda.rootParts is not None and len(anaconda.rootParts) > 0:
+        anaconda.dispatch.skipStep("findinstall", skip = 0)
+        if productName.find("Red Hat Enterprise Linux") == -1:
+            anaconda.dispatch.skipStep("installtype", skip = 1)
+    else:
+        anaconda.dispatch.skipStep("findinstall", skip = 1)
+        anaconda.dispatch.skipStep("installtype", skip = 0)
+
+def findExistingRoots(anaconda, upgradeany=False):
+    rootparts = findExistingRootDevices(anaconda, upgradeany=upgradeany)
+    return rootparts
+
+def bindMountDevDirectory(instPath):
+    getFormat("bind",
+              device="/dev",
+              mountpoint="/dev",
+              exists=True).mount(chroot=instPath)
+
+# returns None if no filesystem exist to migrate
+def upgradeMigrateFind(anaconda):
+    migents = anaconda.storage.migratableDevices
+    if not migents or len(migents) < 1:
+        anaconda.dispatch.skipStep("upgrademigratefs")
+    else:
+        anaconda.dispatch.skipStep("upgrademigratefs", skip = 0)
+
+def copyFromSysimage(rootPath, filename):
+    """Mirrors filename from the sysimage on the ramdisk."""
+    sysfile = os.path.normpath("%s/%s" % (rootPath, filename))
+    if os.access(sysfile, os.R_OK):
+        try:
+            # remove our copy if we have one (think liveinstall)
+            os.remove(filename)
+        except OSError:
+            pass
+        try:
+            shutil.copyfile(sysfile, filename)
+        except OSError as e:
+            log.error("Error copying %s to sysimage: %s" %(sysfile, e.strerror))
+            return False
+    else:
+        log.error("Error copying %s to sysimage, file not accessible." % sysfile)
+        return False
+    return True
+
+def restoreTime(anaconda):
+    """Load time setup for upgrade install.
+    
+    We need to find out the timezone and the UTC parameter of the old system and
+    set the system time accordingly, so timestamps are set correctly for the
+    files the upgrade procedure will create.
+
+    This is pretty much what packages.setupTimezone() does in reverse.
+    """
+    if anaconda.dir == DISPATCH_BACK:
+        return
+    if os.environ.has_key("TZ"):
+        del os.environ["TZ"]
+    copyFromSysimage(anaconda.rootPath, '/etc/localtime')
+    copyFromSysimage(anaconda.rootPath, '/etc/adjtime')
+    if iutil.isS390():
+        return
+    args = [ "--hctosys" ]
+    try:
+        iutil.execWithRedirect("/usr/sbin/hwclock", args,stdout = "/dev/tty5",
+                               stderr = "/dev/tty5")
+    except RuntimeError:
+        log.error("Failed to set the clock.")
+
+# returns None if no more swap is needed
+def upgradeSwapSuggestion(anaconda):
+    # mem is in kb -- round it up to the nearest 4Mb
+    mem = iutil.memInstalled()
+    rem = mem % 16384
+    if rem:
+	mem = mem + (16384 - rem)
+    mem = mem / 1024
+
+    anaconda.dispatch.skipStep("addswap", 0)
+    
+    # don't do this if we have more then 250 MB
+    if mem > 250:
+        anaconda.dispatch.skipStep("addswap", 1)
+        return
+    
+    swap = iutil.swapAmount() / 1024
+
+    # if we have twice as much swap as ram and at least 192 megs
+    # total, we're safe 
+    if (swap >= (mem * 1.5)) and (swap + mem >= 192):
+        anaconda.dispatch.skipStep("addswap", 1)
+	return
+
+    # if our total is 512 megs or more, we should be safe
+    if (swap + mem >= 512):
+        anaconda.dispatch.skipStep("addswap", 1)
+	return
+
+    fsList = []
+
+    for device in anaconda.storage.fsset.devices:
+        if not device.format:
+            continue
+        if device.format.mountable and device.format.linuxNative:
+            if not device.format.status:
+                continue
+            space = isys.pathSpaceAvailable(anaconda.rootPath + device.format.mountpoint)
+            if space > 16:
+                info = (device, space)
+                fsList.append(info)
+
+    suggestion = mem * 2 - swap
+    if (swap + mem + suggestion) < 192:
+        suggestion = 192 - (swap + mem)
+    if suggestion < 32:
+        suggestion = 32
+    suggSize = 0
+    suggMnt = None
+    for (device, size) in fsList:
+	if (size > suggSize) and (size > (suggestion + 100)):
+	    suggDev = device
+
+    anaconda.upgradeSwapInfo = (fsList, suggestion, suggDev)
+
+# XXX handle going backwards
+def upgradeMountFilesystems(anaconda):
+    # mount everything and turn on swap
+
+    try:
+        mountExistingSystem(anaconda, anaconda.upgradeRoot[0], allowDirty = 0)
+    except ValueError as e:
+        log.error("Error mounting filesystem: %s" % e)
+        anaconda.intf.messageWindow(_("Mount failed"),
+            _("The following error occurred when mounting the file "
+              "systems listed in /etc/fstab.  Please fix this problem "
+              "and try to upgrade again.\n%s" % e))
+        sys.exit(0)
+    except IndexError as e:
+        # The upgrade root is search earlier but we give the message here.
+        log.debug("No upgrade root was found.")
+        if anaconda.ksdata and anaconda.ksdata.upgrade.upgrade:
+            anaconda.intf.messageWindow(_("Upgrade root not found"),
+                _("The root for the previously installed system was not "
+                  "found."), type="custom",
+                custom_icon="info",
+                custom_buttons=[_("Exit installer")])
+            sys.exit(0)
+        else:
+            rc = anaconda.intf.messageWindow(_("Upgrade root not found"),
+                    _("The root for the previously installed system was not "
+                      "found.  You can exit installer or backtrack to choose "
+                      "installation instead of upgrade."),
+                type="custom",
+                custom_buttons = [ _("_Back"),
+                                   _("_Exit installer") ],
+                custom_icon="question")
+            if rc == 0:
+                return DISPATCH_BACK
+            elif rc == 1:
+                sys.exit(0)
+
+    checkLinks = ( '/etc', '/var', '/var/lib', '/var/lib/rpm',
+                   '/boot', '/tmp', '/var/tmp', '/root',
+                   '/bin/sh', '/usr/tmp')
+    badLinks = []
+    for n in checkLinks:
+        if not os.path.islink(anaconda.rootPath + n): continue
+        l = os.readlink(anaconda.rootPath + n)
+        if l[0] == '/':
+            badLinks.append(n)
+
+    if badLinks:
+        message = _("The following files are absolute symbolic " 
+                    "links, which we do not support during an " 
+                    "upgrade. Please change them to relative "
+                    "symbolic links and restart the upgrade.\n\n")
+        for n in badLinks:
+            message = message + '\t' + n + '\n'
+        anaconda.intf.messageWindow(_("Absolute Symlinks"), message)
+        sys.exit(0)
+
+    # fix for 80446
+    badLinks = []
+    mustBeLinks = ( '/usr/tmp', )
+    for n in mustBeLinks:
+        if not os.path.islink(anaconda.rootPath + n):
+            badLinks.append(n)
+
+    if badLinks: 
+        message = _("The following are directories which should instead "
+                    "be symbolic links, which will cause problems with the "
+                    "upgrade.  Please return them to their original state "
+                    "as symbolic links and restart the upgrade.\n\n")
+        for n in badLinks:
+            message = message + '\t' + n + '\n'
+        anaconda.intf.messageWindow(_("Invalid Directories"), message)
+        sys.exit(0)
+
+    anaconda.storage.turnOnSwap(upgrading=True)
+    anaconda.storage.mkDevRoot()
+
+    # Move /etc/rpm/platform out of the way.
+    if os.path.exists(anaconda.rootPath + "/etc/rpm/platform"):
+        shutil.move(anaconda.rootPath + "/etc/rpm/platform",
+                    anaconda.rootPath + "/etc/rpm/platform.rpmsave")
+
+    # if they've been booting with selinux disabled, then we should
+    # disable it during the install as well (#242510)
+    try:
+        if os.path.exists(anaconda.rootPath + "/.autorelabel"):
+            ctx = selinux.getfilecon(anaconda.rootPath + "/.autorelabel")[1]
+            if not ctx or ctx == "unlabeled":
+                flags.selinux = False
+                log.info("Disabled SELinux for upgrade based on /.autorelabel")
+    except Exception, e:
+        log.warning("error checking selinux state: %s" %(e,))
+
+def setSteps(anaconda):
+    dispatch = anaconda.dispatch
+    dispatch.setStepList(
+                "language",
+                "keyboard",
+                "welcome",
+                "filtertype",
+                "filter",
+                "cleardiskssel",
+                "installtype",
+                "storageinit",
+                "findrootparts",
+                "findinstall",
+                "upgrademount",
+                "restoretime",
+                "upgrademigfind",
+                "upgrademigratefs",
+                "enablefilesystems",
+                "upgradecontinue",
+                "reposetup",
+                "upgbootloader",
+                "checkdeps",
+                "dependencies",
+                "confirmupgrade",
+                "postselection",
+                "reipl",
+                "install",
+                "preinstallconfig",
+                "installpackages",
+                "postinstallconfig",
+                "instbootloader",
+                "dopostaction",
+                "methodcomplete",
+                "postscripts",
+                "copylogs",
+                "complete"
+            )
+
+    if not iutil.isX86():
+        dispatch.skipStep("bootloader")
+
+    if not iutil.isX86():
+        dispatch.skipStep("upgbootloader")            
diff --git a/pyanaconda/users.py b/pyanaconda/users.py
new file mode 100644
index 0000000..67d15b2
--- /dev/null
+++ b/pyanaconda/users.py
@@ -0,0 +1,307 @@
+#
+# users.py:  Code for creating user accounts and setting the root password
+#
+# Copyright (C) 2006, 2007, 2008 Red Hat, Inc.  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 as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# 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, see <http://www.gnu.org/licenses/>.
+#
+# Author(s): Chris Lumens <clumens@xxxxxxxxxx>
+#
+
+import libuser
+import string
+import crypt
+import random
+import tempfile
+import os
+import os.path
+
+import logging
+log = logging.getLogger("anaconda")
+
+def createLuserConf(instPath, algoname='sha512'):
+    """Writes a libuser.conf for instPath."""
+    createTmp = False
+    try:
+        fn = os.environ["LIBUSER_CONF"]
+        if os.access(fn, os.F_OK):
+            log.info("removing libuser.conf at %s" % (os.getenv("LIBUSER_CONF")))
+            os.unlink(fn)
+        log.info("created new libuser.conf at %s with instPath=\"%s\"" % \
+                (fn,instPath))
+        fd = open(fn, 'w')
+    except:
+        createTmp = True
+
+    if createTmp:
+        (fp, fn) = tempfile.mkstemp(prefix="libuser.")
+        log.info("created new libuser.conf at %s with instPath=\"%s\"" % \
+                (fn,instPath))
+        fd = os.fdopen(fp, 'w')
+
+    buf = """
+[defaults]
+skeleton = %(instPath)s/etc/skel
+mailspooldir = %(instPath)s/var/mail
+crypt_style = %(algo)s
+modules = files shadow
+create_modules = files shadow
+[files]
+directory = %(instPath)s/etc
+[shadow]
+directory = %(instPath)s/etc
+""" % {"instPath": instPath, "algo": algoname}
+
+    fd.write(buf)
+    fd.close()
+    os.environ["LIBUSER_CONF"] = fn
+
+    return fn
+
+# These are explained in crypt/crypt-entry.c in glibc's code.  The prefixes
+# we use for the different crypt salts:
+#     $1$    MD5
+#     $5$    SHA256
+#     $6$    SHA512
+def cryptPassword(password, algo=None):
+    salts = {'md5': '$1$', 'sha256': '$5$', 'sha512': '$6$'}
+    saltlen = 2
+
+    if algo is None:
+        algo = 'sha512'
+
+    if algo == 'md5' or algo == 'sha256' or algo == 'sha512':
+        saltlen = 16
+
+    saltstr = salts[algo]
+
+    for i in range(saltlen):
+        saltstr = saltstr + random.choice (string.letters +
+                                           string.digits + './')
+
+    return crypt.crypt (password, saltstr)
+
+class Users:
+    def __init__ (self, anaconda):
+        self.anaconda = anaconda
+        self.admin = libuser.admin()
+        self.rootPassword = { "isCrypted": False, "password": "", "lock": False }
+
+    def createGroup (self, name=None, gid=None, root="/mnt/sysimage"):
+        childpid = os.fork()
+
+        if not childpid:
+            if not root in ["","/"]:
+                os.chroot(root)
+                del(os.environ["LIBUSER_CONF"])
+
+            self.admin = libuser.admin()
+
+            try:
+                if self.admin.lookupGroupByName(name):
+                    os._exit(1)
+
+                groupEnt = self.admin.initGroup(name)
+
+                if gid >= 0:
+                    groupEnt.set(libuser.GIDNUMBER, gid)
+
+                self.admin.addGroup(groupEnt)
+                os._exit(0)
+            except Exception, e:
+                log.critical("Error when creating new group: %s" % str(e))
+                os._exit(1)
+
+        try:
+            (pid, status) = os.waitpid(childpid, 0)
+        except OSError as e:
+            log.critical("exception from waitpid while creating a group: %s %s" % (e.errno, e.strerror))
+            return False
+
+        if os.WIFEXITED(status) and (os.WEXITSTATUS(status) == 0):
+            return True
+        else:
+            return False
+
+    def createUser (self, name=None, password=None, isCrypted=False, groups=[],
+                    homedir=None, shell=None, uid=None, algo=None, lock=False,
+                    root="/mnt/sysimage", gecos=None):
+        childpid = os.fork()
+
+        if not childpid:
+            if not root in ["","/"]:
+                os.chroot(root)
+                del(os.environ["LIBUSER_CONF"])
+
+            self.admin = libuser.admin()
+
+            try:
+                if self.admin.lookupUserByName(name):
+                    os._exit(1)
+
+                userEnt = self.admin.initUser(name)
+                groupEnt = self.admin.initGroup(name)
+
+                grpLst = filter(lambda grp: grp,
+                                map(lambda name: self.admin.lookupGroupByName(name), groups))
+                userEnt.set(libuser.GIDNUMBER, [groupEnt.get(libuser.GIDNUMBER)[0]] +
+                            map(lambda grp: grp.get(libuser.GIDNUMBER)[0], grpLst))
+
+                if not homedir:
+                    homedir = "/home/" + name
+
+                userEnt.set(libuser.HOMEDIRECTORY, homedir)
+
+                if shell:
+                    userEnt.set(libuser.LOGINSHELL, shell)
+
+                if uid >= 0:
+                    userEnt.set(libuser.UIDNUMBER, uid)
+
+                if gecos:
+                    userEnt.set(libuser.GECOS, gecos)
+
+                self.admin.addUser(userEnt)
+                self.admin.addGroup(groupEnt)
+
+                if password:
+                    if isCrypted:
+                        self.admin.setpassUser(userEnt, password, True)
+                    else:
+                        self.admin.setpassUser(userEnt,
+                                            cryptPassword(password, algo=algo),
+                                            True)
+
+                if lock:
+                    self.admin.lockUser(userEnt)
+
+                # Add the user to all the groups they should be part of.
+                grpLst.append(self.admin.lookupGroupByName(name))
+                for grp in grpLst:
+                    grp.add(libuser.MEMBERNAME, name)
+                    self.admin.modifyGroup(grp)
+
+                os._exit(0)
+            except Exception, e:
+                log.critical("Error when creating new user: %s" % str(e))
+                os._exit(1)
+
+        try:
+            (pid, status) = os.waitpid(childpid, 0)
+        except OSError as e:
+            log.critical("exception from waitpid while creating a user: %s %s" % (e.errno, e.strerror))
+            return False
+
+        if os.WIFEXITED(status) and (os.WEXITSTATUS(status) == 0):
+            return True
+        else:
+            return False
+
+    def checkUserExists(self, username, root="/mnt/sysimage"):
+        childpid = os.fork()
+
+        if not childpid:
+            if not root in ["","/"]:
+                os.chroot(root)
+                del(os.environ["LIBUSER_CONF"])
+
+            self.admin = libuser.admin()
+
+            try:
+                if self.admin.lookupUserByName(username):
+                    os._exit(0)
+            except Exception, e:
+                log.critical("Error when searching for user: %s" % str(e))
+            os._exit(1)
+
+        try:
+            (pid, status) = os.waitpid(childpid, 0)
+        except OSError as e:
+            log.critical("exception from waitpid while creating a user: %s %s" % (e.errno, e.strerror))
+            return False
+
+        if os.WIFEXITED(status) and (os.WEXITSTATUS(status) == 0):
+            return True
+        else:
+            return False
+
+    # Reads the auth string and returns a string indicating our desired
+    # password encoding algorithm.
+    def getPassAlgo(self):
+        if self.anaconda.security.auth.find("--enablemd5") != -1 or \
+           self.anaconda.security.auth.find("--passalgo=md5") != -1:
+            return 'md5'
+        elif self.anaconda.security.auth.find("--passalgo=sha256") != -1:
+            return 'sha256'
+        elif self.anaconda.security.auth.find("--passalgo=sha512") != -1:
+            return 'sha512'
+        else:
+            return None
+
+    def setUserPassword(self, username, password, isCrypted, lock, algo=None):
+        user = self.admin.lookupUserByName(username)
+
+        if isCrypted:
+            self.admin.setpassUser(user, password, True)
+        else:
+            self.admin.setpassUser(user, cryptPassword(password, algo=algo), True)
+
+        if lock:
+            self.admin.lockUser(user)
+
+        self.admin.modifyUser(user)
+
+    def setRootPassword(self, algo=None):
+        return self.setUserPassword("root", self.rootPassword["password"],
+                                    self.rootPassword["isCrypted"],
+                                    self.rootPassword["lock"], algo)
+
+    def write(self, instPath):
+        # make sure crypt_style in libuser.conf matches the salt we're using
+        createLuserConf(instPath, algoname=self.getPassAlgo())
+
+        # User should already exist, just without a password.
+        self.setRootPassword(algo=self.getPassAlgo())
+
+        if self.anaconda.ksdata:
+            for gd in self.anaconda.ksdata.group.groupList:
+                if not self.createGroup(name=gd.name,
+                                        gid=gd.gid,
+                                        root=instPath):
+                    log.error("Group %s already exists, not creating." % gd.name)
+
+            for ud in self.anaconda.ksdata.user.userList:
+                if not self.createUser(name=ud.name,
+                                       password=ud.password,
+                                       isCrypted=ud.isCrypted,
+                                       groups=ud.groups,
+                                       homedir=ud.homedir,
+                                       shell=ud.shell,
+                                       uid=ud.uid,
+                                       algo=self.getPassAlgo(),
+                                       lock=ud.lock,
+                                       root=instPath,
+                                       gecos=ud.gecos):
+                    log.error("User %s already exists, not creating." % ud.name)
+
+    def writeKS(self, f):
+        if self.rootPassword["isCrypted"]:
+            args = " --iscrypted %s" % self.rootPassword["password"]
+        else:
+            args = " --iscrypted %s" % cryptPassword(self.rootPassword["password"], algo=self.getPassAlgo())
+
+        if self.rootPassword["lock"]:
+            args += " --lock"
+
+        f.write("rootpw %s\n" % args)
diff --git a/pyanaconda/vnc.py b/pyanaconda/vnc.py
new file mode 100644
index 0000000..0a6a049
--- /dev/null
+++ b/pyanaconda/vnc.py
@@ -0,0 +1,437 @@
+#
+# vnc.py: VNC related installer functionality
+#
+# Copyright (C) 2004, 2007  Red Hat, Inc.  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 as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# 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, see <http://www.gnu.org/licenses/>.
+#
+# Author(s): Jeremy Katz <katzj@xxxxxxxxxx>
+#
+
+import os, sys, string
+import time
+from snack import *
+from constants import *
+from constants_text import *
+import network
+import isys
+import product
+import socket
+import subprocess
+
+import gettext
+_ = lambda x: gettext.ldgettext("anaconda", x)
+P_ = lambda x, y, z: gettext.ldngettext("anaconda", x, y, z)
+
+import logging
+log = logging.getLogger("anaconda")
+stdoutLog = logging.getLogger("anaconda.stdout")
+
+class VncServer:
+
+    def __init__(self, display="1", root="/", ip=None, name=None,
+                desktop="Desktop", password="", vncconnecthost="",
+                vncconnectport="", log_file="/tmp/vncserver.log",
+                pw_file="/tmp/vncpassword", pw_init_file="/tmp/vncpassword.dat"):
+        self.display = display
+        self.root = root
+        self.ip = ip
+        self.name = name
+        self.desktop = desktop
+        self.password = password
+        self.vncconnecthost = vncconnecthost
+        self.vncconnectport = vncconnectport
+        self.log_file = log_file
+        self.pw_file = pw_file
+        self.pw_init_file = pw_init_file
+        self.connxinfo = None
+        self.anaconda = None
+        self.log = logging.getLogger("anaconda.stdout")
+
+    def recoverVNCPassword(self):
+        """Rescue the vncpassword from where loader left it 
+
+        We are not to check for validity yet, if there is a file
+        pass it to the variable, if there is not, set the var 
+        to ''. We will check valididty later.
+        """
+        # see if there is a vnc password file
+        try:
+            pfile = open(self.pw_init_file, "r")
+            self.password=pfile.readline().strip()
+            pfile.close()
+            os.unlink(self.pw_init_file)
+        except:
+            self.password=""
+
+    def setVNCPassword(self):
+        """Change the vnc server password. Output to file. """
+
+        if len(self.password) == 0:
+            self.setVNCParam("SecurityTypes", "None")
+            self.setVNCParam("rfbauth","0")
+            return
+
+        # If there is a password the SecurityTypes = VncAuth for all connections.
+        self.setVNCParam("SecurityTypes", "VncAuth")
+        self.setVNCParam("rfbauth",self.pw_file)
+
+        # password input combination.
+        pwinput = "%s\n%s\n" % (self.password, self.password)
+        vnccommand = [self.root+"/usr/bin/vncpasswd", self.pw_file]
+        vncpswdo = subprocess.Popen(vnccommand, stdin=subprocess.PIPE, stdout=subprocess.PIPE)# We pipe the output
+                                                                                              # so the user does not see it.
+        (out, err) = vncpswdo.communicate(input=pwinput)
+        return vncpswdo.returncode
+
+    def initialize(self):
+        """Here is were all the relative vars get initialized. """
+
+        # see if we can sniff out network info
+        netinfo = network.Network()
+
+        devices = netinfo.netdevices
+        active_devs = network.getActiveNetDevs()
+
+        if active_devs != []:
+            dev = devices[active_devs[0]]
+
+            try:
+                self.ip = isys.getIPAddress(dev.get("DEVICE"))
+                log.info("ip of %s is %s" % (dev.get("DEVICE"), self.ip))
+
+                if self.ip == "127.0.0.1" or self.ip == "::1":
+                    self.ip = None
+            except Exception, e:
+                log.warning("Got an exception trying to get the self.ip addr "
+                            "of %s: %s" % (dev.get("DEVICE"), e))
+        else:
+            self.ip = None
+
+        self.name = network.getDefaultHostname(self.anaconda)
+        ipstr = self.ip
+
+        if self.ip.find(':') != -1:
+            ipstr = "[%s]" % (self.ip,)
+
+        if (self.name is not None) and (not self.name.startswith('localhost')) and (ipstr is not None):
+            self.connxinfo = "%s:%s (%s)" % (socket.getfqdn(name=self.name), self.display, ipstr,)
+        elif ipstr is not None:
+            self.connxinfo = "%s:%s" % (ipstr, self.display,)
+        else:
+            self.connxinfo = None
+
+        # figure out product info
+        if self.name is not None:
+            self.desktop = _("%(productName)s %(productVersion)s installation "
+                             "on host %(name)s") \
+                           % {'productName': product.productName,
+                              'productVersion': product.productVersion,
+                              'name': self.name}
+        else:
+            self.desktop = _("%(productName)s %(productVersion)s installation")\
+                           % {'productName': product.productName,
+                              'productVersion': product.productVersion}
+
+    def setVNCParam(self, param, value):
+        """Set a parameter in the Xvnc server. 
+
+        Possible values for param and value. param=(values)
+        SecurityTypes=(VncAuth,None)
+        """
+        vncconfigcommand = [self.root+"/usr/bin/vncconfig", "-display", ":%s"%self.display , "-set" , "%s=%s" %(param, value)]
+        vncconfo = subprocess.Popen(vncconfigcommand)# we dont want output
+        return vncconfo.returncode
+
+    def openlogfile(self):
+        try:
+            err = os.open(self.log_file, os.O_RDWR | os.O_CREAT)
+            if err < 0:
+                sys.stderr.write("error opening %s\n", log)
+                return None
+            else:
+                return err
+        except:
+                return None
+
+    def connectToView(self):
+        """Attempt to connect to self.vncconnecthost"""
+
+        maxTries = 10
+        self.log.info(_("Attempting to connect to vnc client on host %s...") % (self.vncconnecthost,))
+
+        if self.vncconnectport != "":
+            hostarg = self.vncconnecthost + ":" + self.vncconnectport
+        else:
+            hostarg = self.vncconnecthost
+
+        vncconfigcommand = [self.root+"/usr/bin/vncconfig", "-display", ":%s"%self.display, "-connect", hostarg]
+
+        for i in range(maxTries):
+            vncconfp = subprocess.Popen(vncconfigcommand, stdout=subprocess.PIPE, stderr=subprocess.PIPE) # vncconfig process
+            (out, err) = vncconfp.communicate()
+
+            if err == '':
+                self.log.info(_("Connected!"))
+                return True
+            elif err.startswith("connecting") and err.endswith("failed\n"):
+                self.log.info(_("Will try to connect again in 15 seconds..."))
+                time.sleep(15)
+                continue
+            else:
+                log.critical(err)
+                sys.exit(1)
+        self.log.error(P_("Giving up attempting to connect after %d try!\n",
+                          "Giving up attempting to connect after %d tries!\n",
+                          maxTries) % (maxTries,))
+        return False
+
+    def VNCListen(self):
+        """Put the server in listening mode.
+
+        We dont really have to do anything for the server to listen :)
+        """
+        if self.connxinfo != None:
+            self.log.info(_("Please manually connect your vnc client to %s to begin the install.") % (self.connxinfo,))
+        else:
+            self.log.info(_("Please manually connect your vnc client to begin the install."))
+
+    def startServer(self):
+        self.log.info(_("Starting VNC..."))
+
+        # Lets call it from here for now.
+        self.initialize()
+
+        # Lets start the xvnc regardless of vncconnecthost and password.
+        # We can change the configuration on the fly later.
+        xvnccommand =  [ self.root + "/usr/bin/Xvnc", ":%s" % self.display, "-nevershared",
+                        "-depth", "16", "-geometry", "800x600", "-br",
+                        "IdleTimeout=0", "-auth", "/dev/null", "-once",
+                        "DisconnectClients=false", "desktop=%s" % (self.desktop,),
+                        "SecurityTypes=None"]
+        try:
+            xvncp = subprocess.Popen(xvnccommand, stdout=self.openlogfile(), stderr=subprocess.STDOUT)
+        except:
+            stdoutLog.critical("Could not start the VNC server.  Aborting.")
+            sys.exit(1)
+
+        # Lets give the xvnc time to initialize
+        time.sleep(1)
+
+        # Make sure it hasn't blown up
+        if xvncp.poll() != None:
+            sys.exit(1)
+        else:
+            self.log.info(_("The VNC server is now running."))
+
+        # Lets look at the password stuff
+        if self.password == "":
+            pass
+        elif len(self.password) < 6:
+            self.changeVNCPasswdWindow()
+
+        # Create the password file.
+        self.setVNCPassword()
+
+        # Lets tell the user what we are going to do.
+        if self.vncconnecthost != "":
+            self.log.warning(_("\n\nYou chose to connect to a listening vncviewer. \n"
+                                "This does not require a password to be set.  If you \n"
+                                "set a password, it will be used in case the connection \n"
+                                "to the vncviewer is unsuccessful\n\n"))
+        elif self.password == "":
+             self.log.warning(_("\n\nWARNING!!! VNC server running with NO PASSWORD!\n"
+                                "You can use the vncpassword=<password> boot option\n"
+                                "if you would like to secure the server.\n\n"))
+        elif self.password != "":
+             self.log.warning(_("\n\nYou chose to execute vnc with a password. \n\n"))
+        else:
+             self.log.warning(_("\n\nUnknown Error.  Aborting. \n\n"))
+             sys.exit(1)
+
+        # Lets try to configure the vnc server to whatever the user specified
+        if self.vncconnecthost != "":
+            connected = self.connectToView()
+            if not connected:
+                self.VNCListen()
+        else:
+            self.VNCListen()
+
+        os.environ["DISPLAY"]=":%s" % self.display
+
+    def changeVNCPasswdWindow(self):
+        """ Change the password to a sane parameter.
+
+        We ask user to input a password that len(password) > 6
+        or password == ''. Have to find a way to put askVncWindow
+        and this method together.
+        """
+
+        screen = SnackScreen()
+        grid = GridFormHelp(screen, _("VNC Configuration"),"vnc", 1, 10)
+
+        bb = ButtonBar(screen, (TEXT_OK_BUTTON,
+                                (_("No password"), "nopass")))
+
+        text = _("A password will prevent unauthorized listeners "
+                 "connecting and monitoring your installation progress.  "
+                 "Please enter a password to be used for the installation")
+        grid.add(TextboxReflowed(40, text), 0, 0, (0, 0, 0, 1))
+
+        entry1 = Entry (16, password = 1)
+        entry2 = Entry (16, password = 1)
+        passgrid = Grid (2, 2)
+        passgrid.setField (Label (_("Password:")), 0, 0, (0, 0, 1, 0), anchorLeft = 1)
+        passgrid.setField (Label (_("Password (confirm):")), 0, 1, (0, 0, 1, 0), anchorLeft = 1)
+        passgrid.setField (entry1, 1, 0)
+        passgrid.setField (entry2, 1, 1)
+        grid.add (passgrid, 0, 1, (0, 0, 0, 1))
+
+        grid.add(bb, 0, 8, (0, 1, 1, 0), growx = 1)
+
+        while 1:
+            res = grid.run()
+            rc = bb.buttonPressed(res)
+
+            if rc == "nopass":
+                screen.finish()
+                return ""
+            else:
+                pw = entry1.value()
+                cf = entry2.value()
+                if pw != cf:
+                    ButtonChoiceWindow(screen, _("Password Mismatch"),
+                                       _("The passwords you entered were "
+                                         "different. Please try again."),
+                                       buttons = [ TEXT_OK_BUTTON ],
+                                       width = 50)
+                elif len(pw) < 6:
+                    ButtonChoiceWindow(screen, _("Password Length"),
+                                       _("The password must be at least "
+                                         "six characters long."),
+                                       buttons = [ TEXT_OK_BUTTON ],
+                                       width = 50)
+                else:
+                    screen.finish()
+                    self.password = pw
+                    return 
+
+                entry1.set("")
+                entry2.set("")
+                continue
+            continue
+
+def askVncWindow(title = None, message = None):
+    if not os.access('/usr/bin/Xvnc', os.X_OK):
+        return -1
+
+    if not network.hasActiveNetDev():
+        return -1
+
+    if not title:
+        title = _("Unable to Start X")
+    if not message:
+        message = _("X was unable to start on your "
+                    "machine.  Would you like to "
+                    "start VNC to connect to "
+                    "this computer from another "
+                    "computer and perform a "
+                    "graphical install or continue "
+                    "with a text mode install?")
+
+    screen = SnackScreen()
+    vncpass = None
+    vncconnect = 0
+
+    STEP_MESSAGE = 0
+    STEP_PASS = 1
+    STEP_DONE = 3
+    step = 0
+    while step < STEP_DONE:
+        if step == STEP_MESSAGE:
+            button = ButtonChoiceWindow(screen, title, message,
+                                        buttons = [ _("Start VNC"),
+                                                    _("Use text mode") ])
+
+	    if button == string.lower (_("Use text mode")):
+                screen.finish()
+                return -1
+            else:
+                step = STEP_PASS
+                continue
+
+        if step == STEP_PASS:
+            grid = GridFormHelp(screen, _("VNC Configuration"),
+                                "vnc", 1, 10)
+
+            bb = ButtonBar(screen, (TEXT_OK_BUTTON,
+                                    (_("No password"), "nopass"),
+                                    TEXT_BACK_BUTTON))
+
+            text = _("A password will prevent unauthorized listeners "
+                     "connecting and monitoring your installation progress.  "
+                     "Please enter a password to be used for the installation")
+            grid.add(TextboxReflowed(40, text), 0, 0, (0, 0, 0, 1))
+
+            entry1 = Entry (16, password = 1)
+            entry2 = Entry (16, password = 1)
+            passgrid = Grid (2, 2)
+            passgrid.setField (Label (_("Password:")), 0, 0, (0, 0, 1, 0), anchorLeft = 1)
+            passgrid.setField (Label (_("Password (confirm):")), 0, 1, (0, 0, 1, 0), anchorLeft = 1)
+            passgrid.setField (entry1, 1, 0)
+            passgrid.setField (entry2, 1, 1)
+            grid.add (passgrid, 0, 1, (0, 0, 0, 1))
+
+            grid.add(bb, 0, 8, (0, 1, 1, 0), growx = 1)
+
+            while 1:
+                res = grid.run()
+                rc = bb.buttonPressed(res)
+
+                if rc == TEXT_BACK_CHECK:
+                    screen.popWindow()
+                    step = STEP_MESSAGE
+                    break
+                elif rc == "nopass":
+                    screen.finish()
+                    return None
+                else:
+                    pw = entry1.value()
+                    cf = entry2.value()
+                    if pw != cf:
+                        ButtonChoiceWindow(screen, _("Password Mismatch"),
+                                           _("The passwords you entered were "
+                                             "different. Please try again."),
+                                           buttons = [ TEXT_OK_BUTTON ],
+                                           width = 50)
+                    elif len(pw) < 6:
+                        ButtonChoiceWindow(screen, _("Password Length"),
+                                           _("The password must be at least "
+                                             "six characters long."),
+                                           buttons = [ TEXT_OK_BUTTON ],
+                                           width = 50)
+                    else:
+                        screen.finish()
+                        return pw
+
+                    entry1.set("")
+                    entry2.set("")
+                    continue
+                continue
+
+    screen.finish()
+    return -1
+
+if __name__ == "__main__":
+    askVncWindow()
diff --git a/pyanaconda/xutils.c b/pyanaconda/xutils.c
new file mode 100644
index 0000000..372ffca
--- /dev/null
+++ b/pyanaconda/xutils.c
@@ -0,0 +1,268 @@
+/*
+ * xutils.c - a Python wrapper for common Xlib ops
+ *
+ * Copyright (C) 2002  Red Hat, Inc.  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 as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ *
+ * Author(s): Michael Fulbright <msf@xxxxxxxxxx>
+ */
+
+#include <Python.h>
+#include <X11/Xlib.h>
+#include <X11/Xatom.h>
+#include <gdk/gdkx.h>
+
+static PyObject * setRootResource(PyObject * s, PyObject * args);
+static PyObject * getXatom(PyObject *s, PyObject *args);
+
+
+static PyMethodDef xutilsMethods[] = {
+    { "setRootResource", setRootResource, 1, NULL },
+    { "getXatom", getXatom, 1, NULL },
+    { NULL, NULL, 0, NULL }
+};
+
+typedef struct _Resource {
+    char *key, *val;
+} Resource;
+
+static int
+openDisplay(Display **dpy, Window *root) 
+{
+    int     scrn;
+
+    *dpy=XOpenDisplay("");
+    if (!*dpy)
+	return -1;
+
+    scrn=DefaultScreen(*dpy);
+    *root = RootWindow(*dpy, scrn);
+    return 0;
+}
+
+static void
+closeDisplay(Display *dpy)
+{
+   XCloseDisplay(dpy);
+}    
+
+static Resource **
+getCurrentResources(Display *dpy)
+{
+    char *resource_string, *p;
+    Resource **rc;
+    int  nrec;
+
+    /* read through current resources, split on newlines */
+    resource_string = XResourceManagerString(dpy);
+
+    if (!resource_string)
+	return NULL;
+
+    rc = (Resource **)malloc(sizeof(Resource *));
+    p = resource_string;
+    nrec = 0;
+    while (1) {
+	char *eol;
+	char *sep;
+	int nleft;
+
+	/* find next newline, defines end of current record */
+	eol = strchr(p, '\n');
+
+	if (!eol)
+	    break;
+
+	/* find colon separating key and value */
+	/* if no colon skip this record        */
+	sep = strchr(p, ':');
+	if (sep) {
+	    int  len;
+	    Resource *newrec;
+
+	    newrec = (Resource *) malloc(sizeof(Resource));
+
+	    len = sep - p + 1;
+	    newrec->key = (char *) malloc(len*sizeof(char));
+	    memcpy(newrec->key, p, len);
+	    newrec->key[len-1] = '\0';
+
+	    len = eol - sep;
+	    newrec->val = (char *) malloc(len*sizeof(char));
+	    memcpy(newrec->val, sep+1, len);
+	    newrec->val[len-1] = '\0';
+
+	    rc = (Resource **) realloc(rc, (nrec+1) * sizeof(Resource *));
+	    rc[nrec] = newrec;
+	    nrec = nrec + 1;
+	}
+
+	nleft = strlen(resource_string) - (eol-resource_string);
+	if (nleft <= 0)
+	    break;
+
+	p = eol + 1;
+    }
+
+    if (nrec > 0) {
+	rc = (Resource **) realloc(rc, (nrec+1) * sizeof(Resource *));
+	rc[nrec] = NULL;
+    } else {
+	rc = NULL;
+    }
+
+    return rc;
+}
+
+static void
+freeResources(Resource **rc)
+{
+    int idx;
+
+    if (!rc)
+	return;
+
+    idx = 0;
+    while (rc[idx]) {
+	free(rc[idx]->key);
+	free(rc[idx]->val);
+	free(rc[idx]);
+
+	idx++;
+    }
+
+    free(rc);
+}
+
+static PyObject *
+setRootResource(PyObject *s, PyObject *args)
+{
+    Display *dpy;
+    Window  root;
+    Resource **resources, **p;
+    char *key, *val, *rstring;
+    int fnd, nrec;
+
+    if (!PyArg_ParseTuple(args, "ss", &key, &val)) {
+	return NULL;
+    }
+
+    if (openDisplay(&dpy, &root) < 0) {
+	PyErr_SetString(PyExc_SystemError, "Could not open display.");
+	return NULL;
+    }
+
+    resources = getCurrentResources(dpy);
+    fnd = 0;
+    nrec = 0;
+    if (resources) {
+	p = resources;
+	while (*p) {
+	    if (!strcmp(key, (*p)->key)) {
+		free((*p)->val);
+		(*p)->val = strdup(val);
+		fnd = 1;
+		break;
+	    }
+
+	    p++;
+	}
+
+	p = resources;
+	while (*p) {
+	    nrec++;
+	    p++;
+	}
+    }
+
+    if (!fnd) {
+	Resource *newrec;
+
+	newrec = (Resource *) malloc(sizeof(Resource));
+	newrec->key = strdup(key);
+	newrec->val = strdup(val);
+
+	if (nrec > 0)
+	    resources = (Resource **) realloc(resources, (nrec+2) * sizeof(Resource *));
+	else
+	    resources = (Resource **) malloc(2*sizeof(Resource *));
+
+	resources[nrec] = newrec;
+	resources[nrec+1] = NULL;
+    }
+
+    rstring = NULL;
+    p = resources;
+    while (*p) {
+	int len;
+	char *tmpstr;
+
+	len = strlen((*p)->key) + strlen((*p)->val) + 3;
+	tmpstr = (char *) malloc(len*sizeof(char));
+	strcpy(tmpstr, (*p)->key);
+	strcat(tmpstr, ":");
+	strcat(tmpstr, (*p)->val);
+	strcat(tmpstr, "\n");
+
+	if (rstring) {
+	    rstring = (char *)realloc(rstring, (strlen(rstring)+len+1)*sizeof(char));
+	    strcat(rstring, tmpstr);
+	} else {
+	    rstring = tmpstr;
+	}
+
+	p++;
+    }
+
+    XChangeProperty(dpy, root, XA_RESOURCE_MANAGER, XA_STRING, 
+		    8, PropModeReplace, (unsigned char *)rstring,
+		    strlen(rstring));
+
+    free(rstring);
+    freeResources(resources);
+
+    closeDisplay(dpy);
+
+    Py_INCREF(Py_None);
+    return Py_None;
+}
+
+/* this assumes you've already imported gtk and thus have a display */
+static PyObject * 
+getXatom(PyObject *s, PyObject *args)
+{
+    char *atomname;
+    Atom theatom;
+
+    if (!PyArg_ParseTuple(args, "s", &atomname)) {
+	return NULL;
+    }
+
+    theatom = gdk_x11_get_xatom_by_name(atomname);
+    if (XGetSelectionOwner (GDK_DISPLAY(), theatom) != None) {
+        Py_INCREF(Py_True);
+        return Py_True;
+    }
+    Py_INCREF(Py_False);
+    return Py_False;
+}
+
+void 
+initxutils ()
+{
+    PyObject * d;
+
+    d = Py_InitModule ("xutils", xutilsMethods);
+}
diff --git a/pyanaconda/yuminstall.py b/pyanaconda/yuminstall.py
new file mode 100644
index 0000000..3e0b1e2
--- /dev/null
+++ b/pyanaconda/yuminstall.py
@@ -0,0 +1,2024 @@
+#
+# yuminstall.py
+#
+# Copyright (C) 2005, 2006, 2007  Red Hat, Inc.  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 as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# 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, see <http://www.gnu.org/licenses/>.
+#
+
+from flags import flags
+from errors import *
+
+import sys
+import os
+import os.path
+import shutil
+import time
+import warnings
+import types
+import locale
+import glob
+import tempfile
+import itertools
+import re
+
+
+import anaconda_log
+import rpm
+import rpmUtils
+import urlgrabber.progress
+import urlgrabber.grabber
+from urlgrabber.grabber import URLGrabber, URLGrabError
+import yum
+import iniparse
+from yum.constants import *
+from yum.Errors import *
+from yum.misc import to_unicode
+from yum.yumRepo import YumRepository
+from backend import AnacondaBackend
+from product import *
+from sortedtransaction import SplitMediaTransactionData
+from constants import *
+from image import *
+from compssort import *
+import packages
+
+import gettext
+_ = lambda x: gettext.ldgettext("anaconda", x)
+P_ = lambda x, y, z: gettext.ldngettext("anaconda", x, y, z)
+
+import network
+
+# specspo stuff
+rpm.addMacro("_i18ndomains", "redhat-dist")
+
+import logging
+log = logging.getLogger("anaconda")
+
+import urlparse
+urlparse.uses_fragment.append('media')
+
+urlgrabber.grabber.default_grabber.opts.user_agent = "%s (anaconda)/%s" %(productName, productVersion)
+
+import iutil
+import isys
+
+def size_string (size):
+    def number_format(s):
+        return locale.format("%s", s, 1)
+
+    retval = None
+
+    if size > 1024 * 1024:
+        size = size / (1024*1024)
+        retval = _("%s MB") %(number_format(size),)
+    elif size > 1024:
+        size = size / 1024
+        retval = _("%s KB") %(number_format(size),)
+    else:
+        retval = P_("%s Byte", "%s Bytes", size) % (number_format(size),)
+
+    return to_unicode(retval)
+
+class AnacondaCallback:
+
+    def __init__(self, ayum, anaconda, instLog, modeText):
+        self.repos = ayum.repos
+        self.ts = ayum.ts
+        self.ayum = ayum
+
+        self.messageWindow = anaconda.intf.messageWindow
+        self.pulseWindow = anaconda.intf.progressWindow
+        self.progress = anaconda.intf.instProgress
+        self.progressWindowClass = anaconda.intf.progressWindow
+        self.rootPath = anaconda.rootPath
+
+        self.initWindow = None
+
+        self.progressWindow = None
+        self.lastprogress = 0
+        self.incr = 20
+
+        self.instLog = instLog
+        self.modeText = modeText
+
+        self.openfile = None
+        self.inProgressPo = None
+
+    def setSizes(self, numpkgs, totalSize, totalFiles):
+        self.numpkgs = numpkgs
+        self.totalSize = totalSize
+        self.totalFiles = totalFiles
+
+        self.donepkgs = 0
+        self.doneSize = 0
+        self.doneFiles = 0
+        
+
+    def callback(self, what, amount, total, h, user):
+        if what == rpm.RPMCALLBACK_TRANS_START:
+            # step 6 is the bulk of the ts processing time
+            if amount == 6:
+                self.progressWindow = \
+                    self.progressWindowClass (_("Preparing to install"),
+                                              _("Preparing transaction from installation source"),
+                                              total)
+                self.incr = total / 10
+
+        if what == rpm.RPMCALLBACK_TRANS_PROGRESS:
+            if self.progressWindow and amount > self.lastprogress + self.incr:
+                self.progressWindow.set(amount)
+                self.lastprogress = amount
+
+        if what == rpm.RPMCALLBACK_TRANS_STOP and self.progressWindow:
+            self.progressWindow.pop()
+
+        if what == rpm.RPMCALLBACK_INST_OPEN_FILE:
+            (hdr, rpmloc) = h
+            # hate hate hate at epochs...
+            epoch = hdr['epoch']
+            if epoch is not None:
+                epoch = str(epoch)
+            txmbrs = self.ayum.tsInfo.matchNaevr(hdr['name'], hdr['arch'],
+                                                 epoch, hdr['version'],
+                                                 hdr['release'])
+            if len(txmbrs) == 0:
+                raise RuntimeError, "Unable to find package %s-%s-%s.%s" %(hdr['name'], hdr['version'], hdr['release'], hdr['arch'])
+            po = txmbrs[0].po
+
+            repo = self.repos.getRepo(po.repoid)
+
+            pkgStr = "%s-%s-%s.%s" % (po.name, po.version, po.release, po.arch)
+            s = to_unicode(_("<b>Installing %(pkgStr)s</b> (%(size)s)\n")) \
+                    % {'pkgStr': pkgStr, 'size': size_string(hdr['size'])}
+            summary = to_unicode(gettext.ldgettext("redhat-dist", hdr['summary'] or ""))
+            s += summary.strip()
+            self.progress.set_label(s)
+
+            self.instLog.write(self.modeText % str(pkgStr))
+
+            self.instLog.flush()
+            self.openfile = None
+
+            while self.openfile is None:
+                try:
+                    fn = repo.getPackage(po)
+
+                    f = open(fn, 'r')
+                    self.openfile = f
+                except yum.Errors.NoMoreMirrorsRepoError:
+                    self.ayum._handleFailure(po)
+                except IOError:
+                    self.ayum._handleFailure(po)
+                except yum.Errors.RepoError, e:
+                    continue
+            self.inProgressPo = po
+
+            return self.openfile.fileno()
+
+        elif what == rpm.RPMCALLBACK_INST_CLOSE_FILE:
+            if self.initWindow:
+                self.initWindow.pop()
+                self.initWindow = None
+
+            (hdr, rpmloc) = h
+
+            fn = self.openfile.name
+            self.openfile.close()
+            self.openfile = None
+
+            if os.path.dirname(fn).startswith("%s/var/cache/yum/" % self.rootPath):
+                try:
+                    os.unlink(fn)
+                except OSError as e:
+                    log.debug("unable to remove file %s" %(e.strerror,))
+
+            self.donepkgs += 1
+            self.doneSize += self.inProgressPo.returnSimple("installedsize") / 1024.0
+            self.doneFiles += len(hdr[rpm.RPMTAG_BASENAMES])
+
+            if self.donepkgs <= self.numpkgs:
+                self.progress.set_text(P_("Packages completed: "
+                                          "%(donepkgs)d of %(numpkgs)d",
+                                          "Packages completed: "
+                                          "%(donepkgs)d of %(numpkgs)d",
+                                          self.numpkgs)
+                                       % {'donepkgs': self.donepkgs,
+                                          'numpkgs': self.numpkgs})
+            self.progress.set_fraction(float(self.doneSize / self.totalSize))
+            self.progress.processEvents()
+
+            self.inProgressPo = None
+
+        elif what in (rpm.RPMCALLBACK_UNINST_START,
+                      rpm.RPMCALLBACK_UNINST_STOP):
+            if self.initWindow is None:
+                self.initWindow = self.pulseWindow(_("Finishing upgrade"),
+                                                   _("Finishing upgrade process.  This may take a little while."),
+                                                   0, pulse=True)
+            else:
+                self.initWindow.pulse()
+
+        elif what in (rpm.RPMCALLBACK_CPIO_ERROR,
+                      rpm.RPMCALLBACK_UNPACK_ERROR,
+                      rpm.RPMCALLBACK_SCRIPT_ERROR):
+            if not isinstance(h, types.TupleType):
+                h = (h, None)
+
+            (hdr, rpmloc) = h
+
+            # If this is a cleanup/remove, then hdr is a string not a header.
+            if isinstance(hdr, rpm.hdr):
+                name = hdr['name']
+            else:
+                name = hdr
+
+            # Script errors store whether or not they're fatal in "total".  So,
+            # we should only error out for fatal script errors or the cpio and
+            # unpack problems.
+            if what != rpm.RPMCALLBACK_SCRIPT_ERROR or total:
+                self.messageWindow(_("Error Installing Package"),
+                    _("A fatal error occurred when installing the %s "
+                      "package.  This could indicate errors when reading "
+                      "the installation media.  Installation cannot "
+                      "continue.") % name,
+                    type="custom", custom_icon="error",
+                    custom_buttons=[_("_Exit installer")])
+                sys.exit(1)
+
+        if self.initWindow is None:
+            self.progress.processEvents()
+
+class AnacondaYumRepo(YumRepository):
+    def __init__(self, *args, **kwargs):
+        YumRepository.__init__(self, *args, **kwargs)
+        self.enablegroups = True
+        self._anacondaBaseURLs = []
+
+    def needsNetwork(self):
+        def _isURL(s):
+            return s.startswith("http") or s.startswith("ftp")
+
+        if len(self.baseurl) > 0:
+            return len(filter(lambda s: _isURL(s), self.baseurl)) > 0
+        elif self.mirrorlist:
+            return _isURL(self.mirrorlist)
+        else:
+            return False
+
+    def dirCleanup(self):
+        cachedir = self.getAttribute('cachedir')
+
+        if os.path.isdir(cachedir):
+            if not self.needsNetwork() or self.name == "Installation Repo":
+                shutil.rmtree(cachedir)
+            else:
+                if os.path.exists("%s/headers" % cachedir):
+                    shutil.rmtree("%s/headers" % cachedir)
+                if os.path.exists("%s/packages" % cachedir):
+                    shutil.rmtree("%s/packages" % cachedir)
+
+    # needed to store nfs: repo url that yum doesn't know
+    def _getAnacondaBaseURLs(self):
+        return self._anacondaBaseURLs or self.baseurl or [self.mirrorlist]
+
+    def _setAnacondaBaseURLs(self, value):
+        self._anacondaBaseURLs = value
+
+    anacondaBaseURLs = property(_getAnacondaBaseURLs, _setAnacondaBaseURLs,
+                                doc="Extends AnacondaYum.baseurl to store non-yum urls:")
+
+class YumSorter(yum.YumBase):
+    def _transactionDataFactory(self):
+        return SplitMediaTransactionData()
+
+class AnacondaYum(YumSorter):
+    def __init__(self, anaconda):
+        YumSorter.__init__(self)
+        self.anaconda = anaconda
+        self._timestamp = None
+
+        self.repoIDcounter = itertools.count()
+
+        # Only needed for hard drive and nfsiso installs.
+        self._discImages = {}
+        self.isodir = None
+
+        # Only needed for media installs.
+        self.currentMedia = None
+        self.mediagrabber = None
+
+        # Where is the source media mounted?  This is the directory
+        # where Packages/ is located.
+        self.tree = "/mnt/source"
+
+        self.macros = {}
+
+        if flags.selinux:
+            for directory in ("/tmp/updates",
+                        "/etc/selinux/targeted/contexts/files",
+                        "/etc/security/selinux/src/policy/file_contexts",
+                        "/etc/security/selinux"):
+                fn = "%s/file_contexts" %(directory,)
+                if os.access(fn, os.R_OK):
+                    break
+            self.macros["__file_context_path"] = fn
+        else:
+            self.macros["__file_context_path"]  = "%{nil}"
+
+        self.updates = []
+        self.localPackages = []
+
+    def setup(self):
+        # yum doesn't understand all our method URLs, so use this for all
+        # except FTP and HTTP installs.
+        self._baseRepoURL = "file://%s" % self.tree
+
+        while True:
+            try:
+                self.configBaseURL()
+                break
+            except SystemError, e:
+                self.anaconda.intf.messageWindow(_("Error Setting Up Repository"),
+                    _("The following error occurred while setting up the "
+                      "installation repository:\n\n%(e)s\n\nPlease provide the "
+                      "correct information for installing %(productName)s.")
+                    % {'e': e, 'productName': productName})
+
+                self.anaconda.methodstr = self.anaconda.intf.methodstrRepoWindow(self.anaconda.methodstr or "cdrom:")
+
+        self.doConfigSetup(root=self.anaconda.rootPath)
+        self.conf.installonlypkgs = []
+
+    def _switchCD(self, discnum):
+        if os.access("%s/.discinfo" % self.tree, os.R_OK):
+            f = open("%s/.discinfo" % self.tree)
+            self._timestamp = f.readline().strip()
+            f.close()
+
+        dev = self.anaconda.storage.devicetree.getDeviceByName(self.anaconda.mediaDevice)
+        dev.format.mountpoint = self.tree
+
+        # If self.currentMedia is None, then there shouldn't be anything
+        # mounted.  Before going further, see if the correct disc is already
+        # in the drive.  This saves a useless eject and insert if the user
+        # has for some reason already put the disc in the drive.
+        if self.currentMedia is None:
+            try:
+                dev.format.mount()
+
+                if verifyMedia(self.tree, discnum, None):
+                    self.currentMedia = discnum
+                    return
+
+                dev.format.unmount()
+            except:
+                pass
+        else:
+            unmountCD(dev, self.anaconda.intf.messageWindow)
+            self.currentMedia = None
+
+        dev.eject()
+
+        while True:
+            if self.anaconda.intf:
+                self.anaconda.intf.beep()
+
+            self.anaconda.intf.messageWindow(_("Change Disc"),
+                _("Please insert %(productName)s disc %(discnum)d to continue.")
+                % {'productName': productName, 'discnum': discnum})
+
+            try:
+                dev.format.mount()
+
+                if verifyMedia(self.tree, discnum, self._timestamp):
+                    self.currentMedia = discnum
+                    break
+
+                self.anaconda.intf.messageWindow(_("Wrong Disc"),
+                        _("That's not the correct %s disc.")
+                          % (productName,))
+
+                dev.format.unmount()
+                dev.eject()
+            except:
+                self.anaconda.intf.messageWindow(_("Error"),
+                        _("Unable to access the disc."))
+
+    def _switchImage(self, discnum):
+        umountImage(self.tree, self.currentMedia)
+        self.currentMedia = None
+
+        # mountDirectory checks before doing anything, so it's safe to
+        # call this repeatedly.
+        mountDirectory(self.anaconda.methodstr,
+                       self.anaconda.intf.messageWindow)
+
+        self._discImages = mountImage(self.isodir, self.tree, discnum,
+                                      self.anaconda.intf.messageWindow,
+                                      discImages=self._discImages)
+        self.currentMedia = discnum
+
+    def configBaseURL(self):
+        # We only have a methodstr if method= or repo= was passed to
+        # anaconda.  No source for this base repo (the CD media, NFS,
+        # whatever) is mounted yet since loader only mounts the source
+        # for the stage2 image.  We need to set up the source mount
+        # now.
+        if flags.cmdline.has_key("preupgrade"):
+            path = "/var/cache/yum/preupgrade"
+            self.anaconda.methodstr = "hd::%s" % path 
+            self._baseRepoURL = "file:///mnt/sysimage/%s" % path
+        elif self.anaconda.methodstr:
+            m = self.anaconda.methodstr
+
+            if m.startswith("hd:"):
+                if m.count(":") == 2:
+                    (device, path) = m[3:].split(":")
+                else:
+                    (device, fstype, path) = m[3:].split(":")
+
+                self.isodir = "/mnt/isodir/%s" % path
+
+                # This takes care of mounting /mnt/isodir first.
+                self._switchImage(1)
+                self.mediagrabber = self.mediaHandler
+            elif m.startswith("nfsiso:"):
+                self.isodir = "/mnt/isodir"
+
+                # Calling _switchImage takes care of mounting /mnt/isodir first.
+                if not network.hasActiveNetDev():
+                    if not self.anaconda.intf.enableNetwork():
+                        self._baseRepoURL = None
+                        return
+
+                    urlgrabber.grabber.reset_curl_obj()
+
+                self._switchImage(1)
+                self.mediagrabber = self.mediaHandler
+            elif m.startswith("http") or m.startswith("ftp:"):
+                self._baseRepoURL = m
+            elif m.startswith("nfs:"):
+                if not network.hasActiveNetDev():
+                    if not self.anaconda.intf.enableNetwork():
+                        self._baseRepoURL = None
+
+                    urlgrabber.grabber.reset_curl_obj()
+
+                (opts, server, path) = iutil.parseNfsUrl(m)
+                isys.mount(server+":"+path, self.tree, "nfs", options=opts)
+
+                # This really should be fixed in loader instead but for now see
+                # if there's images and if so go with this being an NFSISO
+                # install instead.
+                images = findIsoImages(self.tree, self.anaconda.intf.messageWindow)
+                if images != {}:
+                    isys.umount(self.tree, removeDir=False)
+                    self.anaconda.methodstr = "nfsiso:%s" % m[4:]
+                    self.configBaseURL()
+                    return
+            elif m.startswith("cdrom:"):
+                self._switchCD(1)
+                self.mediagrabber = self.mediaHandler
+                self._baseRepoURL = "file://%s" % self.tree
+        else:
+            # No methodstr was given.  In order to find an installation source,
+            # we should first check to see if there's a CD/DVD with packages
+            # on it, and then default to the mirrorlist URL.  The user can
+            # always change the repo with the repo editor later.
+            cdr = scanForMedia(self.tree, self.anaconda.storage)
+            if cdr:
+                self.mediagrabber = self.mediaHandler
+                self.anaconda.mediaDevice = cdr
+                self.currentMedia = 1
+                log.info("found installation media on %s" % cdr)
+            else:
+                # No CD with media on it and no repo=/method= parameter, so
+                # default to using whatever's enabled in /etc/yum.repos.d/
+                self._baseRepoURL = None
+
+    def configBaseRepo(self, root='/'):
+        # Create the "base" repo object, assuming there is one.  Otherwise we
+        # just skip all this and use the defaults from /etc/yum.repos.d.
+        if not self._baseRepoURL:
+            return
+
+        # add default repos
+        anacondabaseurl = (self.anaconda.methodstr or
+                           "cdrom:%s" % (self.anaconda.mediaDevice))
+        anacondabasepaths = self.anaconda.instClass.getPackagePaths(anacondabaseurl)
+        for (name, uri) in self.anaconda.instClass.getPackagePaths(self._baseRepoURL).items():
+            rid = name.replace(" ", "")
+
+            repo = AnacondaYumRepo("anaconda-%s-%s" % (rid, productStamp))
+            repo.baseurl = uri
+            repo.anacondaBaseURLs = anacondabasepaths[name]
+
+            repo.name = name
+            repo.cost = 100
+
+            if self.anaconda.mediaDevice or self.isodir:
+                repo.mediaid = getMediaId(self.tree)
+                log.info("set mediaid of repo %s to: %s" % (rid, repo.mediaid))
+
+            repo.enable()
+            self.repos.add(repo)
+
+    def mediaHandler(self, *args, **kwargs):
+        mediaid = kwargs["mediaid"]
+        discnum = kwargs["discnum"]
+        relative = kwargs["relative"]
+
+        # The package exists on media other than what's mounted right now.
+        if discnum != self.currentMedia:
+            log.info("switching from media #%s to #%s for %s" %
+                     (self.currentMedia, discnum, relative))
+
+            # Unmount any currently mounted ISO images and mount the one
+            # containing the requested packages.
+            if self.isodir:
+                self._switchImage(discnum)
+            else:
+                self._switchCD(discnum)
+
+        ug = URLGrabber(checkfunc=kwargs["checkfunc"])
+        ug.urlgrab("%s/%s" % (self.tree, kwargs["relative"]), kwargs["local"],
+                   text=kwargs["text"], range=kwargs["range"], copy_local=1)
+        return kwargs["local"]
+
+    # XXX: This is straight out of yum, but we need to override it here in
+    # order to use our own repo class.
+    def readRepoConfig(self, parser, section):
+        '''Parse an INI file section for a repository.
+
+        @param parser: ConfParser or similar to read INI file values from.
+        @param section: INI file section to read.
+        @return: YumRepository instance.
+        '''
+        repo = AnacondaYumRepo(section)
+        repo.populate(parser, section, self.conf)
+
+        # Ensure that the repo name is set
+        if not repo.name:
+            repo.name = section
+            self.logger.error(_('Repository %r is missing name in configuration, '
+                    'using id') % section)
+
+        # Set attributes not from the config file
+        repo.yumvar.update(self.conf.yumvar)
+        repo.cfg = parser
+
+        if "-source" in repo.id or "-debuginfo" in repo.id:
+            name = repo.name
+            del(repo)
+            raise RepoError, "Repo %s contains -source or -debuginfo, excluding" % name
+
+        # this is a little hard-coded, but it's effective
+        if not BETANAG and ("rawhide" in repo.id or "development" in repo.id):
+            name = repo.name
+            del(repo)
+            raise RepoError, "Excluding devel repo %s for non-devel anaconda" % name
+
+        if BETANAG and not repo.enabled:
+            name = repo.name
+            del(repo)
+            raise RepoError, "Excluding disabled repo %s for prerelease" % name
+
+        # If repo=/method= was passed in, we want to default these extra
+        # repos to off.
+        if self._baseRepoURL:
+            repo.enabled = False
+
+        return repo
+
+    # We need to make sure $releasever gets set up before .repo files are
+    # read.  Since there's no redhat-release package in /mnt/sysimage (and
+    # won't be for quite a while), we need to do our own substutition.
+    def _getReleasever(self):
+        from ConfigParser import ConfigParser
+        c = ConfigParser()
+
+        try:
+            if os.access("%s/.treeinfo" % self.anaconda.methodstr, os.R_OK):
+                ConfigParser.read(c, "%s/.treeinfo" % self.anaconda.methodstr)
+            else:
+                ug = URLGrabber()
+                ug.urlgrab("%s/.treeinfo" % self.anaconda.methodstr,
+                           "/tmp/.treeinfo", copy_local=1)
+                ConfigParser.read(c, "/tmp/.treeinfo")
+
+            return c.get("general", "version")
+        except:
+            return productVersion
+
+    # Override this method so yum doesn't nuke our existing logging config.
+    def doLoggingSetup(self, *args, **kwargs):
+
+        import yum.logginglevels
+
+        file_handler = logging.FileHandler("/tmp/yum.log")
+        file_formatter = logging.Formatter("[%(asctime)s] %(levelname)-8s: %(message)s")
+        file_handler.setFormatter(file_formatter)
+
+        tty3_handler = logging.FileHandler("/dev/tty3")
+        tty3_formatter = logging.Formatter(anaconda_log.TTY_FORMAT,
+                                           anaconda_log.DATE_FORMAT)
+        tty3_handler.setFormatter(tty3_formatter)
+
+        verbose = logging.getLogger("yum.verbose")
+        verbose.setLevel(logging.DEBUG)
+        verbose.propagate = False
+        verbose.addHandler(file_handler)
+
+        logger = logging.getLogger("yum")
+        logger.propagate = False
+        logger.setLevel(yum.logginglevels.INFO_2)
+        logger.addHandler(file_handler)
+        anaconda_log.autoSetLevel(tty3_handler, True)
+        tty3_handler.setLevel(anaconda_log.logger.tty_loglevel)
+        logger.addHandler(tty3_handler)
+
+        # XXX filelogger is set in setFileLog - do we or user want it?
+        filelogger = logging.getLogger("yum.filelogging")
+        filelogger.setLevel(logging.INFO)
+        filelogger.propagate = False
+
+
+    def doConfigSetup(self, fn='/tmp/anaconda-yum.conf', root='/'):
+        if hasattr(self, "preconf"):
+            self.preconf.fn = fn
+            self.preconf.root = root
+            self.preconf.releasever = self._getReleasever()
+            self.preconf.enabled_plugins = ["whiteout", "blacklist"]
+            YumSorter._getConfig(self)
+        else:
+            YumSorter._getConfig(self, fn=fn, root=root,
+                                 enabled_plugins=["whiteout", "blacklist"])
+        self.configBaseRepo(root=root)
+
+        extraRepos = []
+
+        ddArch = os.uname()[4]
+
+        #Add the Driver disc repos to Yum
+        for d in glob.glob(DD_RPMS):
+            dirname = os.path.basename(d)
+            rid = "anaconda-%s" % dirname
+
+            repo = AnacondaYumRepo(rid)
+            repo.baseurl = [ "file:///%s" % d ]
+            repo.name = "Driver Disk %s" % dirname.split("-")[1]
+            repo.enable()
+            extraRepos.append(repo)
+
+        if self.anaconda.ksdata:
+            # This is the same pattern as from loader/urls.c:splitProxyParam.
+            pattern = re.compile("([[:alpha:]]+://)?(([[:alnum:]]+)(:[^:@]+)?@)?([^:]+)(:[[:digit:]]+)?(/.*)?")
+
+            for ksrepo in self.anaconda.ksdata.repo.repoList:
+                anacondaBaseURLs = [ksrepo.baseurl]
+
+                # yum doesn't understand nfs:// and doesn't want to.  We need
+                # to first do the mount, then translate it into a file:// that
+                # yum does understand.
+                # "nfs:" and "nfs://" prefixes are accepted in ks repo --baseurl
+                if ksrepo.baseurl and ksrepo.baseurl.startswith("nfs:"):
+                    if not network.hasActiveNetDev() and not self.anaconda.intf.enableNetwork():
+                        self.anaconda.intf.messageWindow(_("No Network Available"),
+                            _("Some of your software repositories require "
+                              "networking, but there was an error enabling the "
+                              "network on your system."),
+                            type="custom", custom_icon="error",
+                            custom_buttons=[_("_Exit installer")])
+                        sys.exit(1)
+
+                    urlgrabber.grabber.reset_curl_obj()
+
+                    dest = tempfile.mkdtemp("", ksrepo.name.replace(" ", ""), "/mnt")
+
+                    # handle "nfs://" prefix
+                    if ksrepo.baseurl[4:6] == '//':
+                        ksrepo.baseurl = ksrepo.baseurl.replace('//', '', 1)
+                        anacondaBaseURLs = [ksrepo.baseurl]
+                    try:
+                        isys.mount(ksrepo.baseurl[4:], dest, "nfs")
+                    except Exception as e:
+                        log.error("error mounting NFS repo: %s" % e)
+
+                    ksrepo.baseurl = "file://%s" % dest
+
+                repo = AnacondaYumRepo(ksrepo.name)
+                repo.mirrorlist = ksrepo.mirrorlist
+                repo.name = ksrepo.name
+
+                if not ksrepo.baseurl:
+                    repo.baseurl = []
+                else:
+                    repo.baseurl = [ ksrepo.baseurl ]
+                repo.anacondaBaseURLs = anacondaBaseURLs
+
+                if ksrepo.cost:
+                    repo.cost = ksrepo.cost
+
+                if ksrepo.excludepkgs:
+                    repo.exclude = ksrepo.excludepkgs
+
+                if ksrepo.includepkgs:
+                    repo.include = ksrepo.includepkgs
+
+                if ksrepo.proxy:
+                    m = pattern.match(ksrepo.proxy)
+
+                    if m and m.group(5):
+                        # If both a host and port was found, just paste them
+                        # together using the colon at the beginning of the port
+                        # match as a separator.  Otherwise, just use the host.
+                        if m.group(6):
+                            repo.proxy = m.group(5) + m.group(6)
+                        else:
+                            repo.proxy = m.group(5)
+
+                        # yum also requires a protocol.  If none was given,
+                        # default to http.
+                        if m.group(1):
+                            repo.proxy = m.group(1) + repo.proxy
+                        else:
+                            repo.proxy = "http://"; + repo.proxy
+
+                    if m and m.group(3):
+                        repo.proxy_username = m.group(3)
+
+                    if m and m.group(4):
+                        # Skip the leading colon.
+                        repo.proxy_password = m.group(4)[1:]
+
+                repo.enable()
+                extraRepos.append(repo)
+
+        for repo in extraRepos:
+            try:
+                self.repos.add(repo)
+                log.info("added repository %s with URL %s" % (repo.name, repo.mirrorlist or repo.baseurl))
+            except:
+                log.warning("ignoring duplicate repository %s with URL %s" % (repo.name, repo.mirrorlist or repo.baseurl))
+
+        self.repos.setCacheDir(self.conf.cachedir)
+
+        if os.path.exists("%s/boot/upgrade/install.img" % self.anaconda.rootPath):
+            log.info("REMOVING stage2 image from %s /boot/upgrade" % self.anaconda.rootPath )
+            try:
+                os.unlink("%s/boot/upgrade/install.img" % self.anaconda.rootPath)
+            except:
+                log.warning("failed to clean /boot/upgrade")
+
+    def downloadHeader(self, po):
+        while True:
+            # retrying version of download header
+            try:
+                YumSorter.downloadHeader(self, po)
+                break
+            except yum.Errors.NoMoreMirrorsRepoError:
+                self._handleFailure(po)
+            except IOError:
+                self._handleFailure(po)
+            except yum.Errors.RepoError, e:
+                continue
+
+    def _handleFailure(self, package):
+        if not self.isodir and self.currentMedia:
+            buttons = [_("Re_boot"), _("_Eject")]
+        else:
+            buttons = [_("Re_boot"), _("_Retry")]
+
+        pkgFile = to_unicode(os.path.basename(package.remote_path))
+        rc = self.anaconda.intf.messageWindow(_("Error"),
+                   _("The file %s cannot be opened.  This is due to a missing "
+                     "file, a corrupt package or corrupt media.  Please "
+                     "verify your installation source.\n\n"
+                     "If you exit, your system will be left in an inconsistent "
+                     "state that will likely require reinstallation.\n\n") %
+                                              (pkgFile,),
+                                    type="custom", custom_icon="error",
+                                    custom_buttons=buttons)
+
+        if rc == 0:
+            sys.exit(0)
+        else:
+            if os.path.exists(package.localPkg()):
+                os.unlink(package.localPkg())
+
+            if not self.isodir and self.currentMedia:
+                self._switchCD(self.currentMedia)
+            else:
+                return
+
+    def mirrorFailureCB (self, obj, *args, **kwargs):
+        # This gets called when a mirror fails, but it cannot know whether
+        # or not there are other mirrors left to try, since it cannot know
+        # which mirror we were on when we started this particular download. 
+        # Whenever we have run out of mirrors the grabber's get/open/retrieve
+        # method will raise a URLGrabError exception with errno 256.
+        grab = self.repos.getRepo(kwargs["repo"]).grab
+        log.warning("Failed to get %s from mirror %d/%d, "
+                    "or downloaded file is corrupt" % (obj.url, grab._next + 1,
+                                                       len(grab.mirrors)))
+
+        if self.currentMedia:
+            dev = self.anaconda.storage.devicetree.getDeviceByName(self.anaconda.mediaDevice)
+            dev.format.mountpoint = self.tree
+            unmountCD(dev, self.anaconda.intf.messageWindow)
+            self.currentMedia = None
+
+    def urlgrabberFailureCB (self, obj, *args, **kwargs):
+        if hasattr(obj, "exception"):
+            log.warning("Try %s/%s for %s failed: %s" % (obj.tries, obj.retry, obj.url, obj.exception))
+        else:
+            log.warning("Try %s/%s for %s failed" % (obj.tries, obj.retry, obj.url))
+
+        if obj.tries == obj.retry:
+            return
+
+        delay = 0.25*(2**(obj.tries-1))
+        if delay > 1:
+            w = self.anaconda.intf.waitWindow(_("Retrying"), _("Retrying download."))
+            time.sleep(delay)
+            w.pop()
+        else:
+            time.sleep(delay)
+
+    def getDownloadPkgs(self):
+        downloadpkgs = []
+        totalSize = 0
+        totalFiles = 0
+        for txmbr in self.tsInfo.getMembersWithState(output_states=TS_INSTALL_STATES):
+            if txmbr.po:
+                totalSize += int(txmbr.po.returnSimple("installedsize")) / 1024
+                for filetype in txmbr.po.returnFileTypes():
+                    totalFiles += len(txmbr.po.returnFileEntries(ftype=filetype))
+                downloadpkgs.append(txmbr.po)
+
+        return (downloadpkgs, totalSize, totalFiles)
+
+    def setColor(self):
+        if rpmUtils.arch.isMultiLibArch():
+            self.ts.ts.setColor(3)
+
+    def run(self, instLog, cb, intf, id):
+        def mediasort(a, b):
+            # sort so that first CD comes first, etc.  -99 is a magic number
+            # to tell us that the cd should be last
+            if a == -99:
+                return 1
+            elif b == -99:
+                return -1
+            if a < b:
+                return -1
+            elif a > b:
+                return 1
+            return 0
+
+        self.initActionTs()
+        if self.anaconda.upgrade:
+            self.ts.ts.setProbFilter(~rpm.RPMPROB_FILTER_DISKSPACE)
+        self.setColor()
+
+        # If we don't have any required media assume single disc
+        if self.tsInfo.reqmedia == {}:
+            self.tsInfo.reqmedia[0] = None
+        mkeys = self.tsInfo.reqmedia.keys()
+        mkeys.sort(mediasort)
+
+        stage2img = "%s/images/install.img" % self.tree
+        if os.path.exists(stage2img):
+            if self.anaconda.backend.mountInstallImage(self.anaconda, stage2img):
+                self.anaconda.storage.umountFilesystems()
+                return DISPATCH_BACK
+
+        for i in mkeys:
+            self.tsInfo.curmedia = i
+            if i > 0:
+                pkgtup = self.tsInfo.reqmedia[i][0]
+
+            try:
+                self.dsCallback = DownloadHeaderProgress(intf, self)
+                self.populateTs(keepold=0)
+                self.dsCallback.pop()
+                self.dsCallback = None
+            except RepoError, e:
+                msg = _("There was an error running your transaction for "
+                        "the following reason: %s\n") % str(e)
+
+                if self.anaconda.upgrade:
+                    rc = intf.messageWindow(_("Error"), msg, type="custom",
+                                            custom_icon="error",
+                                            custom_buttons=[_("_Exit installer")])
+                    sys.exit(1)
+                else:
+                    rc = intf.messageWindow(_("Error"), msg,
+                            type="custom", custom_icon="error",
+                            custom_buttons=[_("_Back"), _("_Exit installer")])
+
+                if rc == 1:
+                    sys.exit(1)
+                else:
+                    self.tsInfo.curmedia = None
+                    return DISPATCH_BACK
+
+            self.ts.check()
+            self.ts.order()
+
+            if self._run(instLog, cb, intf) == DISPATCH_BACK:
+                self.tsInfo.curmedia = None
+                return DISPATCH_BACK
+
+            self.ts.close()
+
+    def _run(self, instLog, cb, intf):
+        # set log fd.  FIXME: this is ugly.  see changelog entry from 2005-09-13
+        self.ts.ts.scriptFd = instLog.fileno()
+        rpm.setLogFile(instLog)
+
+        uniqueProbs = {}
+        spaceneeded = {}
+        spaceprob = ""
+        fileConflicts = []
+        fileprob = ""
+
+        try:
+            self.runTransaction(cb=cb)
+        except YumBaseError, probs:
+            # FIXME: we need to actually look at these problems...
+            probTypes = { rpm.RPMPROB_NEW_FILE_CONFLICT : _('file conflicts'),
+                          rpm.RPMPROB_FILE_CONFLICT : _('file conflicts'),
+                          rpm.RPMPROB_OLDPACKAGE: _('older package(s)'),
+                          rpm.RPMPROB_DISKSPACE: _('insufficient disk space'),
+                          rpm.RPMPROB_DISKNODES: _('insufficient disk inodes'),
+                          rpm.RPMPROB_CONFLICT: _('package conflicts'),
+                          rpm.RPMPROB_PKG_INSTALLED: _('package already installed'),
+                          rpm.RPMPROB_REQUIRES: _('required package'),
+                          rpm.RPMPROB_BADARCH: _('package for incorrect arch'),
+                          rpm.RPMPROB_BADOS: _('package for incorrect os'),
+            }
+
+            for (descr, (ty, mount, need)) in probs.value: # FIXME: probs.value???
+                log.error("%s: %s" %(probTypes[ty], descr))
+                if not uniqueProbs.has_key(ty) and probTypes.has_key(ty):
+                    uniqueProbs[ty] = probTypes[ty]
+
+                if ty == rpm.RPMPROB_DISKSPACE:
+                    spaceneeded[mount] = need
+                elif ty in [rpm.RPMPROB_NEW_FILE_CONFLICT, rpm.RPMPROB_FILE_CONFLICT]:
+                    fileConflicts.append(descr)
+
+            if spaceneeded:
+                spaceprob = _("You need more space on the following "
+                              "file systems:\n")
+
+                for (mount, need) in spaceneeded.items():
+                    log.info("(%s, %s)" %(mount, need))
+
+                    if mount.startswith("/mnt/sysimage/"):
+                        mount.replace("/mnt/sysimage", "")
+                    elif mount.startswith("/mnt/sysimage"):
+                        mount = "/" + mount.replace("/mnt/sysimage", "")
+
+                    spaceprob += "%d M on %s\n" % (need / (1024*1024), mount)
+            elif fileConflicts:
+                fileprob = _("There were file conflicts when checking the "
+                             "packages to be installed:\n%s\n") % ("\n".join(fileConflicts),)
+
+            msg = _("There was an error running your transaction for "
+                    "the following reason(s): %s.\n") % ', '.join(uniqueProbs.values())
+
+            spaceprob = to_unicode(spaceprob)
+            fileprob = to_unicode(fileprob)
+
+            if len(self.anaconda.backend.getRequiredMedia()) > 1 or self.anaconda.upgrade:
+                intf.detailedMessageWindow(_("Error Running Transaction"),
+                   msg, spaceprob + "\n" + fileprob, type="custom",
+                   custom_icon="error", custom_buttons=[_("_Exit installer")])
+                sys.exit(1)
+            else:
+                rc = intf.detailedMessageWindow(_("Error Running Transaction"),
+                        msg, spaceprob + "\n" + fileprob, type="custom",
+                        custom_icon="error",
+                        custom_buttons=[_("_Back"), _("_Exit installer")])
+
+            if rc == 1:
+                sys.exit(1)
+            else:
+                self._undoDepInstalls()
+                return DISPATCH_BACK
+
+    def doMacros(self):
+        for (key, val) in self.macros.items():
+            rpm.addMacro(key, val)
+
+    def simpleDBInstalled(self, name, arch=None):
+        # FIXME: doing this directly instead of using self.rpmdb.installed()
+        # speeds things up by 400%
+        mi = self.ts.ts.dbMatch('name', name)
+        if mi.count() == 0:
+            return False
+        if arch is None:
+            return True
+        if arch in map(lambda h: h['arch'], mi):
+            return True
+        return False
+
+    def isPackageInstalled(self, name = None, epoch = None, version = None,
+                           release = None, arch = None, po = None):
+        # FIXME: this sucks.  we should probably suck it into yum proper
+        # but it'll need a bit of cleanup first.
+        if po is not None:
+            (name, epoch, version, release, arch) = po.returnNevraTuple()
+
+        installed = False
+        if name and not (epoch or version or release or arch):
+            installed = self.simpleDBInstalled(name)
+        elif self.rpmdb.installed(name = name, epoch = epoch, ver = version,
+                                rel = release, arch = arch):
+            installed = True
+
+        lst = self.tsInfo.matchNaevr(name = name, epoch = epoch,
+                                     ver = version, rel = release,
+                                     arch = arch)
+        for txmbr in lst:
+            if txmbr.output_state in TS_INSTALL_STATES:
+                return True
+        if installed and len(lst) > 0:
+            # if we get here, then it was installed, but it's in the tsInfo
+            # for an erase or obsoleted --> not going to be installed at end
+            return False
+        return installed
+
+    def isGroupInstalled(self, grp):
+        if grp.selected:
+            return True
+        elif grp.installed and not grp.toremove:
+            return True
+        return False
+
+    def _pkgExists(self, pkg):
+        """Whether or not a given package exists in our universe."""
+        try:
+            pkgs = self.pkgSack.returnNewestByName(pkg)
+            return True
+        except yum.Errors.PackageSackError:
+            pass
+        try:
+            pkgs = self.rpmdb.returnNewestByName(pkg)
+            return True
+        except (IndexError, yum.Errors.PackageSackError):
+            pass
+        return False
+
+    def _groupHasPackages(self, grp):
+        # this checks to see if the given group has any packages available
+        # (ie, already installed or in the sack of available packages)
+        # so that we don't show empty groups.  also, if there are mandatory
+        # packages and we have none of them, don't show
+        for pkg in grp.mandatory_packages.keys():
+            if self._pkgExists(pkg):
+                return True
+        if len(grp.mandatory_packages) > 0:
+            return False
+        for pkg in grp.default_packages.keys() + grp.optional_packages.keys() + \
+                   grp.conditional_packages.keys():
+            if self._pkgExists(pkg):
+                return True
+        return False
+
+class YumBackend(AnacondaBackend):
+    def __init__ (self, anaconda):
+        AnacondaBackend.__init__(self, anaconda)
+        self.supportsPackageSelection = True
+
+        buf = """
+[main]
+installroot=%s
+cachedir=/var/cache/yum/$basearch/$releasever
+keepcache=0
+logfile=/tmp/yum.log
+metadata_expire=0
+obsoletes=True
+pluginpath=/usr/lib/yum-plugins,/tmp/updates/yum-plugins
+pluginconfpath=/etc/yum/pluginconf.d,/tmp/updates/pluginconf.d
+plugins=1
+reposdir=/etc/anaconda.repos.d,/tmp/updates/anaconda.repos.d,/tmp/product/anaconda.repos.d
+""" % (anaconda.rootPath)
+
+        if anaconda.proxy:
+            buf += "proxy=%s\n" % anaconda.proxy
+
+            if anaconda.proxyUsername:
+                buf += "proxy_username=%s\n" % anaconda.proxyUsername
+
+            if anaconda.proxyPassword:
+                buf += "proxy_password=%s\n" % anaconda.proxyPassword
+
+        fd = open("/tmp/anaconda-yum.conf", "w")
+        fd.write(buf)
+        fd.close()
+
+    def complete(self, anaconda):
+        if not anaconda.mediaDevice and os.path.ismount(self.ayum.tree):
+            isys.umount(self.ayum.tree)
+
+        anaconda.backend.removeInstallImage()
+
+        # clean up rpmdb locks so that kickstart %post scripts aren't
+        # unhappy (#496961)
+        iutil.resetRpmDb(anaconda.rootPath)
+
+    def doBackendSetup(self, anaconda):
+        if anaconda.dir == DISPATCH_BACK:
+            return DISPATCH_BACK
+
+        if anaconda.upgrade:
+           # FIXME: make sure that the rpmdb doesn't have stale locks :/
+           iutil.resetRpmDb(anaconda.rootPath)
+
+        iutil.writeRpmPlatform()
+        anaconda.backend.freetmp(anaconda)
+        self.ayum = AnacondaYum(anaconda)
+        self.ayum.setup()
+
+        self.ayum.doMacros()
+
+        # If any enabled repositories require networking, go ahead and bring
+        # it up now.  No need to have people wait for the timeout when we
+        # know this in advance.
+        for repo in self.ayum.repos.listEnabled():
+            if repo.needsNetwork() and not network.hasActiveNetDev():
+                if not anaconda.intf.enableNetwork():
+                    anaconda.intf.messageWindow(_("No Network Available"),
+                        _("Some of your software repositories require "
+                          "networking, but there was an error enabling the "
+                          "network on your system."),
+                        type="custom", custom_icon="error",
+                        custom_buttons=[_("_Exit installer")])
+                    sys.exit(1)
+
+                urlgrabber.grabber.reset_curl_obj()
+                break
+
+        self.doRepoSetup(anaconda)
+        self.doSackSetup(anaconda)
+        self.doGroupSetup(anaconda)
+
+        self.ayum.doMacros()
+
+    def doGroupSetup(self, anaconda):
+        while True:
+            try:
+                self.ayum.doGroupSetup()
+            except (GroupsError, NoSuchGroup, RepoError), e:
+                buttons = [_("_Exit installer"), _("_Retry")]
+            else:
+                break # success
+
+            rc = anaconda.intf.messageWindow(_("Error"),
+                                        _("Unable to read group information "
+                                          "from repositories.  This is "
+                                          "a problem with the generation "
+                                          "of your install tree."),
+                                        type="custom", custom_icon="error",
+                                        custom_buttons = buttons)
+            if rc == 0:
+                sys.exit(0)
+            else:
+                self.ayum._setGroups(None)
+                continue
+
+    def doRepoSetup(self, anaconda, thisrepo = None, fatalerrors = True):
+        self.__withFuncDo(anaconda, lambda r: self.ayum.doRepoSetup(thisrepo=r.id),
+                          thisrepo=thisrepo, fatalerrors=fatalerrors)
+
+    def doSackSetup(self, anaconda, thisrepo = None, fatalerrors = True):
+        self.__withFuncDo(anaconda, lambda r: self.ayum.doSackSetup(thisrepo=r.id),
+                          thisrepo=thisrepo, fatalerrors=fatalerrors)
+
+    def __withFuncDo(self, anaconda, fn, thisrepo=None, fatalerrors=True):
+        # Don't do this if we're being called as a dispatcher step (instead
+        # of being called when a repo is added via the UI) and we're going
+        # back.
+        if thisrepo is None and anaconda.dir == DISPATCH_BACK:
+            return
+
+        # We want to call the function one repo at a time so we have some
+        # concept of which repo didn't set up correctly.
+        if thisrepo is not None:
+            repos = [self.ayum.repos.getRepo(thisrepo)]
+        else:
+            repos = self.ayum.repos.listEnabled()
+
+        for repo in repos:
+            if repo.name is None:
+                txt = _("Retrieving installation information.")
+            else:
+                txt = _("Retrieving installation information for %s.")%(repo.name)
+
+            waitwin = anaconda.intf.waitWindow(_("Installation Progress"), txt)
+
+            while True:
+                try:
+                    fn(repo)
+                    waitwin.pop()
+                except RepoError, e:
+                    waitwin.pop()
+                    buttons = [_("_Exit installer"), _("Edit"), _("_Retry")]
+                else:
+                    break # success
+
+                if anaconda.ksdata:
+                    buttons.append(_("_Continue"))
+
+                if not fatalerrors:
+                    raise RepoError, e
+
+                rc = anaconda.intf.messageWindow(_("Error"),
+                                   _("Unable to read package metadata. This may be "
+                                     "due to a missing repodata directory.  Please "
+                                     "ensure that your install tree has been "
+                                     "correctly generated.\n\n%s" % e),
+                                     type="custom", custom_icon="error",
+                                     custom_buttons=buttons)
+                if rc == 0:
+                    # abort
+                    sys.exit(0)
+                elif rc == 1:
+                    # edit
+                    anaconda.intf.editRepoWindow(repo)
+                    break
+                elif rc == 2:
+                    # retry, but only if button is present
+                    continue
+                else:
+                    # continue, but only if button is present
+                    self.ayum.repos.delete(repo.id)
+                    break
+
+            # if we're in kickstart the repo may have been deleted just above
+            try:
+                self.ayum.repos.getRepo(repo.id)
+            except RepoError:
+                log.debug("repo %s has been removed" % (repo.id,))
+                continue
+
+            repo.setFailureObj(self.ayum.urlgrabberFailureCB)
+            repo.setMirrorFailureObj((self.ayum.mirrorFailureCB, (),
+                                     {"repo": repo.id}))
+
+        self.ayum.repos.callback = None
+
+    def getDefaultGroups(self, anaconda):
+        langs = anaconda.instLanguage.getCurrentLangSearchList()
+        rc = map(lambda x: x.groupid,
+                 filter(lambda x: x.default, self.ayum.comps.groups))
+        for g in self.ayum.comps.groups:
+            if g.langonly in langs:
+                rc.append(g.groupid)
+        return rc
+
+    def resetPackageSelections(self):
+        """Reset the package selection to an empty state."""
+        for txmbr in self.ayum.tsInfo:
+            self.ayum.tsInfo.remove(txmbr.pkgtup)
+        self.ayum.tsInfo.conditionals.clear()
+        for grp in self.ayum.comps.groups:
+            grp.selected = False
+
+    def selectModulePackages(self, anaconda, kernelPkgName):
+        (base, sep, ext) = kernelPkgName.partition("-")
+
+        moduleProvides = []
+
+        for (path, name) in anaconda.extraModules:
+            if ext != "":
+                moduleProvides.append("dud-%s-%s" % (name, ext))
+            else:
+                moduleProvides.append("dud-%s" % name)
+
+        #We need to install the packages which contain modules from DriverDiscs
+        for modPath in isys.modulesWithPaths():
+            if modPath.startswith(DD_EXTRACTED):
+                moduleProvides.append(modPath[len(DD_EXTRACTED):])
+            else:
+                continue
+
+        for module in moduleProvides:
+            pkgs = self.ayum.returnPackagesByDep(module)
+
+            if not pkgs:
+                log.warning("Didn't find any package providing %s" % module)
+
+            for pkg in pkgs:
+                log.info("selecting package %s for %s" % (pkg.name, module))
+                self.ayum.install(po=pkg)
+
+    def selectBestKernel(self, anaconda):
+        """Find the best kernel package which is available and select it."""
+
+        def getBestKernelByArch(pkgname, ayum):
+            """Convenience func to find the best arch of a kernel by name"""
+            try:
+                pkgs = ayum.pkgSack.returnNewestByName(pkgname)
+            except yum.Errors.PackageSackError:
+                return None
+
+            pkgs = self.ayum.bestPackagesFromList(pkgs)
+            if len(pkgs) == 0:
+                return None
+            return pkgs[0]
+
+        def selectKernel(pkgname):
+            try:
+                pkg = getBestKernelByArch(pkgname, self.ayum)
+            except PackageSackError:
+                log.debug("no %s package" % pkgname)
+                return False
+
+            if not pkg:
+                return False
+
+            log.info("selected %s package for kernel" % pkg.name)
+            self.ayum.install(po=pkg)
+            self.selectModulePackages(anaconda, pkg.name)
+
+            if len(self.ayum.tsInfo.matchNaevr(name="gcc")) > 0:
+                log.debug("selecting %s-devel" % pkg.name)
+                self.selectPackage("%s-devel.%s" % (pkg.name, pkg.arch))
+
+            return True
+
+        foundkernel = False
+
+        if not foundkernel and isys.isPaeAvailable():
+            if selectKernel("kernel-PAE"):
+                foundkernel = True
+
+        if not foundkernel:
+            selectKernel("kernel")
+
+    def selectFSPackages(self, storage):
+        for device in storage.fsset.devices:
+            # this takes care of device and filesystem packages
+            map(self.selectPackage, device.packages)
+
+    # anaconda requires several programs on the installed system to complete
+    # installation, but we have no guarantees that some of these will be
+    # installed (they could have been removed in kickstart).  So we'll force
+    # it.
+    def selectAnacondaNeeds(self):
+        for pkg in ['authconfig', 'chkconfig', 'system-config-firewall-base']:
+            self.selectPackage(pkg)
+
+    def doPostSelection(self, anaconda):
+        # Only solve dependencies on the way through the installer, not the way back.
+        if anaconda.dir == DISPATCH_BACK:
+            return
+
+        dscb = YumDepSolveProgress(anaconda.intf, self.ayum)
+        self.ayum.dsCallback = dscb
+
+        # do some sanity checks for kernel and bootloader
+        if not anaconda.upgrade:
+            # New installs only - upgrades will already have all this stuff.
+            self.selectBestKernel(anaconda)
+            map(self.selectPackage, anaconda.platform.packages)
+            self.selectFSPackages(anaconda.storage)
+            self.selectAnacondaNeeds()
+        else:
+            self.ayum.update()
+
+        while True:
+            try:
+                (code, msgs) = self.ayum.buildTransaction()
+
+                # If %packages --ignoremissing was given, don't bother
+                # prompting for missing dependencies.
+                if anaconda.ksdata and anaconda.ksdata.packages.handleMissing == KS_MISSING_IGNORE:
+                    break
+
+                if code == 1 and not anaconda.upgrade:
+                    # resolveDeps returns 0 if empty transaction, 1 if error,
+                    # 2 if success
+                    depprob = "\n".join(msgs)
+
+                    rc = anaconda.intf.detailedMessageWindow(_("Warning"),
+                            _("Some of the packages you have selected for "
+                              "install are missing dependencies.  You can "
+                              "exit the installation, go back and change "
+                              "your package selections, or continue "
+                              "installing these packages without their "
+                              "dependencies.  If you continue, these packages "
+                              "may not work correctly due to missing components."),
+                            depprob + "\n", type="custom", custom_icon="error",
+                            custom_buttons=[_("_Exit installer"), _("_Back"),
+                                            _("_Continue")])
+                    dscb.pop()
+
+                    if rc == 0:
+                        sys.exit(1)
+                    elif rc == 1:
+                        self.ayum._undoDepInstalls()
+                        return DISPATCH_BACK
+
+                break
+            except RepoError, e:
+                # FIXME: would be nice to be able to recover here
+                rc = anaconda.intf.messageWindow(_("Error"),
+                               _("Unable to read package metadata. This may be "
+                                 "due to a missing repodata directory.  Please "
+                                 "ensure that your install tree has been "
+                                 "correctly generated.\n\n%s" % e),
+                                 type="custom", custom_icon="error",
+                                 custom_buttons=[_("_Exit installer"), _("_Retry")])
+                dscb.pop()
+
+                if rc == 0:
+                    sys.exit(0)
+                else:
+                    continue
+            else:
+                break
+
+        (self.dlpkgs, self.totalSize, self.totalFiles)  = self.ayum.getDownloadPkgs()
+
+        if not anaconda.upgrade:
+            largePart = anaconda.storage.mountpoints.get("/usr", anaconda.storage.rootDevice)
+
+            if largePart and largePart.size < self.totalSize / 1024:
+                rc = anaconda.intf.messageWindow(_("Error"),
+                                        _("Your selected packages require %d MB "
+                                          "of free space for installation, but "
+                                          "you do not have enough available.  "
+                                          "You can change your selections or "
+                                          "exit the installer." % (self.totalSize / 1024)),
+                                        type="custom", custom_icon="error",
+                                        custom_buttons=[_("_Back"), _("_Exit installer")])
+
+                dscb.pop()
+
+                if rc == 1:
+                    sys.exit(1)
+                else:
+                    self.ayum._undoDepInstalls()
+                    return DISPATCH_BACK
+
+        dscb.pop()
+
+        if anaconda.mediaDevice and not anaconda.ksdata:
+           rc = presentRequiredMediaMessage(anaconda)
+           if rc == 0:
+               rc2 = anaconda.intf.messageWindow(_("Reboot?"),
+                                       _("The system will be rebooted now."),
+                                       type="custom", custom_icon="warning",
+                                       custom_buttons=[_("_Back"), _("_Reboot")])
+               if rc2 == 1:
+                   sys.exit(0)
+               else:
+                   return DISPATCH_BACK
+           elif rc == 1: # they asked to go back
+               return DISPATCH_BACK
+
+        self.ayum.dsCallback = None
+
+    def doPreInstall(self, anaconda):
+        if anaconda.dir == DISPATCH_BACK:
+            for d in ("/selinux", "/dev", "/proc/bus/usb"):
+                try:
+                    isys.umount(anaconda.rootPath + d, removeDir = False)
+                except Exception, e:
+                    log.error("unable to unmount %s: %s" %(d, e))
+            return
+
+        if anaconda.upgrade:
+            # An old mtab can cause confusion (esp if loop devices are
+            # in it).  Be extra special careful and delete any mtab first,
+            # in case the user has done something funny like make it into
+            # a symlink.
+            if os.access(anaconda.rootPath + "/etc/mtab", os.F_OK):
+                os.remove(anaconda.rootPath + "/etc/mtab")
+
+            f = open(anaconda.rootPath + "/etc/mtab", "w+")
+            f.close()
+
+            # we really started writing modprobe.conf out before things were
+            # all completely ready.  so now we need to nuke old modprobe.conf's
+            # if you're upgrading from a 2.4 dist so that we can get the
+            # transition right
+            if (os.path.exists(anaconda.rootPath + "/etc/modules.conf") and
+                os.path.exists(anaconda.rootPath + "/etc/modprobe.conf") and
+                not os.path.exists(anaconda.rootPath + "/etc/modprobe.conf.anacbak")):
+                log.info("renaming old modprobe.conf -> modprobe.conf.anacbak")
+                os.rename(anaconda.rootPath + "/etc/modprobe.conf",
+                          anaconda.rootPath + "/etc/modprobe.conf.anacbak")
+
+        dirList = ['/var', '/var/lib', '/var/lib/rpm', '/tmp', '/dev', '/etc',
+                   '/etc/sysconfig', '/etc/sysconfig/network-scripts',
+                   '/etc/X11', '/root', '/var/tmp', '/etc/rpm', '/var/cache',
+                   '/var/cache/yum', '/etc/modprobe.d']
+
+        # If there are any protected partitions we want to mount, create their
+        # mount points now.
+        for protected in anaconda.storage.protectedDevices:
+            if getattr(protected.format, "mountpoint", None):
+                dirList.append(protected.format.mountpoint)
+
+        for i in dirList:
+            try:
+                os.mkdir(anaconda.rootPath + i)
+            except os.error, (errno, msg):
+                pass
+#            log.error("Error making directory %s: %s" % (i, msg))
+
+        self.initLog(anaconda.rootPath)
+
+        # setup /etc/rpm/ for the post-install environment
+        iutil.writeRpmPlatform(anaconda.rootPath)
+
+        try:
+            # FIXME: making the /var/lib/rpm symlink here is a hack to
+            # workaround db->close() errors from rpm
+            iutil.mkdirChain("/var/lib")
+            for path in ("/var/tmp", "/var/lib/rpm"):
+                if os.path.exists(path) and not os.path.islink(path):
+                    shutil.rmtree(path)
+                if not os.path.islink(path):
+                    os.symlink("%s/%s" %(anaconda.rootPath, path), "%s" %(path,))
+                else:
+                    log.warning("%s already exists as a symlink to %s" %(path, os.readlink(path),))
+        except Exception, e:
+            # how this could happen isn't entirely clear; log it in case
+            # it does and causes problems later
+            log.error("error creating symlink, continuing anyway: %s" %(e,))
+
+        # SELinux hackery (#121369)
+        if flags.selinux:
+            try:
+                os.mkdir(anaconda.rootPath + "/selinux")
+            except Exception, e:
+                pass
+            try:
+                isys.mount("/selinux", anaconda.rootPath + "/selinux", "selinuxfs")
+            except Exception, e:
+                log.error("error mounting selinuxfs: %s" %(e,))
+
+        # For usbfs
+        try:
+            isys.mount("/proc/bus/usb", anaconda.rootPath + "/proc/bus/usb", "usbfs")
+        except Exception, e:
+            log.error("error mounting usbfs: %s" %(e,))
+
+        # write out the fstab
+        if not anaconda.upgrade:
+            anaconda.storage.fsset.write(anaconda.rootPath)
+            if os.access("/etc/modprobe.d/anaconda.conf", os.R_OK):
+                shutil.copyfile("/etc/modprobe.d/anaconda.conf", 
+                                anaconda.rootPath + "/etc/modprobe.d/anaconda.conf")
+            anaconda.network.write(instPath=anaconda.rootPath, anaconda=anaconda)
+            anaconda.storage.write(anaconda.rootPath)
+            if not anaconda.isHeadless:
+                anaconda.keyboard.write(anaconda.rootPath)
+
+        # make a /etc/mtab so mkinitrd can handle certain hw (usb) correctly
+        f = open(anaconda.rootPath + "/etc/mtab", "w+")
+        f.write(anaconda.storage.mtab)
+        f.close()
+
+    def checkSupportedUpgrade(self, anaconda):
+        if anaconda.dir == DISPATCH_BACK:
+            return
+        self._checkUpgradeVersion(anaconda)
+        self._checkUpgradeArch(anaconda)
+
+    def _checkUpgradeVersion(self, anaconda):
+        # Figure out current version for upgrade nag and for determining weird
+        # upgrade cases
+        supportedUpgradeVersion = -1
+        for pkgtup in self.ayum.rpmdb.whatProvides('redhat-release', None, None):
+            n, a, e, v, r = pkgtup
+            if supportedUpgradeVersion <= 0:
+                val = rpmUtils.miscutils.compareEVR((None, '3', '1'),
+                                                    (e, v,r))
+                if val > 0:
+                    supportedUpgradeVersion = 0
+                else:
+                    supportedUpgradeVersion = 1
+                    break
+
+        if "Red Hat Enterprise Linux" not in productName:
+            supportedUpgradeVersion = 1
+
+        if supportedUpgradeVersion == 0:
+            rc = anaconda.intf.messageWindow(_("Warning"),
+                                    _("You appear to be upgrading from a system "
+                                      "which is too old to upgrade to this "
+                                      "version of %s.  Are you sure you wish to "
+                                      "continue the upgrade "
+                                      "process?") %(productName,),
+                                    type = "yesno")
+            if rc == 0:
+                iutil.resetRpmDb(anaconda.rootPath)
+                sys.exit(0)
+
+    def _checkUpgradeArch(self, anaconda):
+        def compareArch(a, b):
+            if re.match("i.86", a) and re.match("i.86", b):
+                return True
+            else:
+                return a == b
+
+        # get the arch of the initscripts package
+        try:
+            pkgs = self.ayum.pkgSack.returnNewestByName('initscripts')
+        except yum.Errors.PackageSackError:
+            log.info("no packages named initscripts")
+            return None
+
+        pkgs = self.ayum.bestPackagesFromList(pkgs)
+        if len(pkgs) == 0:
+            log.info("no best package")
+            return
+        myarch = pkgs[0].arch
+
+        log.info("initscripts is arch: %s" %(myarch,))
+        for po in self.ayum.rpmdb.getProvides('initscripts'):
+            log.info("po.arch is arch: %s" %(po.arch,))
+            if not compareArch(po.arch, myarch):
+                rc = anaconda.intf.messageWindow(_("Warning"),
+                         _("The arch of the release of %(productName)s you "
+                           "are upgrading to appears to be %(myarch)s which "
+                           "does not match your previously installed arch of "
+                           "%(arch)s.  This is likely to not succeed.  Are "
+                           "you sure you wish to continue the upgrade "
+                           "process?")
+                         % {'productName': productName,
+                            'myarch': myarch,
+                            'arch': po.arch},
+                         type="yesno")
+                if rc == 0:
+                    iutil.resetRpmDb(anaconda.rootPath)
+                    sys.exit(0)
+                else:
+                    log.warning("upgrade between possibly incompatible "
+                                "arches %s -> %s" %(po.arch, myarch))
+                    break
+
+    def doInstall(self, anaconda):
+        log.info("Preparing to install packages")
+
+        if not anaconda.upgrade:
+            rpm.addMacro("__dbi_htconfig",
+                         "hash nofsync %{__dbi_other} %{__dbi_perms}")
+
+        if anaconda.ksdata and anaconda.ksdata.packages.excludeDocs:
+            rpm.addMacro("_excludedocs", "1")
+
+        cb = AnacondaCallback(self.ayum, anaconda,
+                              self.instLog, self.modeText)
+        cb.setSizes(len(self.dlpkgs), self.totalSize, self.totalFiles)
+
+        rc = self.ayum.run(self.instLog, cb, anaconda.intf, anaconda.id)
+
+        if cb.initWindow is not None:
+            cb.initWindow.pop()
+
+        self.instLog.write("*** FINISHED INSTALLING PACKAGES ***")
+        self.instLog.close ()
+
+        anaconda.intf.setInstallProgressClass(None)
+
+        if rc == DISPATCH_BACK:
+            return DISPATCH_BACK
+
+    def doPostInstall(self, anaconda):
+        if anaconda.upgrade:
+            w = anaconda.intf.waitWindow(_("Post Upgrade"),
+                                    _("Performing post-upgrade configuration"))
+        else:
+            w = anaconda.intf.waitWindow(_("Post Installation"),
+                                    _("Performing post-installation configuration"))
+
+        packages.rpmSetupGraphicalSystem(anaconda)
+
+        for repo in self.ayum.repos.listEnabled():
+            repo.dirCleanup()
+
+        # expire yum caches on upgrade
+        if anaconda.upgrade and os.path.exists("%s/var/cache/yum" %(anaconda.rootPath,)):
+            log.info("Expiring yum caches")
+            try:
+                iutil.execWithRedirect("yum", ["clean", "all"],
+                                       stdout="/dev/tty5", stderr="/dev/tty5",
+                                       root = anaconda.rootPath)
+            except:
+                pass
+
+        # nuke preupgrade
+        if flags.cmdline.has_key("preupgrade") and os.path.exists("%s/var/cache/yum/anaconda-upgrade" %(anaconda.rootPath,)):
+            try:
+                shutil.rmtree("%s/var/cache/yum/anaconda-upgrade" %(anaconda.rootPath,))
+            except:
+                pass
+
+        # XXX: write proper lvm config
+
+        AnacondaBackend.doPostInstall(self, anaconda)
+        w.pop()
+
+    def kernelVersionList(self, rootPath="/"):
+        # FIXME: using rpm here is a little lame, but otherwise, we'd
+        # be pulling in filelists
+        return packages.rpmKernelVersionList(rootPath)
+
+    def __getGroupId(self, group):
+        """Get the groupid for the given name (english or translated)."""
+        for g in self.ayum.comps.groups:
+            if group == g.name:
+                return g.groupid
+            for trans in g.translated_name.values():
+                if group == trans:
+                    return g.groupid
+
+    def isGroupSelected(self, group):
+        try:
+            grp = self.ayum.comps.return_group(group)
+            if grp.selected: return True
+        except yum.Errors.GroupsError, e:
+            pass
+        return False
+
+    def selectGroup(self, group, *args):
+        if not self.ayum.comps.has_group(group):
+            log.debug("no such group %s" % group)
+            raise NoSuchGroup, group
+
+        types = ["mandatory"]
+
+        if args:
+            if args[0][0]:
+                types.append("default")
+            if args[0][1]:
+                types.append("optional")
+        else:
+            types.append("default")
+
+        try:
+            mbrs = self.ayum.selectGroup(group, group_package_types=types)
+            if len(mbrs) == 0 and self.isGroupSelected(group):
+                return
+        except yum.Errors.GroupsError, e:
+            # try to find out if it's the name or translated name
+            gid = self.__getGroupId(group)
+            if gid is not None:
+                mbrs = self.ayum.selectGroup(gid, group_package_types=types)
+                if len(mbrs) == 0 and self.isGroupSelected(gid):
+                    return
+            else:
+                log.debug("no such group %s" %(group,))
+                raise NoSuchGroup, group
+
+    def deselectGroup(self, group, *args):
+        try:
+            self.ayum.deselectGroup(group)
+        except yum.Errors.GroupsError, e:
+            # try to find out if it's the name or translated name
+            gid = self.__getGroupId(group)
+            if gid is not None:
+                self.ayum.deselectGroup(gid)
+            else:
+                log.debug("no such group %s" %(group,))
+
+    def selectPackage(self, pkg, *args):
+        if self.ayum.tsInfo.matchNaevr(name=pkg):
+            return 0
+
+        try:
+            mbrs = self.ayum.install(pattern=pkg)
+            return len(mbrs)
+        except yum.Errors.InstallError:
+            log.debug("no package matching %s" %(pkg,))
+            return 0
+
+    def deselectPackage(self, pkg, *args):
+        sp = pkg.rsplit(".", 2)
+        txmbrs = []
+        if len(sp) == 2:
+            txmbrs = self.ayum.tsInfo.matchNaevr(name=sp[0], arch=sp[1])
+
+        if len(txmbrs) == 0:
+            exact, match, unmatch = yum.packages.parsePackages(self.ayum.pkgSack.returnPackages(), [pkg], casematch=1)
+            for p in exact + match:
+                txmbrs.append(p)
+
+        if len(txmbrs) > 0:
+            for x in txmbrs:
+                self.ayum.tsInfo.remove(x.pkgtup)
+                # we also need to remove from the conditionals
+                # dict so that things don't get pulled back in as a result
+                # of them.  yes, this is ugly.  conditionals should die.
+                for req, pkgs in self.ayum.tsInfo.conditionals.iteritems():
+                    if x in pkgs:
+                        pkgs.remove(x)
+                        self.ayum.tsInfo.conditionals[req] = pkgs
+            return len(txmbrs)
+        else:
+            log.debug("no such package %s to remove" %(pkg,))
+            return 0
+
+    def groupListExists(self, grps):
+        """Returns bool of whether all of the given groups exist."""
+        for gid in grps:
+            g = self.ayum.comps.return_group(gid)
+            if not g:
+                log.debug("no such group %s" % (gid,))
+                return False
+        return True
+
+    def groupListDefault(self, grps):
+        """Returns bool of whether all of the given groups are default"""
+        rc = False
+        for gid in grps:
+            g = self.ayum.comps.return_group(gid)
+            if g and not g.default:
+                return False
+            elif g:
+                rc = True
+        return rc
+
+    def writeKS(self, f):
+        for repo in self.ayum.repos.listEnabled():
+            if repo.name == "Installation Repo":
+                continue
+
+            line = "repo --name=\"%s\" " % (repo.name or repo.repoid)
+
+            if repo.baseurl:
+                line += " --baseurl=%s\n" % repo.baseurl[0]
+            else:
+                line += " --mirrorlist=%s\n" % repo.mirrorlist
+
+            f.write(line)
+
+    def writePackagesKS(self, f, anaconda):
+        if anaconda.ksdata:
+            f.write(anaconda.ksdata.packages.__str__())
+            return
+
+        groups = []
+        installed = []
+        removed = []
+
+        # Faster to grab all the package names up front rather than call
+        # searchNevra in the loop below.
+        allPkgNames = map(lambda pkg: pkg.name, self.ayum.pkgSack.returnPackages())
+        allPkgNames.sort()
+
+        # On CD/DVD installs, we have one transaction per CD and will end up
+        # checking allPkgNames against a very short list of packages.  So we
+        # have to reset to media #0, which is an all packages transaction.
+        old = self.ayum.tsInfo.curmedia
+        self.ayum.tsInfo.curmedia = 0
+
+        self.ayum.tsInfo.makelists()
+        txmbrNames = map (lambda x: x.name, self.ayum.tsInfo.getMembers())
+
+        self.ayum.tsInfo.curmedia = old
+
+        if len(self.ayum.tsInfo.instgroups) == 0 and len(txmbrNames) == 0:
+            return
+
+        f.write("\n%packages\n")
+
+        for grp in filter(lambda x: x.selected, self.ayum.comps.groups):
+            groups.append(grp.groupid)
+
+            defaults = grp.default_packages.keys() + grp.mandatory_packages.keys()
+            optionals = grp.optional_packages.keys()
+
+            for pkg in filter(lambda x: x in defaults and (not x in txmbrNames and x in allPkgNames), grp.packages):
+                removed.append(pkg)
+
+            for pkg in filter(lambda x: x in txmbrNames, optionals):
+                installed.append(pkg)
+
+        for grp in groups:
+            f.write("@%s\n" % grp)
+
+        for pkg in installed:
+            f.write("%s\n" % pkg)
+
+        for pkg in removed:
+            f.write("-%s\n" % pkg)
+
+        f.write("%end")
+
+    def writeConfiguration(self):
+        return
+
+    def getRequiredMedia(self):
+        return self.ayum.tsInfo.reqmedia.keys()
+
+class DownloadHeaderProgress:
+    def __init__(self, intf, ayum=None):
+        window = intf.progressWindow(_("Installation Starting"),
+                                     _("Starting installation process"),
+                                     1.0, 0.01)
+        self.window = window
+        self.ayum = ayum
+        self.current = self.loopstart = 0
+        self.incr = 1
+
+        if self.ayum is not None and self.ayum.tsInfo is not None:
+            self.numpkgs = len(self.ayum.tsInfo.getMembers())
+            if self.numpkgs != 0:
+                self.incr = (1.0 / self.numpkgs) * (1.0 - self.loopstart)
+        else:
+            self.numpkgs = 0
+
+        self.refresh()
+
+        self.restartLoop = self.downloadHeader = self.transactionPopulation = self.refresh
+        self.procReq = self.procConflict = self.unresolved = self.noop
+
+    def noop(self, *args, **kwargs):
+        pass
+
+    def pkgAdded(self, *args):
+        if self.numpkgs:
+            self.set(self.current + self.incr)
+
+    def pop(self):
+        self.window.pop()
+
+    def refresh(self, *args):
+        self.window.refresh()
+
+    def set(self, value):
+        self.current = value
+        self.window.set(self.current)
+
+class YumDepSolveProgress:
+    def __init__(self, intf, ayum = None):
+        window = intf.progressWindow(_("Dependency Check"),
+                                     _("Checking dependencies in packages selected for installation"),
+                                     1.0, 0.01)
+        self.window = window
+
+        self.numpkgs = None
+        self.loopstart = None
+        self.incr = None
+        self.ayum = ayum
+        self.current = 0
+
+        self.restartLoop = self.downloadHeader = self.transactionPopulation = self.refresh
+        self.procReq = self.procConflict = self.unresolved = self.noop
+
+    def tscheck(self, num = None):
+        self.refresh()
+        if num is None and self.ayum is not None and self.ayum.tsInfo is not None:
+            num = len(self.ayum.tsInfo.getMembers())
+
+        if num:
+            self.numpkgs = num
+            self.loopstart = self.current
+            self.incr = (1.0 / num) * ((1.0 - self.loopstart) / 2)
+
+    def pkgAdded(self, *args):
+        if self.numpkgs:
+            self.set(self.current + self.incr)
+
+    def noop(self, *args, **kwargs):
+        pass
+
+    def refresh(self, *args):
+        self.window.refresh()
+
+    def set(self, value):
+        self.current = value
+        self.window.set(self.current)
+
+    def start(self):
+        self.set(0.0)
+        self.refresh()
+
+    def end(self):
+        self.window.set(1.0)
+        self.window.refresh()
+
+    def pop(self):
+        self.window.pop()
diff --git a/pyudev.py b/pyudev.py
deleted file mode 100644
index e51ee33..0000000
--- a/pyudev.py
+++ /dev/null
@@ -1,225 +0,0 @@
-from __future__ import print_function
-
-import sys
-import os
-import fnmatch
-from ctypes import *
-
-
-# XXX this one may need some tweaking...
-def find_library(name, somajor=0):
-    env = os.environ.get("LD_LIBRARY_PATH")
-    common = ["/lib64", "/lib"]
-
-    if env:
-        libdirs = env.split(":") + common
-    else:
-        libdirs = common
-
-    libdirs = filter(os.path.isdir, libdirs)
-
-    for dir in libdirs:
-        files = fnmatch.filter(os.listdir(dir), "lib%s.so.%d" % (name, somajor))
-        files = [os.path.join(dir, file) for file in files]
-
-        if files:
-            break
-
-    if files:
-        return files[0]
-    else:
-        return None
-
-# find the udev library
-libudev = find_library(name="udev", somajor=0)
-
-if not libudev or not os.path.exists(libudev):
-    raise ImportError, "No library named %s" % libudev
-
-# load the udev library
-libudev = CDLL(libudev)
-
-
-# create aliases for needed functions and set the return types where needed
-libudev_udev_new = libudev.udev_new
-libudev_udev_new.argtypes = []
-libudev_udev_new.restype = c_void_p
-libudev_udev_unref = libudev.udev_unref
-libudev_udev_unref.argtypes = [ c_void_p ]
-
-libudev_udev_device_new_from_syspath = libudev.udev_device_new_from_syspath
-libudev_udev_device_new_from_syspath.restype = c_void_p
-libudev_udev_device_new_from_syspath.argtypes = [ c_void_p, c_char_p ]
-libudev_udev_device_unref = libudev.udev_device_unref
-libudev_udev_device_unref.argtypes = [ c_void_p ]
-
-libudev_udev_device_get_syspath = libudev.udev_device_get_syspath
-libudev_udev_device_get_syspath.restype = c_char_p
-libudev_udev_device_get_syspath.argtypes = [ c_void_p ]
-libudev_udev_device_get_sysname = libudev.udev_device_get_sysname
-libudev_udev_device_get_sysname.restype = c_char_p
-libudev_udev_device_get_sysname.argtypes = [ c_void_p ]
-libudev_udev_device_get_devpath = libudev.udev_device_get_devpath
-libudev_udev_device_get_devpath.restype = c_char_p
-libudev_udev_device_get_devpath.argtypes = [ c_void_p ]
-libudev_udev_device_get_devtype = libudev.udev_device_get_devtype
-libudev_udev_device_get_devtype.restype = c_char_p
-libudev_udev_device_get_devtype.argtypes = [ c_void_p ]
-libudev_udev_device_get_devnode = libudev.udev_device_get_devnode
-libudev_udev_device_get_devnode.restype = c_char_p
-libudev_udev_device_get_devnode.argtypes = [ c_void_p ]
-libudev_udev_device_get_subsystem = libudev.udev_device_get_subsystem
-libudev_udev_device_get_subsystem.restype = c_char_p
-libudev_udev_device_get_subsystem.argtypes = [ c_void_p ]
-libudev_udev_device_get_sysnum = libudev.udev_device_get_sysnum
-libudev_udev_device_get_sysnum.restype = c_char_p
-libudev_udev_device_get_sysnum.argtypes = [ c_void_p ]
-
-libudev_udev_device_get_properties_list_entry = libudev.udev_device_get_properties_list_entry
-libudev_udev_device_get_properties_list_entry.restype = c_void_p
-libudev_udev_device_get_properties_list_entry.argtypes = [ c_void_p ]
-libudev_udev_list_entry_get_next = libudev.udev_list_entry_get_next
-libudev_udev_list_entry_get_next.restype = c_void_p
-libudev_udev_list_entry_get_next.argtypes = [ c_void_p ]
-
-libudev_udev_list_entry_get_name = libudev.udev_list_entry_get_name
-libudev_udev_list_entry_get_name.restype = c_char_p
-libudev_udev_list_entry_get_name.argtypes = [ c_void_p ]
-libudev_udev_list_entry_get_value = libudev.udev_list_entry_get_value
-libudev_udev_list_entry_get_value.restype = c_char_p
-libudev_udev_list_entry_get_value.argtypes = [ c_void_p ]
-
-libudev_udev_enumerate_new = libudev.udev_enumerate_new
-libudev_udev_enumerate_new.restype = c_void_p
-libudev_udev_enumerate_new.argtypes = [ c_void_p ]
-libudev_udev_enumerate_unref = libudev.udev_enumerate_unref
-libudev_udev_enumerate_unref.argtypes = [ c_void_p ]
-
-libudev_udev_enumerate_add_match_subsystem = libudev.udev_enumerate_add_match_subsystem
-libudev_udev_enumerate_add_match_subsystem.restype = c_int
-libudev_udev_enumerate_add_match_subsystem.argtypes = [ c_void_p, c_char_p ]
-libudev_udev_enumerate_scan_devices = libudev.udev_enumerate_scan_devices
-libudev_udev_enumerate_scan_devices.restype = c_int
-libudev_udev_enumerate_scan_devices.argtypes = [ c_void_p ]
-libudev_udev_enumerate_get_list_entry = libudev.udev_enumerate_get_list_entry
-libudev_udev_enumerate_get_list_entry.restype = c_void_p
-libudev_udev_enumerate_get_list_entry.argtypes = [ c_void_p ]
-
-libudev_udev_device_get_devlinks_list_entry = libudev.udev_device_get_devlinks_list_entry
-libudev_udev_device_get_devlinks_list_entry.restype = c_void_p
-libudev_udev_device_get_devlinks_list_entry.argtypes = [ c_void_p ]
-
-
-class UdevDevice(dict):
-
-    def __init__(self, udev, sysfs_path):
-        dict.__init__(self)
-
-        # create new udev device from syspath
-        udev_device = libudev_udev_device_new_from_syspath(udev, sysfs_path)
-        if not udev_device:
-            # device does not exist
-            return
-
-        # set syspath and sysname properties
-        self.syspath = libudev_udev_device_get_syspath(udev_device)
-        self.sysname = libudev_udev_device_get_sysname(udev_device)
-
-        # get the devlinks list
-        devlinks = []
-        devlinks_entry = libudev_udev_device_get_devlinks_list_entry(udev_device)
-
-        while devlinks_entry:
-            path = libudev_udev_list_entry_get_name(devlinks_entry)
-            devlinks.append(path)
-
-            devlinks_entry = libudev_udev_list_entry_get_next(devlinks_entry)
-
-        # add devlinks list to the dictionary
-        self["symlinks"] = devlinks
-
-        # get the first property entry
-        property_entry = libudev_udev_device_get_properties_list_entry(udev_device)
-
-        while property_entry:
-            name = libudev_udev_list_entry_get_name(property_entry)
-            value = libudev_udev_list_entry_get_value(property_entry)
-
-            # XXX some of the strings contain a list of values in them,
-            # we want to split them and make a list
-            if value.count(" %s=" % name):
-                value = value.split(" %s=" % name)
-
-            self[name] = value
-
-            # get next property entry
-            property_entry = libudev_udev_list_entry_get_next(property_entry)
-
-        # set additional properties
-        self.devpath = libudev_udev_device_get_devpath(udev_device)
-        self.subsystem = libudev_udev_device_get_subsystem(udev_device)
-        self.devtype = libudev_udev_device_get_devtype(udev_device)
-        self.sysnum = libudev_udev_device_get_sysnum(udev_device)
-        self.devnode = libudev_udev_device_get_devnode(udev_device)
-
-        # cleanup
-        libudev_udev_device_unref(udev_device)
-
-
-class Udev(object):
-
-    def __init__(self):
-        self.udev = libudev_udev_new()
-
-    def create_device(self, sysfs_path):
-        return UdevDevice(self.udev, sysfs_path)
-
-    def enumerate_devices(self, subsystem=None):
-        enumerate = libudev_udev_enumerate_new(self.udev)
-
-        # add the match subsystem
-        if subsystem is not None:
-            rc = libudev_udev_enumerate_add_match_subsystem(enumerate, subsystem)
-            if not rc == 0:
-                print("error: unable to add the match subsystem", file=sys.stderr)
-                libudev_udev_enumerate_unref(enumerate)
-                return []
-
-        # scan the devices
-        rc = libudev_udev_enumerate_scan_devices(enumerate)
-        if not rc == 0:
-            print("error: unable to enumerate the devices", file=sys.stderr)
-            libudev_udev_enumerate_unref(enumerate)
-            return []
-
-        # create the list of sysfs paths
-        sysfs_paths = []
-
-        # get the first list entry
-        list_entry = libudev_udev_enumerate_get_list_entry(enumerate)
-
-        while list_entry:
-            sysfs_path = libudev_udev_list_entry_get_name(list_entry)
-            sysfs_paths.append(sysfs_path)
-
-            # get next list entry
-            list_entry = libudev_udev_list_entry_get_next(list_entry)
-
-        # cleanup
-        libudev_udev_enumerate_unref(enumerate)
-
-        return sysfs_paths
-
-    def scan_devices(self, sysfs_paths=None):
-        if sysfs_paths is None:
-            sysfs_paths = self.enumerate_devices()
-
-        for sysfs_path in sysfs_paths:
-            device = self.create_device(sysfs_path)
-
-            if device:
-                yield device
-
-    def unref(self):
-        libudev_udev_unref(self.udev)
-        self.udev = None
diff --git a/rescue.py b/rescue.py
deleted file mode 100644
index 92d5a09..0000000
--- a/rescue.py
+++ /dev/null
@@ -1,508 +0,0 @@
-#
-# rescue.py - anaconda rescue mode setup
-#
-# Copyright (C) 2001, 2002, 2003, 2004  Red Hat, Inc.  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 as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# 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, see <http://www.gnu.org/licenses/>.
-#
-# Author(s): Mike Fulbright <msf@xxxxxxxxxx>
-#            Jeremy Katz <katzj@xxxxxxxxxx>
-#
-
-import upgrade
-from snack import *
-from constants import *
-from constants_text import *
-from text import WaitWindow, OkCancelWindow, ProgressWindow, PassphraseEntryWindow, stepToClasses
-from flags import flags
-import sys
-import os
-import isys
-from storage import mountExistingSystem
-from installinterfacebase import InstallInterfaceBase
-from add_drive_text import addDriveDialog
-import iutil
-import shutil
-import time
-import network
-import subprocess
-
-import gettext
-_ = lambda x: gettext.ldgettext("anaconda", x)
-
-import logging
-log = logging.getLogger("anaconda")
-
-class RescueInterface(InstallInterfaceBase):
-    def waitWindow(self, title, text):
-        return WaitWindow(self.screen, title, text)
-
-    def progressWindow(self, title, text, total):
-        return ProgressWindow(self.screen, title, text, total)
-
-    def detailedMessageWindow(self, title, text, longText=None, type="ok",
-                              default=None, custom_icon=None,
-                              custom_buttons=[], expanded=False):
-        return self.messageWindow(title, text, type, default, custom_icon,
-                                  custom_buttons)
-
-    def messageWindow(self, title, text, type = "ok", default = None,
-                      custom_icon=None, custom_buttons=[]):
-	if type == "ok":
-	    ButtonChoiceWindow(self.screen, title, text,
-			       buttons=[TEXT_OK_BUTTON])
-        elif type == "yesno":
-            if default and default == "no":
-                btnlist = [TEXT_NO_BUTTON, TEXT_YES_BUTTON]
-            else:
-                btnlist = [TEXT_YES_BUTTON, TEXT_NO_BUTTON]
-	    rc = ButtonChoiceWindow(self.screen, title, text,
-			       buttons=btnlist)
-            if rc == "yes":
-                return 1
-            else:
-                return 0
-	elif type == "custom":
-	    tmpbut = []
-	    for but in custom_buttons:
-		tmpbut.append(string.replace(but,"_",""))
-
-	    rc = ButtonChoiceWindow(self.screen, title, text, width=60,
-				    buttons=tmpbut)
-
-	    idx = 0
-	    for b in tmpbut:
-		if string.lower(b) == rc:
-		    return idx
-		idx = idx + 1
-	    return 0
-	else:
-	    return OkCancelWindow(self.screen, title, text)
-
-    def enableNetwork(self, anaconda):
-        if len(anaconda.network.netdevices) == 0:
-            return False
-        from netconfig_text import NetworkConfiguratorText
-        w = NetworkConfiguratorText(self.screen, anaconda)
-        ret = w.run()
-        return ret != INSTALL_BACK
-
-    def passphraseEntryWindow(self, device):
-        w = PassphraseEntryWindow(self.screen, device)
-        (passphrase, isglobal) = w.run()
-        w.pop()
-        return (passphrase, isglobal)
-
-    def resetInitializeDiskQuestion(self):
-        self._initLabelAnswers = {}
-
-    def resetReinitInconsistentLVMQuestion(self):
-        self._inconsistentLVMAnswers = {}
-
-    def questionInitializeDisk(self, path, description, size, details=""):
-        # Never initialize disks in rescue mode!
-        return False
-
-    def questionReinitInconsistentLVM(self, pv_names=None, lv_name=None, vg_name=None):
-        # Never reinit VG's in rescue mode!
-        return False
-
-    def questionInitializeDASD(self, c, devs):
-        # Special return value to let dasd.py know we're rescue mode
-        return 1
-
-    def shutdown (self):
-        pass
-
-    def suspend(self):
-        pass
-
-    def resume(self):
-        pass
-
-    def __init__(self, screen):
-        InstallInterfaceBase.__init__(self)
-        self.screen = screen
-
-# XXX grub-install is stupid and uses df output to figure out
-# things when installing grub.  make /etc/mtab be at least
-# moderately useful.  
-def makeMtab(instPath, storage):
-    try:
-        f = open(instPath + "/etc/mtab", "w+")
-    except IOError, e:
-        log.info("failed to open /etc/mtab for write: %s" % e)
-        return
-
-    try:
-        f.write(storage.mtab)
-    finally:
-        f.close()
-
-def makeFStab(instPath = ""):
-    if os.access("/proc/mounts", os.R_OK):
-        f = open("/proc/mounts", "r")
-        buf = f.read()
-        f.close()
-    else:
-        buf = ""
-
-    try:
-        f = open(instPath + "/etc/fstab", "a")
-        if buf:
-            f.write(buf)
-        f.close()
-    except IOError, e:
-        log.info("failed to write /etc/fstab: %s" % e)
-
-# make sure they have a resolv.conf in the chroot
-def makeResolvConf(instPath):
-    if not os.access("/etc/resolv.conf", os.R_OK):
-        return
-
-    if os.access("%s/etc/resolv.conf" %(instPath,), os.R_OK):
-        f = open("%s/etc/resolv.conf" %(instPath,), "r")
-        buf = f.read()
-        f.close()
-    else:
-        buf = ""
-
-    # already have a nameserver line, don't worry about it
-    if buf.find("nameserver") != -1:
-        return
-
-    f = open("/etc/resolv.conf", "r")
-    buf = f.read()
-    f.close()
-
-    # no nameserver, we can't do much about it
-    if buf.find("nameserver") == -1:
-        return
-
-    shutil.copyfile("%s/etc/resolv.conf" %(instPath,),
-                    "%s/etc/resolv.conf.bak" %(instPath,))
-    f = open("%s/etc/resolv.conf" %(instPath,), "w+")
-    f.write(buf)
-    f.close()
-
-#
-# Write out something useful for networking and start interfaces
-#
-def startNetworking(network, intf):
-    # do lo first
-    try:
-        os.system("/usr/sbin/ifconfig lo 127.0.0.1")
-    except:
-        log.error("Error trying to start lo in rescue.py::startNetworking()")
-
-    # start up dhcp interfaces first
-    if not network.bringUp():
-        log.error("Error bringing up network interfaces")
-
-def runShell(screen = None, msg=""):
-    if screen:
-        screen.suspend()
-
-    print
-    if msg:
-        print (msg)
-    print(_("When finished please exit from the shell and your "
-            "system will reboot."))
-    print
-
-    proc = None
-
-    if os.path.exists("/usr/bin/firstaidkit-qs"):
-        proc = subprocess.Popen(["/usr/bin/firstaidkit-qs"])
-        proc.wait()
-    
-    if proc is None or proc.returncode!=0:
-        if os.path.exists("/bin/bash"):
-            iutil.execConsole()
-        else:
-            print(_("Unable to find /bin/sh to execute!  Not starting shell"))
-            time.sleep(5)
-
-    if screen:
-        screen.finish()
-
-def runRescue(anaconda):
-    for file in [ "services", "protocols", "group", "joe", "man.config",
-                  "nsswitch.conf", "selinux", "mke2fs.conf" ]:
-        try:
-            os.symlink('/mnt/runtime/etc/' + file, '/etc/' + file)
-        except:
-            pass
-
-    # see if they would like networking enabled
-    if not network.hasActiveNetDev():
-        screen = SnackScreen()
-
-        while True:
-            rc = ButtonChoiceWindow(screen, _("Setup Networking"),
-                _("Do you want to start the network interfaces on "
-                  "this system?"), [_("Yes"), _("No")])
-
-            if rc != string.lower(_("No")):
-                anaconda.intf = RescueInterface(screen)
-
-                if not anaconda.intf.enableNetwork(anaconda):
-                    anaconda.intf.messageWindow(_("No Network Available"),
-                        _("Unable to activate a networking device.  Networking "
-                          "will not be available in rescue mode."))
-                    break
-
-                startNetworking(anaconda.network, anaconda.intf)
-                break
-            else:
-                break
-
-        anaconda.intf = None
-        screen.finish()
-
-    # Early shell access with no disk access attempts
-    if not anaconda.rescue_mount:
-        # the %post should be responsible for mounting all needed file systems
-        # NOTE: 1st script must be bash or simple python as nothing else might be available in the rescue image
-        if anaconda.ksdata:
-           from kickstart import runPostScripts
-           runPostScripts(anaconda)
-        else:
-           runShell()
-
-        sys.exit(0)
-
-    screen = SnackScreen()
-    anaconda.intf = RescueInterface(screen)
-
-    if anaconda.ksdata:
-        if anaconda.ksdata.rescue and anaconda.ksdata.rescue.romount:
-            readOnly = 1
-        else:
-            readOnly = 0
-    else:
-        # prompt to see if we should try and find root filesystem and mount
-        # everything in /etc/fstab on that root
-        while True:
-            rc = ButtonChoiceWindow(screen, _("Rescue"),
-                _("The rescue environment will now attempt to find your "
-                  "Linux installation and mount it under the directory "
-                  "%s.  You can then make any changes required to your "
-                  "system.  If you want to proceed with this step choose "
-                  "'Continue'.  You can also choose to mount your file systems "
-                  "read-only instead of read-write by choosing 'Read-Only'.  "
-                  "If you need to activate SAN devices choose 'Advanced'."
-                  "\n\n"
-                  "If for some reason this process fails you can choose 'Skip' "
-                  "and this step will be skipped and you will go directly to a "
-                  "command shell.\n\n") % (anaconda.rootPath,),
-                  [_("Continue"), _("Read-Only"), _("Skip"), _("Advanced")] )
-
-            if rc == string.lower(_("Skip")):
-                runShell(screen)
-                sys.exit(0)
-            elif rc == string.lower(_("Advanced")):
-                addDialog = addDriveDialog(anaconda)
-                addDialog.addDriveDialog(screen)
-                continue
-            elif rc == string.lower(_("Read-Only")):
-                readOnly = 1
-            else:
-                readOnly = 0
-            break
-
-    import storage
-    storage.storageInitialize(anaconda)
-
-    disks = upgrade.findExistingRoots(anaconda, upgradeany=True)
-
-    if not disks:
-        root = None
-    elif (len(disks) == 1) or anaconda.ksdata:
-        root = disks[0]
-    else:
-        height = min (len (disks), 12)
-        if height == 12:
-            scroll = 1
-        else:
-            scroll = 0
-
-        devList = []
-        for (device, relstr) in disks:
-            if getattr(device.format, "label", None):
-                devList.append("%s (%s) - %s" % (device.name, device.format.label, relstr))
-            else:
-                devList.append("%s - %s" % (device.name, relstr))
-
-        (button, choice) = \
-            ListboxChoiceWindow(screen, _("System to Rescue"),
-                                _("Which device holds the root partition "
-                                  "of your installation?"), devList,
-                                [ _("OK"), _("Exit") ], width = 30,
-                                scroll = scroll, height = height,
-                                help = "multipleroot")
-
-        if button == string.lower (_("Exit")):
-            root = None
-        else:
-            root = disks[choice]
-
-    rootmounted = 0
-
-    if root:
-        try:
-            rc = mountExistingSystem(anaconda, root,
-                                     allowDirty = 1, warnDirty = 1,
-                                     readOnly = readOnly)
-
-            if rc == -1:
-                if anaconda.ksdata:
-                    log.error("System had dirty file systems which you chose not to mount")
-                else:
-                    ButtonChoiceWindow(screen, _("Rescue"),
-                        _("Your system had dirty file systems which you chose not "
-                          "to mount.  Press return to get a shell from which "
-                          "you can fsck and mount your partitions.  The system "
-                          "will reboot automatically when you exit from the "
-                          "shell."), [_("OK")], width = 50)
-                rootmounted = 0
-            else:
-                if anaconda.ksdata:
-                    log.info("System has been mounted under: %s" % anaconda.rootPath)
-                else:
-                    ButtonChoiceWindow(screen, _("Rescue"),
-                       _("Your system has been mounted under %(rootPath)s.\n\n"
-                         "Press <return> to get a shell. If you would like to "
-                         "make your system the root environment, run the command:\n\n"
-                         "\tchroot %(rootPath)s\n\nThe system will reboot "
-                         "automatically when you exit from the shell.") %
-                                       {'rootPath': anaconda.rootPath},
-                                       [_("OK")] )
-                rootmounted = 1
-
-                # now turn on swap
-                if not readOnly:
-                    try:
-                        anaconda.storage.turnOnSwap()
-                    except:
-                        log.error("Error enabling swap")
-
-                # and /selinux too
-                if flags.selinux and os.path.isdir("%s/selinux" %(anaconda.rootPath,)):
-                    try:
-                        isys.mount("/selinux", "%s/selinux" %(anaconda.rootPath,),
-                                   "selinuxfs")
-                    except Exception, e:
-                        log.error("error mounting selinuxfs: %s" %(e,))
-
-                    # we have to catch the possible exception
-                    # because we support read-only mounting
-                    try:
-                        fd = open("%s/.autorelabel" % anaconda.rootPath, "w+")
-                        fd.close()
-                    except Exception, e:
-                        log.warning("cannot touch /.autorelabel")
-
-                # set a library path to use mounted fs
-                libdirs = os.environ["LD_LIBRARY_PATH"].split(":")
-                mounted = map(lambda dir: "/mnt/sysimage%s" % dir, libdirs)
-                os.environ["LD_LIBRARY_PATH"] = ":".join(libdirs + mounted)
-
-                # find groff data dir
-                try:
-                    glst = os.listdir("/mnt/sysimage/usr/share/groff")
-
-                    # find a directory which is a numeral, its where
-                    # data files are
-                    gversion = None
-                    for gdir in glst:
-                        try:
-                            isone = 1
-                            for idx in range(0, len(gdir)):
-                                if string.find(string.digits + '.', gdir[idx]) == -1:
-                                    isone = 0
-                                    break
-                            if isone:
-                                gversion = gdir
-                                break
-                        except:
-                            gversion = None
-                            continue
-                except:
-                    gversion = None
-
-                if gversion is not None:
-                    gpath = "/mnt/sysimage/usr/share/groff/"+gversion
-                    os.environ["GROFF_FONT_PATH"] = gpath + '/font'
-                    os.environ["GROFF_TMAC_PATH"] = "%s:/mnt/sysimage/usr/share/groff/site-tmac" % (gpath + '/tmac',)
-
-                # do we have bash?
-                try:
-                    if os.access("/usr/bin/bash", os.R_OK):
-                        os.symlink ("/usr/bin/bash", "/bin/bash")
-                except:
-                    pass
-        except:
-            # This looks horrible, but all it does is catch every exception,
-            # and reraise those in the tuple check. This lets programming
-            # errors raise exceptions, while any runtime error will
-            # still result in a shell
-            (exc, val) = sys.exc_info()[0:2]
-            log.error(str(exc)+": "+str(val))
-            if exc in (IndexError, ValueError, SyntaxError):
-                raise exc, val, sys.exc_info()[2]
-
-            if anaconda.ksdata:
-                log.error("An error occurred trying to mount some or all of your system")
-            else:
-                ButtonChoiceWindow(screen, _("Rescue"),
-                    _("An error occurred trying to mount some or all of your "
-                      "system. Some of it may be mounted under %s.\n\n"
-                      "Press <return> to get a shell. The system will reboot "
-                      "automatically when you exit from the shell.") % (anaconda.rootPath,),
-                      [_("OK")] )
-    else:
-        if anaconda.ksdata:
-            log.info("No Linux partitions found")
-            screen.finish()
-            print(_("You don't have any Linux partitions.  Rebooting.\n"))
-            sys.exit(0)
-        else:
-            ButtonChoiceWindow(screen, _("Rescue Mode"),
-                               _("You don't have any Linux partitions. Press "
-                                 "return to get a shell. The system will reboot "
-                                 "automatically when you exit from the shell."),
-                               [ _("OK") ], width = 50)
-
-    msgStr = ""
-
-    if rootmounted and not readOnly:
-        makeMtab(anaconda.rootPath, anaconda.storage)
-        try:
-            makeResolvConf(anaconda.rootPath)
-        except Exception, e:
-            log.error("error making a resolv.conf: %s" %(e,))
-        msgStr = _("Your system is mounted under the %s directory.") % (anaconda.rootPath,)
-
-    #create /etc/fstab in ramdisk, so it is easier to work with RO mounted filesystems
-    makeFStab()
-
-    # run %post if we've mounted everything
-    if anaconda.ksdata:
-        from kickstart import runPostScripts
-        runPostScripts(anaconda)
-    else:
-        runShell(screen, msgStr)
-
-    sys.exit(0)
diff --git a/run_test.py b/run_test.py
deleted file mode 100755
index 2a7ad2d..0000000
--- a/run_test.py
+++ /dev/null
@@ -1,109 +0,0 @@
-#!/usr/bin/python
-#-*- coding:utf-8 -*-
-
-from distutils.sysconfig import get_python_lib
-import sys
-
-REQUIRED_PATHS = ["%s/pyanaconda" % get_python_lib(plat_specific=1),
-                  "/usr/share/system-config-date"]
-sys.path.extend(REQUIRED_PATHS)
-
-import unittest
-import tests
-import string
-from optparse import OptionParser
-
-
-def getFullTestName(test, full_test_names):
-    tests = []
-    for full_test_name in full_test_names:
-        if full_test_name.lower().find(test) != -1:
-            tests.append(full_test_name)
-
-    return tests
-
-
-if __name__ == "__main__":
-    usage = "usage: %prog [options] [test1 test2 ...]"
-    parser = OptionParser(usage)
-    parser.add_option("-l", "--list", action="store_true", default=False,
-                      help="print all available tests and exit")
-
-    (options, args) = parser.parse_args(sys.argv[1:])
-
-    print "Searching for test suites"
-    available_suites = tests.getAvailableSuites()
-    test_keys = available_suites.keys()
-    if not test_keys:
-        print "No test suites available, exiting"
-        sys.exit(1)
-
-    test_keys.sort()
-
-    if options.list:
-        print "\nAvailable tests:"
-        for test_name in test_keys:
-            print test_name
-        sys.exit(0)
-
-    tests_to_run = []
-
-    if len(args) == 0:
-        # interactive mode
-        print "Running in interactive mode"
-        print "\nAvailable tests:"
-        test_num = 0
-        for test_name in test_keys:
-            print "[%3d] %s" % (test_num, test_name)
-            test_num += 1
-        print
-
-        try:
-            input_string = raw_input("Type in the test you want to run, "
-                                     "or \"all\" to run all listed tests: ")
-        except KeyboardInterrupt as e:
-            print "\nAborted by user"
-            sys.exit(1)
-
-        for arg in input_string.split():
-            if arg.isdigit():
-                arg = int(arg)
-                try:
-                    args.append(test_keys[arg])
-                except KeyError as e:
-                    pass
-            else:
-                args.append(arg)
-
-    args = map(string.lower, args)
-    if "all" in args:
-        tests_to_run = test_keys[:]
-    else:
-        for arg in args:
-            matching_tests = getFullTestName(arg, test_keys)
-            tests_to_run.extend(filter(lambda test: test not in tests_to_run,
-                                       matching_tests))
-
-    # run the tests
-    if tests_to_run:
-        tests_to_run.sort()
-        print "Running tests: %s" % tests_to_run
-        test_suite = unittest.TestSuite([available_suites[test]
-                                         for test in tests_to_run])
-
-        try:
-            result = unittest.TextTestRunner(verbosity=2).run(test_suite)
-        except KeyboardInterrupt as e:
-            print "\nAborted by user"
-            sys.exit(1)
-
-        if result.wasSuccessful():
-            print "\nAll tests OK"
-            sys.exit(0)
-        else:
-            print "\nTests finished with %d errors and %d failures" % (len(result.errors),
-                                                                       len(result.failures))
-            sys.exit(2)
-    else:
-        print "No test suites matching your criteria found, exiting"
-        sys.exit(1)
diff --git a/security.py b/security.py
deleted file mode 100644
index 219d465..0000000
--- a/security.py
+++ /dev/null
@@ -1,87 +0,0 @@
-#
-# security.py - security install data and installation
-#
-# Copyright (C) 2004  Red Hat, Inc.  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 as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# 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, see <http://www.gnu.org/licenses/>.
-#
-# Author(s): Jeremy Katz <katzj@xxxxxxxxxx>
-#
-
-import iutil, shlex
-from flags import flags
-from pykickstart.constants import *
-
-import logging
-log = logging.getLogger("anaconda")
-
-selinux_states = { SELINUX_DISABLED: "disabled",
-                   SELINUX_ENFORCING: "enforcing",
-                   SELINUX_PERMISSIVE: "permissive" }
-
-class Security:
-    def __init__(self):
-        self.auth = "--enableshadow --passalgo=sha512 --enablefingerprint"
-
-        if flags.selinux == 1:
-            self.selinux = SELINUX_ENFORCING
-        else:
-            self.selinux = SELINUX_DISABLED
-
-    def setSELinux(self, val):
-        if not selinux_states.has_key(val):
-            log.error("Tried to set to invalid SELinux state: %s" %(val,))
-            val = SELINUX_DISABLED
-
-        self.selinux = val
-
-    def getSELinux(self):
-        return self.selinux
-
-    def writeKS(self, f):
-        if not selinux_states.has_key(self.selinux):
-            log.error("unknown selinux state: %s" %(self.selinux,))
-            return
-
-	f.write("selinux --%s\n" %(selinux_states[self.selinux],))
-
-        if self.auth.strip() != "":
-            f.write("authconfig %s\n" % self.auth)
-
-    def write(self, instPath):
-        args = []
-
-        if not selinux_states.has_key(self.selinux):
-            log.error("unknown selinux state: %s" %(self.selinux,))
-            return
-
-        args = args + [ "--selinux=%s" %(selinux_states[self.selinux],) ]
-
-        try:
-            iutil.execWithRedirect("/usr/sbin/lokkit", args,
-                                   root = instPath, stdout = "/dev/null",
-                                   stderr = "/dev/null")
-        except RuntimeError, msg:
-            log.error ("lokkit run failed: %s" %(msg,))
-        except OSError as e:
-            log.error ("lokkit run failed: %s" % e.strerror)
-
-        args = ["--update", "--nostart"] + shlex.split(self.auth)
-
-        try:
-            iutil.execWithRedirect("/usr/sbin/authconfig", args,
-                                   stdout = "/dev/tty5", stderr = "/dev/tty5",
-                                   root = instPath)
-        except RuntimeError, msg:
-                log.error("Error running %s: %s", args, msg)
diff --git a/simpleconfig.py b/simpleconfig.py
deleted file mode 100644
index b3e6c90..0000000
--- a/simpleconfig.py
+++ /dev/null
@@ -1,88 +0,0 @@
-#
-# simpleconifg.py - representation of a simple configuration file (sh-like)
-#
-# Matt Wilson <msw@xxxxxxxxxx>
-# Jeremy Katz <katzj@xxxxxxxxxx>
-#
-# Copyright 1999-2002 Red Hat, Inc.
-#
-# This software may be freely redistributed under the terms of the GNU
-# library public license.
-#
-# You should have received a copy of the GNU Library Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-#
-
-import string
-import os
-
-# use our own ASCII only uppercase function to avoid locale issues
-# not going to be fast but not important
-def uppercase_ASCII_string(str):
-    newstr = ""
-    for i in range(0,len(str)):
-	if str[i] in string.lowercase:
-	    newstr += chr(ord(str[i])-32)
-	else:
-	    newstr += str[i]
-
-    return newstr
-
-class SimpleConfigFile:
-    def __str__ (self):
-        s = ""
-        keys = self.info.keys ()
-        keys.sort ()
-        for key in keys:
-            # FIXME - use proper escaping
-            if type (self.info[key]) == type(""):
-                s = s + key + "=\"" + self.info[key] + "\"\n"
-        return s
-
-    def __init__ (self):
-        self.info = {}
-
-    def write(self, file):
-        f = open(file, "w")
-        f.write(self.__str__())
-        f.close()
-
-    def read(self, file):
-        if not os.access(file, os.R_OK):
-            return
-
-        f = open(file, "r")
-        lines = f.readlines()
-        f.close()
-
-        for line in lines:
-            fields = line[:-1].split('=', 2)
-            if len(fields) < 2:
-                # how am I supposed to know what to do here?
-                continue
-            key = uppercase_ASCII_string(fields[0])
-            value = fields[1]
-            # XXX hack
-            value = value.replace('"', '')
-            value = value.replace("'", '')
-            self.info[key] = value
-
-    def set (self, *args):
-        for (key, data) in args:
-            self.info[uppercase_ASCII_string(key)] = data
-
-    def unset (self, *keys):
-        for key in keys:
-            key = uppercase_ASCII_string(key)
-            if self.info.has_key (key):
-               del self.info[key]
-
-    def get (self, key):
-        key = uppercase_ASCII_string(key)
-        if self.info.has_key (key):
-            return self.info[key]
-        else:
-            return ""
-
-
diff --git a/sitecustomize.py b/sitecustomize.py
deleted file mode 100644
index 8246ed0..0000000
--- a/sitecustomize.py
+++ /dev/null
@@ -1,22 +0,0 @@
-#
-# sitecustomize.py: The python site init code for the Red Hat Installer
-#
-# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007
-# Red Hat, Inc.  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 as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# 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, see <http://www.gnu.org/licenses/>.
-#
-
-import sys
-sys.setdefaultencoding('utf-8')
diff --git a/sortedtransaction.py b/sortedtransaction.py
deleted file mode 100644
index d7384bb..0000000
--- a/sortedtransaction.py
+++ /dev/null
@@ -1,87 +0,0 @@
-#
-# sortedtransaction.py
-#
-# Copyright (C) 2007  Red Hat, Inc.  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 as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# 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, see <http://www.gnu.org/licenses/>.
-#
-
-from yum.transactioninfo import TransactionData, TransactionMember, SortableTransactionData
-from yum.constants import *
-from yum.Errors import YumBaseError
-
-import urlparse
-urlparse.uses_fragment.append('media')
-
-import logging
-log = logging.getLogger("anaconda")
-
-
-class SplitMediaTransactionData(SortableTransactionData):
-    def __init__(self):
-        SortableTransactionData.__init__(self)
-        self.reqmedia = {}
-        self.curmedia = 0 
-
-    def __getMedia(self, po):
-        try:
-            uri = po.returnSimple('basepath')
-            (scheme, netloc, path, query, fragid) = urlparse.urlsplit(uri)
-            if scheme != "media" or not fragid:
-                return -99
-            else:
-                return int(fragid)
-        except (KeyError, AttributeError):
-            return -99
-
-    def getMembers(self, pkgtup=None):
-        if not self.curmedia:
-            return TransactionData.getMembers(self, pkgtup)
-        if pkgtup is None:
-            returnlist = []
-            for ele in self.reqmedia[self.curmedia]:
-                returnlist.extend(self.pkgdict[ele])
-
-            return returnlist
-
-        if pkgtup in self.reqmedia[self.curmedia]:
-            return self.pkgdict[pkgtup]
-        else:
-            return []
-
-    def add(self, txmember):
-        if txmember.output_state in TS_INSTALL_STATES:
-            id = self.__getMedia(txmember.po)
-            if id:
-                if id not in self.reqmedia.keys():
-                    self.reqmedia[id] = [ txmember.pkgtup ]
-                elif txmember.pkgtup not in self.reqmedia[id]:
-                    self.reqmedia[id].append(txmember.pkgtup)
-        SortableTransactionData.add(self, txmember)
-
-    def remove(self, pkgtup):
-        if not self.pkgdict.has_key(pkgtup):
-            return
-        txmembers = self.pkgdict[pkgtup]
-        if len(txmembers) > 0:
-            for txmbr in txmembers:
-                if txmbr.output_state not in TS_INSTALL_STATES:
-                    continue
-                id = self.__getMedia(txmbr.po)
-                if id:
-                    self.reqmedia[id].remove(pkgtup)
-                    if len(self.reqmedia[id]) == 0:
-                        self.reqmedia.pop(id)
-                del txmbr
-                SortableTransactionData.remove(self, pkgtup)
diff --git a/storage/Makefile.am b/storage/Makefile.am
deleted file mode 100644
index 7347694..0000000
--- a/storage/Makefile.am
+++ /dev/null
@@ -1,26 +0,0 @@
-# storage/Makefile.am for anaconda
-#
-# Copyright (C) 2009  Red Hat, Inc.
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU Lesser General Public License as published
-# by the Free Software Foundation; either version 2.1 of the License, or
-# (at your option) any later version.
-#
-# 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 Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public License
-# along with this program.  If not, see <http://www.gnu.org/licenses/>.
-#
-# Author: David Cantrell <dcantrell@xxxxxxxxxx>
-
-pkgpyexecdir = $(pyexecdir)/py$(PACKAGE_NAME)
-storagedir = $(pkgpyexecdir)/storage
-storage_PYTHON = *.py
-
-SUBDIRS = devicelibs formats
-
-MAINTAINERCLEANFILES = Makefile.in
diff --git a/storage/__init__.py b/storage/__init__.py
deleted file mode 100644
index a5366b0..0000000
--- a/storage/__init__.py
+++ /dev/null
@@ -1,2252 +0,0 @@
-# __init__.py
-# Entry point for anaconda's storage configuration module.
-#
-# Copyright (C) 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, or (at your option) any later version.
-# 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.
-#
-# Red Hat Author(s): Dave Lehman <dlehman@xxxxxxxxxx>
-#
-
-import os
-import time
-import stat
-import errno
-import sys
-import statvfs
-
-import nss.nss
-import parted
-
-import isys
-import iutil
-from constants import *
-from pykickstart.constants import *
-from flags import flags
-
-import storage_log
-from errors import *
-from devices import *
-from devicetree import DeviceTree
-from deviceaction import *
-from formats import getFormat
-from formats import get_device_format_class
-from formats import get_default_filesystem_type
-from devicelibs.lvm import safeLvmName
-from devicelibs.dm import name_from_dm_node
-from devicelibs.crypto import generateBackupPassphrase
-from devicelibs.mpath import MultipathConfigWriter
-from devicelibs.edd import get_edd_dict
-from udev import *
-import iscsi
-import fcoe
-import zfcp
-import dasd
-
-import shelve
-import contextlib
-
-import gettext
-_ = lambda x: gettext.ldgettext("anaconda", x)
-
-import logging
-log = logging.getLogger("storage")
-
-def storageInitialize(anaconda):
-    storage = anaconda.storage
-
-    storage.shutdown()
-
-    if anaconda.dir == DISPATCH_BACK:
-        return
-
-    # touch /dev/.in_sysinit so that /lib/udev/rules.d/65-md-incremental.rules
-    # does not mess with any mdraid sets
-    open("/dev/.in_sysinit", "w")
-
-    # XXX I don't understand why I have to do this, but this is needed to
-    #     populate the udev db
-    udev_trigger(subsystem="block", action="change")
-
-    # Before we set up the storage system, we need to know which disks to
-    # ignore, etc.  Luckily that's all in the kickstart data.
-    if anaconda.ksdata:
-        anaconda.storage.zeroMbr = anaconda.ksdata.zerombr.zerombr
-        anaconda.storage.ignoredDisks = anaconda.ksdata.ignoredisk.ignoredisk
-        anaconda.storage.exclusiveDisks = anaconda.ksdata.ignoredisk.onlyuse
-
-        if anaconda.ksdata.clearpart.type is not None:
-            anaconda.storage.clearPartType = anaconda.ksdata.clearpart.type
-            anaconda.storage.clearPartDisks = anaconda.ksdata.clearpart.drives
-            if anaconda.ksdata.clearpart.initAll:
-                anaconda.storage.reinitializeDisks = anaconda.ksdata.clearpart.initAll
-
-    anaconda.intf.resetInitializeDiskQuestion()
-    anaconda.intf.resetReinitInconsistentLVMQuestion()
-
-    # Set up the protected partitions list now.
-    if anaconda.protected:
-        storage.protectedDevSpecs.extend(anaconda.protected)
-        storage.reset()
-
-        if not flags.livecdInstall and not storage.protectedDevices:
-            if anaconda.upgrade:
-                return
-            else:
-                anaconda.intf.messageWindow(_("Unknown Device"),
-                    _("The installation source given by device %s "
-                      "could not be found.  Please check your "
-                      "parameters and try again.") % anaconda.protected,
-                    type="custom", custom_buttons = [_("_Exit installer")])
-                sys.exit(1)
-    else:
-        storage.reset()
-
-    if not storage.disks:
-        rc = anaconda.intf.messageWindow(_("No disks found"),
-                _("No usable disks have been found."),
-                type="custom",
-                custom_buttons = [_("Back"), _("_Exit installer")],
-                default=0)
-        if rc == 0:
-            return DISPATCH_BACK
-        sys.exit(1)
-
-# dispatch.py helper function
-def storageComplete(anaconda):
-    if anaconda.dir == DISPATCH_BACK:
-        rc = anaconda.intf.messageWindow(_("Installation cannot continue."),
-                                _("The storage configuration you have "
-                                  "chosen has already been activated. You "
-                                  "can no longer return to the disk editing "
-                                  "screen. Would you like to continue with "
-                                  "the installation process?"),
-                                type = "yesno")
-        if rc == 0:
-            sys.exit(0)
-        return DISPATCH_FORWARD
-
-    devs = anaconda.storage.devicetree.getDevicesByType("luks/dm-crypt")
-    existing_luks = False
-    new_luks = False
-    for dev in devs:
-        if dev.exists:
-            existing_luks = True
-        else:
-            new_luks = True
-
-    if (anaconda.storage.encryptedAutoPart or new_luks) and \
-       not anaconda.storage.encryptionPassphrase:
-        while True:
-            (passphrase, retrofit) = anaconda.intf.getLuksPassphrase(preexist=existing_luks)
-            if passphrase:
-                anaconda.storage.encryptionPassphrase = passphrase
-                anaconda.storage.encryptionRetrofit = retrofit
-                break
-            else:
-                rc = anaconda.intf.messageWindow(_("Encrypt device?"),
-                            _("You specified block device encryption "
-                              "should be enabled, but you have not "
-                              "supplied a passphrase. If you do not "
-                              "go back and provide a passphrase, "
-                              "block device encryption will be "
-                              "disabled."),
-                              type="custom",
-                              custom_buttons=[_("Back"), _("Continue")],
-                              default=0)
-                if rc == 1:
-                    log.info("user elected to not encrypt any devices.")
-                    undoEncryption(anaconda.storage)
-                    anaconda.storage.encryptedAutoPart = False
-                    break
-
-    if anaconda.storage.encryptionPassphrase:
-        for dev in anaconda.storage.devices:
-            if dev.format.type == "luks" and not dev.format.exists:
-                dev.format.passphrase = anaconda.storage.encryptionPassphrase
-
-    if anaconda.ksdata:
-        return
-
-    rc = anaconda.intf.messageWindow(_("Confirm"),
-                                _("The partitioning options you have selected "
-                                  "will now be written to disk.  Any "
-                                  "data on deleted or reformatted partitions "
-                                  "will be lost."),
-                                type = "custom", custom_icon="warning",
-                                custom_buttons=[_("Go _Back"),
-                                                _("_Write Changes to Disk")],
-                                default = 0)
-
-    # Make sure that all is down, even the disks that we setup after popluate.
-    anaconda.storage.devicetree.teardownAll()
-
-    if rc == 0:
-        return DISPATCH_BACK
-
-def writeEscrowPackets(anaconda):
-    escrowDevices = filter(lambda d: d.format.type == "luks" and \
-                                     d.format.escrow_cert,
-                           anaconda.storage.devices)
-
-    if not escrowDevices:
-        return
-
-    log.debug("escrow: writeEscrowPackets start")
-
-    wait_win = anaconda.intf.waitWindow(_("Running..."),
-                                        _("Storing encryption keys"))
-
-    nss.nss.nss_init_nodb() # Does nothing if NSS is already initialized
-
-    backupPassphrase = generateBackupPassphrase()
-    try:
-        for device in escrowDevices:
-            log.debug("escrow: device %s: %s" %
-                      (repr(device.path), repr(device.format.type)))
-            device.format.escrow(anaconda.rootPath + "/root",
-                                 backupPassphrase)
-
-        wait_win.pop()
-    except (IOError, RuntimeError) as e:
-        wait_win.pop()
-        anaconda.intf.messageWindow(_("Error"),
-                                    _("Error storing an encryption key: "
-                                      "%s\n") % str(e), type="custom",
-                                    custom_icon="error",
-                                    custom_buttons=[_("_Exit installer")])
-        sys.exit(1)
-
-    log.debug("escrow: writeEscrowPackets done")
-
-
-def undoEncryption(storage):
-    for device in storage.devicetree.getDevicesByType("luks/dm-crypt"):
-        if device.exists:
-            continue
-
-        slave = device.slave
-        format = device.format
-
-        # set any devices that depended on the luks device to now depend on
-        # the former slave device
-        for child in storage.devicetree.getChildren(device):
-            child.parents.remove(device)
-            device.removeChild()
-            child.parents.append(slave)
-
-        storage.devicetree.registerAction(ActionDestroyFormat(device))
-        storage.devicetree.registerAction(ActionDestroyDevice(device))
-        storage.devicetree.registerAction(ActionDestroyFormat(slave))
-        storage.devicetree.registerAction(ActionCreateFormat(slave, format))
-
-class Storage(object):
-    def __init__(self, anaconda):
-        self.anaconda = anaconda
-
-        # storage configuration variables
-        self.ignoredDisks = []
-        self.exclusiveDisks = []
-        self.doAutoPart = False
-        self.clearPartType = None
-        self.clearPartDisks = []
-        self.encryptedAutoPart = False
-        self.encryptionPassphrase = None
-        self.escrowCertificates = {}
-        self.autoPartEscrowCert = None
-        self.autoPartAddBackupPassphrase = False
-        self.encryptionRetrofit = False
-        self.reinitializeDisks = False
-        self.zeroMbr = None
-        self.protectedDevSpecs = []
-        self.autoPartitionRequests = []
-        self.eddDict = {}
-
-        self.__luksDevs = {}
-
-        self.iscsi = iscsi.iscsi()
-        self.fcoe = fcoe.fcoe()
-        self.zfcp = zfcp.ZFCP()
-        self.dasd = dasd.DASD()
-
-        self._nextID = 0
-        self.defaultFSType = get_default_filesystem_type()
-        self.defaultBootFSType = get_default_filesystem_type(boot=True)
-        self._dumpFile = "/tmp/storage.state"
-
-        # these will both be empty until our reset method gets called
-        self.devicetree = DeviceTree(intf=self.anaconda.intf,
-                                     ignored=self.ignoredDisks,
-                                     exclusive=self.exclusiveDisks,
-                                     type=self.clearPartType,
-                                     clear=self.clearPartDisks,
-                                     reinitializeDisks=self.reinitializeDisks,
-                                     protected=self.protectedDevSpecs,
-                                     zeroMbr=self.zeroMbr,
-                                     passphrase=self.encryptionPassphrase,
-                                     luksDict=self.__luksDevs,
-                                     iscsi=self.iscsi,
-                                     dasd=self.dasd)
-        self.fsset = FSSet(self.devicetree, self.anaconda.rootPath)
-
-    def doIt(self):
-        self.devicetree.processActions()
-        self.doEncryptionPassphraseRetrofits()
-
-        # now set the boot partition's flag
-        try:
-            boot = self.anaconda.platform.bootDevice()
-            if boot.type == "mdarray":
-                bootDevs = boot.parents
-            else:
-                bootDevs = [boot]
-        except DeviceError:
-            bootDevs = []
-        else:
-            for dev in bootDevs:
-                if hasattr(dev, "bootable"):
-                    # Dos labels can only have one partition marked as active
-                    # and unmarking ie the windows partition is not a good idea
-                    skip = False
-                    if dev.disk.format.partedDisk.type == "msdos":
-                        for p in dev.disk.format.partedDisk.partitions:
-                            if p.type == parted.PARTITION_NORMAL and \
-                               p.getFlag(parted.PARTITION_BOOT):
-                                skip = True
-                                break
-                    if skip:
-                         log.info("not setting boot flag on %s as there is"
-                                  "another active partition" % dev.name)
-                         continue
-                    log.info("setting boot flag on %s" % dev.name)
-                    dev.bootable = True
-                    dev.disk.setup()
-                    dev.disk.format.commitToDisk()
-
-        self.dumpState("final")
-
-    @property
-    def nextID(self):
-        id = self._nextID
-        self._nextID += 1
-        return id
-
-    def shutdown(self):
-        try:
-            self.devicetree.teardownAll()
-        except Exception as e:
-            log.error("failure tearing down device tree: %s" % e)
-
-        self.zfcp.shutdown()
-
-        # TODO: iscsi.shutdown()
-
-    def reset(self):
-        """ Reset storage configuration to reflect actual system state.
-
-            This should rescan from scratch but not clobber user-obtained
-            information like passphrases, iscsi config, &c
-
-        """
-        # save passphrases for luks devices so we don't have to reprompt
-        self.encryptionPassphrase = None
-        for device in self.devices:
-            if device.format.type == "luks" and device.format.exists:
-                self.__luksDevs[device.format.uuid] = device.format._LUKS__passphrase
-
-        w = self.anaconda.intf.waitWindow(_("Finding Devices"),
-                                          _("Finding storage devices"))
-        self.iscsi.startup(self.anaconda.intf)
-        self.fcoe.startup(self.anaconda.intf)
-        self.zfcp.startup()
-        self.dasd.startup(self.anaconda.intf, self.exclusiveDisks, self.zeroMbr)
-        if self.anaconda.upgrade:
-            clearPartType = CLEARPART_TYPE_NONE
-        else:
-            clearPartType = self.clearPartType
-
-        self.devicetree = DeviceTree(intf=self.anaconda.intf,
-                                     ignored=self.ignoredDisks,
-                                     exclusive=self.exclusiveDisks,
-                                     type=clearPartType,
-                                     clear=self.clearPartDisks,
-                                     reinitializeDisks=self.reinitializeDisks,
-                                     protected=self.protectedDevSpecs,
-                                     zeroMbr=self.zeroMbr,
-                                     passphrase=self.encryptionPassphrase,
-                                     luksDict=self.__luksDevs,
-                                     iscsi=self.iscsi,
-                                     dasd=self.dasd)
-        self.devicetree.populate()
-        self.fsset = FSSet(self.devicetree, self.anaconda.rootPath)
-        self.eddDict = get_edd_dict(self.partitioned)
-        self.anaconda.rootParts = None
-        self.anaconda.upgradeRoot = None
-        self.dumpState("initial")
-        w.pop()
-
-    @property
-    def devices(self):
-        """ A list of all the devices in the device tree. """
-        devices = self.devicetree.devices
-        devices.sort(key=lambda d: d.name)
-        return devices
-
-    @property
-    def disks(self):
-        """ A list of the disks in the device tree.
-
-            Ignored disks are not included, as are disks with no media present.
-
-            This is based on the current state of the device tree and
-            does not necessarily reflect the actual on-disk state of the
-            system's disks.
-        """
-        disks = []
-        for device in self.devicetree.devices:
-            if device.isDisk:
-                if not device.mediaPresent:
-                    log.info("Skipping disk: %s: No media present" % device.name)
-                    continue
-                disks.append(device)
-        disks.sort(key=lambda d: d.name, cmp=self.compareDisks)
-        return disks
-
-    @property
-    def partitioned(self):
-        """ A list of the partitioned devices in the device tree.
-
-            Ignored devices are not included, nor disks with no media present.
-
-            Devices of types for which partitioning is not supported are also
-            not included.
-
-            This is based on the current state of the device tree and
-            does not necessarily reflect the actual on-disk state of the
-            system's disks.
-        """
-        partitioned = []
-        for device in self.devicetree.devices:
-            if not device.partitioned:
-                continue
-
-            if not device.mediaPresent:
-                log.info("Skipping device: %s: No media present" % device.name)
-                continue
-
-            partitioned.append(device)
-
-        partitioned.sort(key=lambda d: d.name)
-        return partitioned
-
-    @property
-    def partitions(self):
-        """ A list of the partitions in the device tree.
-
-            This is based on the current state of the device tree and
-            does not necessarily reflect the actual on-disk state of the
-            system's disks.
-        """
-        partitions = self.devicetree.getDevicesByInstance(PartitionDevice)
-        partitions.sort(key=lambda d: d.name)
-        return partitions
-
-    @property
-    def vgs(self):
-        """ A list of the LVM Volume Groups in the device tree.
-
-            This is based on the current state of the device tree and
-            does not necessarily reflect the actual on-disk state of the
-            system's disks.
-        """
-        vgs = self.devicetree.getDevicesByType("lvmvg")
-        vgs.sort(key=lambda d: d.name)
-        return vgs
-
-    @property
-    def lvs(self):
-        """ A list of the LVM Logical Volumes in the device tree.
-
-            This is based on the current state of the device tree and
-            does not necessarily reflect the actual on-disk state of the
-            system's disks.
-        """
-        lvs = self.devicetree.getDevicesByType("lvmlv")
-        lvs.sort(key=lambda d: d.name)
-        return lvs
-
-    @property
-    def pvs(self):
-        """ A list of the LVM Physical Volumes in the device tree.
-
-            This is based on the current state of the device tree and
-            does not necessarily reflect the actual on-disk state of the
-            system's disks.
-        """
-        devices = self.devicetree.devices
-        pvs = [d for d in devices if d.format.type == "lvmpv"]
-        pvs.sort(key=lambda d: d.name)
-        return pvs
-
-    def unusedPVs(self, vg=None):
-        unused = []
-        for pv in self.pvs:
-            used = False
-            for _vg in self.vgs:
-                if _vg.dependsOn(pv) and _vg != vg:
-                    used = True
-                    break
-                elif _vg == vg:
-                    break
-            if not used:
-                unused.append(pv)
-        return unused
-
-    @property
-    def mdarrays(self):
-        """ A list of the MD arrays in the device tree.
-
-            This is based on the current state of the device tree and
-            does not necessarily reflect the actual on-disk state of the
-            system's disks.
-        """
-        arrays = self.devicetree.getDevicesByType("mdarray")
-        arrays.sort(key=lambda d: d.name)
-        return arrays
-
-    @property
-    def mdcontainers(self):
-        """ A list of the MD containers in the device tree. """
-        arrays = self.devicetree.getDevicesByType("mdcontainer")
-        arrays.sort(key=lambda d: d.name)
-        return arrays
-
-    @property
-    def mdmembers(self):
-        """ A list of the MD member devices in the device tree.
-
-            This is based on the current state of the device tree and
-            does not necessarily reflect the actual on-disk state of the
-            system's disks.
-        """
-        devices = self.devicetree.devices
-        members = [d for d in devices if d.format.type == "mdmember"]
-        members.sort(key=lambda d: d.name)
-        return members
-
-    def unusedMDMembers(self, array=None):
-        unused = []
-        for member in self.mdmembers:
-            used = False
-            for _array in self.mdarrays + self.mdcontainers:
-                if _array.dependsOn(member) and _array != array:
-                    used = True
-                    break
-                elif _array == array:
-                    break
-            if not used:
-                unused.append(member)
-        return unused
-
-    @property
-    def unusedMDMinors(self):
-        """ Return a list of unused minors for use in RAID. """
-        raidMinors = range(0,32)
-        for array in self.mdarrays + self.mdcontainers:
-            if array.minor is not None and array.minor in raidMinors:
-                raidMinors.remove(array.minor)
-        return raidMinors
-
-    @property
-    def swaps(self):
-        """ A list of the swap devices in the device tree.
-
-            This is based on the current state of the device tree and
-            does not necessarily reflect the actual on-disk state of the
-            system's disks.
-        """
-        devices = self.devicetree.devices
-        swaps = [d for d in devices if d.format.type == "swap"]
-        swaps.sort(key=lambda d: d.name)
-        return swaps
-
-    @property
-    def protectedDevices(self):
-        devices = self.devicetree.devices
-        protected = [d for d in devices if d.protected]
-        protected.sort(key=lambda d: d.name)
-        return protected
-
-    def exceptionDisks(self):
-        """ Return a list of removable devices to save exceptions to.
-
-            FIXME: This raises the problem that the device tree can be
-                   in a state that does not reflect that actual current
-                   state of the system at any given point.
-
-                   We need a way to provide direct scanning of disks,
-                   partitions, and filesystems without relying on the
-                   larger objects' correctness.
-
-                   Also, we need to find devices that have just been made
-                   available for the purpose of storing the exception
-                   report.
-        """
-        # When a usb is connected from before the start of the installation,
-        # it is not correctly detected.
-        udev_trigger(subsystem="block", action="change")
-        self.reset()
-
-        dests = []
-
-        for disk in self.disks:
-            if not disk.removable and \
-                    disk.format is not None  and \
-                    disk.format.mountable:
-                dests.append([disk.path, disk.name])
-
-        for part in self.partitions:
-            if not part.disk.removable:
-                continue
-
-            elif part.partedPartition.active and \
-                    not part.partedPartition.getFlag(parted.PARTITION_RAID) and \
-                    not part.partedPartition.getFlag(parted.PARTITION_LVM) and \
-                    part.format is not None and part.format.mountable:
-                dests.append([part.path, part.name])
-
-        return dests
-
-    def deviceImmutable(self, device, ignoreProtected=False):
-        """ Return any reason the device cannot be modified/removed.
-
-            Return False if the device can be removed.
-
-            Devices that cannot be removed include:
-
-                - protected partitions
-                - devices that are part of an md array or lvm vg
-                - extended partition containing logical partitions that
-                  meet any of the above criteria
-
-        """
-        if not isinstance(device, Device):
-            raise ValueError("arg1 (%s) must be a Device instance" % device)
-
-        if not ignoreProtected and device.protected:
-            return _("This partition is holding the data for the hard "
-                      "drive install.")
-        elif isinstance(device, PartitionDevice) and device.isProtected:
-            # LDL formatted DASDs always have one partition, you'd have to
-            # reformat the DASD in CDL mode to get rid of it
-            return _("You cannot delete a partition of a LDL formatted "
-                     "DASD.")
-        elif device.format.type == "mdmember":
-            for array in self.mdarrays + self.mdcontainers:
-                if array.dependsOn(device):
-                    if array.minor is not None:
-                        return _("This device is part of the RAID "
-                                 "device %s.") % (array.path,)
-                    else:
-                        return _("This device is part of a RAID device.")
-        elif device.format.type == "lvmpv":
-            for vg in self.vgs:
-                if vg.dependsOn(device):
-                    if vg.name is not None:
-                        return _("This device is part of the LVM "
-                                 "volume group '%s'.") % (vg.name,)
-                    else:
-                        return _("This device is part of a LVM volume "
-                                 "group.")
-        elif device.format.type == "luks":
-            try:
-                luksdev = self.devicetree.getChildren(device)[0]
-            except IndexError:
-                pass
-            else:
-                return self.deviceImmutable(luksdev)
-        elif isinstance(device, PartitionDevice) and device.isExtended:
-            reasons = {}
-            for dep in self.deviceDeps(device):
-                reason = self.deviceImmutable(dep)
-                if reason:
-                    reasons[dep.path] = reason
-            if reasons:
-                msg =  _("This device is an extended partition which "
-                         "contains logical partitions that cannot be "
-                         "deleted:\n\n")
-                for dev in reasons:
-                    msg += "%s: %s" % (dev, reasons[dev])
-                return msg
-
-        for i in self.devicetree.immutableDevices:
-            if i[0] == device.name:
-                return i[1]
-
-        return False
-
-    def deviceDeps(self, device):
-        return self.devicetree.getDependentDevices(device)
-
-    def newPartition(self, *args, **kwargs):
-        """ Return a new PartitionDevice instance for configuring. """
-        if kwargs.has_key("fmt_type"):
-            kwargs["format"] = getFormat(kwargs.pop("fmt_type"),
-                                         mountpoint=kwargs.pop("mountpoint",
-                                                               None),
-                                         **kwargs.pop("fmt_args", {}))
-
-        if kwargs.has_key("disks"):
-            parents = kwargs.pop("disks")
-            if isinstance(parents, Device):
-                kwargs["parents"] = [parents]
-            else:
-                kwargs["parents"] = parents
-
-        if kwargs.has_key("name"):
-            name = kwargs.pop("name")
-        else:
-            name = "req%d" % self.nextID
-
-        return PartitionDevice(name, *args, **kwargs)
-
-    def newMDArray(self, *args, **kwargs):
-        """ Return a new MDRaidArrayDevice instance for configuring. """
-        if kwargs.has_key("fmt_type"):
-            kwargs["format"] = getFormat(kwargs.pop("fmt_type"),
-                                         mountpoint=kwargs.pop("mountpoint",
-                                                               None))
-
-        if kwargs.has_key("minor"):
-            kwargs["minor"] = int(kwargs["minor"])
-        else:
-            kwargs["minor"] = self.unusedMDMinors[0]
-
-        if kwargs.has_key("name"):
-            name = kwargs.pop("name")
-        else:
-            name = "md%d" % kwargs["minor"]
-
-        return MDRaidArrayDevice(name, *args, **kwargs)
-
-    def newVG(self, *args, **kwargs):
-        """ Return a new LVMVolumeGroupDevice instance. """
-        pvs = kwargs.pop("pvs", [])
-        for pv in pvs:
-            if pv not in self.devices:
-                raise ValueError("pv is not in the device tree")
-
-        if kwargs.has_key("name"):
-            name = kwargs.pop("name")
-        else:
-            name = self.createSuggestedVGName(self.anaconda.network)
-
-        if name in [d.name for d in self.devices]:
-            raise ValueError("name already in use")
-
-        return LVMVolumeGroupDevice(name, pvs, *args, **kwargs)
-
-    def newLV(self, *args, **kwargs):
-        """ Return a new LVMLogicalVolumeDevice instance. """
-        if kwargs.has_key("vg"):
-            vg = kwargs.pop("vg")
-
-        mountpoint = kwargs.pop("mountpoint", None)
-        if kwargs.has_key("fmt_type"):
-            kwargs["format"] = getFormat(kwargs.pop("fmt_type"),
-                                         mountpoint=mountpoint)
-
-        if kwargs.has_key("name"):
-            name = kwargs.pop("name")
-        else:
-            if kwargs.get("format") and kwargs["format"].type == "swap":
-                swap = True
-            else:
-                swap = False
-            name = self.createSuggestedLVName(vg,
-                                              swap=swap,
-                                              mountpoint=mountpoint)
-
-        if name in [d.name for d in self.devices]:
-            raise ValueError("name already in use")
-
-        return LVMLogicalVolumeDevice(name, vg, *args, **kwargs)
-
-    def createDevice(self, device):
-        """ Schedule creation of a device.
-
-            TODO: We could do some things here like assign the next
-                  available raid minor if one isn't already set.
-        """
-        self.devicetree.registerAction(ActionCreateDevice(device))
-        if device.format.type:
-            self.devicetree.registerAction(ActionCreateFormat(device))
-
-    def destroyDevice(self, device):
-        """ Schedule destruction of a device. """
-        if device.format.exists and device.format.type:
-            # schedule destruction of any formatting while we're at it
-            self.devicetree.registerAction(ActionDestroyFormat(device))
-
-        action = ActionDestroyDevice(device)
-        self.devicetree.registerAction(action)
-
-    def formatDevice(self, device, format):
-        """ Schedule formatting of a device. """
-        self.devicetree.registerAction(ActionDestroyFormat(device))
-        self.devicetree.registerAction(ActionCreateFormat(device, format))
-
-    def formatByDefault(self, device):
-        """Return whether the device should be reformatted by default."""
-        formatlist = ['/boot', '/var', '/tmp', '/usr']
-        exceptlist = ['/home', '/usr/local', '/opt', '/var/www']
-
-        if not device.format.linuxNative:
-            return False
-
-        if device.format.mountable:
-            if not device.format.mountpoint:
-                return False
-
-            if device.format.mountpoint == "/" or \
-               device.format.mountpoint in formatlist:
-                return True
-
-            for p in formatlist:
-                if device.format.mountpoint.startswith(p):
-                    for q in exceptlist:
-                        if device.format.mountpoint.startswith(q):
-                            return False
-                    return True
-        elif device.format.type == "swap":
-            return True
-
-        # be safe for anything else and default to off
-        return False
-
-    def extendedPartitionsSupported(self):
-        """ Return whether any disks support extended partitions."""
-        for disk in self.partitioned:
-            if disk.format.partedDisk.supportsFeature(parted.DISK_TYPE_EXTENDED):
-                return True
-        return False
-
-    def createSuggestedVGName(self, network):
-        """ Return a reasonable, unused VG name. """
-        # try to create a volume group name incorporating the hostname
-        hn = network.hostname
-        vgnames = [vg.name for vg in self.vgs]
-        if hn is not None and hn != '':
-            if hn == 'localhost' or hn == 'localhost.localdomain':
-                vgtemplate = "VolGroup"
-            elif hn.find('.') != -1:
-                template = "vg_%s" % (hn.split('.')[0].lower(),)
-                vgtemplate = safeLvmName(template)
-            else:
-                template = "vg_%s" % (hn.lower(),)
-                vgtemplate = safeLvmName(template)
-        else:
-            vgtemplate = "VolGroup"
-
-        if vgtemplate not in vgnames and \
-                vgtemplate not in lvm.lvm_vg_blacklist:
-            return vgtemplate
-        else:
-            i = 0
-            while 1:
-                tmpname = "%s%02d" % (vgtemplate, i,)
-                if not tmpname in vgnames and \
-                        tmpname not in lvm.lvm_vg_blacklist:
-                    break
-
-                i += 1
-                if i > 99:
-                    tmpname = ""
-
-            return tmpname
-
-    def createSuggestedLVName(self, vg, swap=None, mountpoint=None):
-        """ Return a suitable, unused name for a new logical volume. """
-        # FIXME: this is not at all guaranteed to work
-        if mountpoint:
-            # try to incorporate the mountpoint into the name
-            if mountpoint == '/':
-                lvtemplate = 'lv_root'
-            else:
-                if mountpoint.startswith("/"):
-                    template = "lv_%s" % mountpoint[1:]
-                else:
-                    template = "lv_%s" % (mountpoint,)
-
-                lvtemplate = safeLvmName(template)
-        else:
-            if swap:
-                if len([s for s in self.swaps if s in vg.lvs]):
-                    idx = len([s for s in self.swaps if s in vg.lvs])
-                    while True:
-                        lvtemplate = "lv_swap%02d" % idx
-                        if lvtemplate in [lv.lvname for lv in vg.lvs]:
-                            idx += 1
-                        else:
-                            break
-                else:
-                    lvtemplate = "lv_swap"
-            else:
-                idx = len(vg.lvs)
-                while True:
-                    lvtemplate = "LogVol%02d" % idx
-                    if lvtemplate in [l.lvname for l in vg.lvs]:
-                        idx += 1
-                    else:
-                        break
-
-        return lvtemplate
-
-    def doEncryptionPassphraseRetrofits(self):
-        """ Add the global passphrase to all preexisting LUKS devices.
-
-            This establishes a common passphrase for all encrypted devices
-            in the system so that users only have to enter one passphrase
-            during system boot.
-        """
-        if not self.encryptionRetrofit:
-            return
-
-        for device in self.devices:
-            if device.format.type == "luks" and \
-               device.format._LUKS__passphrase != self.encryptionPassphrase:
-                log.info("adding new passphrase to preexisting encrypted "
-                         "device %s" % device.path)
-                try:
-                    device.format.addPassphrase(self.encryptionPassphrase)
-                except CryptoError:
-                    log.error("failed to add new passphrase to existing "
-                              "device %s" % device.path)
-
-    def sanityCheck(self):
-        """ Run a series of tests to verify the storage configuration.
-
-            This function is called at the end of partitioning so that
-            we can make sure you don't have anything silly (like no /,
-            a really small /, etc).  Returns (errors, warnings) where
-            each is a list of strings.
-        """
-        checkSizes = [('/usr', 250), ('/tmp', 50), ('/var', 384),
-                      ('/home', 100), ('/boot', 75)]
-        warnings = []
-        errors = []
-
-        mustbeonlinuxfs = ['/', '/var', '/tmp', '/usr', '/home', '/usr/share', '/usr/lib']
-        mustbeonroot = ['/bin','/dev','/sbin','/etc','/lib','/root', '/mnt', 'lost+found', '/proc']
-
-        filesystems = self.mountpoints
-        root = self.fsset.rootDevice
-        swaps = self.fsset.swapDevices
-        try:
-            boot = self.anaconda.platform.bootDevice()
-        except DeviceError:
-            boot = None
-
-        if not root:
-            errors.append(_("You have not defined a root partition (/), "
-                            "which is required for installation of %s "
-                            "to continue.") % (productName,))
-
-        if root and root.size < 250:
-            warnings.append(_("Your root partition is less than 250 "
-                              "megabytes which is usually too small to "
-                              "install %s.") % (productName,))
-
-        if (root and
-            root.size < self.anaconda.backend.getMinimumSizeMB("/")):
-            errors.append(_("Your / partition is less than %(min)s "
-                            "MB which is lower than recommended "
-                            "for a normal %(productName)s install.")
-                          % {'min': self.anaconda.backend.getMinimumSizeMB("/"),
-                             'productName': productName})
-
-        # livecds have to have the rootfs type match up
-        if (root and
-            self.anaconda.backend.rootFsType and
-            root.format.type != self.anaconda.backend.rootFsType):
-            errors.append(_("Your / partition does not match the "
-                            "the live image you are installing from.  "
-                            "It must be formatted as %s.")
-                          % (self.anaconda.backend.rootFsType,))
-
-        for (mount, size) in checkSizes:
-            if mount in filesystems and filesystems[mount].size < size:
-                warnings.append(_("Your %(mount)s partition is less than "
-                                  "%(size)s megabytes which is lower than "
-                                  "recommended for a normal %(productName)s "
-                                  "install.")
-                                % {'mount': mount, 'size': size,
-                                   'productName': productName})
-
-        usb_disks = []
-        firewire_disks = []
-        for disk in self.disks:
-            if isys.driveUsesModule(disk.name, ["usb-storage", "ub"]):
-                usb_disks.append(disk)
-            elif isys.driveUsesModule(disk.name, ["sbp2", "firewire-sbp2"]):
-                firewire_disks.append(disk)
-
-        uses_usb = False
-        uses_firewire = False
-        for device in filesystems.values():
-            for disk in usb_disks:
-                if device.dependsOn(disk):
-                    uses_usb = True
-                    break
-
-            for disk in firewire_disks:
-                if device.dependsOn(disk):
-                    uses_firewire = True
-                    break
-
-        if uses_usb:
-            warnings.append(_("Installing on a USB device.  This may "
-                              "or may not produce a working system."))
-        if uses_firewire:
-            warnings.append(_("Installing on a FireWire device.  This may "
-                              "or may not produce a working system."))
-
-        errors.extend(self.anaconda.platform.checkBootRequest(boot))
-
-        if not swaps:
-            if iutil.memInstalled() < isys.EARLY_SWAP_RAM:
-                errors.append(_("You have not specified a swap partition.  "
-                                "Due to the amount of memory present, a "
-                                "swap partition is required to complete "
-                                "installation."))
-            else:
-                warnings.append(_("You have not specified a swap partition.  "
-                                  "Although not strictly required in all cases, "
-                                  "it will significantly improve performance "
-                                  "for most installations."))
-
-        for (mountpoint, dev) in filesystems.items():
-            if mountpoint in mustbeonroot:
-                errors.append(_("This mount point is invalid.  The %s directory must "
-                                "be on the / file system.") % mountpoint)
-
-            if mountpoint in mustbeonlinuxfs and (not dev.format.mountable or not dev.format.linuxNative):
-                errors.append(_("The mount point %s must be on a linux file system.") % mountpoint)
-
-        return (errors, warnings)
-
-    def isProtected(self, device):
-        """ Return True is the device is protected. """
-        return device.protected
-
-    def checkNoDisks(self):
-        """Check that there are valid disk devices."""
-        if not self.disks:
-            self.anaconda.intf.messageWindow(_("No Drives Found"),
-                               _("An error has occurred - no valid devices were "
-                                 "found on which to create new file systems. "
-                                 "Please check your hardware for the cause "
-                                 "of this problem."))
-            return True
-        return False
-
-    def dumpState(self, suffix):
-        """ Dump the current device list to the storage shelf. """
-        key = "devices.%d.%s" % (time.time(), suffix)
-        with contextlib.closing(shelve.open(self._dumpFile)) as shelf:
-            shelf[key] = [d.dict for d in self.devices]
-
-    def write(self, instPath):
-        self.fsset.write(instPath)
-        self.iscsi.write(instPath, self.anaconda)
-        self.fcoe.write(instPath, self.anaconda)
-        self.zfcp.write(instPath)
-        self.dasd.write(instPath)
-
-    def writeKS(self, f):
-        def useExisting(lst):
-            foundCreateDevice = False
-            foundCreateFormat = False
-
-            for l in lst:
-                if isinstance(l, ActionCreateDevice):
-                    foundCreateDevice = True
-                elif isinstance(l, ActionCreateFormat):
-                    foundCreateFormat = True
-
-            return (foundCreateFormat and not foundCreateDevice)
-
-        log.warning("Storage.writeKS not completely implemented")
-        f.write("# The following is the partition information you requested\n")
-        f.write("# Note that any partitions you deleted are not expressed\n")
-        f.write("# here so unless you clear all partitions first, this is\n")
-        f.write("# not guaranteed to work\n")
-
-        # clearpart
-        if self.clearPartType is None or self.clearPartType == CLEARPART_TYPE_NONE:
-            args = ["--none"]
-        elif self.clearPartType == CLEARPART_TYPE_LINUX:
-            args = ["--linux"]
-        else:
-            args = ["--all"]
-
-        if self.clearPartDisks:
-            args += ["--drives=%s" % ",".join(self.clearPartDisks)]
-        if self.reinitializeDisks:
-            args += ["--initlabel"]
-
-        f.write("#clearpart %s\n" % " ".join(args))
-
-        # ignoredisks
-        if self.ignoredDisks:
-            f.write("#ignoredisk --drives=%s\n" % ",".join(self.ignoredDisks))
-        elif self.exclusiveDisks:
-            f.write("#ignoredisk --only-use=%s\n" % ",".join(self.exclusiveDisks))
-
-        # the various partitioning commands
-        dict = {}
-        actions = filter(lambda x: x.device.format.type != "luks",
-                         self.devicetree.findActions(type="create"))
-
-        for action in actions:
-            if dict.has_key(action.device.path):
-                dict[action.device.path].append(action)
-            else:
-                dict[action.device.path] = [action]
-
-        for device in self.devices:
-            # If there's no action for the given device, it must be one
-            # we are reusing.
-            if not dict.has_key(device.path):
-                noformat = True
-                preexisting = True
-            else:
-                noformat = False
-                preexisting = useExisting(dict[device.path])
-
-            device.writeKS(f, preexisting=preexisting, noformat=noformat)
-            f.write("\n")
-
-        self.iscsi.writeKS(f)
-        self.fcoe.writeKS(f)
-        self.zfcp.writeKS(f)
-
-    def turnOnSwap(self, upgrading=None):
-        self.fsset.turnOnSwap(self.anaconda, upgrading=upgrading)
-
-    def mountFilesystems(self, raiseErrors=None, readOnly=None, skipRoot=False):
-        self.fsset.mountFilesystems(self.anaconda, raiseErrors=raiseErrors,
-                                    readOnly=readOnly, skipRoot=skipRoot)
-
-    def umountFilesystems(self, ignoreErrors=True, swapoff=True):
-        self.fsset.umountFilesystems(ignoreErrors=ignoreErrors, swapoff=swapoff)
-
-    def parseFSTab(self):
-        self.fsset.parseFSTab()
-
-    def mkDevRoot(self):
-        self.fsset.mkDevRoot()
-
-    def createSwapFile(self, device, size):
-        self.fsset.createSwapFile(device, size)
-
-    @property
-    def fsFreeSpace(self):
-        return self.fsset.fsFreeSpace()
-
-    @property
-    def mtab(self):
-        return self.fsset.mtab()
-
-    @property
-    def mountpoints(self):
-        return self.fsset.mountpoints
-
-    @property
-    def migratableDevices(self):
-        return self.fsset.migratableDevices
-
-    @property
-    def rootDevice(self):
-        return self.fsset.rootDevice
-
-    def compareDisks(self, first, second):
-        if self.eddDict.has_key(first) and self.eddDict.has_key(second):
-            one = self.eddDict[first]
-            two = self.eddDict[second]
-            if (one < two):
-                return -1
-            elif (one > two):
-                return 1
-
-        # if one is in the BIOS and the other not prefer the one in the BIOS
-        if self.eddDict.has_key(first):
-            return -1
-        if self.eddDict.has_key(second):
-            return 1
-
-        if first.startswith("hd"):
-            type1 = 0
-        elif first.startswith("sd"):
-            type1 = 1
-        elif (first.startswith("vd") or first.startswith("xvd")):
-            type1 = -1
-        else:
-            type1 = 2
-
-        if second.startswith("hd"):
-            type2 = 0
-        elif second.startswith("sd"):
-            type2 = 1
-        elif (second.startswith("vd") or second.startswith("xvd")):
-            type2 = -1
-        else:
-            type2 = 2
-
-        if (type1 < type2):
-            return -1
-        elif (type1 > type2):
-            return 1
-        else:
-            len1 = len(first)
-            len2 = len(second)
-
-            if (len1 < len2):
-                return -1
-            elif (len1 > len2):
-                return 1
-            else:
-                if (first < second):
-                    return -1
-                elif (first > second):
-                    return 1
-
-        return 0
-
-def getReleaseString(mountpoint):
-    relName = None
-    relVer = None
-
-    filename = "%s/etc/redhat-release" % mountpoint
-    if os.access(filename, os.R_OK):
-        with open(filename) as f:
-            try:
-                relstr = f.readline().strip()
-            except (IOError, AttributeError):
-                relstr = ""
-
-        # get the release name and version
-        # assumes that form is something
-        # like "Red Hat Linux release 6.2 (Zoot)"
-        (product, sep, version) = relstr.partition(" release ")
-        if sep:
-            relName = product
-            relVer = version.split()[0]
-
-    return (relName, relVer)
-
-def findExistingRootDevices(anaconda, upgradeany=False):
-    """ Return a list of all root filesystems in the device tree. """
-    rootDevs = []
-
-    if not os.path.exists(anaconda.rootPath):
-        iutil.mkdirChain(anaconda.rootPath)
-
-    roots = []
-    for device in anaconda.storage.devicetree.leaves:
-        if not device.format.linuxNative or not device.format.mountable:
-            continue
-
-        if device.protected:
-            # can't upgrade the part holding hd: media so why look at it?
-            continue
-
-        try:
-            device.setup()
-        except Exception as e:
-            log.warning("setup of %s failed: %s" % (device.name, e))
-            continue
-
-        try:
-            device.format.mount(options="ro", mountpoint=anaconda.rootPath)
-        except Exception as e:
-            log.warning("mount of %s as %s failed: %s" % (device.name,
-                                                          device.format.type,
-                                                          e))
-            device.teardown()
-            continue
-
-        if os.access(anaconda.rootPath + "/etc/fstab", os.R_OK):
-            (product, version) = getReleaseString(anaconda.rootPath)
-            if upgradeany or \
-               anaconda.instClass.productUpgradable(product, version):
-                rootDevs.append((device, "%s %s" % (product, version)))
-            else:
-                log.info("product %s version %s found on %s is not upgradable"
-                         % (product, version, device.name))
-
-        # this handles unmounting the filesystem
-        device.teardown(recursive=True)
-
-    return rootDevs
-
-def mountExistingSystem(anaconda, rootEnt,
-                        allowDirty=None, warnDirty=None,
-                        readOnly=None):
-    """ Mount filesystems specified in rootDevice's /etc/fstab file. """
-    rootDevice = rootEnt[0]
-    rootPath = anaconda.rootPath
-    fsset = anaconda.storage.fsset
-    if readOnly:
-        readOnly = "ro"
-    else:
-        readOnly = ""
-
-    if rootDevice.protected and os.path.ismount("/mnt/isodir"):
-        isys.mount("/mnt/isodir",
-                   rootPath,
-                   fstype=rootDevice.format.type,
-                   bindMount=True)
-    else:
-        rootDevice.setup()
-        rootDevice.format.mount(chroot=rootPath,
-                                mountpoint="/",
-                                options=readOnly)
-
-    fsset.parseFSTab()
-
-    # check for dirty filesystems
-    dirtyDevs = []
-    for device in fsset.devices:
-        if not hasattr(device.format, "isDirty"):
-            continue
-
-        try:
-            device.setup()
-        except DeviceError as e:
-            # we'll catch this in the main loop
-            continue
-
-        if device.format.isDirty:
-            log.info("%s contains a dirty %s filesystem" % (device.path,
-                                                            device.format.type))
-            dirtyDevs.append(device.path)
-
-    messageWindow = anaconda.intf.messageWindow
-    if not allowDirty and dirtyDevs:
-        messageWindow(_("Dirty File Systems"),
-                      _("The following file systems for your Linux system "
-                        "were not unmounted cleanly.  Please boot your "
-                        "Linux installation, let the file systems be "
-                        "checked and shut down cleanly to upgrade.\n"
-                        "%s") % "\n".join(dirtyDevs))
-        anaconda.storage.devicetree.teardownAll()
-        sys.exit(0)
-    elif warnDirty and dirtyDevs:
-        rc = messageWindow(_("Dirty File Systems"),
-                           _("The following file systems for your Linux "
-                             "system were not unmounted cleanly.  Would "
-                             "you like to mount them anyway?\n"
-                             "%s") % "\n".join(dirtyDevs),
-                             type = "yesno")
-        if rc == 0:
-            return -1
-
-    fsset.mountFilesystems(anaconda, readOnly=readOnly, skipRoot=True)
-
-
-class BlkidTab(object):
-    """ Dictionary-like interface to blkid.tab with device path keys """
-    def __init__(self, chroot=""):
-        self.chroot = chroot
-        self.devices = {}
-
-    def parse(self):
-        path = "%s/etc/blkid/blkid.tab" % self.chroot
-        log.debug("parsing %s" % path)
-        with open(path) as f:
-            for line in f.readlines():
-                # this is pretty ugly, but an XML parser is more work than
-                # is justifiable for this purpose
-                if not line.startswith("<device "):
-                    continue
-
-                line = line[len("<device "):-len("</device>\n")]
-                (data, sep, device) = line.partition(">")
-                if not device:
-                    continue
-
-                self.devices[device] = {}
-                for pair in data.split():
-                    try:
-                        (key, value) = pair.split("=")
-                    except ValueError:
-                        continue
-
-                    self.devices[device][key] = value[1:-1] # strip off quotes
-
-    def __getitem__(self, key):
-        return self.devices[key]
-
-    def get(self, key, default=None):
-        return self.devices.get(key, default)
-
-
-class CryptTab(object):
-    """ Dictionary-like interface to crypttab entries with map name keys """
-    def __init__(self, devicetree, blkidTab=None, chroot=""):
-        self.devicetree = devicetree
-        self.blkidTab = blkidTab
-        self.chroot = chroot
-        self.mappings = {}
-
-    def parse(self, chroot=""):
-        """ Parse /etc/crypttab from an existing installation. """
-        if not chroot or not os.path.isdir(chroot):
-            chroot = ""
-
-        path = "%s/etc/crypttab" % chroot
-        log.debug("parsing %s" % path)
-        with open(path) as f:
-            if not self.blkidTab:
-                try:
-                    self.blkidTab = BlkidTab(chroot=chroot)
-                    self.blkidTab.parse()
-                except Exception:
-                    self.blkidTab = None
-
-            for line in f.readlines():
-                (line, pound, comment) = line.partition("#")
-                fields = line.split()
-                if not 2 <= len(fields) <= 4:
-                    continue
-                elif len(fields) == 2:
-                    fields.extend(['none', ''])
-                elif len(fields) == 3:
-                    fields.append('')
-
-                (name, devspec, keyfile, options) = fields
-
-                # resolve devspec to a device in the tree
-                device = self.devicetree.resolveDevice(devspec,
-                                                       blkidTab=self.blkidTab)
-                if device:
-                    self.mappings[name] = {"device": device,
-                                           "keyfile": keyfile,
-                                           "options": options}
-
-    def populate(self):
-        """ Populate the instance based on the device tree's contents. """
-        for device in self.devicetree.devices:
-            # XXX should we put them all in there or just the ones that
-            #     are part of a device containing swap or a filesystem?
-            #
-            #       Put them all in here -- we can filter from FSSet
-            if device.format.type != "luks":
-                continue
-
-            key_file = device.format.keyFile
-            if not key_file:
-                key_file = "none"
-
-            options = device.format.options
-            if not options:
-                options = ""
-
-            self.mappings[device.format.mapName] = {"device": device,
-                                                    "keyfile": key_file,
-                                                    "options": options}
-
-    def crypttab(self):
-        """ Write out /etc/crypttab """
-        crypttab = ""
-        for name in self.mappings:
-            entry = self[name]
-            crypttab += "%s UUID=%s %s %s\n" % (name,
-                                                entry['device'].format.uuid,
-                                                entry['keyfile'],
-                                                entry['options'])
-        return crypttab                       
-
-    def __getitem__(self, key):
-        return self.mappings[key]
-
-    def get(self, key, default=None):
-        return self.mappings.get(key, default)
-
-def get_containing_device(path, devicetree):
-    """ Return the device that a path resides on. """
-    if not os.path.exists(path):
-        return None
-
-    st = os.stat(path)
-    major = os.major(st.st_dev)
-    minor = os.minor(st.st_dev)
-    link = "/sys/dev/block/%s:%s" % (major, minor)
-    if not os.path.exists(link):
-        return None
-
-    try:
-        device_name = os.path.basename(os.readlink(link))
-    except Exception:
-        return None
-
-    if device_name.startswith("dm-"):
-        # have I told you lately that I love you, device-mapper?
-        device_name = name_from_dm_node(device_name)
-
-    return devicetree.getDeviceByName(device_name)
-
-
-class FSSet(object):
-    """ A class to represent a set of filesystems. """
-    def __init__(self, devicetree, rootpath):
-        self.devicetree = devicetree
-        self.rootpath = rootpath
-        self.cryptTab = None
-        self.blkidTab = None
-        self.origFStab = None
-        self.active = False
-        self._dev = None
-        self._devpts = None
-        self._sysfs = None
-        self._proc = None
-        self._devshm = None
-        self.preserveLines = []     # lines we just ignore and preserve
-
-    @property
-    def sysfs(self):
-        if not self._sysfs:
-            self._sysfs = NoDevice(format=getFormat("sysfs",
-                                                    device="sys",
-                                                    mountpoint="/sys"))
-        return self._sysfs
-
-    @property
-    def dev(self):
-        if not self._dev:
-            self._dev = DirectoryDevice("/dev", format=getFormat("bind",
-                                                                 device="/dev",
-                                                                 mountpoint="/dev",
-                                                                 exists=True),
-                                        exists=True)
-
-        return self._dev
-
-    @property
-    def devpts(self):
-        if not self._devpts:
-            self._devpts = NoDevice(format=getFormat("devpts",
-                                                     device="devpts",
-                                                     mountpoint="/dev/pts"))
-        return self._devpts
-
-    @property
-    def proc(self):
-        if not self._proc:
-            self._proc = NoDevice(format=getFormat("proc",
-                                                   device="proc",
-                                                   mountpoint="/proc"))
-        return self._proc
-
-    @property
-    def devshm(self):
-        if not self._devshm:
-            self._devshm = NoDevice(format=getFormat("tmpfs",
-                                                     device="tmpfs",
-                                                     mountpoint="/dev/shm"))
-        return self._devshm
-
-    @property
-    def devices(self):
-        return sorted(self.devicetree.devices, key=lambda d: d.path)
-
-    @property
-    def mountpoints(self):
-        filesystems = {}
-        for device in self.devices:
-            if device.format.mountable and device.format.mountpoint:
-                filesystems[device.format.mountpoint] = device
-        return filesystems
-
-    def _parseOneLine(self, (devspec, mountpoint, fstype, options, dump, passno)):
-        # find device in the tree
-        device = self.devicetree.resolveDevice(devspec,
-                                               cryptTab=self.cryptTab,
-                                               blkidTab=self.blkidTab)
-        if device:
-            # fall through to the bottom of this block
-            pass
-        elif devspec.startswith("/dev/loop"):
-            # FIXME: create devices.LoopDevice
-            log.warning("completely ignoring your loop mount")
-        elif ":" in devspec and fstype.startswith("nfs"):
-            # NFS -- preserve but otherwise ignore
-            device = NFSDevice(devspec,
-                               format=getFormat(fstype,
-                                                device=devspec))
-        elif devspec.startswith("/") and fstype == "swap":
-            # swap file
-            device = FileDevice(devspec,
-                                parents=get_containing_device(devspec, self.devicetree),
-                                format=getFormat(fstype,
-                                                 device=devspec,
-                                                 exists=True),
-                                exists=True)
-        elif fstype == "bind" or "bind" in options:
-            # bind mount... set fstype so later comparison won't
-            # turn up false positives
-            fstype = "bind"
-
-            # This is probably not going to do anything useful, so we'll
-            # make sure to try again from FSSet.mountFilesystems. The bind
-            # mount targets should be accessible by the time we try to do
-            # the bind mount from there.
-            parents = get_containing_device(devspec, self.devicetree)
-            device = DirectoryDevice(devspec, parents=parents, exists=True)
-            device.format = getFormat("bind",
-                                      device=device.path,
-                                      exists=True)
-        elif mountpoint in ("/proc", "/sys", "/dev/shm", "/dev/pts"):
-            # drop these now -- we'll recreate later
-            return None
-        else:
-            # nodev filesystem -- preserve or drop completely?
-            format = getFormat(fstype)
-            if devspec == "none" or \
-               isinstance(format, get_device_format_class("nodev")):
-                device = NoDevice(format=format)
-            else:
-                device = StorageDevice(devspec, format=format)
-
-        if device is None:
-            log.error("failed to resolve %s (%s) from fstab" % (devspec,
-                                                                fstype))
-            raise UnrecognizedFSTabEntryError()
-
-        if device.format.type is None:
-            log.info("Unrecognized filesystem type for %s (%s)"
-                     % (device.name, fstype))
-            raise UnrecognizedFSTabEntryError()
-
-        # make sure, if we're using a device from the tree, that
-        # the device's format we found matches what's in the fstab
-        fmt = getFormat(fstype, device=device.path)
-        if fmt.type != device.format.type:
-            raise StorageError("scanned format (%s) differs from fstab "
-                        "format (%s)" % (device.format.type, fstype))
-
-        if device.format.mountable:
-            device.format.mountpoint = mountpoint
-            device.format.mountopts = options
-
-        # is this useful?
-        try:
-            device.format.options = options
-        except AttributeError:
-            pass
-
-        return device
-
-    def parseFSTab(self, chroot=None):
-        """ parse /etc/fstab
-
-            preconditions:
-                all storage devices have been scanned, including filesystems
-            postconditions:
-
-            FIXME: control which exceptions we raise
-
-            XXX do we care about bind mounts?
-                how about nodev mounts?
-                loop mounts?
-        """
-        if not chroot or not os.path.isdir(chroot):
-            chroot = self.rootpath
-
-        path = "%s/etc/fstab" % chroot
-        if not os.access(path, os.R_OK):
-            # XXX should we raise an exception instead?
-            log.info("cannot open %s for read" % path)
-            return
-
-        blkidTab = BlkidTab(chroot=chroot)
-        try:
-            blkidTab.parse()
-            log.debug("blkid.tab devs: %s" % blkidTab.devices.keys())
-        except Exception as e:
-            log.info("error parsing blkid.tab: %s" % e)
-            blkidTab = None
-
-        cryptTab = CryptTab(self.devicetree, blkidTab=blkidTab, chroot=chroot)
-        try:
-            cryptTab.parse(chroot=chroot)
-            log.debug("crypttab maps: %s" % cryptTab.mappings.keys())
-        except Exception as e:
-            log.info("error parsing crypttab: %s" % e)
-            cryptTab = None
-
-        self.blkidTab = blkidTab
-        self.cryptTab = cryptTab
-
-        with open(path) as f:
-            log.debug("parsing %s" % path)
-
-            lines = f.readlines()
-
-            # save the original file
-            self.origFStab = ''.join(lines)
-
-            for line in lines:
-                # strip off comments
-                (line, pound, comment) = line.partition("#")
-                fields = line.split()
-
-                if not 4 <= len(fields) <= 6:
-                    continue
-                elif len(fields) == 4:
-                    fields.extend([0, 0])
-                elif len(fields) == 5:
-                    fields.append(0)
-
-                (devspec, mountpoint, fstype, options, dump, passno) = fields
-
-                try:
-                    device = self._parseOneLine((devspec, mountpoint, fstype, options, dump, passno))
-                except UnrecognizedFSTabEntryError:
-                    # just write the line back out as-is after upgrade
-                    self.preserveLines.append(line)
-                    continue
-                except Exception as e:
-                    raise Exception("fstab entry %s is malformed: %s" % (devspec, e))
-
-                if not device:
-                    continue
-
-                if device not in self.devicetree.devices:
-                    try:
-                        self.devicetree._addDevice(device)
-                    except ValueError:
-                        # just write duplicates back out post-install
-                        self.preserveLines.append(line)
-
-    def fsFreeSpace(self, chroot=None):
-        if not chroot:
-            chroot = self.rootpath
-
-        space = []
-        for device in self.devices:
-            if not device.format.mountable or \
-               not device.format.mountpoint or \
-               not device.format.status:
-                continue
-
-            path = "%s/%s" % (chroot, device.format.mountpoint)
-
-            ST_RDONLY = 1   # this should be in python's posix module
-            if not os.path.exists(path) or os.statvfs(path)[statvfs.F_FLAG] & ST_RDONLY:
-                continue
-
-            try:
-                space.append((device.format.mountpoint,
-                              isys.pathSpaceAvailable(path)))
-            except SystemError:
-                log.error("failed to calculate free space for %s" % (device.format.mountpoint,))
-
-        space.sort(key=lambda s: s[1])
-        return space
-
-    def mtab(self):
-        format = "%s %s %s %s 0 0\n"
-        mtab = ""
-        devices = self.mountpoints.values() + self.swapDevices
-        devices.extend([self.devshm, self.devpts, self.sysfs, self.proc])
-        devices.sort(key=lambda d: getattr(d.format, "mountpoint", None))
-        for device in devices:
-            if not device.format.status:
-                continue
-            if not device.format.mountable:
-                continue
-            if device.format.mountpoint:
-                options = device.format.mountopts
-                if options:
-                    options = options.replace("defaults,", "")
-                    options = options.replace("defaults", "")
-
-                if options:
-                    options = "rw," + options
-                else:
-                    options = "rw"
-                mtab = mtab + format % (device.path,
-                                        device.format.mountpoint,
-                                        device.format.type,
-                                        options)
-        return mtab
-
-    def turnOnSwap(self, anaconda, upgrading=None):
-        def swapErrorDialog(msg, device):
-            if not anaconda.intf:
-                sys.exit(0)
-
-            buttons = [_("Skip"), _("Format"), _("_Exit")]
-            ret = anaconda.intf.messageWindow(_("Error"), msg, type="custom",
-                                              custom_buttons=buttons,
-                                              custom_icon="warning")
-
-            if ret == 0:
-                self.devicetree._removeDevice(device)
-                return False
-            elif ret == 1:
-                device.format.create(force=True)
-                return True
-            else:
-                sys.exit(0)
-
-        for device in self.swapDevices:
-            if isinstance(device, FileDevice):
-                # set up FileDevices' parents now that they are accessible
-                targetDir = "%s/%s" % (anaconda.rootPath, device.path)
-                parent = get_containing_device(targetDir, self.devicetree)
-                if not parent:
-                    log.error("cannot determine which device contains "
-                              "directory %s" % device.path)
-                    device.parents = []
-                    self.devicetree._removeDevice(device)
-                    continue
-                else:
-                    device.parents = [parent]
-
-            while True:
-                try:
-                    device.setup()
-                    device.format.setup()
-                except OldSwapError:
-                    msg = _("The swap device:\n\n     %s\n\n"
-                            "is an old-style Linux swap partition.  If "
-                            "you want to use this device for swap space, "
-                            "you must reformat as a new-style Linux swap "
-                            "partition.") \
-                          % device.path
-
-                    if swapErrorDialog(msg, device):
-                        continue
-                except SuspendError:
-                    if upgrading:
-                        msg = _("The swap device:\n\n     %s\n\n"
-                                "in your /etc/fstab file is currently in "
-                                "use as a software suspend device, "
-                                "which means your system is hibernating. "
-                                "To perform an upgrade, please shut down "
-                                "your system rather than hibernating it.") \
-                              % device.path
-                    else:
-                        msg = _("The swap device:\n\n     %s\n\n"
-                                "in your /etc/fstab file is currently in "
-                                "use as a software suspend device, "
-                                "which means your system is hibernating. "
-                                "If you are performing a new install, "
-                                "make sure the installer is set "
-                                "to format all swap devices.") \
-                              % device.path
-
-                    if swapErrorDialog(msg, device):
-                        continue
-                except UnknownSwapError:
-                    msg = _("The swap device:\n\n     %s\n\n"
-                            "does not contain a supported swap volume.  In "
-                            "order to continue installation, you will need "
-                            "to format the device or skip it.") \
-                          % device.path
-
-                    if swapErrorDialog(msg, device):
-                        continue
-                except DeviceError as (msg, name):
-                    if anaconda.intf:
-                        if upgrading:
-                            err = _("Error enabling swap device %(name)s: "
-                                    "%(msg)s\n\n"
-                                    "The /etc/fstab on your upgrade partition "
-                                    "does not reference a valid swap "
-                                    "device.\n\nPress OK to exit the "
-                                    "installer") % {'name': name, 'msg': msg}
-                        else:
-                            err = _("Error enabling swap device %(name)s: "
-                                    "%(msg)s\n\n"
-                                    "This most likely means this swap "
-                                    "device has not been initialized.\n\n"
-                                    "Press OK to exit the installer.") % \
-                                  {'name': name, 'msg': msg}
-                        anaconda.intf.messageWindow(_("Error"), err)
-                    sys.exit(0)
-
-                break
-
-    def mountFilesystems(self, anaconda, raiseErrors=None, readOnly=None,
-                         skipRoot=False):
-        intf = anaconda.intf
-        devices = self.mountpoints.values() + self.swapDevices
-        devices.extend([self.dev, self.devshm, self.devpts, self.sysfs, self.proc])
-        devices.sort(key=lambda d: getattr(d.format, "mountpoint", None))
-
-        for device in devices:
-            if not device.format.mountable or not device.format.mountpoint:
-                continue
-
-            if skipRoot and device.format.mountpoint == "/":
-                continue
-
-            options = device.format.options
-            if "noauto" in options.split(","):
-                continue
-
-            if device.format.type == "bind" and device != self.dev:
-                # set up the DirectoryDevice's parents now that they are
-                # accessible
-                #
-                # -- bind formats' device and mountpoint are always both
-                #    under the chroot. no exceptions. none, damn it.
-                targetDir = "%s/%s" % (anaconda.rootPath, device.path)
-                parent = get_containing_device(targetDir, self.devicetree)
-                if not parent:
-                    log.error("cannot determine which device contains "
-                              "directory %s" % device.path)
-                    device.parents = []
-                    self.devicetree._removeDevice(device)
-                    continue
-                else:
-                    device.parents = [parent]
-
-            try:
-                device.setup()
-            except Exception as msg:
-                # FIXME: need an error popup
-                continue
-
-            if readOnly:
-                options = "%s,%s" % (options, readOnly)
-
-            try:
-                device.format.setup(options=options,
-                                    chroot=anaconda.rootPath)
-            except OSError as e:
-                log.error("OSError: (%d) %s" % (e.errno, e.strerror))
-
-                if intf:
-                    if e.errno == errno.EEXIST:
-                        intf.messageWindow(_("Invalid mount point"),
-                                           _("An error occurred when trying "
-                                             "to create %s.  Some element of "
-                                             "this path is not a directory. "
-                                             "This is a fatal error and the "
-                                             "install cannot continue.\n\n"
-                                             "Press <Enter> to exit the "
-                                             "installer.")
-                                           % (device.format.mountpoint,))
-                    else:
-                        na = {'mountpoint': device.format.mountpoint,
-                              'msg': e.strerror}
-                        intf.messageWindow(_("Invalid mount point"),
-                                           _("An error occurred when trying "
-                                             "to create %(mountpoint)s: "
-                                             "%(msg)s.  This is "
-                                             "a fatal error and the install "
-                                             "cannot continue.\n\n"
-                                             "Press <Enter> to exit the "
-                                             "installer.") % na)
-                sys.exit(0)
-            except SystemError as (num, msg):
-                log.error("SystemError: (%d) %s" % (num, msg) )
-
-                if raiseErrors:
-                    raise
-                if intf and not device.format.linuxNative:
-                    na = {'path': device.path,
-                          'mountpoint': device.format.mountpoint}
-                    ret = intf.messageWindow(_("Unable to mount filesystem"),
-                                             _("An error occurred mounting "
-                                             "device %(path)s as "
-                                             "%(mountpoint)s.  You may "
-                                             "continue installation, but "
-                                             "there may be problems.") % na,
-                                             type="custom",
-                                             custom_icon="warning",
-                                             custom_buttons=[_("_Exit installer"),
-                                                            _("_Continue")])
-
-                    if ret == 0:
-                        sys.exit(0)
-                    else:
-                        continue
-
-                sys.exit(0)
-            except FSError as msg:
-                log.error("FSError: %s" % msg)
-
-                if intf:
-                    na = {'path': device.path,
-                          'mountpoint': device.format.mountpoint,
-                          'msg': msg}
-                    intf.messageWindow(_("Unable to mount filesystem"),
-                                       _("An error occurred mounting "
-                                         "device %(path)s as %(mountpoint)s: "
-                                         "%(msg)s. This is "
-                                         "a fatal error and the install "
-                                         "cannot continue.\n\n"
-                                         "Press <Enter> to exit the "
-                                         "installer.") % na)
-                sys.exit(0)
-
-        self.active = True
-
-    def umountFilesystems(self, ignoreErrors=True, swapoff=True):
-        devices = self.mountpoints.values() + self.swapDevices
-        devices.extend([self.dev, self.devshm, self.devpts, self.sysfs, self.proc])
-        devices.sort(key=lambda d: getattr(d.format, "mountpoint", None))
-        devices.reverse()
-        for device in devices:
-            if not device.format.mountable and \
-               (device.format.type != "swap" or swapoff):
-                continue
-
-            device.format.teardown()
-            device.teardown()
-
-        self.active = False
-
-    def createSwapFile(self, device, size, rootPath=None):
-        """ Create and activate a swap file under rootPath. """
-        if not rootPath:
-            rootPath = self.rootpath
-
-        filename = "/SWAP"
-        count = 0
-        basedir = os.path.normpath("%s/%s" % (rootPath,
-                                              device.format.mountpoint))
-        while os.path.exists("%s/%s" % (basedir, filename)) or \
-              self.devicetree.getDeviceByName(filename):
-            file = os.path.normpath("%s/%s" % (basedir, filename))
-            count += 1
-            filename = "/SWAP-%d" % count
-
-        dev = FileDevice(filename,
-                         size=size,
-                         parents=[device],
-                         format=getFormat("swap", device=filename))
-        dev.create()
-        dev.setup()
-        dev.format.create()
-        dev.format.setup()
-        # nasty, nasty
-        self.devicetree._addDevice(dev)
-
-    def mkDevRoot(self, instPath=None):
-        if not instPath:
-            instPath = self.rootpath
-
-        root = self.rootDevice
-        dev = "%s/%s" % (instPath, root.path)
-        if not os.path.exists("%s/dev/root" %(instPath,)) and os.path.exists(dev):
-            rdev = os.stat(dev).st_rdev
-            os.mknod("%s/dev/root" % (instPath,), stat.S_IFBLK | 0600, rdev)
-
-    @property
-    def swapDevices(self):
-        swaps = []
-        for device in self.devices:
-            if device.format.type == "swap":
-                swaps.append(device)
-        return swaps
-
-    @property
-    def rootDevice(self):
-        for path in ["/", self.rootpath]:
-            for device in self.devices:
-                try:
-                    mountpoint = device.format.mountpoint
-                except AttributeError:
-                    mountpoint = None
-
-                if mountpoint == path:
-                    return device
-
-    @property
-    def migratableDevices(self):
-        """ List of devices whose filesystems can be migrated. """
-        migratable = []
-        for device in self.devices:
-            if device.format.migratable and device.format.exists:
-                migratable.append(device)
-
-        return migratable
-
-    def write(self, instPath=None):
-        """ write out all config files based on the set of filesystems """
-        if not instPath:
-            instPath = self.rootpath
-
-        # /etc/fstab
-        fstab_path = os.path.normpath("%s/etc/fstab" % instPath)
-        fstab = self.fstab()
-        open(fstab_path, "w").write(fstab)
-
-        # /etc/crypttab
-        crypttab_path = os.path.normpath("%s/etc/crypttab" % instPath)
-        crypttab = self.crypttab()
-        open(crypttab_path, "w").write(crypttab)
-
-        # /etc/mdadm.conf
-        mdadm_path = os.path.normpath("%s/etc/mdadm.conf" % instPath)
-        mdadm_conf = self.mdadmConf()
-        if mdadm_conf:
-            open(mdadm_path, "w").write(mdadm_conf)
-
-        # /etc/multipath.conf
-        multipath_path = os.path.normpath("%s/etc/multipath.conf" % instPath)
-        multipath_conf = self.multipathConf()
-        if multipath_conf:
-            open(multipath_path, "w").write(multipath_conf)
-
-    def crypttab(self):
-        # if we are upgrading, do we want to update crypttab?
-        # gut reaction says no, but plymouth needs the names to be very
-        # specific for passphrase prompting
-        if not self.cryptTab:
-            self.cryptTab = CryptTab(self.devicetree)
-            self.cryptTab.populate()
-
-        devices = self.mountpoints.values() + self.swapDevices
-
-        # prune crypttab -- only mappings required by one or more entries
-        for name in self.cryptTab.mappings.keys():
-            keep = False
-            mapInfo = self.cryptTab[name]
-            cryptoDev = mapInfo['device']
-            for device in devices:
-                if device == cryptoDev or device.dependsOn(cryptoDev):
-                    keep = True
-                    break
-
-            if not keep:
-                del self.cryptTab.mappings[name]
-
-        return self.cryptTab.crypttab()
-
-    def mdadmConf(self):
-        """ Return the contents of mdadm.conf. """
-        arrays = self.devicetree.getDevicesByType("mdarray")
-        arrays.extend(self.devicetree.getDevicesByType("mdbiosraidarray"))
-        arrays.extend(self.devicetree.getDevicesByType("mdcontainer"))
-        # Sort it, this not only looks nicer, but this will also put
-        # containers (which get md0, md1, etc.) before their members
-        # (which get md127, md126, etc.). and lame as it is mdadm will not
-        # assemble the whole stack in one go unless listed in the proper order
-        # in mdadm.conf
-        arrays.sort(key=lambda d: d.path)
-
-        conf = "# mdadm.conf written out by anaconda\n"
-        conf += "MAILADDR root\n"
-        conf += "AUTO +imsm +1.x -all\n"
-        devices = self.mountpoints.values() + self.swapDevices
-        for array in arrays:
-            for device in devices:
-                if device == array or device.dependsOn(array):
-                    conf += array.mdadmConfEntry
-                    break
-
-        return conf
-
-    def multipathConf(self):
-        """ Return the contents of multipath.conf. """
-        mpaths = self.devicetree.getDevicesByType("dm-multipath")
-        if not mpaths:
-            return None
-        mpaths.sort(key=lambda d: d.name)
-        config = MultipathConfigWriter()
-        whitelist = []
-        for mpath in mpaths:
-            config.addMultipathDevice(mpath)
-            whitelist.append(mpath.name)
-            whitelist.extend([d.name for d in mpath.parents])
-
-        # blacklist everything we're not using and let the
-        # sysadmin sort it out.
-        for d in self.devicetree.devices:
-            if not d.name in whitelist:
-                config.addBlacklistDevice(d)
-
-        return config.write()
-
-    def fstab (self):
-        format = "%-23s %-23s %-7s %-15s %d %d\n"
-        fstab = """
-#
-# /etc/fstab
-# Created by anaconda on %s
-#
-# Accessible filesystems, by reference, are maintained under '/dev/disk'
-# See man pages fstab(5), findfs(8), mount(8) and/or blkid(8) for more info
-#
-""" % time.asctime()
-
-        devices = sorted(self.mountpoints.values(),
-                         key=lambda d: d.format.mountpoint)
-        devices += self.swapDevices
-        devices.extend([self.devshm, self.devpts, self.sysfs, self.proc])
-        netdevs = self.devicetree.getDevicesByInstance(NetworkStorageDevice)
-        for device in devices:
-            # why the hell do we put swap in the fstab, anyway?
-            if not device.format.mountable and device.format.type != "swap":
-                continue
-
-            # Don't write out lines for optical devices, either.
-            if isinstance(device, OpticalDevice):
-                continue
-
-            fstype = getattr(device.format, "mountType", device.format.type)
-            if fstype == "swap":
-                mountpoint = "swap"
-                options = device.format.options
-            else:
-                mountpoint = device.format.mountpoint
-                options = device.format.options
-                if not mountpoint:
-                    log.warning("%s filesystem on %s has no mountpoint" % \
-                                                            (fstype,
-                                                             device.path))
-                    continue
-
-            options = options or "defaults"
-            for netdev in netdevs:
-                if device.dependsOn(netdev):
-                    options = options + ",_netdev"
-                    break
-            devspec = device.fstabSpec
-            dump = device.format.dump
-            if device.format.check and mountpoint == "/":
-                passno = 1
-            elif device.format.check:
-                passno = 2
-            else:
-                passno = 0
-            fstab = fstab + device.fstabComment
-            fstab = fstab + format % (devspec, mountpoint, fstype,
-                                      options, dump, passno)
-
-        # now, write out any lines we were unable to process because of
-        # unrecognized filesystems or unresolveable device specifications
-        for line in self.preserveLines:
-            fstab += line
-
-        return fstab
diff --git a/storage/dasd.py b/storage/dasd.py
deleted file mode 100644
index f113cfb..0000000
--- a/storage/dasd.py
+++ /dev/null
@@ -1,225 +0,0 @@
-#
-# dasd.py - DASD class
-#
-# Copyright (C) 2009, 2010  Red Hat, Inc.  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 as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# 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, see <http://www.gnu.org/licenses/>.
-#
-# Red Hat Author(s): David Cantrell <dcantrell@xxxxxxxxxx>
-#
-
-import iutil
-import sys
-import os
-from storage.errors import DasdFormatError
-from storage.devices import deviceNameToDiskByPath
-from constants import *
-from flags import flags
-
-import logging
-log = logging.getLogger("anaconda")
-
-import gettext
-_ = lambda x: gettext.ldgettext("anaconda", x)
-P_ = lambda x, y, z: gettext.ldngettext("anaconda", x, y, z)
-
-def getDasdPorts():
-    """ Return comma delimited string of valid DASD ports. """
-    ports = []
-
-    f = open("/proc/dasd/devices", "r")
-    lines = map(lambda x: x.strip(), f.readlines())
-    f.close()
-
-    for line in lines:
-        if "unknown" in line:
-            continue
-
-        if "(FBA )" in line or "(ECKD)" in line:
-            ports.append(line.split('(')[0])
-
-    return ','.join(ports)
-
-class DASD:
-    """ Controlling class for DASD interaction before the storage code in
-        anaconda has initialized.
-
-        The DASD class can determine if any DASD devices on the system are
-        unformatted and can perform a dasdfmt on them.
-    """
-
-    def __init__(self):
-        self._dasdlist = []
-        self._devices = []                  # list of DASDDevice objects
-        self.totalCylinders = 0
-        self._completedCylinders = 0.0
-        self._maxFormatJobs = 0
-        self.dasdfmt = "/sbin/dasdfmt"
-        self.commonArgv = ["-y", "-d", "cdl", "-b", "4096"]
-        self.started = False
-
-    def __call__(self):
-        return self
-
-    def startup(self, intf, exclusiveDisks, zeroMbr):
-        """ Look for any unformatted DASDs in the system and offer the user
-            the option for format them with dasdfmt or exit the installer.
-        """
-        if self.started:
-            return
-
-        self.started = True
-        out = "/dev/tty5"
-        err = "/dev/tty5"
-
-        if not iutil.isS390():
-            return
-
-        log.info("Checking for unformatted DASD devices:")
-
-        for device in os.listdir("/sys/block"):
-            if not device.startswith("dasd"):
-                continue
-
-            statusfile = "/sys/block/%s/device/status" % (device,)
-            if not os.path.isfile(statusfile):
-                continue
-
-            f = open(statusfile, "r")
-            status = f.read().strip()
-            f.close()
-
-            if status in ["unformatted"] and device not in exclusiveDisks:
-                bypath = deviceNameToDiskByPath(device)
-                if not bypath:
-                    bypath = "/dev/" + device
-
-                log.info("    %s (%s) status is %s, needs dasdfmt" % (device,
-                                                                      bypath,
-                                                                      status,))
-                self._dasdlist.append((device, bypath))
-
-        if not len(self._dasdlist):
-            log.info("    no unformatted DASD devices found")
-            return
-
-        askUser = True
-
-        if zeroMbr:
-            askUser = False
-        elif not intf and not zeroMbr:
-            log.info("    non-interactive kickstart install without zerombr "
-                     "command, unable to run dasdfmt, exiting installer")
-            sys.exit(0)
-
-        c = len(self._dasdlist)
-
-        if intf and askUser:
-            devs = ''
-            for dasd, bypath in self._dasdlist:
-                devs += "%s\n" % (bypath,)
-
-            rc = intf.questionInitializeDASD(c, devs)
-            if rc == 1:
-                log.info("    not running dasdfmt, continuing installation")
-                return
-
-        # gather total cylinder count
-        argv = ["-t", "-v"] + self.commonArgv
-        for dasd, bypath in self._dasdlist:
-            buf = iutil.execWithCapture(self.dasdfmt, argv + ["/dev/" + dasd],
-                                        stderr=err)
-            for line in buf.splitlines():
-                if line.startswith("Drive Geometry: "):
-                    # line will look like this:
-                    # Drive Geometry: 3339 Cylinders * 15 Heads =  50085 Tracks
-                    cyls = long(filter(lambda s: s, line.split(' '))[2])
-                    self.totalCylinders += cyls
-                    break
-
-        # format DASDs
-        argv = ["-P"] + self.commonArgv
-        update = self._updateProgressWindow
-
-        title = P_("Formatting DASD Device", "Formatting DASD Devices", c)
-        msg = P_("Preparing %d DASD device for use with Linux..." % c,
-                 "Preparing %d DASD devices for use with Linux..." % c, c)
-
-        if intf:
-            if self.totalCylinders:
-                pw = intf.progressWindow(title, msg, 1.0)
-            else:
-                pw = intf.progressWindow(title, msg, 100, pulse=True)
-
-        for dasd, bypath in self._dasdlist:
-            log.info("Running dasdfmt on %s" % (bypath,))
-            arglist = argv + ["/dev/" + dasd]
-
-            try:
-                if intf and self.totalCylinders:
-                    rc = iutil.execWithCallback(self.dasdfmt, arglist,
-                                                stdout=out, stderr=err,
-                                                callback=update,
-                                                callback_data=pw,
-                                                echo=False)
-                elif intf:
-                    rc = iutil.execWithPulseProgress(self.dasdfmt, arglist,
-                                                     stdout=out, stderr=err,
-                                                     progress=pw)
-                else:
-                    rc = iutil.execWithRedirect(self.dasdfmt, arglist,
-                                                stdout=out, stderr=err)
-            except Exception as e:
-                raise DasdFormatError(e, bypath)
-
-            if rc:
-                raise DasdFormatError("dasdfmt failed: %s" % rc, bypath)
-
-        if intf:
-            pw.pop()
-
-    def addDASD(self, dasd):
-        """ Adds a DASDDevice to the internal list of DASDs. """
-        if dasd:
-            self._devices.append(dasd)
-
-    def write(self, instPath):
-        """ Write /etc/dasd.conf to target system for all DASD devices
-            configured during installation.
-        """
-        if self._devices == []:
-            return
-
-        f = open(os.path.realpath(instPath + "/etc/dasd.conf"), "w")
-        for dasd in self._devices:
-            fields = [dasd.busid] + dasd.getOpts()
-            f.write("%s\n" % (" ".join(fields),))
-        f.close()
-
-    def _updateProgressWindow(self, data, callback_data=None):
-        """ Reads progress output from dasdfmt and collects the number of
-            cylinders completed so the progress window can update.
-        """
-        if not callback_data:
-            return
-
-        if data == '\n':
-            # each newline we see in this output means one more cylinder done
-            self._completedCylinders += 1.0
-            callback_data.set(self._completedCylinders / self.totalCylinders)
-
-# Create DASD singleton
-DASD = DASD()
-
-# vim:tw=78:ts=4:et:sw=4
diff --git a/storage/deviceaction.py b/storage/deviceaction.py
deleted file mode 100644
index 4524e7c..0000000
--- a/storage/deviceaction.py
+++ /dev/null
@@ -1,376 +0,0 @@
-# deviceaction.py
-# Device modification action classes for anaconda's storage configuration
-# module.
-#
-# Copyright (C) 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, or (at your option) any later version.
-# 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.
-#
-# Red Hat Author(s): Dave Lehman <dlehman@xxxxxxxxxx>
-#
-
-from udev import *
-
-from devices import StorageDevice, PartitionDevice
-from formats import getFormat
-from errors import *
-from parted import partitionFlag, PARTITION_LBA
-
-import gettext
-_ = lambda x: gettext.ldgettext("anaconda", x)
-
-import logging
-log = logging.getLogger("storage")
-
-
-# The values are just hints as to the ordering.
-# Eg: fsmod and devmod ordering depends on the mod (shrink -v- grow)
-ACTION_TYPE_NONE = 0
-ACTION_TYPE_DESTROY = 1000
-ACTION_TYPE_RESIZE = 500
-ACTION_TYPE_MIGRATE = 250
-ACTION_TYPE_CREATE = 100
-
-action_strings = {ACTION_TYPE_NONE: "None",
-                  ACTION_TYPE_DESTROY: "Destroy",
-                  ACTION_TYPE_RESIZE: "Resize",
-                  ACTION_TYPE_MIGRATE: "Migrate",
-                  ACTION_TYPE_CREATE: "Create"}
-
-ACTION_OBJECT_NONE = 0
-ACTION_OBJECT_FORMAT = 1
-ACTION_OBJECT_DEVICE = 2
-
-object_strings = {ACTION_OBJECT_NONE: "None",
-                  ACTION_OBJECT_FORMAT: "Format",
-                  ACTION_OBJECT_DEVICE: "Device"}
-
-RESIZE_SHRINK = 88
-RESIZE_GROW = 89
-
-resize_strings = {RESIZE_SHRINK: "Shrink",
-                  RESIZE_GROW: "Grow"}
-
-def action_type_from_string(type_string):
-    if type_string is None:
-        return None
-
-    for (k,v) in action_strings.items():
-        if v.lower() == type_string.lower():
-            return k
-
-    return resize_type_from_string(type_string)
-
-def action_object_from_string(type_string):
-    if type_string is None:
-        return None
-
-    for (k,v) in object_strings.items():
-        if v.lower() == type_string.lower():
-            return k
-
-def resize_type_from_string(type_string):
-    if type_string is None:
-        return None
-
-    for (k,v) in resize_strings.items():
-        if v.lower() == type_string.lower():
-            return k
-
-class DeviceAction(object):
-    """ An action that will be carried out in the future on a Device.
-
-        These classes represent actions to be performed on devices or
-        filesystems.
-
-        The operand Device instance will be modified according to the
-        action, but no changes will be made to the underlying device or
-        filesystem until the DeviceAction instance's execute method is
-        called. The DeviceAction instance's cancel method should reverse
-        any modifications made to the Device instance's attributes.
-
-        If the Device instance represents a pre-existing device, the
-        constructor should call any methods or set any attributes that the
-        action will eventually change. Device/DeviceFormat classes should verify
-        that the requested modifications are reasonable and raise an
-        exception if not.
-
-        Only one action of any given type/object pair can exist for any
-        given device at any given time. This is enforced by the
-        DeviceTree.
-
-        Basic usage:
-
-            a = DeviceAction(dev)
-            a.execute()
-
-            OR
-
-            a = DeviceAction(dev)
-            a.cancel()
-
-
-        XXX should we back up the device with a deep copy for forcibly
-            cancelling actions?
-
-            The downside is that we lose any checking or verification that
-            would get done when resetting the Device instance's attributes to
-            their original values.
-
-            The upside is that we would be guaranteed to achieve a total
-            reversal. No chance of, eg: resizes ending up altering Device
-            size due to rounding or other miscalculation.
-"""
-    type = ACTION_TYPE_NONE
-    obj = ACTION_OBJECT_NONE
-
-    def __init__(self, device):
-        if not isinstance(device, StorageDevice):
-            raise ValueError("arg 1 must be a StorageDevice instance")
-        self.device = device
-
-
-    def execute(self, intf=None):
-        """ perform the action """
-        pass
-
-    def cancel(self):
-        """ cancel the action """
-        pass
-
-    def isDestroy(self):
-        return self.type == ACTION_TYPE_DESTROY
-
-    def isCreate(self):
-        return self.type == ACTION_TYPE_CREATE
-
-    def isMigrate(self):
-        return self.type == ACTION_TYPE_MIGRATE
-
-    def isResize(self):
-        return self.type == ACTION_TYPE_RESIZE
-
-    def isShrink(self):
-        return (self.type == ACTION_TYPE_RESIZE and self.dir == RESIZE_SHRINK)
-
-    def isGrow(self):
-        return (self.type == ACTION_TYPE_RESIZE and self.dir == RESIZE_GROW)
-
-    def isDevice(self):
-        return self.obj == ACTION_OBJECT_DEVICE
-
-    def isFormat(self):
-        return self.obj == ACTION_OBJECT_FORMAT
-
-    @property
-    def format(self):
-        return self.device.format
-
-    def __str__(self):
-        s = "%s %s" % (action_strings[self.type], object_strings[self.obj])
-        if self.isResize():
-            s += " (%s)" % resize_strings[self.dir]
-        if self.isFormat():
-            s += " %s on" % self.format.type
-        if self.isMigrate():
-            s += " to %s" % self.format.migrationTarget
-        s += " %s %s (id %d)" % (self.device.type, self.device.name,
-                                 self.device.id)
-        return s
-
-class ActionCreateDevice(DeviceAction):
-    """ Action representing the creation of a new device. """
-    type = ACTION_TYPE_CREATE
-    obj = ACTION_OBJECT_DEVICE
-
-    def __init__(self, device):
-        # FIXME: assert device.fs is None
-        DeviceAction.__init__(self, device)
-
-    def execute(self, intf=None):
-        self.device.create(intf=intf)
-
-
-class ActionDestroyDevice(DeviceAction):
-    """ An action representing the deletion of an existing device. """
-    type = ACTION_TYPE_DESTROY
-    obj = ACTION_OBJECT_DEVICE
-
-    def __init__(self, device):
-        # XXX should we insist that device.fs be None?
-        DeviceAction.__init__(self, device)
-        if device.exists:
-            device.teardown()
-
-    def execute(self, intf=None):
-        self.device.destroy()
-
-        # Make sure libparted does not keep cached info for this device
-        # and returns it when we create a new device with the same name
-        if self.device.partedDevice:
-            self.device.partedDevice.removeFromCache()
-
-
-class ActionResizeDevice(DeviceAction):
-    """ An action representing the resizing of an existing device. """
-    type = ACTION_TYPE_RESIZE
-    obj = ACTION_OBJECT_DEVICE
-
-    def __init__(self, device, newsize):
-        if device.currentSize == newsize:
-            raise ValueError("new size same as old size")
-
-        if not device.resizable:
-            raise ValueError("device is not resizable")
-
-        DeviceAction.__init__(self, device)
-        if newsize > device.currentSize:
-            self.dir = RESIZE_GROW
-        else:
-            self.dir = RESIZE_SHRINK
-        self.origsize = device.targetSize
-        self.device.targetSize = newsize
-
-    def execute(self, intf=None):
-        self.device.resize(intf=intf)
-
-    def cancel(self):
-        self.device.targetSize = self.origsize
-
-
-class ActionCreateFormat(DeviceAction):
-    """ An action representing creation of a new filesystem. """
-    type = ACTION_TYPE_CREATE
-    obj = ACTION_OBJECT_FORMAT
-
-    def __init__(self, device, format=None):
-        DeviceAction.__init__(self, device)
-        if format:
-            self.origFormat = device.format
-            if self.device.format.exists:
-                self.device.format.teardown()
-            self.device.format = format
-        else:
-            self.origFormat = getFormat(None)
-
-    def execute(self, intf=None):
-        self.device.setup()
-
-        if isinstance(self.device, PartitionDevice):
-            for flag in partitionFlag.keys():
-                # Keep the LBA flag on pre-existing partitions
-                if flag in [ PARTITION_LBA, self.format.partedFlag ]:
-                    continue
-                self.device.unsetFlag(flag)
-
-            if self.format.partedFlag is not None:
-                self.device.setFlag(self.format.partedFlag)
-
-            if self.format.partedSystem is not None:
-                self.device.partedPartition.system = self.format.partedSystem
-
-            self.device.disk.format.commitToDisk()
-
-        self.device.format.create(intf=intf,
-                                  device=self.device.path,
-                                  options=self.device.formatArgs)
-        # Get the UUID now that the format is created
-        udev_settle()
-        self.device.updateSysfsPath()
-        info = udev_get_block_device(self.device.sysfsPath)
-        self.device.format.uuid = udev_device_get_uuid(info)
-
-    def cancel(self):
-        self.device.format = self.origFormat
-
-
-class ActionDestroyFormat(DeviceAction):
-    """ An action representing the removal of an existing filesystem.
-
-        XXX this seems unnecessary
-    """
-    type = ACTION_TYPE_DESTROY
-    obj = ACTION_OBJECT_FORMAT
-
-    def __init__(self, device):
-        DeviceAction.__init__(self, device)
-        self.origFormat = self.device.format
-        if device.format.exists:
-            device.format.teardown()
-        self.device.format = None
-
-    def execute(self, intf=None):
-        """ wipe the filesystem signature from the device """
-        if self.origFormat:
-            self.device.setup(orig=True)
-            self.origFormat.destroy()
-            udev_settle()
-            self.device.teardown()
-
-    def cancel(self):
-        self.device.format = self.origFormat
-
-    @property
-    def format(self):
-        return self.origFormat
-
-
-class ActionResizeFormat(DeviceAction):
-    """ An action representing the resizing of an existing filesystem.
-
-        XXX Do we even want to support resizing of a filesystem without
-            also resizing the device it resides on?
-    """
-    type = ACTION_TYPE_RESIZE
-    obj = ACTION_OBJECT_FORMAT
-
-    def __init__(self, device, newsize):
-        if device.format.targetSize == newsize:
-            raise ValueError("new size same as old size")
-
-        DeviceAction.__init__(self, device)
-        if newsize > device.format.currentSize:
-            self.dir = RESIZE_GROW
-        else:
-            self.dir = RESIZE_SHRINK
-        self.origSize = self.device.format.targetSize
-        self.device.format.targetSize = newsize
-
-    def execute(self, intf=None):
-        self.device.setup(orig=True)
-        self.device.format.doResize(intf=intf)
-
-    def cancel(self):
-        self.device.format.targetSize = self.origSize
-
-class ActionMigrateFormat(DeviceAction):
-    """ An action representing the migration of an existing filesystem. """
-    type = ACTION_TYPE_MIGRATE
-    obj = ACTION_OBJECT_FORMAT
-
-    def __init__(self, device):
-        if not device.format.migratable or not device.format.exists:
-            raise ValueError("device format is not migratable")
-
-        DeviceAction.__init__(self, device)
-        self.device.format.migrate = True
-
-    def execute(self, intf=None):
-        self.device.setup(orig=True)
-        self.device.format.doMigrate(intf=intf)
-
-    def cancel(self):
-        self.device.format.migrate = False
-
diff --git a/storage/devicelibs/Makefile.am b/storage/devicelibs/Makefile.am
deleted file mode 100644
index 86a7d5e..0000000
--- a/storage/devicelibs/Makefile.am
+++ /dev/null
@@ -1,24 +0,0 @@
-# storage/devicelibs/Makefile.am for anaconda
-#
-# Copyright (C) 2009  Red Hat, Inc.
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU Lesser General Public License as published
-# by the Free Software Foundation; either version 2.1 of the License, or
-# (at your option) any later version.
-#
-# 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 Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public License
-# along with this program.  If not, see <http://www.gnu.org/licenses/>.
-#
-# Author: David Cantrell <dcantrell@xxxxxxxxxx>
-
-pkgpyexecdir = $(pyexecdir)/py$(PACKAGE_NAME)
-storagedevicelibsdir = $(pkgpyexecdir)/storage/devicelibs
-storagedevicelibs_PYTHON = *.py
-
-MAINTAINERCLEANFILES = Makefile.in
diff --git a/storage/devicelibs/__init__.py b/storage/devicelibs/__init__.py
deleted file mode 100644
index e69de29..0000000
diff --git a/storage/devicelibs/crypto.py b/storage/devicelibs/crypto.py
deleted file mode 100644
index 136435d..0000000
--- a/storage/devicelibs/crypto.py
+++ /dev/null
@@ -1,193 +0,0 @@
-#
-# crypto.py
-#
-# Copyright (C) 2009  Red Hat, Inc.  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 as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# 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, see <http://www.gnu.org/licenses/>.
-#
-# Author(s): Dave Lehman <dlehman@xxxxxxxxxx>
-#            Martin Sivak <msivak@xxxxxxxxxx>
-#
-
-import os
-from pycryptsetup import CryptSetup
-import iutil
-
-from ..errors import *
-
-import gettext
-_ = lambda x: gettext.ldgettext("anaconda", x)
-
-# Keep the character set size a power of two to make sure all characters are
-# equally likely
-GENERATED_PASSPHRASE_CHARSET = ("0123456789"
-                                "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
-                                "abcdefghijklmnopqrstuvwxyz"
-                                "./")
-# 20 chars * 6 bits per char = 120 "bits of security"
-GENERATED_PASSPHRASE_LENGTH = 20
-
-def generateBackupPassphrase():
-    rnd = os.urandom(GENERATED_PASSPHRASE_LENGTH)
-    cs = GENERATED_PASSPHRASE_CHARSET
-    raw = "".join([cs[ord(c) % len(cs)] for c in rnd])
-
-    # Make the result easier to read
-    parts = []
-    for i in xrange(0, len(raw), 5):
-        parts.append(raw[i : i + 5])
-    return "-".join(parts)
-
-def askyes(question):
-    return True
-
-def dolog(priority, text):
-    pass
-
-def is_luks(device):
-    cs = CryptSetup(yesDialog = askyes, logFunc = dolog)
-    return cs.isLuks(device)
-
-def luks_uuid(device):
-    cs = CryptSetup(yesDialog = askyes, logFunc = dolog)
-    return cs.luksUUID(device).strip()
-
-def luks_status(name):
-    """True means active, False means inactive (or non-existent)"""
-    cs = CryptSetup(yesDialog = askyes, logFunc = dolog)
-    return cs.luksStatus(name)!=0
-
-def luks_format(device,
-                passphrase=None, key_file=None,
-                cipher=None, key_size=None):
-    cs = CryptSetup(yesDialog = askyes, logFunc = dolog)
-    key_file_unlink = False
-
-    if passphrase:
-        key_file = cs.prepare_passphrase_file(passphrase)
-        key_file_unlink = True
-    elif key_file and os.path.isfile(key_file):
-        pass
-    else:
-        raise ValueError("luks_format requires either a passphrase or a key file")
-
-    #None is not considered as default value and pycryptsetup doesn't accept it
-    #so we need to filter out all Nones
-    kwargs = {}
-    kwargs["device"] = device
-    if   cipher: kwargs["cipher"]  = cipher
-    if key_file: kwargs["keyfile"] = key_file
-    if key_size: kwargs["keysize"] = key_size
-
-    rc = cs.luksFormat(**kwargs)
-    if key_file_unlink: os.unlink(key_file)
-
-    if rc:
-        raise CryptoError("luks_format failed for '%s'" % device)
-
-def luks_open(device, name, passphrase=None, key_file=None):
-    cs = CryptSetup(yesDialog = askyes, logFunc = dolog)
-    key_file_unlink = False
-
-    if passphrase:
-        key_file = cs.prepare_passphrase_file(passphrase)
-        key_file_unlink = True
-    elif key_file and os.path.isfile(key_file):
-        pass
-    else:
-        raise ValueError("luks_open requires either a passphrase or a key file")
-
-    rc = cs.luksOpen(device = device, name = name, keyfile = key_file)
-    if key_file_unlink: os.unlink(key_file)
-    if rc:
-        raise CryptoError("luks_open failed for %s (%s)" % (device, name))
-
-def luks_close(name):
-    cs = CryptSetup(yesDialog = askyes, logFunc = dolog)
-    rc = cs.luksClose(name)
-    if rc:
-        raise CryptoError("luks_close failed for %s" % name)
-
-def luks_add_key(device,
-                 new_passphrase=None, new_key_file=None,
-                 passphrase=None, key_file=None):
-
-    params = ["-q"]
-
-    p = os.pipe()
-    if passphrase:
-        os.write(p[1], "%s\n" % passphrase)
-    elif key_file and os.path.isfile(key_file):
-        params.extend(["--key-file", key_file])
-    else:
-        raise CryptoError("luks_add_key requires either a passphrase or a key file")
-
-    params.extend(["luksAddKey", device])
-
-    if new_passphrase:
-        os.write(p[1], "%s\n" % new_passphrase)
-    elif new_key_file and os.path.isfile(new_key_file):
-        params.append("%s" % new_key_file)
-    else:
-        raise CryptoError("luks_add_key requires either a passphrase or a key file to add")
-
-    os.close(p[1])
-
-    rc = iutil.execWithRedirect("cryptsetup", params,
-                                stdin = p[0],
-                                stdout = "/dev/tty5",
-                                stderr = "/dev/tty5")
-
-    os.close(p[0])
-    if rc:
-        raise CryptoError("luks add key failed with errcode %d" % (rc,))
-
-def luks_remove_key(device,
-                    del_passphrase=None, del_key_file=None,
-                    passphrase=None, key_file=None):
-
-    params = []
-
-    p = os.pipe()
-    if del_passphrase: #the first question is about the key we want to remove
-        os.write(p[1], "%s\n" % del_passphrase)
-
-    if passphrase:
-        os.write(p[1], "%s\n" % passphrase)
-    elif key_file and os.path.isfile(key_file):
-        params.extend(["--key-file", key_file])
-    else:
-        raise CryptoError("luks_remove_key requires either a passphrase or a key file")
-
-    params.extend(["luksRemoveKey", device])
-
-    if del_passphrase:
-        pass
-    elif del_key_file and os.path.isfile(del_key_file):
-        params.append("%s" % del_key_file)
-    else:
-        raise CryptoError("luks_remove_key requires either a passphrase or a key file to remove")
-
-    os.close(p[1])
-
-    rc = iutil.execWithRedirect("cryptsetup", params,
-                                stdin = p[0],
-                                stdout = "/dev/tty5",
-                                stderr = "/dev/tty5")
-
-    os.close(p[0])
-    if rc:
-        raise CryptoError("luks_remove_key failed with errcode %d" % (rc,))
-
-
diff --git a/storage/devicelibs/dm.py b/storage/devicelibs/dm.py
deleted file mode 100644
index 02745e0..0000000
--- a/storage/devicelibs/dm.py
+++ /dev/null
@@ -1,130 +0,0 @@
-#
-# dm.py
-# device-mapper functions
-#
-# Copyright (C) 2009  Red Hat, Inc.  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 as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# 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, see <http://www.gnu.org/licenses/>.
-#
-# Author(s): Dave Lehman <dlehman@xxxxxxxxxx>
-#
-
-import os
-
-import block
-import iutil
-from ..errors import *
-
-import gettext
-_ = lambda x: gettext.ldgettext("anaconda", x)
-
-import logging
-log = logging.getLogger("storage")
-
-def name_from_dm_node(dm_node):
-    name = block.getNameFromDmNode(dm_node)
-    if name is not None:
-        return name
-
-    st = os.stat("/dev/%s" % dm_node)
-    major = os.major(st.st_rdev)
-    minor = os.minor(st.st_rdev)
-    name = iutil.execWithCapture("dmsetup",
-                                 ["info", "--columns",
-                                  "--noheadings", "-o", "name",
-                                  "-j", str(major), "-m", str(minor)],
-                                 stderr="/dev/tty5")
-    log.debug("name_from_dm(%s) returning '%s'" % (dm_node, name.strip()))
-    return name.strip()
-
-def dm_node_from_name(map_name):
-    dm_node = block.getDmNodeFromName(map_name)
-    if dm_node is not None:
-        return dm_node
-
-    devnum = iutil.execWithCapture("dmsetup",
-                                   ["info", "--columns",
-                                    "--noheadings",
-                                    "-o", "devno",
-                                    map_name],
-                                    stderr="/dev/tty5")
-    (major, sep, minor) = devnum.strip().partition(":")
-    if not sep:
-        raise DMError("dm device does not exist")
-
-    dm_node = "dm-%d" % int(minor)
-    log.debug("dm_node_from_name(%s) returning '%s'" % (map_name, dm_node))
-    return dm_node
-
-def dm_is_multipath(info):
-    major = None
-    minor = None
-
-    if info.has_key('MAJOR'):
-        major = info['MAJOR']
-    elif info.has_key('DM_MAJOR'):
-        major = info['DM_MAJOR']
-    if info.has_key('MINOR'):
-        minor = info['MINOR']
-    elif info.has_key('DM_MINOR'):
-        minor = info['DM_MINOR']
-
-    if major is None or minor is None:
-        return False
-
-    for map in block.dm.maps():
-        dev = map.dev
-        if dev.major == int(major) and dev.minor == int(minor):
-            for table in map.table:
-                if table.type == 'multipath':
-                    return True
-
-def _get_backing_devnums_from_map(map_name):
-    ret = []
-    buf = iutil.execWithCapture("dmsetup",
-                                ["info", "--columns",
-                                 "--noheadings",
-                                 "-o", "devnos_used",
-                                 map_name],
-                                stderr="/dev/tty5")
-    dev_nums = buf.split()
-    for dev_num in dev_nums:
-        (major, colon, minor) = dev_num.partition(":")
-        ret.append((int(major), int(minor)))
-
-    return ret
-
-def get_backing_devnums(dm_node):
-    #dm_node = dm_node_from_name(map_name)
-    if not dm_node:
-        return None
-
-    top_dir = "/sys/block"
-    backing_devs = os.listdir("%s/%s/slaves/" % (top_dir, dm_node))
-    dev_nums = []
-    for backing_dev in backing_devs:
-        dev_num = open("%s/%s/dev" % (top_dir, backing_dev)).read().strip()
-        (_major, _minor) = dev_num.split(":")
-        dev_nums.append((int(_major), int(_minor)))
-
-    return dev_nums
-
-def get_backing_devs_from_name(map_name):
-    dm_node = dm_node_from_name(map_name)
-    if not dm_node:
-        return None
-
-    slave_devs = os.listdir("/sys/block/virtual/%s" % dm_node)
-    return slave_devs
-
diff --git a/storage/devicelibs/edd.py b/storage/devicelibs/edd.py
deleted file mode 100644
index da03914..0000000
--- a/storage/devicelibs/edd.py
+++ /dev/null
@@ -1,97 +0,0 @@
-#
-# edd.py
-# BIOS EDD data parsing functions
-#
-# Copyright (C) 2010  Red Hat, Inc.  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 as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# 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, see <http://www.gnu.org/licenses/>.
-#
-# Author(s): Hans de Goede <hdegoede@xxxxxxxxxx>
-#
-
-import os
-import struct
-
-import logging
-log = logging.getLogger("storage")
-
-def get_edd_dict(devices):
-    """Given an array of devices return a dict with the BIOS ID for them."""
-    edd_dict = {}
-
-    for biosdev in range(80, 80 + 15):
-        sysfspath = "/sys/firmware/edd/int13_dev%d" % biosdev
-        if not os.path.exists(sysfspath):
-            break # We are done
-
-        sysfspath = "/sys/firmware/edd/int13_dev%d/mbr_signature" % biosdev
-        if not os.path.exists(sysfspath):
-            log.warning("No mbrsig for biosdev: %d" % biosdev)
-            continue
-
-        try:
-            file = open(sysfspath, "r")
-            eddsig = file.read()
-            file.close()
-        except (IOError, OSError) as e:
-            log.warning("Error reading EDD mbrsig for %d: %s" %
-                        (biosdev, str(e)))
-            continue
-
-        sysfspath = "/sys/firmware/edd/int13_dev%d/sectors" % biosdev
-        try:
-            file = open(sysfspath, "r")
-            eddsize = file.read()
-            file.close()
-        except (IOError, OSError) as e:
-            eddsize = None
-
-        found = []
-        for dev in devices:
-            try:
-                fd = os.open(dev.path, os.O_RDONLY)
-                os.lseek(fd, 440, 0) 
-                mbrsig = struct.unpack('I', os.read(fd, 4))
-                os.close(fd)
-            except OSError as e:
-                log.warning("Error reading mbrsig from disk %s: %s" %
-                            (dev.name, str(e)))
-                continue
-
-            mbrsigStr = "0x%08x\n" % mbrsig
-            if mbrsigStr == eddsig:
-                if eddsize:
-                    sysfspath = "/sys%s/size" % dev.sysfsPath
-                    try:
-                        file = open(sysfspath, "r")
-                        size = file.read()
-                        file.close()
-                    except (IOError, OSError) as e:
-                        log.warning("Error getting size for: %s" % dev.name)
-                        continue
-                    if eddsize != size:
-                        continue
-                found.append(dev.name)
-
-        if not found:
-            log.error("No matching mbr signature found for biosdev %d" %
-                      biosdev)
-        elif len(found) > 1:
-            log.error("Multiple signature matches found for biosdev %d: %s" %
-                      (biosdev, str(found)))
-        else:
-            log.info("Found %s for biosdev %d" %(found[0], biosdev))
-            edd_dict[found[0]] = biosdev
-
-    return edd_dict
diff --git a/storage/devicelibs/lvm.py b/storage/devicelibs/lvm.py
deleted file mode 100644
index fd74f56..0000000
--- a/storage/devicelibs/lvm.py
+++ /dev/null
@@ -1,419 +0,0 @@
-#
-# lvm.py
-# lvm functions
-#
-# Copyright (C) 2009  Red Hat, Inc.  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 as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# 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, see <http://www.gnu.org/licenses/>.
-#
-# Author(s): Dave Lehman <dlehman@xxxxxxxxxx>
-#
-
-import os
-import math
-import re
-
-import iutil
-
-from ..errors import *
-from constants import *
-
-import gettext
-_ = lambda x: gettext.ldgettext("anaconda", x)
-
-MAX_LV_SLOTS = 256
-
-def has_lvm():
-    has_lvm = False
-    for path in os.environ["PATH"].split(":"):
-        if os.access("%s/lvm" % path, os.X_OK):
-            has_lvm = True
-            break
-
-    if has_lvm:
-        has_lvm = False
-        for line in open("/proc/devices").readlines():
-            if "device-mapper" in line.split():
-                has_lvm = True
-                break
-
-    return has_lvm
-
-# Start config_args handling code
-#
-# Theoretically we can handle all that can be handled with the LVM --config
-# argument.  For every time we call an lvm_cc (lvm compose config) funciton
-# we regenerate the config_args with all global info.
-config_args = [] # Holds the final argument list
-config_args_data = { "filterRejects": [],    # regular expressions to reject.
-                            "filterAccepts": [] }   # regexp to accept
-
-def _composeConfig():
-    """lvm command accepts lvm.conf type arguments preceded by --config. """
-    global config_args, config_args_data
-    config_args = []
-
-    filter_string = ""
-    rejects = config_args_data["filterRejects"]
-    # we don't need the accept for now.
-    # accepts = config_args_data["filterAccepts"]
-    # if len(accepts) > 0:
-    #   for i in range(len(rejects)):
-    #       filter_string = filter_string + ("\"a|%s|\", " % accpets[i])
-
-    if len(rejects) > 0:
-        for i in range(len(rejects)):
-            filter_string = filter_string + ("\"r|%s|\"," % rejects[i])
-
-
-    filter_string = " filter=[%s] " % filter_string.strip(",")
-
-    # As we add config strings we should check them all.
-    if filter_string == "":
-        # Nothing was really done.
-        return
-
-    # devices_string can have (inside the brackets) "dir", "scan",
-    # "preferred_names", "filter", "cache_dir", "write_cache_state",
-    # "types", "sysfs_scan", "md_component_detection".  see man lvm.conf.
-    devices_string = " devices {%s} " % (filter_string) # strings can be added
-    config_string = devices_string # more strings can be added.
-    config_args = ["--config", config_string]
-
-def lvm_cc_addFilterRejectRegexp(regexp):
-    """ Add a regular expression to the --config string."""
-    global config_args_data
-    config_args_data["filterRejects"].append(regexp)
-
-    # compoes config once more.
-    _composeConfig()
-
-def lvm_cc_resetFilter():
-    global config_args, config_args_data
-    config_args_data["filterRejects"] = []
-    config_args_data["filterAccepts"] = []
-    config_args = []
-# End config_args handling code.
-
-# Names that should not be used int the creation of VGs
-lvm_vg_blacklist = []
-def blacklistVG(name):
-    global lvm_vg_blacklist
-    lvm_vg_blacklist.append(name)
-
-def getPossiblePhysicalExtents(floor=0):
-    """Returns a list of integers representing the possible values for
-       the physical extent of a volume group.  Value is in KB.
-
-       floor - size (in KB) of smallest PE we care about.
-    """
-
-    possiblePE = []
-    curpe = 8
-    while curpe <= 16384*1024:
-	if curpe >= floor:
-	    possiblePE.append(curpe)
-	curpe = curpe * 2
-
-    return possiblePE
-
-def getMaxLVSize():
-    """ Return the maximum size (in MB) of a logical volume. """
-    if iutil.getArch() in ("x86_64", "ppc64", "alpha", "ia64", "s390", "sparc"): #64bit architectures
-        return (8*1024*1024*1024*1024) #Max is 8EiB (very large number..)
-    else:
-        return (16*1024*1024) #Max is 16TiB
-
-# LVM sources set the maximum length limit on VG and LV names at 128.  Set
-# our default to 2 below that to account for 0 through 99 entries we may
-# make with this name as a prefix.  LVM doesn't seem to impose a limit of
-# 99, but we do in anaconda.
-def safeLvmName(name, maxlen=126):
-    tmp = name.strip()
-    tmp = tmp.replace("/", "_")
-    tmp = re.sub("[^0-9a-zA-Z._]", "", tmp)
-    tmp = tmp.lstrip("_")
-
-    if len(tmp) > maxlen:
-        tmp = tmp[:maxlen]
-
-    return tmp
-
-def clampSize(size, pesize, roundup=None):
-    if roundup:
-        round = math.ceil
-    else:
-        round = math.floor
-
-    return long(round(float(size)/float(pesize)) * pesize)
-
-def lvm(args, progress=None):
-    rc = iutil.execWithPulseProgress("lvm", args,
-                                     stdout = "/dev/tty5",
-                                     stderr = "/dev/tty5",
-                                     progress=progress)
-    if not rc:
-        return
-
-    try:
-        # grab the last line of program.log and strip off the timestamp
-        msg = open("/tmp/program.log").readlines()[-1]
-        msg = msg.split("program: ", 1)[1].strip()
-    except Exception:
-        msg = ""
-
-    raise LVMError(msg)
-
-def pvcreate(device, progress=None):
-    args = ["pvcreate"] + \
-            config_args + \
-            [device]
-
-    try:
-        lvm(args, progress=progress)
-    except LVMError as msg:
-        raise LVMError("pvcreate failed for %s: %s" % (device, msg))
-
-def pvresize(device, size):
-    args = ["pvresize"] + \
-            ["--setphysicalvolumesize", ("%dm" % size)] + \
-            config_args + \
-            [device]
-
-    try:
-        lvm(args)
-    except LVMError as msg:
-        raise LVMError("pvresize failed for %s: %s" % (device, msg))
-
-def pvremove(device):
-    args = ["pvremove"] + \
-            config_args + \
-            [device]
-
-    try:
-        lvm(args)
-    except LVMError as msg:
-        raise LVMError("pvremove failed for %s: %s" % (device, msg))
-
-def pvinfo(device):
-    """
-        If the PV was created with '--metadacopies 0', lvm will do some
-        scanning of devices to determine from their metadata which VG
-        this PV belongs to.
-
-        pvs -o pv_name,pv_mda_count,vg_name,vg_uuid --config \
-            'devices { scan = "/dev" filter = ["a/loop0/", "r/.*/"] }'
-    """
-    #cfg = "'devices { scan = \"/dev\" filter = [\"a/%s/\", \"r/.*/\"] }'" 
-    args = ["pvs", "--noheadings"] + \
-            ["--units", "m"] + \
-            ["-o", "pv_name,pv_mda_count,vg_name,vg_uuid"] + \
-            config_args + \
-            [device]
-
-    rc = iutil.execWithCapture("lvm", args,
-                                stderr = "/dev/tty5")
-    vals = rc.split()
-    if not vals:
-        raise LVMError("pvinfo failed for %s" % device)
-
-    # don't raise an exception if pv is not a part of any vg
-    pv_name = vals[0]
-    try:
-        vg_name, vg_uuid = vals[2], vals[3]
-    except IndexError:
-        vg_name, vg_uuid = "", ""
-    
-    info = {'pv_name': pv_name,
-            'vg_name': vg_name,
-            'vg_uuid': vg_uuid}
-
-    return info
-
-def vgcreate(vg_name, pv_list, pe_size, progress=None):
-    argv = ["vgcreate"]
-    if pe_size:
-        argv.extend(["-s", "%dm" % pe_size])
-    argv.extend(config_args)
-    argv.append(vg_name)
-    argv.extend(pv_list)
-
-    try:
-        lvm(argv, progress=progress)
-    except LVMError as msg:
-        raise LVMError("vgcreate failed for %s: %s" % (vg_name, msg))
-
-def vgremove(vg_name):
-    args = ["vgremove", "--force"] + \
-            config_args +\
-            [vg_name]
-
-    try:
-        lvm(args)
-    except LVMError as msg:
-        raise LVMError("vgremove failed for %s: %s" % (vg_name, msg))
-
-def vgactivate(vg_name):
-    args = ["vgchange", "-a", "y"] + \
-            config_args + \
-            [vg_name]
-
-    try:
-        lvm(args)
-    except LVMError as msg:
-        raise LVMError("vgactivate failed for %s: %s" % (vg_name, msg))
-
-def vgdeactivate(vg_name):
-    args = ["vgchange", "-a", "n"] + \
-            config_args + \
-            [vg_name]
-
-    try:
-        lvm(args)
-    except LVMError as msg:
-        raise LVMError("vgdeactivate failed for %s: %s" % (vg_name, msg))
-
-def vgreduce(vg_name, pv_list, rm=False):
-    """ Reduce a VG.
-
-    rm -> with RemoveMissing option.
-    Use pv_list when rm=False, otherwise ignore pv_list and call vgreduce with
-    the --removemissing option.
-    """
-    args = ["vgreduce"]
-    if rm:
-        args.extend(["--removemissing", vg_name])
-    else:
-        args.extend([vg_name] + pv_list)
-
-    try:
-        lvm(args)
-    except LVMError as msg:
-        raise LVMError("vgreduce failed for %s: %s" % (vg_name, msg))
-
-def vginfo(vg_name):
-    args = ["vgs", "--noheadings", "--nosuffix"] + \
-            ["--units", "m"] + \
-            ["-o", "uuid,size,free,extent_size,extent_count,free_count,pv_count"] + \
-            config_args + \
-            [vg_name]
-
-    buf = iutil.execWithCapture("lvm",
-                                args,
-                                stderr="/dev/tty5")
-    info = buf.split()
-    if len(info) != 7:
-        raise LVMError(_("vginfo failed for %s" % vg_name))
-
-    d = {}
-    (d['uuid'],d['size'],d['free'],d['pe_size'],
-     d['pe_count'],d['pe_free'],d['pv_count']) = info
-    return d
-
-def lvs(vg_name):
-    args = ["lvs", "--noheadings", "--nosuffix"] + \
-            ["--units", "m"] + \
-            ["-o", "lv_name,lv_uuid,lv_size,lv_attr"] + \
-            config_args + \
-            [vg_name]
-
-    buf = iutil.execWithCapture("lvm",
-                                args,
-                                stderr="/dev/tty5")
-
-    lvs = {}
-    for line in buf.splitlines():
-        line = line.strip()
-        if not line:
-            continue
-        (name, uuid, size, attr) = line.split()
-        lvs[name] = {"size": size,
-                     "uuid": uuid,
-                     "attr": attr}
-
-    if not lvs:
-        raise LVMError(_("lvs failed for %s" % vg_name))
-
-    return lvs
-
-def lvorigin(vg_name, lv_name):
-    args = ["lvs", "--noheadings", "-o", "origin"] + \
-            config_args + \
-            ["%s/%s" % (vg_name, lv_name)]
-
-    buf = iutil.execWithCapture("lvm",
-                                args,
-                                stderr="/dev/tty5")
-
-    try:
-        origin = buf.splitlines()[0].strip()
-    except IndexError:
-        origin = ''
-
-    return origin
-
-def lvcreate(vg_name, lv_name, size, progress=None):
-    args = ["lvcreate"] + \
-            ["-L", "%dm" % size] + \
-            ["-n", lv_name] + \
-            config_args + \
-            [vg_name]
-
-    try:
-        lvm(args, progress=progress)
-    except LVMError as msg:
-        raise LVMError("lvcreate failed for %s/%s: %s" % (vg_name, lv_name, msg))
-
-def lvremove(vg_name, lv_name):
-    args = ["lvremove"] + \
-            config_args + \
-            ["%s/%s" % (vg_name, lv_name)]
-
-    try:
-        lvm(args)
-    except LVMError as msg:
-        raise LVMError("lvremove failed for %s: %s" % (lv_name, msg))
-
-def lvresize(vg_name, lv_name, size):
-    args = ["lvresize"] + \
-            ["--force", "-L", "%dm" % size] + \
-            config_args + \
-            ["%s/%s" % (vg_name, lv_name)]
-
-    try:
-        lvm(args)
-    except LVMError as msg:
-        raise LVMError("lvresize failed for %s: %s" % (lv_name, msg))
-
-def lvactivate(vg_name, lv_name):
-    # see if lvchange accepts paths of the form 'mapper/$vg-$lv'
-    args = ["lvchange", "-a", "y"] + \
-            config_args + \
-            ["%s/%s" % (vg_name, lv_name)]
-
-    try:
-        lvm(args)
-    except LVMError as msg:
-        raise LVMError("lvactivate failed for %s: %s" % (lv_name, msg))
-
-def lvdeactivate(vg_name, lv_name):
-    args = ["lvchange", "-a", "n"] + \
-            config_args + \
-            ["%s/%s" % (vg_name, lv_name)]
-
-    try:
-        lvm(args)
-    except LVMError as msg:
-        raise LVMError("lvdeactivate failed for %s: %s" % (lv_name, msg))
-
diff --git a/storage/devicelibs/mdraid.py b/storage/devicelibs/mdraid.py
deleted file mode 100644
index a04965d..0000000
--- a/storage/devicelibs/mdraid.py
+++ /dev/null
@@ -1,236 +0,0 @@
-#
-# mdraid.py
-# mdraid functions
-#
-# Copyright (C) 2009  Red Hat, Inc.  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 as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# 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, see <http://www.gnu.org/licenses/>.
-#
-# Author(s): Dave Lehman <dlehman@xxxxxxxxxx>
-#
-
-import os
-
-import iutil
-from ..errors import *
-
-import gettext
-_ = lambda x: gettext.ldgettext("anaconda", x)
-
-import logging
-log = logging.getLogger("storage")
-
-# raidlevels constants
-RAID10 = 10
-RAID6 = 6
-RAID5 = 5
-RAID4 = 4
-RAID1 = 1
-RAID0 = 0
-
-def getRaidLevels():
-    mdstat_descriptors = {
-        RAID10: ("[RAID10]", "[raid10]"),
-        RAID6: ("[RAID6]", "[raid6]"),
-        RAID5: ("[RAID5]", "[raid5]"),
-        RAID4: ("[RAID4]", "[raid4]"),
-        RAID1: ("[RAID1]", "[raid1]"),
-        RAID0: ("[RAID0]", "[raid0]"),
-    }
-    avail = []
-    try:
-        f = open("/proc/mdstat", "r")
-    except IOError:
-        pass
-    else:
-        for l in f.readlines():
-            if not l.startswith("Personalities"):
-                continue
-
-            lst = l.split()
-
-            for level in mdstat_descriptors:
-                for d in mdstat_descriptors[level]:
-                    if d in lst:
-                        avail.append(level)
-                        break
-
-        f.close()
-
-    avail.sort()
-    return avail
-
-raid_levels = getRaidLevels()
-
-def raidLevel(descriptor):
-    for level in raid_levels:
-        if isRaid(level, descriptor):
-            return level
-    else:
-        raise ValueError, "invalid raid level descriptor %s" % descriptor
-
-def isRaid(raid, raidlevel):
-    """Return whether raidlevel is a valid descriptor of raid"""
-    raid_descriptors = {RAID10: ("RAID10", "raid10", "10", 10),
-                        RAID6: ("RAID6", "raid6", "6", 6),
-                        RAID5: ("RAID5", "raid5", "5", 5),
-                        RAID4: ("RAID4", "raid4", "4", 4),
-                        RAID1: ("mirror", "RAID1", "raid1", "1", 1),
-                        RAID0: ("stripe", "RAID0", "raid0", "0", 0)}
-
-    if raid in raid_descriptors:
-        return raidlevel in raid_descriptors[raid]
-    else:
-        raise ValueError, "invalid raid level %d" % raid
-
-def get_raid_min_members(raidlevel):
-    """Return the minimum number of raid members required for raid level"""
-    raid_min_members = {RAID10: 2,
-                        RAID6: 4,
-                        RAID5: 3,
-                        RAID4: 3,
-                        RAID1: 2,
-                        RAID0: 2}
-
-    for raid, min_members in raid_min_members.items():
-        if isRaid(raid, raidlevel):
-            return min_members
-
-    raise ValueError, "invalid raid level %d" % raidlevel
-
-def get_raid_max_spares(raidlevel, nummembers):
-    """Return the maximum number of raid spares for raidlevel."""
-    raid_max_spares = {RAID10: lambda: max(0, nummembers - get_raid_min_members(RAID10)),
-                       RAID6: lambda: max(0, nummembers - get_raid_min_members(RAID6)),
-                       RAID5: lambda: max(0, nummembers - get_raid_min_members(RAID5)),
-                       RAID4: lambda: max(0, nummembers - get_raid_min_members(RAID4)),
-                       RAID1: lambda: max(0, nummembers - get_raid_min_members(RAID1)),
-                       RAID0: lambda: 0}
-
-    for raid, max_spares_func in raid_max_spares.items():
-        if isRaid(raid, raidlevel):
-            return max_spares_func()
-
-    raise ValueError, "invalid raid level %d" % raidlevel
-
-def mdadm(args, progress=None):
-    rc = iutil.execWithPulseProgress("mdadm", args,
-                                     stdout = "/dev/tty5",
-                                     stderr = "/dev/tty5",
-                                     progress=progress)
-    if not rc:
-        return
-
-    try:
-        # grab the last line of program.log and strip off the timestamp
-        msg = open("/tmp/program.log").readlines()[-1]
-        msg = msg.split("program: ", 1)[1].strip()
-    except Exception:
-        msg = ""
-
-    raise MDRaidError(msg)
-
-def mdcreate(device, level, disks, spares=0, metadataVer=None, bitmap=False,
-             progress=None):
-    argv = ["--create", device, "--run", "--level=%s" % level]
-    raid_devs = len(disks) - spares
-    argv.append("--raid-devices=%d" % raid_devs)
-    if spares:
-        argv.append("--spare-devices=%d" % spares)
-    if metadataVer:
-        argv.append("--metadata=%s" % metadataVer)
-    if bitmap:
-        argv.append("--bitmap=internal")
-    argv.extend(disks)
-    
-    try:
-        mdadm(argv, progress=progress)
-    except MDRaidError as msg:
-        raise MDRaidError("mdcreate failed for %s: %s" % (device, msg))
-
-def mddestroy(device):
-    args = ["--zero-superblock", device]
-
-    try:
-        mdadm(args)
-    except MDRaidError as msg:
-        raise MDRaidError("mddestroy failed for %s: %s" % (device, msg))
-
-def mdadd(device, no_degraded=False):
-    args = ["--incremental", "--quiet"]
-    if no_degraded:
-        args.append("--no-degraded")
-    args.append(device)
-
-    try:
-        mdadm(args)
-    except MDRaidError as msg:
-        raise MDRaidError("mdadd failed for %s: %s" % (device, msg))
-
-def mdactivate(device, members=[], super_minor=None, update_super_minor=False,
-               uuid=None):
-    if super_minor is None and not uuid:
-        raise ValueError("mdactivate requires either a uuid or a super-minor")
-    
-    if uuid:
-        identifier = "--uuid=%s" % uuid
-    elif super_minor is not None:
-        identifier = "--super-minor=%d" % super_minor
-    else:
-        identifier = ""
-
-    if update_super_minor:
-        extra_args = ["--update=super-minor"]
-    else:
-        extra_args = [ ]
-
-    args = ["--assemble", device, identifier, "--run", "--auto=md"]
-    args += extra_args
-    args += members
-
-    try:
-        mdadm(args)
-    except MDRaidError as msg:
-        raise MDRaidError("mdactivate failed for %s: %s" % (device, msg))
-
-def mddeactivate(device):
-    args = ["--stop", device]
-
-    try:
-        mdadm(args)
-    except MDRaidError as msg:
-        raise MDRaidError("mddeactivate failed for %s: %s" % (device, msg))
-
-def mdexamine(device):
-    vars = iutil.execWithCapture("mdadm",
-                                 ["--examine", "--brief", device],
-                                 stderr="/dev/tty5").split()
-
-    info = {}
-    if vars:
-        try:
-            info["device"] = vars[1]
-            vars = vars[2:]
-        except IndexError:
-            return {}
-
-    for var in vars:
-        (name, equals, value) = var.partition("=")
-        if not equals:
-            continue
-
-        info[name.lower()] = value.strip()
-
-    return info
-
diff --git a/storage/devicelibs/mpath.py b/storage/devicelibs/mpath.py
deleted file mode 100644
index adb2644..0000000
--- a/storage/devicelibs/mpath.py
+++ /dev/null
@@ -1,228 +0,0 @@
-from ..udev import *
-import iutil
-
-def parseMultipathOutput(output):
-    # this function parses output from "multipath -d", so we can use its
-    # logic for our topology.
-    # The input looks like:
-    # create: mpathb (1ATA     ST3120026AS                                         5M) undef ATA,ST3120026AS
-    # size=112G features='0' hwhandler='0' wp=undef
-    # `-+- policy='round-robin 0' prio=1 status=undef
-    #   `- 2:0:0:0 sda 8:0  undef ready running
-    # create: mpatha (36006016092d21800703762872c60db11) undef DGC,RAID 5
-    # size=10G features='1 queue_if_no_path' hwhandler='1 emc' wp=undef
-    # `-+- policy='round-robin 0' prio=2 status=undef
-    #   |- 6:0:0:0 sdb 8:16 undef ready running
-    #   `- 7:0:0:0 sdc 8:32 undef ready running
-    #
-    # (In anaconda, the first one there won't be included because we blacklist
-    # "ATA" as a vendor.)
-    #
-    # It returns a structure like:
-    # [ {'mpatha':['sdb','sdc']}, ... ]
-    mpaths = {}
-    if output is None:
-        return mpaths
-
-    name = None
-    devices = []
-
-    lines = output.split('\n')
-    for line in lines:
-        lexemes = line.split()
-        if not lexemes:
-            break
-        if lexemes[0] == 'create:':
-            if name and devices:
-                mpaths[name] = devices
-                name = None
-                devices = []
-            name = lexemes[1]
-        elif lexemes[0].startswith('size='):
-            pass
-        elif lexemes[0] == '`-+-':
-            pass
-        elif lexemes[0] in ['|-','`-']:
-            devices.append(lexemes[2].replace('!', '/'))
-    
-    if name and devices:
-        mpaths[name] = devices
-
-    return mpaths
-
-def identifyMultipaths(devices):
-    # this function does a couple of things
-    # 1) identifies multipath disks
-    # 2) sets their ID_FS_TYPE to multipath_member
-    # 3) removes the individual members of an mpath's partitions
-    # sample input with multipath pair [sdb,sdc]
-    # [sr0, sda, sda1, sdb, sdb1, sdb2, sdc, sdc1, sdd, sdd1, sdd2]
-    # sample output:
-    # [sda, sdd], [[sdb, sdc]], [sr0, sda1, sdd1, sdd2]]
-    log.info("devices to scan for multipath: %s" % [d['name'] for d in devices])
-
-    topology = parseMultipathOutput(iutil.execWithCapture("multipath", ["-d",]))
-    # find the devices that aren't in topology, and add them into it...
-    topodevs = reduce(lambda x,y: x.union(y), topology.values(), set())
-    for name in set([d['name'] for d in devices]).difference(topodevs):
-        topology[name] = [name]
-    
-    devmap = {}
-    non_disk_devices = {}
-    for d in devices:
-        if not udev_device_is_disk(d):
-            non_disk_devices[d['name']] = d
-            log.info("adding %s to non_disk_device list" % (d['name'],))
-            continue
-        devmap[d['name']] = d
-
-    singlepath_disks = []
-    multipaths = []
-
-    for name, disks in topology.items():
-        if len(disks) == 1:
-            if not non_disk_devices.has_key(disks[0]):
-                log.info("adding %s to singlepath_disks" % (disks[0],))
-                singlepath_disks.append(devmap[disks[0]])
-        else:
-            # some usb cardreaders use multiple lun's (for different slots)
-            # and report a fake disk serial which is the same for all the
-            # lun's (#517603)
-            all_usb = True
-            # see if we've got any non-disk devices on our mpath list.
-            # If so, they're probably false-positives.
-            non_disks = False
-            for disk in disks:
-                d = devmap[disk]
-                if d.get("ID_USB_DRIVER") != "usb-storage":
-                    all_usb = False
-                if (not devmap.has_key(disk)) and non_disk_devices.has_key(disk):
-                    log.warning("non-disk device %s is part of an mpath" %
-                                (disk,))
-                    non_disks = True
-
-            if all_usb:
-                log.info("adding multi lun usb mass storage device to singlepath_disks: %s" %
-                         (disks,))
-                singlepath_disks.extend([devmap[d] for d in disks])
-                continue
-
-            if non_disks:
-                for disk in disks:
-                    if devmap.has_key(disk):
-                        del devmap[disk]
-                    if topology.has_key(disk):
-                        del topology[disk]
-                continue
-
-            log.info("found multipath set: %s" % (disks,))
-            for disk in disks:
-                d = devmap[disk]
-                log.info("adding %s to multipath_disks" % (disk,))
-                d["ID_FS_TYPE"] = "multipath_member"
-                d["ID_MPATH_NAME"] = name
-            
-            multipaths.append([devmap[d] for d in disks])
-
-    non_disk_serials = {}
-    for name,device in non_disk_devices.items():
-        serial = udev_device_get_serial(device)
-        non_disk_serials.setdefault(serial, [])
-        non_disk_serials[serial].append(device)
-
-    for mpath in multipaths:
-        for serial in [d.get('ID_SERIAL_SHORT') for d in mpath]:
-            if non_disk_serials.has_key(serial):
-                log.info("filtering out non disk devices [%s]" % [d['name'] for d in non_disk_serials[serial]])
-                for name in [d['name'] for d in non_disk_serials[serial]]:
-                    if non_disk_devices.has_key(name):
-                        del non_disk_devices[name]
-
-    partition_devices = []
-    for device in non_disk_devices.values():
-        partition_devices.append(device)
-
-    # this is the list of devices we want to keep from the original
-    # device list, but we want to maintain its original order.
-    singlepath_disks = filter(lambda d: d in devices, singlepath_disks)
-    #multipaths = filter(lambda d: d in devices, multipaths)
-    partition_devices = filter(lambda d: d in devices, partition_devices)
-
-    mpathStr = "["
-    for mpath in multipaths:
-        mpathStr += str([d['name'] for d in mpath])
-    mpathStr += "]"
-
-    s = "(%s, %s, %s)" % ([d['name'] for d in singlepath_disks], \
-                          mpathStr, \
-                          [d['name'] for d in partition_devices])
-    log.info("devices post multipath scan: %s" % s)
-    return (singlepath_disks, multipaths, partition_devices)
-
-class MultipathConfigWriter:
-    def __init__(self):
-        self.blacklist_devices = []
-        self.mpaths = []
-
-    def addBlacklistDevice(self, device):
-        self.blacklist_devices.append(device)
-
-    def addMultipathDevice(self, mpath):
-        self.mpaths.append(mpath)
-
-    def write(self):
-        # if you add anything here, be sure and also add it to anaconda's
-        # multipath.conf
-        ret = ''
-        ret += """\
-# multipath.conf written by anaconda
-
-defaults {
-	user_friendly_names yes
-}
-blacklist {
-	devnode "^(ram|raw|loop|fd|md|dm-|sr|scd|st)[0-9]*"
-	devnode "^hd[a-z]"
-	devnode "^dcssblk[0-9]*"
-	device {
-		vendor "DGC"
-		product "LUNZ"
-	}
-	device {
-		vendor "IBM"
-		product "S/390.*"
-	}
-	# don't count normal SATA devices as multipaths
-	device {
-		vendor  "ATA"
-	}
-	# don't count 3ware devices as multipaths
-	device {
-		vendor  "3ware"
-	}
-	device {
-		vendor  "AMCC"
-	}
-	# nor highpoint devices
-	device {
-		vendor  "HPT"
-	}
-"""
-        for device in self.blacklist_devices:
-            if device.serial:
-                ret += '\twwid %s\n' % device.serial
-            elif device.vendor and device.model:
-                ret += '\tdevice {\n'
-                ret += '\t\tvendor %s\n' % device.vendor
-                ret += '\t\tproduct %s\n' % device.model
-                ret += '\t}\n'
-        ret += '}\n'
-        ret += 'multipaths {\n'
-        for mpath in self.mpaths:
-            ret += '\tmultipath {\n'
-            for k,v in mpath.config.items():
-                ret += '\t\t%s %s\n' % (k, v)
-            ret += '\t}\n'
-        ret += '}\n'
-
-        return ret
diff --git a/storage/devicelibs/swap.py b/storage/devicelibs/swap.py
deleted file mode 100644
index 92dfe93..0000000
--- a/storage/devicelibs/swap.py
+++ /dev/null
@@ -1,125 +0,0 @@
-# swap.py
-# Python module for managing swap devices.
-#
-# Copyright (C) 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, or (at your option) any later version.
-# 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.
-#
-# Red Hat Author(s): Dave Lehman <dlehman@xxxxxxxxxx>
-#
-
-import resource
-
-import iutil
-import os
-
-from ..errors import *
-from . import dm
-
-import gettext
-_ = lambda x: gettext.ldgettext("anaconda", x)
-
-
-def mkswap(device, label='', progress=None):
-    # We use -f to force since mkswap tends to refuse creation on lvs with
-    # a message about erasing bootbits sectors on whole disks. Bah.
-    argv = ["-f"]
-    if label:
-        argv.extend(["-L", label])
-    argv.append(device)
-
-    rc = iutil.execWithPulseProgress("mkswap", argv,
-                                     stderr = "/dev/tty5",
-                                     stdout = "/dev/tty5",
-                                     progress=progress)
-
-    if rc:
-        raise SwapError("mkswap failed for '%s'" % device)
-
-def swapon(device, priority=None):
-    pagesize = resource.getpagesize()
-    buf = None
-    sig = None
-
-    if pagesize > 2048:
-        num = pagesize
-    else:
-        num = 2048
-
-    try:
-        fd = os.open(device, os.O_RDONLY)
-        buf = os.read(fd, num)
-    except OSError:
-        pass
-    finally:
-        try:
-            os.close(fd)
-        except (OSError, UnboundLocalError):
-            pass
-
-    if buf is not None and len(buf) == pagesize:
-        sig = buf[pagesize - 10:]
-        if sig == 'SWAP-SPACE':
-            raise OldSwapError
-        if sig == 'S1SUSPEND\x00' or sig == 'S2SUSPEND\x00':
-            raise SuspendError
-
-    if sig != 'SWAPSPACE2':
-        raise UnknownSwapError
-
-    argv = []
-    if isinstance(priority, int) and 0 <= priority <= 32767:
-        argv.extend(["-p", "%d" % priority])
-    argv.append(device)
-        
-    rc = iutil.execWithRedirect("swapon",
-                                argv,
-                                stderr = "/dev/tty5",
-                                stdout = "/dev/tty5")
-
-    if rc:
-        raise SwapError("swapon failed for '%s'" % device)
-
-def swapoff(device):
-    rc = iutil.execWithRedirect("swapoff", [device],
-                                stderr = "/dev/tty5",
-                                stdout = "/dev/tty5")
-
-    if rc:
-        raise SwapError("swapoff failed for '%s'" % device)
-
-def swapstatus(device):
-    alt_dev = None
-    if device.startswith("/dev/mapper/"):
-        # get the real device node for device-mapper devices since the ones
-        # with meaningful names are just symlinks
-        try:
-            alt_dev = "/dev/%s" % dm.dm_node_from_name(device.split("/")[-1])
-        except DMError:
-            alt_dev = None
-
-    lines = open("/proc/swaps").readlines()
-    status = False
-    for line in lines:
-        if not line.strip():
-            continue
-
-        swap_dev = line.split()[0]
-        if swap_dev in [device, alt_dev]:
-            status = True
-            break
-
-    return status
-
diff --git a/storage/devices.py b/storage/devices.py
deleted file mode 100644
index d51cf6d..0000000
--- a/storage/devices.py
+++ /dev/null
@@ -1,3564 +0,0 @@
-# devices.py
-# Device classes for anaconda's storage configuration module.
-# 
-# Copyright (C) 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, or (at your option) any later version.
-# 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.
-#
-# Red Hat Author(s): Dave Lehman <dlehman@xxxxxxxxxx>
-#
-
-
-"""
-    Device classes for use by anaconda.
-
-    This is the hierarchy of device objects that anaconda will use for
-    managing storage devices in the system. These classes will
-    individually make use of external support modules as needed to
-    perform operations specific to the type of device they represent.
-
-    TODO:
-        - see how to do network devices (NetworkManager may help)
-          - perhaps just a wrapper here
-        - document return values of all methods/functions
-        - find out what other kinds of wild and crazy devices we need to
-          represent here (iseries? xen? more mainframe? mac? ps?)
-            - PReP
-              - this is a prime candidate for a PseudoDevice
-            - DASD
-            - ZFCP
-            - XEN
-
-    What specifications do we allow?              new        existing
-        partitions                              
-            usage                                  +            +
-                filesystem, partition type are implicit
-            mountpoint                             +            +
-            size
-                exact                              +            -
-                range                              +            -
-                resize                             -            +
-            format                                 -            +
-            encryption                             +            +
-
-            disk                                                 
-                exact                              +            -
-                set                                +            -
-                    how will we specify this?
-                        partition w/ multiple parents cannot otherwise occur
-            primary                                +            -
-
-        mdraid sets
-            filesystem (*)                         +            +
-            mountpoint                             +            +
-            size?                                                
-            format                                 -            +
-            encryption                             +            +
-
-            level                                  +            ? 
-            device minor                           +            ? 
-            member devices                         +            ? 
-            spares                                 +            ? 
-            name?
-            bitmap? (boolean)                      +            -
-
-        volume groups
-            name                                   +            - 
-            member pvs                             +            +
-            pesize                                 +            ?
-
-        logical volumes
-            filesystem                             +            +
-            mountpoint                             +            +
-            size
-                exact                              +            ?
-            format                                 -            +
-            encryption                             +            +
-
-            name                                   +            ?
-            vgname                                 +            ?
-
-
-"""
-
-import os
-import math
-import copy
-import time
-
-# device backend modules
-from devicelibs import mdraid
-from devicelibs import lvm
-from devicelibs import dm
-import parted
-import _ped
-import platform
-import block
-
-from errors import *
-from iutil import notify_kernel, numeric_type
-from .storage_log import log_method_call
-from udev import *
-from formats import get_device_format_class, getFormat, DeviceFormat
-
-import gettext
-_ = lambda x: gettext.ldgettext("anaconda", x)
-P_ = lambda x, y, z: gettext.ldngettext("anaconda", x, y, z)
-
-import logging
-log = logging.getLogger("storage")
-
-def get_device_majors():
-    majors = {}
-    for line in open("/proc/devices").readlines():
-        try:
-            (major, device) = line.split()
-        except ValueError:
-            continue
-        try:
-            majors[int(major)] = device
-        except ValueError:
-            continue
-    return majors
-device_majors = get_device_majors()
-
-
-def devicePathToName(devicePath):
-    if devicePath.startswith("/dev/"):
-        name = devicePath[5:]
-    else:
-        name = devicePath
-
-    if name.startswith("mapper/"):
-        name = name[7:]
-
-    return name
-
-
-def deviceNameToDiskByPath(deviceName=None):
-    if not deviceName:
-        return ""
-
-    for dev in udev_get_block_devices():
-        if udev_device_get_name(dev) == deviceName:
-            return udev_device_get_by_path(dev)
-
-    return None
-
-
-class Device(object):
-    """ A generic device.
-
-        Device instances know which devices they depend upon (parents
-        attribute). They do not know which devices depend upon them, but
-        they do know whether or not they have any dependent devices
-        (isleaf attribute).
-
-        A Device's setup method should set up all parent devices as well
-        as the device itself. It should not run the resident format's
-        setup method.
-
-            Which Device types rely on their parents' formats being active?
-                DMCryptDevice
-
-        A Device's teardown method should accept the keyword argument
-        recursive, which takes a boolean value and indicates whether or
-        not to recursively close parent devices.
-
-        A Device's create method should create all parent devices as well
-        as the device itself. It should also run the Device's setup method
-        after creating the device. The create method should not create a
-        device's resident format.
-
-            Which device type rely on their parents' formats to be created
-            before they can be created/assembled?
-                VolumeGroup
-                DMCryptDevice
-
-        A Device's destroy method should destroy any resident format
-        before destroying the device itself.
-
-    """
-
-    # This is a counter for generating unique ids for Devices.
-    _id = 0
-
-    _type = "generic device"
-    _packages = []
-
-    def __init__(self, name, parents=None):
-        """ Create a Device instance.
-
-            Arguments:
-
-                name -- the device name (generally a device node's basename)
-
-            Keyword Arguments:
-
-                parents -- a list of required Device instances
-
-        """
-        self._name = name
-        if parents is None:
-            parents = []
-        elif not isinstance(parents, list):
-            raise ValueError("parents must be a list of Device instances")
-        self.parents = parents
-        self.kids = 0
-
-        # Set this instance's id and increment the counter.
-        self.id = Device._id
-        Device._id += 1
-
-        for parent in self.parents:
-            parent.addChild()
-
-    def __deepcopy__(self, memo):
-        """ Create a deep copy of a Device instance.
-
-            We can't do copy.deepcopy on parted objects, which is okay.
-            For these parted objects, we just do a shallow copy.
-        """
-        new = self.__class__.__new__(self.__class__)
-        memo[id(self)] = new
-        dont_copy_attrs = ('_raidSet',)
-        shallow_copy_attrs = ('_partedDevice', '_partedPartition')
-        for (attr, value) in self.__dict__.items():
-            if attr in dont_copy_attrs:
-                setattr(new, attr, value)
-            elif attr in shallow_copy_attrs:
-                setattr(new, attr, copy.copy(value))
-            else:
-                setattr(new, attr, copy.deepcopy(value, memo))
-
-        return new
-
-    def __str__(self):
-        s = ("%(type)s instance (%(id)s) --\n"
-             "  name = %(name)s  status = %(status)s"
-             "  parents = %(parents)s\n"
-             "  kids = %(kids)s\n"
-             "  id = %(dev_id)s\n" %
-             {"type": self.__class__.__name__, "id": "%#x" % id(self),
-              "name": self.name, "parents": self.parents, "kids": self.kids,
-              "status": self.status, "dev_id": self.id})
-        return s
-
-    @property
-    def dict(self):
-        d =  {"type": self.type, "name": self.name,
-              "parents": [p.name for p in self.parents]}
-        return d
-
-    def writeKS(self, f, preexisting=False, noformat=False, s=None):
-        return
-
-    def removeChild(self):
-        log_method_call(self, name=self.name, kids=self.kids)
-        self.kids -= 1
-
-    def addChild(self):
-        log_method_call(self, name=self.name, kids=self.kids)
-        self.kids += 1
-
-    def setup(self, intf=None):
-        """ Open, or set up, a device. """
-        raise NotImplementedError("setup method not defined for Device")
-
-    def teardown(self, recursive=None):
-        """ Close, or tear down, a device. """
-        raise NotImplementedError("teardown method not defined for Device")
-
-    def create(self, intf=None):
-        """ Create the device. """
-        raise NotImplementedError("create method not defined for Device")
-
-    def destroy(self):
-        """ Destroy the device. """
-        raise NotImplementedError("destroy method not defined for Device")
-
-    def setupParents(self, orig=False):
-        """ Run setup method of all parent devices. """
-        log_method_call(self, name=self.name, orig=orig, kids=self.kids)
-        for parent in self.parents:
-            parent.setup(orig=orig)
-
-    def teardownParents(self, recursive=None):
-        """ Run teardown method of all parent devices. """
-        for parent in self.parents:
-            parent.teardown(recursive=recursive)
-
-    def createParents(self):
-        """ Run create method of all parent devices. """
-        log.info("NOTE: recursive device creation disabled")
-        for parent in self.parents:
-            if not parent.exists:
-                raise DeviceError("parent device does not exist", self.name)
-            #parent.create()
-
-    def dependsOn(self, dep):
-        """ Return True if this device depends on dep. """
-        # XXX does a device depend on itself?
-        if dep in self.parents:
-            return True
-
-        for parent in self.parents:
-            if parent.dependsOn(dep):
-                return True
-
-        return False
-
-    def dracutSetupString(self):
-        return ""
-
-    @property
-    def status(self):
-        """ This device's status.
-
-            For now, this should return a boolean:
-                True    the device is open and ready for use
-                False   the device is not open
-        """
-        return False
-
-    @property
-    def name(self):
-        """ This device's name. """
-        return self._name
-
-    @property
-    def isleaf(self):
-        """ True if this device has no children. """
-        return self.kids == 0
-
-    @property
-    def typeDescription(self):
-        """ String describing the device type. """
-        return self._type
-
-    @property
-    def type(self):
-        """ Device type. """
-        return self._type
-
-    @property
-    def packages(self):
-        """ List of packages required to manage devices of this type.
-
-            This list includes the packages required by its parent devices.
-        """
-        packages = self._packages
-        for parent in self.parents:
-            for package in parent.packages:
-                if package not in packages:
-                    packages.append(package)
-
-        return packages
-
-    @property
-    def mediaPresent(self):
-        return True
-
-
-class NetworkStorageDevice(object):
-    """ Virtual base class for network backed storage devices """
-
-    def __init__(self, host_address=None, nic=None):
-        """ Create a NetworkStorage Device instance. Note this class is only
-            to be used as a baseclass and then only with multiple inheritance.
-            The only correct use is:
-            class MyStorageDevice(StorageDevice, NetworkStorageDevice):
-
-            The sole purpose of this class is to:
-            1) Be able to check if a StorageDevice is network backed
-               (using isinstance).
-            2) To be able to get the host address of the host (server) backing
-               the storage *or* the NIC through which the storage is connected
-
-            Arguments:
-
-                host_address -- host address of the backing server
-                nic -- nic to which the storage is bound
-        """
-        self.host_address = host_address
-        self.nic = nic
-
-
-class StorageDevice(Device):
-    """ A generic storage device.
-
-        A fully qualified path to the device node can be obtained via the
-        path attribute, although it is not guaranteed to be useful, or
-        even present, unless the StorageDevice's setup method has been
-        run.
-
-        StorageDevice instances can optionally contain a filesystem,
-        represented by an FS instance. A StorageDevice's create method
-        should create a filesystem if one has been specified.
-    """
-    _type = "storage device"
-    _devDir = "/dev"
-    sysfsBlockDir = "class/block"
-    _resizable = False
-    _partitionable = False
-    _isDisk = False
-
-    def __init__(self, device, format=None,
-                 size=None, major=None, minor=None,
-                 sysfsPath='', parents=None, exists=None, serial=None,
-                 vendor="", model="", bus=""):
-        """ Create a StorageDevice instance.
-
-            Arguments:
-
-                device -- the device name (generally a device node's basename)
-
-            Keyword Arguments:
-
-                size -- the device's size (units/format TBD)
-                major -- the device major
-                minor -- the device minor
-                sysfsPath -- sysfs device path
-                format -- a DeviceFormat instance
-                parents -- a list of required Device instances
-                serial -- the ID_SERIAL_SHORT for this device
-                vendor -- the manufacturer of this Device
-                model -- manufacturer's device model string
-                bus -- the interconnect this device uses
-
-        """
-        # allow specification of individual parents
-        if isinstance(parents, Device):
-            parents = [parents]
-
-        self.exists = exists
-        Device.__init__(self, device, parents=parents)
-
-        self.uuid = None
-        self._format = None
-        self._size = numeric_type(size)
-        self.major = numeric_type(major)
-        self.minor = numeric_type(minor)
-        self.sysfsPath = sysfsPath
-        self._serial = serial
-        self._vendor = vendor
-        self._model = model
-        self.bus = bus
-
-        self.protected = False
-
-        self.format = format
-        self.originalFormat = self.format
-        self.fstabComment = ""
-        self._targetSize = self._size
-
-        self._partedDevice = None
-
-    @property
-    def packages(self):
-        """ List of packages required to manage devices of this type.
-
-            This list includes the packages required by this device's
-            format type as well those required by all of its parent 
-            devices.
-        """
-        packages = super(StorageDevice, self).packages
-        packages.extend(self.format.packages)
-        for parent in self.parents:
-            for package in parent.format.packages:
-                if package not in packages:
-                    packages.append(package)
-
-        return packages
-
-    @property
-    def partedDevice(self):
-        if self.exists and self.status and not self._partedDevice:
-            log.debug("looking up parted Device: %s" % self.path)
-
-            # We aren't guaranteed to be able to get a device.  In
-            # particular, built-in USB flash readers show up as devices but
-            # do not always have any media present, so parted won't be able
-            # to find a device.
-            try:
-                self._partedDevice = parted.Device(path=self.path)
-            except (_ped.IOException, _ped.DeviceException):
-                pass
-
-        return self._partedDevice
-
-    def _getTargetSize(self):
-        return self._targetSize
-
-    def _setTargetSize(self, newsize):
-        self._targetSize = newsize
-
-    targetSize = property(lambda s: s._getTargetSize(),
-                          lambda s, v: s._setTargetSize(v),
-                          doc="Target size of this device")
-
-    def __str__(self):
-        s = Device.__str__(self)
-        s += ("  uuid = %(uuid)s  format = %(format)r  size = %(size)s\n"
-              "  major = %(major)s  minor = %(minor)r  exists = %(exists)s\n"
-              "  sysfs path = %(sysfs)s  partedDevice = %(partedDevice)r\n"
-              "  target size = %(targetSize)s  path = %(path)s\n"
-              "  format args = %(formatArgs)s  originalFormat = %(origFmt)s" %
-              {"uuid": self.uuid, "format": self.format, "size": self.size,
-               "major": self.major, "minor": self.minor, "exists": self.exists,
-               "sysfs": self.sysfsPath, "partedDevice": self.partedDevice,
-               "targetSize": self.targetSize, "path": self.path,
-               "formatArgs": self.formatArgs, "origFmt": self.originalFormat})
-        return s
-
-    @property
-    def dict(self):
-        d =  super(StorageDevice, self).dict
-        d.update({"uuid": self.uuid, "size": self.size,
-                  "format": self.format.dict, "removable": self.removable,
-                  "major": self.major, "minor": self.minor,
-                  "exists": self.exists, "sysfs": self.sysfsPath,
-                  "targetSize": self.targetSize, "path": self.path})
-        return d
-
-    @property
-    def path(self):
-        """ Device node representing this device. """
-        return "%s/%s" % (self._devDir, self.name)
-
-    def updateSysfsPath(self):
-        """ Update this device's sysfs path. """
-        log_method_call(self, self.name, status=self.status)
-        sysfsName = self.name.replace("/", "!")
-        path = os.path.join("/sys", self.sysfsBlockDir, sysfsName)
-        self.sysfsPath = os.path.realpath(path)[4:]
-        log.debug("%s sysfsPath set to %s" % (self.name, self.sysfsPath))
-
-    @property
-    def formatArgs(self):
-        """ Device-specific arguments to format creation program. """
-        return []
-
-    @property
-    def resizable(self):
-        """ Can this type of device be resized? """
-        return self._resizable and self.exists and \
-               ((self.format and self.format.resizable) or not self.format)
-
-    def notifyKernel(self):
-        """ Send a 'change' uevent to the kernel for this device. """
-        log_method_call(self, self.name, status=self.status)
-        if not self.exists:
-            log.debug("not sending change uevent for non-existent device")
-            return
-
-        if not self.status:
-            log.debug("not sending change uevent for inactive device")
-            return
-
-        path = os.path.normpath("/sys/%s" % self.sysfsPath)
-        try:
-            notify_kernel(path, action="change")
-        except Exception, e:
-            log.warning("failed to notify kernel of change: %s" % e)
-
-    @property
-    def fstabSpec(self):
-        spec = self.path
-        if self.format and self.format.uuid:
-            spec = "UUID=%s" % self.format.uuid
-        return spec
-
-    def resize(self, intf=None):
-        """ Resize the device.
-
-            New size should already be set.
-        """
-        raise NotImplementedError("resize method not defined for StorageDevice")
-
-    def setup(self, intf=None, orig=False):
-        """ Open, or set up, a device. """
-        log_method_call(self, self.name, orig=orig, status=self.status)
-        if not self.exists:
-            raise DeviceError("device has not been created", self.name)
-
-        self.setupParents(orig=orig)
-        for parent in self.parents:
-            if orig:
-                parent.originalFormat.setup()
-            else:
-                parent.format.setup()
-
-    def teardown(self, recursive=None):
-        """ Close, or tear down, a device. """
-        log_method_call(self, self.name, status=self.status)
-        if not self.exists and not recursive:
-            raise DeviceError("device has not been created", self.name)
-
-        if self.status:
-            if self.originalFormat.exists:
-                self.originalFormat.teardown()
-            if self.format.exists:
-                self.format.teardown()
-            udev_settle()
-
-        if recursive:
-            self.teardownParents(recursive=recursive)
-
-    def _getSize(self):
-        """ Get the device's size in MB, accounting for pending changes. """
-        if self.exists and not self.mediaPresent:
-            return 0
-
-        if self.exists and self.partedDevice:
-            self._size = self.currentSize
-
-        size = self._size
-        if self.exists and self.resizable and self.targetSize != size:
-            size = self.targetSize
-
-        return size
-
-    def _setSize(self, newsize):
-        """ Set the device's size to a new value. """
-        if newsize > self.maxSize:
-            raise DeviceError("device cannot be larger than %s MB" %
-                              (self.maxSize(),), self.name)
-        self._size = newsize
-
-    size = property(lambda x: x._getSize(),
-                    lambda x, y: x._setSize(y),
-                    doc="The device's size in MB, accounting for pending changes")
-
-    @property
-    def currentSize(self):
-        """ The device's actual size. """
-        size = 0
-        if self.exists and self.partedDevice:
-            size = self.partedDevice.getSize()
-        elif self.exists:
-            size = self._size
-        return size
-
-    @property
-    def minSize(self):
-        """ The minimum size this device can be. """
-        if self.format.minSize:
-            return self.format.minSize
-        else:
-            return self.size
-
-    @property
-    def maxSize(self):
-        """ The maximum size this device can be. """
-        if self.format.maxSize > self.currentSize:
-            return self.currentSize
-        else:
-            return self.format.maxSize
-
-    @property
-    def status(self):
-        """ This device's status.
-
-            For now, this should return a boolean:
-                True    the device is open and ready for use
-                False   the device is not open
-        """
-        if not self.exists:
-            return False
-        return os.access(self.path, os.W_OK)
-
-    def _setFormat(self, format):
-        """ Set the Device's format. """
-        if not format:
-            format = getFormat(None, device=self.path, exists=self.exists)
-        log_method_call(self, self.name, type=format.type,
-                        current=getattr(self._format, "type", None))
-        if self._format and self._format.status:
-            # FIXME: self.format.status doesn't mean much
-            raise DeviceError("cannot replace active format", self.name)
-
-        self._format = format
-
-    def _getFormat(self):
-        return self._format
-
-    format = property(lambda d: d._getFormat(),
-                      lambda d,f: d._setFormat(f),
-                      doc="The device's formatting.")
-
-    def preCommitFixup(self, *args, **kwargs):
-        """ Do any necessary pre-commit fixups."""
-        pass
-
-    def create(self, intf=None):
-        """ Create the device. """
-        log_method_call(self, self.name, status=self.status)
-        if self.exists:
-            raise DeviceError("device has already been created", self.name)
-
-        self.createParents()
-        self.setupParents()
-        self.exists = True
-        self.setup()
-
-    def destroy(self):
-        """ Destroy the device. """
-        log_method_call(self, self.name, status=self.status)
-        if not self.exists:
-            raise DeviceError("device has not been created", self.name)
-
-        if not self.isleaf:
-            raise DeviceError("Cannot destroy non-leaf device", self.name)
-
-        self.exists = False
-        # we already did this in DeviceTree._removeDevice
-        #for parent in self.parents:
-        #    parent.removeChild()
-
-    @property
-    def removable(self):
-        devpath = os.path.normpath("/sys/%s" % self.sysfsPath)
-        remfile = os.path.normpath("%s/removable" % devpath)
-        return (self.sysfsPath and os.path.exists(devpath) and
-                os.access(remfile, os.R_OK) and
-                open(remfile).readline().strip() == "1")
-
-    @property
-    def isDisk(self):
-        return self._isDisk
-
-    @property
-    def partitionable(self):
-        return self._partitionable
-
-    @property
-    def partitioned(self):
-        return self.format.type == "disklabel" and self.partitionable
-
-    @property
-    def serial(self):
-        return self._serial
-
-    @property
-    def model(self):
-        if not self._model:
-            self._model = getattr(self.partedDevice, "model", "")
-        return self._model
-
-    @property
-    def vendor(self):
-        return self._vendor
-
-class DiskDevice(StorageDevice):
-    """ A disk """
-    _type = "disk"
-    _partitionable = True
-    _isDisk = True
-
-    def __init__(self, device, format=None,
-                 size=None, major=None, minor=None, sysfsPath='',
-                 parents=None, serial=None, vendor="", model="", bus="",
-                 exists=True):
-        """ Create a DiskDevice instance.
-
-            Arguments:
-
-                device -- the device name (generally a device node's basename)
-
-            Keyword Arguments:
-
-                size -- the device's size (units/format TBD)
-                major -- the device major
-                minor -- the device minor
-                sysfsPath -- sysfs device path
-                format -- a DeviceFormat instance
-                parents -- a list of required Device instances
-                removable -- whether or not this is a removable device
-                serial -- the ID_SERIAL_SHORT for this device
-                vendor -- the manufacturer of this Device
-                model -- manufacturer's device model string
-                bus -- the interconnect this device uses
-
-
-            DiskDevices always exist.
-        """
-        StorageDevice.__init__(self, device, format=format, size=size,
-                               major=major, minor=minor, exists=exists,
-                               sysfsPath=sysfsPath, parents=parents,
-                               serial=serial, model=model,
-                               vendor=vendor, bus=bus)
-
-    def __str__(self):
-        s = StorageDevice.__str__(self)
-        s += ("  removable = %(removable)s  partedDevice = %(partedDevice)r" %
-              {"removable": self.removable, "partedDevice": self.partedDevice})
-        return s
-
-    @property
-    def mediaPresent(self):
-        if not self.partedDevice:
-            return False
-
-        # Some drivers (cpqarray <blegh>) make block device nodes for
-        # controllers with no disks attached and then report a 0 size,
-        # treat this as no media present
-        return self.partedDevice.getSize() != 0
-
-    @property
-    def description(self):
-        return self.model
-
-    @property
-    def size(self):
-        """ The disk's size in MB """
-        return super(DiskDevice, self).size
-    #size = property(StorageDevice._getSize)
-
-    def probe(self):
-        """ Probe for any missing information about this device.
-
-            pyparted should be able to tell us anything we want to know.
-            size, disklabel type, maybe even partition layout
-        """
-        log_method_call(self, self.name, size=self.size, partedDevice=self.partedDevice)
-
-    def destroy(self):
-        """ Destroy the device. """
-        log_method_call(self, self.name, status=self.status)
-        if not self.mediaPresent:
-            raise DeviceError("cannot destroy disk with no media", self.name)
-
-        self.teardown()
-
-    def setup(self, intf=None, orig=False):
-        """ Open, or set up, a device. """
-        log_method_call(self, self.name, orig=orig, status=self.status)
-        if not os.path.exists(self.path):
-            raise DeviceError("device does not exist", self.name)
-
-
-class PartitionDevice(StorageDevice):
-    """ A disk partition.
-
-        On types and flags...
-
-        We don't need to deal with numerical partition types at all. The
-        only type we are concerned with is primary/logical/extended. Usage
-        specification is accomplished through the use of flags, which we
-        will set according to the partition's format.
-    """
-    _type = "partition"
-    _resizable = True
-    defaultSize = 500
-
-    def __init__(self, name, format=None,
-                 size=None, grow=False, maxsize=None,
-                 major=None, minor=None, bootable=None,
-                 sysfsPath='', parents=None, exists=None,
-                 partType=None, primary=False, weight=0):
-        """ Create a PartitionDevice instance.
-
-            Arguments:
-
-                name -- the device name (generally a device node's basename)
-
-            Keyword Arguments:
-
-                exists -- indicates whether this is an existing device
-                format -- the device's format (DeviceFormat instance)
-
-                For existing partitions:
-
-                    parents -- the disk that contains this partition
-                    major -- the device major
-                    minor -- the device minor
-                    sysfsPath -- sysfs device path
-
-                For new partitions:
-
-                    partType -- primary,extended,&c (as parted constant)
-                    grow -- whether or not to grow the partition
-                    maxsize -- max size for growable partitions (in MB)
-                    size -- the device's size (in MB)
-                    bootable -- whether the partition is bootable
-                    parents -- a list of potential containing disks
-                    weight -- an initial sorting weight to assign
-        """
-        self.req_disks = []
-        self.req_partType = None
-        self.req_primary = None
-        self.req_grow = None
-        self.req_bootable = None
-        self.req_size = 0
-        self.req_base_size = 0
-        self.req_max_size = 0
-        self.req_base_weight = 0
-
-        self._bootable = False
-
-        StorageDevice.__init__(self, name, format=format, size=size,
-                               major=major, minor=minor, exists=exists,
-                               sysfsPath=sysfsPath, parents=parents)
-
-        if not exists:
-            # this is a request, not a partition -- it has no parents
-            self.req_disks = self.parents[:]
-            for dev in self.parents:
-                dev.removeChild()
-            self.parents = []
-
-        # FIXME: Validate partType, but only if this is a new partition
-        #        Otherwise, overwrite it with the partition's type.
-        self._partType = None
-        self.partedFlags = {}
-        self._partedPartition = None
-        self._origPath = None
-        self._currentSize = 0
-
-        # FIXME: Validate size, but only if this is a new partition.
-        #        For existing partitions we will get the size from
-        #        parted.
-
-        if self.exists:
-            log.debug("looking up parted Partition: %s" % self.path)
-            self._partedPartition = self.disk.format.partedDisk.getPartitionByPath(self.path)
-            if not self._partedPartition:
-                raise DeviceError("cannot find parted partition instance", self.name)
-
-            self._origPath = self.path
-            # collect information about the partition from parted
-            self.probe()
-            if self.getFlag(parted.PARTITION_PREP):
-                # the only way to identify a PPC PReP Boot partition is to
-                # check the partition type/flags, so do it here.
-                self.format = getFormat("prepboot", device=self.path, exists=True)
-        else:
-            # XXX It might be worthwhile to create a shit-simple
-            #     PartitionRequest class and pass one to this constructor
-            #     for new partitions.
-            if not self._size:
-                # default size for new partition requests
-                self._size = self.defaultSize
-            self.req_name = name
-            self.req_partType = partType
-            self.req_primary = primary
-            self.req_max_size = numeric_type(maxsize)
-            self.req_grow = grow
-            self.req_bootable = bootable
-
-            # req_size may be manipulated in the course of partitioning
-            self.req_size = self._size
-
-            # req_base_size will always remain constant
-            self.req_base_size = self._size
-
-            self.req_base_weight = weight
-
-    def __str__(self):
-        s = StorageDevice.__str__(self)
-        s += ("  grow = %(grow)s  max size = %(maxsize)s  bootable = %(bootable)s\n"
-              "  part type = %(partType)s  primary = %(primary)s\n"
-              "  partedPartition = %(partedPart)r  disk = %(disk)r\n" %
-              {"grow": self.req_grow, "maxsize": self.req_max_size,
-               "bootable": self.bootable, "partType": self.partType,
-               "primary": self.req_primary,
-               "partedPart": self.partedPartition, "disk": self.disk})
-
-        if self.partedPartition:
-            s += ("  start = %(start)s  end = %(end)s  length = %(length)s\n"
-                  "  flags = %(flags)s" %
-                  {"length": self.partedPartition.geometry.length,
-                   "start": self.partedPartition.geometry.start,
-                   "end": self.partedPartition.geometry.end,
-                   "flags": self.partedPartition.getFlagsAsString()})
-
-        return s
-
-    @property
-    def dict(self):
-        d = super(PartitionDevice, self).dict
-        d.update({"type": self.partType})
-        if not self.exists:
-            d.update({"grow": self.req_grow, "maxsize": self.req_max_size,
-                      "bootable": self.bootable,
-                      "primary": self.req_primary})
-
-        if self.partedPartition:
-            d.update({"length": self.partedPartition.geometry.length,
-                      "start": self.partedPartition.geometry.start,
-                      "end": self.partedPartition.geometry.end,
-                      "flags": self.partedPartition.getFlagsAsString()})
-        return d
-
-    def writeKS(self, f, preexisting=False, noformat=False, s=None):
-        args = []
-
-        if self.isExtended:
-            return
-
-        if self.req_grow:
-            args.append("--grow")
-        if self.req_max_size:
-            args.append("--maxsize=%s" % self.req_max_size)
-        if self.req_primary:
-            args.append("--asprimary")
-        if self.req_size:
-            args.append("--size=%s" % (self.req_size or self.defaultSize))
-        if preexisting:
-            if len(self.req_disks) == 1:
-                args.append("--ondisk=%s" % self.req_disks[0].name)
-            else:
-                args.append("--onpart=%s" % self.name)
-        if noformat:
-            args.append("--noformat")
-
-        f.write("#part ")
-        self.format.writeKS(f)
-        f.write(" %s" % " ".join(args))
-        if s:
-            f.write(" %s" % s)
-
-    def _setTargetSize(self, newsize):
-        if newsize != self.currentSize:
-            # change this partition's geometry in-memory so that other
-            # partitioning operations can complete (e.g., autopart)
-            self._targetSize = newsize
-            disk = self.disk.format.partedDisk
-
-            # resize the partition's geometry in memory
-            (constraint, geometry) = self._computeResize(self.partedPartition)
-            disk.setPartitionGeometry(partition=self.partedPartition,
-                                      constraint=constraint,
-                                      start=geometry.start, end=geometry.end)
-
-    @property
-    def path(self):
-        """ Device node representing this device. """
-        if not self.parents:
-            # Bogus, but code in various places compares devices by path
-            # So we must return something unique
-            return self.name
-
-        return "%s/%s" % (self.parents[0]._devDir, self.name)
-
-    @property
-    def partType(self):
-        """ Get the partition's type (as parted constant). """
-        try:
-            ptype = self.partedPartition.type
-        except AttributeError:
-            ptype = self._partType
-
-        if not self.exists and ptype is None:
-            ptype = self.req_partType
-
-        return ptype
-
-    @property
-    def isExtended(self):
-        return (self.partType is not None and
-                self.partType & parted.PARTITION_EXTENDED)
-
-    @property
-    def isLogical(self):
-        return (self.partType is not None and
-                self.partType & parted.PARTITION_LOGICAL)
-
-    @property
-    def isPrimary(self):
-        return (self.partType is not None and
-                self.partType == parted.PARTITION_NORMAL)
-
-    @property
-    def isProtected(self):
-        return (self.partType is not None and
-                self.partType & parted.PARTITION_PROTECTED)
-
-    @property
-    def fstabSpec(self):
-        spec = self.path
-        if self.disk and self.disk.type == 'dasd':
-            spec = deviceNameToDiskByPath(self.name)
-        elif self.format and self.format.uuid:
-            spec = "UUID=%s" % self.format.uuid
-        return spec
-
-    def _getPartedPartition(self):
-        return self._partedPartition
-
-    def _setPartedPartition(self, partition):
-        """ Set this PartitionDevice's parted Partition instance. """
-        log_method_call(self, self.name)
-        if partition is None:
-            path = None
-        elif isinstance(partition, parted.Partition):
-            path = partition.path
-        else:
-            raise ValueError("partition must be a parted.Partition instance")
-
-        log.debug("device %s new partedPartition %s has path %s" % (self.name,
-                                                                    partition,
-                                                                    path))
-        self._partedPartition = partition
-        self.updateName()
-
-    partedPartition = property(lambda d: d._getPartedPartition(),
-                               lambda d,p: d._setPartedPartition(p))
-
-    def preCommitFixup(self, *args, **kwargs):
-        """ Re-get self.partedPartition from the original disklabel. """
-        log_method_call(self, self.name)
-        if not self.exists:
-            return
-
-        # find the correct partition on the original parted.Disk since the
-        # name/number we're now using may no longer match
-        _disklabel = self.disk.originalFormat
-
-        if self.isExtended:
-            # getPartitionBySector doesn't work on extended partitions
-            _partition = _disklabel.extendedPartition
-            log.debug("extended lookup found partition %s"
-                        % devicePathToName(getattr(_partition, "path", None)))
-        else:
-            # lookup the partition by sector to avoid the renumbering
-            # nonsense entirely
-            _sector = self.partedPartition.geometry.start
-            _partition = _disklabel.partedDisk.getPartitionBySector(_sector)
-            log.debug("sector-based lookup found partition %s"
-                        % devicePathToName(getattr(_partition, "path", None)))
-
-        self.partedPartition = _partition
-
-    def _getWeight(self):
-        return self.req_base_weight
-
-    def _setWeight(self, weight):
-        self.req_base_weight = weight
-
-    weight = property(lambda d: d._getWeight(),
-                      lambda d,w: d._setWeight(w))
-
-    def updateSysfsPath(self):
-        """ Update this device's sysfs path. """
-        log_method_call(self, self.name, status=self.status)
-        if not self.parents:
-            self.sysfsPath = ''
-
-        elif self.parents[0]._devDir == "/dev/mapper":
-            dm_node = dm.dm_node_from_name(self.name)
-            path = os.path.join("/sys", self.sysfsBlockDir, dm_node)
-            self.sysfsPath = os.path.realpath(path)[4:]
-
-        else:
-            StorageDevice.updateSysfsPath(self)
-
-    def updateName(self):
-        if self.partedPartition is None:
-            self._name = self.req_name
-        else:
-            self._name = \
-                devicePathToName(self.partedPartition.getDeviceNodeName())
-
-    def dependsOn(self, dep):
-        """ Return True if this device depends on dep. """
-        if isinstance(dep, PartitionDevice) and dep.isExtended and \
-           self.isLogical and self.disk == dep.disk:
-            return True
-
-        return Device.dependsOn(self, dep)
-
-    def _setFormat(self, format):
-        """ Set the Device's format. """
-        log_method_call(self, self.name)
-        StorageDevice._setFormat(self, format)
-
-    def _setBootable(self, bootable):
-        """ Set the bootable flag for this partition. """
-        if self.partedPartition:
-            if iutil.isS390():
-                return
-            if self.flagAvailable(parted.PARTITION_BOOT):
-                if bootable:
-                    self.setFlag(parted.PARTITION_BOOT)
-                else:
-                    self.unsetFlag(parted.PARTITION_BOOT)
-            else:
-                raise DeviceError("boot flag not available for this partition", self.name)
-
-            self._bootable = bootable
-        else:
-            self.req_bootable = bootable
-
-    def _getBootable(self):
-        return self._bootable or self.req_bootable
-
-    bootable = property(_getBootable, _setBootable)
-
-    def flagAvailable(self, flag):
-        log_method_call(self, path=self.path, flag=flag)
-        if not self.partedPartition:
-            return
-
-        return self.partedPartition.isFlagAvailable(flag)
-
-    def getFlag(self, flag):
-        log_method_call(self, path=self.path, flag=flag)
-        if not self.partedPartition or not self.flagAvailable(flag):
-            return
-
-        return self.partedPartition.getFlag(flag)
-
-    def setFlag(self, flag):
-        log_method_call(self, path=self.path, flag=flag)
-        if not self.partedPartition or not self.flagAvailable(flag):
-            return
-
-        self.partedPartition.setFlag(flag)
-
-    def unsetFlag(self, flag):
-        log_method_call(self, path=self.path, flag=flag)
-        if not self.partedPartition or not self.flagAvailable(flag):
-            return
-
-        self.partedPartition.unsetFlag(flag)
-
-    def probe(self):
-        """ Probe for any missing information about this device.
-
-            size, partition type, flags
-        """
-        log_method_call(self, self.name, exists=self.exists)
-        if not self.exists:
-            return
-
-        # this is in MB
-        self._size = self.partedPartition.getSize()
-        self._currentSize = self._size
-        self.targetSize = self._size
-
-        self._partType = self.partedPartition.type
-
-        self._bootable = self.getFlag(parted.PARTITION_BOOT)
-
-    def create(self, intf=None):
-        """ Create the device. """
-        log_method_call(self, self.name, status=self.status)
-        if self.exists:
-            raise DeviceError("device already exists", self.name)
-
-        w = None
-        if intf:
-            w = intf.waitWindow(_("Creating"),
-                                _("Creating device %s") % (self.path,))
-
-        try:
-            self.createParents()
-            self.setupParents()
-
-            self.disk.format.addPartition(self.partedPartition)
-
-            try:
-                self.disk.format.commit()
-            except DiskLabelCommitError:
-                part = self.disk.format.partedDisk.getPartitionByPath(self.path)
-                self.disk.format.removePartition(part)
-                raise
-
-            if not self.isExtended:
-                # Ensure old metadata which lived in freespace so did not get
-                # explictly destroyed by a destroyformat action gets wiped
-                DeviceFormat(device=self.path, exists=True).destroy()
-        except Exception:
-            raise
-        else:
-            self.partedPartition = self.disk.format.partedDisk.getPartitionByPath(self.path)
-
-            self.exists = True
-            self._currentSize = self.partedPartition.getSize()
-            self.setup()
-        finally:
-            if w:
-                w.pop()
-
-    def _computeResize(self, partition):
-        log_method_call(self, self.name, status=self.status)
-
-        # compute new size for partition
-        currentGeom = partition.geometry
-        currentDev = currentGeom.device
-        newLen = long(self.targetSize * 1024 * 1024) / currentDev.sectorSize
-        newGeometry = parted.Geometry(device=currentDev,
-                                      start=currentGeom.start,
-                                      length=newLen)
-        # and align the end sector
-        newGeometry.end = self.disk.format.endAlignment.alignDown(newGeometry,
-                                                               newGeometry.end)
-        constraint = parted.Constraint(exactGeom=newGeometry)
-
-        return (constraint, newGeometry)
-
-    def resize(self, intf=None):
-        """ Resize the device.
-
-            self.targetSize must be set to the new size.
-        """
-        log_method_call(self, self.name, status=self.status)
-
-        if self.targetSize != self.currentSize:
-            # partedDisk has been restored to _origPartedDisk, so
-            # recalculate resize geometry because we may have new
-            # partitions on the disk, which could change constraints
-            partedDisk = self.disk.format.partedDisk
-            partition = partedDisk.getPartitionByPath(self.path)
-            (constraint, geometry) = self._computeResize(partition)
-
-            partedDisk.setPartitionGeometry(partition=partition,
-                                            constraint=constraint,
-                                            start=geometry.start,
-                                            end=geometry.end)
-
-            self.disk.format.commit()
-            self._currentSize = partition.getSize()
-
-    def destroy(self):
-        """ Destroy the device. """
-        log_method_call(self, self.name, status=self.status)
-        if not self.exists:
-            raise DeviceError("device has not been created", self.name)
-
-        if not self.sysfsPath:
-            return
-
-        if not self.isleaf:
-            raise DeviceError("Cannot destroy non-leaf device", self.name)
-
-        self.setupParents(orig=True)
-
-        # we should have already set self.partedPartition to point to the
-        # partition on the original disklabel
-        self.disk.originalFormat.removePartition(self.partedPartition)
-        self.disk.originalFormat.commit()
-
-        self.exists = False
-
-    def teardown(self, recursive=None):
-        """ Close, or tear down, a device. """
-        log_method_call(self, self.name, status=self.status)
-        if not self.exists and not recursive:
-            raise DeviceError("device has not been created", self.name)
-
-        if self.status:
-            if self.originalFormat.exists:
-                self.originalFormat.teardown()
-            if self.format.exists:
-                self.format.teardown()
-            if self.parents[0].type == 'dm-multipath':
-                devmap = block.getMap(major=self.major, minor=self.minor)
-                if devmap:
-                    try:
-                        block.removeDeviceMap(devmap)
-                    except Exception as e:
-                        raise DeviceTeardownError("failed to tear down device-mapper partition %s: %s" % (self.name, e))
-                udev_settle()
-
-        StorageDevice.teardown(self, recursive=recursive)
-
-    def _getSize(self):
-        """ Get the device's size. """
-        size = self._size
-        if self.partedPartition:
-            # this defaults to MB
-            size = self.partedPartition.getSize()
-        return size
-
-    def _setSize(self, newsize):
-        """ Set the device's size (for resize, not creation).
-
-            Arguments:
-
-                newsize -- the new size (in MB)
-
-        """
-        log_method_call(self, self.name,
-                        status=self.status, size=self._size, newsize=newsize)
-        if not self.exists:
-            raise DeviceError("device does not exist", self.name)
-
-        if newsize > self.disk.size:
-            raise ValueError("partition size would exceed disk size")
-
-        # this defaults to MB
-        maxAvailableSize = self.partedPartition.getMaxAvailableSize()
-
-        if newsize > maxAvailableSize:
-            raise ValueError("new size is greater than available space")
-
-         # now convert the size to sectors and update the geometry
-        geometry = self.partedPartition.geometry
-        physicalSectorSize = geometry.device.physicalSectorSize
-
-        new_length = (newsize * (1024 * 1024)) / physicalSectorSize
-        geometry.length = new_length
-
-    def _getDisk(self):
-        """ The disk that contains this partition."""
-        try:
-            disk = self.parents[0]
-        except IndexError:
-            disk = None
-        return disk
-
-    def _setDisk(self, disk):
-        """Change the parent.
-
-        Setting up a disk is not trivial.  It has the potential to change
-        the underlying object.  If necessary we must also change this object.
-        """
-        log_method_call(self, self.name, old=getattr(self.disk, "name", None),
-                        new=getattr(disk, "name", None))
-        if self.disk:
-            self.disk.removeChild()
-
-        if disk:
-            self.parents = [disk]
-            disk.addChild()
-        else:
-            self.parents = []
-
-    disk = property(lambda p: p._getDisk(), lambda p,d: p._setDisk(d))
-
-    @property
-    def maxSize(self):
-        """ The maximum size this partition can be. """
-        # XXX: this is MB by default
-        maxPartSize = self.partedPartition.getMaxAvailableSize()
-
-        if self.format.maxSize > maxPartSize:
-            return maxPartSize
-        else:
-            return self.format.maxSize
-
-    @property
-    def currentSize(self):
-        """ The device's actual size. """
-        if self.exists:
-            return self._currentSize
-        else:
-            return 0
-
-
-class DMDevice(StorageDevice):
-    """ A device-mapper device """
-    _type = "dm"
-    _devDir = "/dev/mapper"
-
-    def __init__(self, name, format=None, size=None, dmUuid=None,
-                 target=None, exists=None, parents=None, sysfsPath=''):
-        """ Create a DMDevice instance.
-
-            Arguments:
-
-                name -- the device name (generally a device node's basename)
-
-            Keyword Arguments:
-
-                target -- the device-mapper target type (string)
-                size -- the device's size (units/format TBD)
-                dmUuid -- the device's device-mapper UUID
-                sysfsPath -- sysfs device path
-                format -- a DeviceFormat instance
-                parents -- a list of required Device instances
-                exists -- indicates whether this is an existing device
-        """
-        StorageDevice.__init__(self, name, format=format, size=size,
-                               exists=exists,
-                               parents=parents, sysfsPath=sysfsPath)
-        self.target = target
-        self.dmUuid = dmUuid
-
-    def __str__(self):
-        s = StorageDevice.__str__(self)
-        s += ("  target = %(target)s  dmUuid = %(dmUuid)s" %
-              {"target": self.target, "dmUuid": self.dmUuid})
-        return s
-
-    @property
-    def dict(self):
-        d = super(DMDevice, self).dict
-        d.update({"target": self.target, "dmUuid": self.dmUuid})
-        return d
-
-    @property
-    def fstabSpec(self):
-        """ Return the device specifier for use in /etc/fstab. """
-        return self.path
-
-    @property
-    def mapName(self):
-        """ This device's device-mapper map name """
-        return self.name
-
-    @property
-    def status(self):
-        _status = False
-        for map in block.dm.maps():
-            if map.name == self.mapName:
-                _status = map.live_table and not map.suspended
-                break
-
-        return _status
-
-    def updateSysfsPath(self):
-        """ Update this device's sysfs path. """
-        log_method_call(self, self.name, status=self.status)
-        if not self.exists:
-            raise DeviceError("device has not been created", self.name)
-
-        if self.status:
-            dm_node = self.getDMNode()
-            path = os.path.join("/sys", self.sysfsBlockDir, dm_node)
-            self.sysfsPath = os.path.realpath(path)[4:]
-        else:
-            self.sysfsPath = ''
-
-    #def getTargetType(self):
-    #    return dm.getDmTarget(name=self.name)
-
-    def getDMNode(self):
-        """ Return the dm-X (eg: dm-0) device node for this device. """
-        log_method_call(self, self.name, status=self.status)
-        if not self.exists:
-            raise DeviceError("device has not been created", self.name)
-
-        return dm.dm_node_from_name(self.name)
-
-    def _setName(self, name):
-        """ Set the device's map name. """
-        log_method_call(self, self.name, status=self.status)
-        if self.status:
-            raise DeviceError("cannot rename active device", self.name)
-
-        self._name = name
-        #self.sysfsPath = "/dev/disk/by-id/dm-name-%s" % self.name
-
-    name = property(lambda d: d._name,
-                    lambda d,n: d._setName(n))
-
-
-class DMCryptDevice(DMDevice):
-    """ A dm-crypt device """
-    _type = "dm-crypt"
-
-    def __init__(self, name, format=None, size=None, uuid=None,
-                 exists=None, sysfsPath='', parents=None):
-        """ Create a DMCryptDevice instance.
-
-            Arguments:
-
-                name -- the device name (generally a device node's basename)
-
-            Keyword Arguments:
-
-                size -- the device's size (units/format TBD)
-                sysfsPath -- sysfs device path
-                format -- a DeviceFormat instance
-                parents -- a list of required Device instances
-                exists -- indicates whether this is an existing device
-        """
-        DMDevice.__init__(self, name, format=format, size=size,
-                          parents=parents, sysfsPath=sysfsPath,
-                          exists=exists, target="crypt")
-
-class LUKSDevice(DMCryptDevice):
-    """ A mapped LUKS device. """
-    _type = "luks/dm-crypt"
-
-    def __init__(self, name, format=None, size=None, uuid=None,
-                 exists=None, sysfsPath='', parents=None):
-        """ Create a LUKSDevice instance.
-
-            Arguments:
-
-                name -- the device name
-
-            Keyword Arguments:
-
-                size -- the device's size in MB
-                uuid -- the device's UUID
-                sysfsPath -- sysfs device path
-                format -- a DeviceFormat instance
-                parents -- a list of required Device instances
-                exists -- indicates whether this is an existing device
-        """
-        DMCryptDevice.__init__(self, name, format=format, size=size,
-                               parents=parents, sysfsPath=sysfsPath,
-                               uuid=None, exists=exists)
-
-    def writeKS(self, f, preexisting=False, noformat=False, s=None):
-        self.slave.writeKS(f, preexisting=preexisting, noformat=noformat, s=s)
-        self.format.writeKS(f)
-        if s:
-            f.write(" %s" % s)
-
-    @property
-    def size(self):
-        if not self.exists or not self.partedDevice:
-            # the LUKS header takes up 4040 512-byte sectors w/ a 512-bit key
-            size = float(self.slave.size) - ((4040 * 2.0) / 1024)
-        else:
-            size = self.partedDevice.getSize()
-        return size
-
-    def create(self, intf=None):
-        """ Create the device. """
-        log_method_call(self, self.name, status=self.status)
-        if self.exists:
-            raise DeviceError("device already exists", self.name)
-
-        self.createParents()
-        self.setupParents()
-
-        #if not self.slave.format.exists:
-        #    self.slave.format.create()
-        self._name = self.slave.format.mapName
-        self.exists = True
-        self.setup()
-
-    def setup(self, intf=None, orig=False):
-        """ Open, or set up, a device. """
-        log_method_call(self, self.name, orig=orig, status=self.status)
-        if not self.exists:
-            raise DeviceError("device has not been created", self.name)
-
-        self.slave.setup(orig=orig)
-        if orig:
-            self.slave.originalFormat.setup()
-        else:
-            self.slave.format.setup()
-        udev_settle()
-
-        # we always probe since the device may not be set up when we want
-        # information about it
-        self._size = self.currentSize
-
-    def teardown(self, recursive=False):
-        """ Close, or tear down, a device. """
-        log_method_call(self, self.name, status=self.status)
-        if not self.exists and not recursive:
-            raise DeviceError("device has not been created", self.name)
-
-        if self.status:
-            if self.originalFormat.exists:
-                self.originalFormat.teardown()
-            if self.format.exists:
-                self.format.teardown()
-            udev_settle()
-
-        if self.slave.originalFormat.exists:
-            self.slave.originalFormat.teardown()
-            udev_settle()
-
-        if self.slave.format.exists:
-            self.slave.format.teardown()
-            udev_settle()
-
-        if recursive:
-            self.teardownParents(recursive=recursive)
-
-    def destroy(self):
-        log_method_call(self, self.name, status=self.status)
-        self.format.teardown()
-        udev_settle()
-        self.teardown()
-
-    @property
-    def req_grow(self):
-        return getattr(self.slave, "req_grow", None)
-
-    @property
-    def slave(self):
-        """ This device's backing device. """
-        return self.parents[0]
-
-    def dracutSetupString(self):
-        return "rd_LUKS_UUID=luks-%s" % self.slave.format.uuid
-
-
-class LVMVolumeGroupDevice(DMDevice):
-    """ An LVM Volume Group
-
-        XXX Maybe this should inherit from StorageDevice instead of
-            DMDevice since there's no actual device.
-    """
-    _type = "lvmvg"
-
-    def __init__(self, name, parents, size=None, free=None,
-                 peSize=None, peCount=None, peFree=None, pvCount=None,
-                 lvNames=[], uuid=None, exists=None, sysfsPath=''):
-        """ Create a LVMVolumeGroupDevice instance.
-
-            Arguments:
-
-                name -- the device name (generally a device node's basename)
-                parents -- a list of physical volumes (StorageDevice)
-
-            Keyword Arguments:
-
-                peSize -- physical extent size (in MB)
-                exists -- indicates whether this is an existing device
-                sysfsPath -- sysfs device path
-
-                For existing VG's only:
-
-                    size -- the VG's size (in MB)
-                    free -- amount of free space in the VG
-                    peFree -- number of free extents
-                    peCount -- total number of extents
-                    pvCount -- number of PVs in this VG
-                    lvNames -- the names of this VG's LVs
-                    uuid -- the VG's UUID
-
-        """
-        self.pvClass = get_device_format_class("lvmpv")
-        if not self.pvClass:
-            raise StorageError("cannot find 'lvmpv' class")
-
-        if isinstance(parents, list):
-            for dev in parents:
-                if not isinstance(dev.format, self.pvClass):
-                    raise ValueError("constructor requires a list of PVs")
-        elif not isinstance(parents.format, self.pvClass):
-            raise ValueError("constructor requires a list of PVs")
-
-        DMDevice.__init__(self, name, parents=parents,
-                          exists=exists, sysfsPath=sysfsPath)
-
-        self.uuid = uuid
-        self.free = numeric_type(free)
-        self.peSize = numeric_type(peSize)
-        self.peCount = numeric_type(peCount)
-        self.peFree = numeric_type(peFree)
-        self.pvCount = numeric_type(pvCount)
-        self.lvNames = lvNames
-
-        # circular references, here I come
-        self._lvs = []
-
-        # TODO: validate peSize if given
-        if not self.peSize:
-            self.peSize = 32.0   # MB
-
-        #self.probe()
-
-    def __str__(self):
-        s = DMDevice.__str__(self)
-        s += ("  free = %(free)s  PE Size = %(peSize)s  PE Count = %(peCount)s\n"
-              "  PE Free = %(peFree)s  PV Count = %(pvCount)s\n"
-              "  LV Names = %(lvNames)s  modified = %(modified)s\n"
-              "  extents = %(extents)s  free space = %(freeSpace)s\n"
-              "  free extents = %(freeExtents)s\n"
-              "  PVs = %(pvs)s\n"
-              "  LVs = %(lvs)s" %
-              {"free": self.free, "peSize": self.peSize, "peCount": self.peCount,
-               "peFree": self.peFree, "pvCount": self.pvCount,
-               "lvNames": self.lvNames, "modified": self.isModified,
-               "extents": self.extents, "freeSpace": self.freeSpace,
-               "freeExtents": self.freeExtents, "pvs": self.pvs, "lvs": self.lvs})
-        return s
-
-    @property
-    def dict(self):
-        d = super(LVMVolumeGroupDevice, self).dict
-        d.update({"free": self.free, "peSize": self.peSize,
-                  "peCount": self.peCount, "peFree": self.peFree,
-                  "pvCount": self.pvCount, "extents": self.extents,
-                  "freeSpace": self.freeSpace,
-                  "freeExtents": self.freeExtents,
-                  "lvNames": [lv.name for lv in self.lvs]})
-        return d
-
-    def writeKS(self, f, preexisting=False, noformat=False, s=None):
-        args = ["--pesize=%s" % int(self.peSize * 1024)]
-        pvs = []
-
-        for pv in self.pvs:
-            pvs.append("pv.%s" % pv.format.uuid)
-
-        if preexisting:
-            args.append("--useexisting")
-        if noformat:
-            args.append("--noformat")
-
-        f.write("#volgroup %s %s %s" % (self.name, " ".join(args), " ".join(pvs)))
-        if s:
-            f.write(" %s" % s)
-
-    def probe(self):
-        """ Probe for any information about this device. """
-        log_method_call(self, self.name, status=self.status)
-        if not self.exists:
-            raise DeviceError("device has not been created", self.name)
-
-    @property
-    def mapName(self):
-        """ This device's device-mapper map name """
-        # Thank you lvm for this lovely hack.
-        return self.name.replace("-","--")
-
-    @property
-    def path(self):
-        """ Device node representing this device. """
-        return "%s/%s" % (self._devDir, self.mapName)
-
-    def updateSysfsPath(self):
-        """ Update this device's sysfs path. """
-        log_method_call(self, self.name, status=self.status)
-        if not self.exists:
-            raise DeviceError("device has not been created", self.name)
-
-        self.sysfsPath = ''
-
-    @property
-    def status(self):
-        """ The device's status (True means active). """
-        if not self.exists:
-            return False
-
-        # certainly if any of this VG's LVs are active then so are we
-        for lv in self.lvs:
-            if lv.status:
-                return True
-
-        # if any of our PVs are not active then we cannot be
-        for pv in self.pvs:
-            if not pv.status:
-                return False
-
-        # if we are missing some of our PVs we cannot be active
-        if len(self.pvs) != self.pvCount:
-            return False
-
-        return True
-
-    def _addDevice(self, device):
-        """ Add a new physical volume device to the volume group.
-
-            XXX This is for use by device probing routines and is not
-                intended for modification of the VG.
-        """
-        log_method_call(self,
-                        self.name,
-                        device=device.name,
-                        status=self.status)
-        if not self.exists:
-            raise DeviceError("device does not exist", self.name)
-
-        if not isinstance(device.format, self.pvClass):
-            raise ValueError("addDevice requires a PV arg")
-
-        if self.uuid and device.format.vgUuid != self.uuid:
-            raise ValueError("UUID mismatch")
-
-        if device in self.pvs:
-            raise ValueError("device is already a member of this VG")
-
-        self.parents.append(device)
-        device.addChild()
-
-        # now see if the VG can be activated
-        if len(self.parents) == self.pvCount:
-            self.setup()
-
-    def _removeDevice(self, device):
-        """ Remove a physical volume from the volume group.
-
-            This is for cases like clearing of preexisting partitions.
-        """
-        log_method_call(self,
-                        self.name,
-                        device=device.name,
-                        status=self.status)
-        try:
-            self.parents.remove(device)
-        except ValueError, e:
-            raise ValueError("cannot remove non-member PV device from VG")
-
-        device.removeChild()
-
-    def setup(self, intf=None, orig=False):
-        """ Open, or set up, a device.
-
-            XXX we don't do anything like "vgchange -ay" because we don't
-                want all of the LVs activated, just the VG itself.
-        """
-        log_method_call(self, self.name, orig=orig, status=self.status)
-        if not self.exists:
-            raise DeviceError("device has not been created", self.name)
-
-        if self.status:
-            return
-
-        if len(self.parents) < self.pvCount:
-            raise DeviceError("cannot activate VG with missing PV(s)", self.name)
-
-        self.setupParents(orig=orig)
-
-    def teardown(self, recursive=None):
-        """ Close, or tear down, a device. """
-        log_method_call(self, self.name, status=self.status)
-        if not self.exists and not recursive:
-            raise DeviceError("device has not been created", self.name)
-
-        if self.status:
-            lvm.vgdeactivate(self.name)
-
-        if recursive:
-            self.teardownParents(recursive=recursive)
-
-    def create(self, intf=None):
-        """ Create the device. """
-        log_method_call(self, self.name, status=self.status)
-        if self.exists:
-            raise DeviceError("device already exists", self.name)
-
-        w = None
-        if intf:
-            w = intf.progressWindow(_("Creating"),
-                                    _("Creating device %s")
-                                    % (self.path,),
-                                    100, pulse = True)
-        try:
-            self.createParents()
-            self.setupParents()
-
-            pv_list = [pv.path for pv in self.parents]
-            lvm.vgcreate(self.name, pv_list, self.peSize, progress=w)
-        except Exception:
-            raise
-        else:
-            # FIXME set / update self.uuid here
-            self.exists = True
-            self.setup()
-        finally:
-            if w:
-                w.pop()
-
-    def destroy(self):
-        """ Destroy the device. """
-        log_method_call(self, self.name, status=self.status)
-        if not self.exists:
-            raise DeviceError("device has not been created", self.name)
-
-        # set up the pvs since lvm needs access to them to do the vgremove
-        self.setupParents(orig=True)
-
-        # this sometimes fails for some reason.
-        try:
-            lvm.vgreduce(self.name, [], rm=True)
-            lvm.vgremove(self.name)
-        except lvm.LVMError:
-            raise DeviceError("Could not completely remove VG", self.name)
-        finally:
-            self.exists = False
-
-    def reduce(self, pv_list):
-        """ Remove the listed PVs from the VG. """
-        log_method_call(self, self.name, status=self.status)
-        if not self.exists:
-            raise DeviceError("device has not been created", self.name)
-
-        lvm.vgreduce(self.name, pv_list)
-        # XXX do we need to notify the kernel?
-
-    def _addLogVol(self, lv):
-        """ Add an LV to this VG. """
-        if lv in self._lvs:
-            raise ValueError("lv is already part of this vg")
-
-        # verify we have the space, then add it
-        # do not verify for growing vg (because of ks)
-        if not lv.exists and \
-           not [pv for pv in self.pvs if getattr(pv, "req_grow", None)] and \
-           lv.size > self.freeSpace:
-            raise DeviceError("new lv is too large to fit in free space", self.name)
-
-        self._lvs.append(lv)
-
-    def _removeLogVol(self, lv):
-        """ Remove an LV from this VG. """
-        if lv not in self.lvs:
-            raise ValueError("specified lv is not part of this vg")
-
-        self._lvs.remove(lv)
-
-    def _addPV(self, pv):
-        """ Add a PV to this VG. """
-        if pv in self.pvs:
-            raise ValueError("pv is already part of this vg")
-
-        # for the time being we will not allow vgextend
-        if self.exists:
-            raise DeviceError("cannot add pv to existing vg", self.name)
-
-        self.parents.append(pv)
-        pv.addChild()
-
-    def _removePV(self, pv):
-        """ Remove an PV from this VG. """
-        if not pv in self.pvs:
-            raise ValueError("specified pv is not part of this vg")
-
-        # for the time being we will not allow vgreduce
-        if self.exists:
-            raise DeviceError("cannot remove pv from existing vg", self.name)
-
-        self.parents.remove(pv)
-        pv.removeChild()
-
-    # We can't rely on lvm to tell us about our size, free space, &c
-    # since we could have modifications queued, unless the VG and all of
-    # its PVs already exist.
-    #
-    #        -- liblvm may contain support for in-memory devices
-
-    @property
-    def isModified(self):
-        """ Return True if the VG has changes queued that LVM is unaware of. """
-        modified = True
-        if self.exists and not filter(lambda d: not d.exists, self.pvs):
-            modified = False
-
-        return modified
-
-    @property
-    def size(self):
-        """ The size of this VG """
-        # TODO: just ask lvm if isModified returns False
-
-        # sum up the sizes of the PVs and align to pesize
-        size = 0
-        for pv in self.pvs:
-            size += max(0, self.align(pv.size - pv.format.peStart))
-
-        return size
-
-    @property
-    def extents(self):
-        """ Number of extents in this VG """
-        # TODO: just ask lvm if isModified returns False
-
-        return self.size / self.peSize
-
-    @property
-    def freeSpace(self):
-        """ The amount of free space in this VG (in MB). """
-        # TODO: just ask lvm if isModified returns False
-
-        # total the sizes of any LVs
-        used = 0
-        size = self.size
-        log.debug("%s size is %dMB" % (self.name, size))
-        for lv in self.lvs:
-            log.debug("lv %s uses %dMB" % (lv.name, lv.vgSpaceUsed))
-            used += self.align(lv.vgSpaceUsed, roundup=True)
-
-        free = self.size - used
-        log.debug("vg %s has %dMB free" % (self.name, free))
-        return free
-
-    @property
-    def freeExtents(self):
-        """ The number of free extents in this VG. """
-        # TODO: just ask lvm if isModified returns False
-        return self.freeSpace / self.peSize
-
-    def align(self, size, roundup=None):
-        """ Align a size to a multiple of physical extent size. """
-        size = numeric_type(size)
-
-        if roundup:
-            round = math.ceil
-        else:
-            round = math.floor
-
-        # we want Kbytes as a float for our math
-        size *= 1024.0
-        pesize = self.peSize * 1024.0
-        return long((round(size / pesize) * pesize) / 1024)
-
-    @property
-    def pvs(self):
-        """ A list of this VG's PVs """
-        return self.parents[:]  # we don't want folks changing our list
-
-    @property
-    def lvs(self):
-        """ A list of this VG's LVs """
-        return self._lvs[:]     # we don't want folks changing our list
-
-    @property
-    def complete(self):
-        """Check if the vg has all its pvs in the system
-        Return True if complete.
-        """
-        return len(self.pvs) == self.pvCount or not self.exists
-
-
-class LVMLogicalVolumeDevice(DMDevice):
-    """ An LVM Logical Volume """
-    _type = "lvmlv"
-    _resizable = True
-
-    def __init__(self, name, vgdev, size=None, uuid=None,
-                 stripes=1, logSize=0, snapshotSpace=0,
-                 format=None, exists=None, sysfsPath='',
-                 grow=None, maxsize=None, percent=None):
-        """ Create a LVMLogicalVolumeDevice instance.
-
-            Arguments:
-
-                name -- the device name (generally a device node's basename)
-                vgdev -- volume group (LVMVolumeGroupDevice instance)
-
-            Keyword Arguments:
-
-                size -- the device's size (in MB)
-                uuid -- the device's UUID
-                stripes -- number of copies in the vg (>1 for mirrored lvs)
-                logSize -- size of log volume (for mirrored lvs)
-                snapshotSpace -- sum of sizes of snapshots of this lv
-                sysfsPath -- sysfs device path
-                format -- a DeviceFormat instance
-                exists -- indicates whether this is an existing device
-
-                For new (non-existent) LVs only:
-
-                    grow -- whether to grow this LV
-                    maxsize -- maximum size for growable LV (in MB)
-                    percent -- percent of VG space to take
-
-        """
-        if isinstance(vgdev, list):
-            if len(vgdev) != 1:
-                raise ValueError("constructor requires a single LVMVolumeGroupDevice instance")
-            elif not isinstance(vgdev[0], LVMVolumeGroupDevice):
-                raise ValueError("constructor requires a LVMVolumeGroupDevice instance")
-        elif not isinstance(vgdev, LVMVolumeGroupDevice):
-            raise ValueError("constructor requires a LVMVolumeGroupDevice instance")
-        DMDevice.__init__(self, name, size=size, format=format,
-                          sysfsPath=sysfsPath, parents=vgdev,
-                          exists=exists)
-
-        self.uuid = uuid
-        self.snapshotSpace = snapshotSpace
-        self.stripes = stripes
-        self.logSize = logSize
-
-        self.req_grow = None
-        self.req_max_size = 0
-        self.req_size = 0   
-        self.req_percent = 0
-
-        if not self.exists:
-            self.req_grow = grow
-            self.req_max_size = numeric_type(maxsize)
-            # XXX should we enforce that req_size be pe-aligned?
-            self.req_size = self._size
-            self.req_percent = numeric_type(percent)
-
-        # here we go with the circular references
-        self.vg._addLogVol(self)
-
-    def __str__(self):
-        s = DMDevice.__str__(self)
-        s += ("  VG device = %(vgdev)r  percent = %(percent)s\n"
-              "  mirrored = %(mirrored)s stripes = %(stripes)d"
-              "  snapshot total =  %(snapshots)dMB\n"
-              "  VG space used = %(vgspace)dMB" %
-              {"vgdev": self.vg, "percent": self.req_percent,
-               "mirrored": self.mirrored, "stripes": self.stripes,
-               "snapshots": self.snapshotSpace, "vgspace": self.vgSpaceUsed })
-        return s
-
-    @property
-    def dict(self):
-        d = super(LVMLogicalVolumeDevice, self).dict
-        if self.exists:
-            d.update({"mirrored": self.mirrored, "stripes": self.stripes,
-                      "snapshots": self.snapshotSpace,
-                      "vgspace": self.vgSpaceUsed})
-        else:
-            d.update({"percent": self.req_percent})
-
-        return d
-
-    def writeKS(self, f, preexisting=False, noformat=False, s=None):
-        args = ["--name=%s" % self.lvname,
-                "--vgname=%s" % self.vg.name]
-
-        if self.req_grow:
-            args.extend(["--grow", "--size=%s" % (self.req_size or 1)])
-
-            if self.req_max_size > 0:
-                args.append("--maxsize=%s" % self.req_max_size)
-        else:
-            if self.req_percent > 0:
-                args.append("--percent=%s" % self.req_percent)
-            elif self.req_size > 0:
-                args.append("--size=%s" % self.req_size)
-
-        if preexisting:
-            args.append("--useexisting")
-        if noformat:
-            args.append("--noformat")
-
-        f.write("#logvol ")
-        self.format.writeKS(f)
-        f.write(" %s" % " ".join(args))
-        if s:
-            f.write(" %s" % s)
-
-    @property
-    def mirrored(self):
-        return self.stripes > 1
-
-    def _setSize(self, size):
-        size = self.vg.align(numeric_type(size))
-        log.debug("trying to set lv %s size to %dMB" % (self.name, size))
-        if size <= (self.vg.freeSpace + self._size):
-            self._size = size
-            self.targetSize = size
-        else:
-            log.debug("failed to set size: %dMB short" % (size - (self.vg.freeSpace + self._size),))
-            raise ValueError("not enough free space in volume group")
-
-    size = property(StorageDevice._getSize, _setSize)
-
-    @property
-    def vgSpaceUsed(self):
-        return self.size * self.stripes + self.logSize + self.snapshotSpace
-
-    @property
-    def vg(self):
-        """ This Logical Volume's Volume Group. """
-        return self.parents[0]
-
-    @property
-    def mapName(self):
-        """ This device's device-mapper map name """
-        # Thank you lvm for this lovely hack.
-        return "%s-%s" % (self.vg.mapName, self._name.replace("-","--"))
-
-    @property
-    def path(self):
-        """ Device node representing this device. """
-        return "%s/%s" % (self._devDir, self.mapName)
-
-    def getDMNode(self):
-        """ Return the dm-X (eg: dm-0) device node for this device. """
-        log_method_call(self, self.name, status=self.status)
-        if not self.exists:
-            raise DeviceError("device has not been created", self.name)
-
-        return dm.dm_node_from_name(self.mapName)
-
-    @property
-    def name(self):
-        """ This device's name. """
-        return "%s-%s" % (self.vg.name, self._name)
-
-    @property
-    def lvname(self):
-        """ The LV's name (not including VG name). """
-        return self._name
-
-    @property
-    def complete(self):
-        """ Test if vg exits and if it has all pvs. """
-        return self.vg.complete
-
-    def setup(self, intf=None, orig=False):
-        """ Open, or set up, a device. """
-        log_method_call(self, self.name, orig=orig, status=self.status)
-        if not self.exists:
-            raise DeviceError("device has not been created", self.name)
-
-        if self.status:
-            return
-
-        self.vg.setup(orig=orig)
-        lvm.lvactivate(self.vg.name, self._name)
-
-        # we always probe since the device may not be set up when we want
-        # information about it
-        self._size = self.currentSize
-
-    def teardown(self, recursive=None):
-        """ Close, or tear down, a device. """
-        log_method_call(self, self.name, status=self.status)
-        if not self.exists and not recursive:
-            raise DeviceError("device has not been created", self.name)
-
-        if self.status:
-            if self.originalFormat.exists:
-                self.originalFormat.teardown()
-            if self.format.exists:
-                self.format.teardown()
-            udev_settle()
-
-        if self.status:
-            lvm.lvdeactivate(self.vg.name, self._name)
-
-        if recursive:
-            # It's likely that teardown of a VG will fail due to other
-            # LVs being active (filesystems mounted, &c), so don't let
-            # it bring everything down.
-            try:
-                self.vg.teardown(recursive=recursive)
-            except Exception as e:
-                log.debug("vg %s teardown failed; continuing" % self.vg.name)
-
-    def create(self, intf=None):
-        """ Create the device. """
-        log_method_call(self, self.name, status=self.status)
-        if self.exists:
-            raise DeviceError("device already exists", self.name)
-
-        w = None
-        if intf:
-            w = intf.progressWindow(_("Creating"),
-                                    _("Creating device %s")
-                                    % (self.path,),
-                                    100, pulse = True)
-        try:
-            self.createParents()
-            self.setupParents()
-
-            # should we use --zero for safety's sake?
-            lvm.lvcreate(self.vg.name, self._name, self.size, progress=w)
-        except Exception:
-            raise
-        else:
-            # FIXME set / update self.uuid here
-            self.exists = True
-            self.setup()
-        finally:
-            if w:
-                w.pop()
-
-    def destroy(self):
-        """ Destroy the device. """
-        log_method_call(self, self.name, status=self.status)
-        if not self.exists:
-            raise DeviceError("device has not been created", self.name)
-
-        self.teardown()
-        # set up the vg's pvs so lvm can remove the lv
-        self.vg.setupParents(orig=True)
-        lvm.lvremove(self.vg.name, self._name)
-        self.exists = False
-
-    def resize(self, intf=None):
-        # XXX resize format probably, right?
-        log_method_call(self, self.name, status=self.status)
-        if not self.exists:
-            raise DeviceError("device has not been created", self.name)
-
-        # Setup VG parents (in case they are dmraid partitions for example)
-        self.vg.setupParents(orig=True)
-
-        if self.originalFormat.exists:
-            self.originalFormat.teardown()
-        if self.format.exists:
-            self.format.teardown()
-
-        udev_settle()
-        lvm.lvresize(self.vg.name, self._name, self.size)
-
-    def dracutSetupString(self):
-        # Note no mapName usage here, this is a lvm cmdline name, which
-        # is different (ofcourse)
-        return "rd_LVM_LV=%s/%s" % (self.vg.name, self._name)
-
-
-class MDRaidArrayDevice(StorageDevice):
-    """ An mdraid (Linux RAID) device. """
-    _type = "mdarray"
-
-    def __init__(self, name, level=None, major=None, minor=None, size=None,
-                 memberDevices=None, totalDevices=None,
-                 uuid=None, format=None, exists=None,
-                 parents=None, sysfsPath=''):
-        """ Create a MDRaidArrayDevice instance.
-
-            Arguments:
-
-                name -- the device name (generally a device node's basename)
-
-            Keyword Arguments:
-
-                level -- the device's RAID level (a string, eg: '1' or 'raid1')
-                parents -- list of member devices (StorageDevice instances)
-                size -- the device's size (units/format TBD)
-                uuid -- the device's UUID
-                minor -- the device minor
-                sysfsPath -- sysfs device path
-                format -- a DeviceFormat instance
-                exists -- indicates whether this is an existing device
-        """
-        StorageDevice.__init__(self, name, format=format, exists=exists,
-                               major=major, minor=minor, size=size,
-                               parents=parents, sysfsPath=sysfsPath)
-
-        self.level = level
-        if level == "container":
-            self._type = "mdcontainer"
-        elif level is not None:
-            self.level = mdraid.raidLevel(level)
-
-        # For new arrays check if we have enough members
-        if (not exists and parents and
-                len(parents) < mdraid.get_raid_min_members(self.level)):
-            raise ValueError, P_("A RAID%d set requires at least %d member",
-                                 "A RAID%d set requires at least %d members",
-                                 mdraid.get_raid_min_members(self.level)) % \
-                                 (self.level, mdraid.get_raid_min_members(self.level))
-
-        self.uuid = uuid
-        self._totalDevices = numeric_type(totalDevices)
-        self._memberDevices = numeric_type(memberDevices)
-        self.sysfsPath = "/devices/virtual/block/%s" % name
-        self.chunkSize = 64.0 / 1024.0          # chunk size in MB
-        self.superBlockSize = 128.0 / 1024.0    # superblock size in MB
-
-        self.createMetadataVer = "1.1"
-        # bitmaps are not meaningful on raid0 according to mdadm-3.0.3
-        self.createBitmap = self.level != 0
-
-        # For container members probe size now, as we cannot determine it
-        # when teared down.
-        if self.parents and self.parents[0].type == "mdcontainer":
-            self._size = self.currentSize
-            self._type = "mdbiosraidarray"
-
-        self.formatClass = get_device_format_class("mdmember")
-        if not self.formatClass:
-            raise DeviceError("cannot find class for 'mdmember'", self.name)
-
-        if self.exists and self.uuid:
-            # this is a hack to work around mdadm's insistence on giving
-            # really high minors to arrays it has no config entry for
-            open("/etc/mdadm.conf", "a").write("ARRAY %s UUID=%s\n"
-                                                % (self.path, self.uuid))
-
-    @property
-    def smallestMember(self):
-        try:
-            smallest = sorted(self.devices, key=lambda d: d.size)[0]
-        except IndexError:
-            smallest = None
-        return smallest
-
-    @property
-    def size(self):
-        if not self.devices:
-            return 0
-
-        # For container members return probed size, as we cannot determine it
-        # when teared down.
-        if self.type == "mdbiosraidarray":
-            return self._size
-
-        size = 0
-        smallestMemberSize = self.smallestMember.size - self.superBlockSize
-        if not self.exists or not self.partedDevice:
-            if self.level == mdraid.RAID0:
-                size = self.memberDevices * smallestMemberSize
-                size -= size % self.chunkSize
-            elif self.level == mdraid.RAID1:
-                size = smallestMemberSize
-            elif self.level == mdraid.RAID4:
-                size = (self.memberDevices - 1) * smallestMemberSize
-                size -= size % self.chunkSize
-            elif self.level == mdraid.RAID5:
-                size = (self.memberDevices - 1) * smallestMemberSize
-                size -= size % self.chunkSize
-            elif self.level == mdraid.RAID6:
-                size = (self.memberDevices - 2) * smallestMemberSize
-                size -= size % self.chunkSize
-            elif self.level == mdraid.RAID10:
-                size = (self.memberDevices / 2.0) * smallestMemberSize
-                size -= size % self.chunkSize
-        else:
-            size = self.partedDevice.getSize()
-
-        return size
-
-    @property
-    def description(self):
-        if self.level == mdraid.RAID0:
-            levelstr = "stripe"
-        elif self.level == mdraid.RAID1:
-            levelstr = "mirror"
-        else:
-            levelstr = "raid%s" % self.level
-
-        if self.type == "mdcontainer":
-            return "BIOS RAID container"
-        elif self.type == "mdbiosraidarray":
-            return "BIOS RAID set (%s)" % levelstr
-        else:
-            return "MDRAID set (%s)" % levelstr
-
-    def __str__(self):
-        s = StorageDevice.__str__(self)
-        s += ("  level = %(level)s  spares = %(spares)s\n"
-              "  members = %(memberDevices)s\n"
-              "  total devices = %(totalDevices)s" %
-              {"level": self.level, "spares": self.spares,
-               "memberDevices": self.memberDevices, "totalDevices": self.totalDevices})
-        return s
-
-    @property
-    def dict(self):
-        d = super(MDRaidArrayDevice, self).dict
-        d.update({"level": self.level,
-                  "spares": self.spares, "memberDevices": self.memberDevices,
-                  "totalDevices": self.totalDevices})
-        return d
-
-    def writeKS(self, f, preexisting=False, noformat=False, s=None):
-        args = ["--level=%s" % self.level,
-                "--device=%s" % self.name]
-        mems = []
-
-        if self.spares > 0:
-            args.append("--spares=%s" % self.spares)
-        if preexisting:
-            args.append("--useexisting")
-        if noformat:
-            args.append("--noformat")
-
-        for mem in self.parents:
-            mems.append("raid.%s" % mem.format.uuid)
-
-        f.write("#raid ")
-        self.format.writeKS(f)
-        f.write(" %s" % " ".join(args))
-        f.write(" %s" % " ".join(mems))
-        if s:
-            f.write(" %s" % s)
-
-    @property
-    def mdadmConfEntry(self):
-        """ This array's mdadm.conf entry. """
-        if self.level is None or self.memberDevices is None or not self.uuid:
-            raise DeviceError("array is not fully defined", self.name)
-
-        # containers and the sets within must only have a UUID= parameter
-        if self.type == "mdcontainer" or self.type == "mdbiosraidarray":
-            fmt = "ARRAY %s UUID=%s\n"
-            return fmt % (self.path, self.uuid)
-
-        fmt = "ARRAY %s level=raid%d num-devices=%d UUID=%s\n"
-        return fmt % (self.path, self.level, self.memberDevices, self.uuid)
-
-    @property
-    def totalDevices(self):
-        """ Total number of devices in the array, including spares. """
-        count = len(self.parents)
-        if not self.exists:
-            count = self._totalDevices
-        return count
-
-    def _getMemberDevices(self):
-        return self._memberDevices
-
-    def _setMemberDevices(self, number):
-        if not isinstance(number, int):
-            raise ValueError("memberDevices is an integer")
-
-        if number > self.totalDevices:
-            raise ValueError("memberDevices cannot be greater than totalDevices")
-        self._memberDevices = number
-
-    memberDevices = property(_getMemberDevices, _setMemberDevices,
-                             doc="number of member devices")
-
-    def _getSpares(self):
-        spares = 0
-        if self.memberDevices is not None:
-            if self.totalDevices is not None:
-                spares = self.totalDevices - self.memberDevices
-            else:
-                spares = self.memberDevices
-                self._totalDevices = self.memberDevices
-        return spares
-
-    def _setSpares(self, spares):
-        # FIXME: this is too simple to be right
-        if self.totalDevices > spares:
-            self.memberDevices = self.totalDevices - spares
-
-    spares = property(_getSpares, _setSpares)
-
-    def probe(self):
-        """ Probe for any missing information about this device.
-
-            I'd like to avoid paying any attention to "Preferred Minor"
-            as it seems problematic.
-        """
-        log_method_call(self, self.name, status=self.status)
-        if not self.exists:
-            raise DeviceError("device has not been created", self.name)
-
-        try:
-            self.devices[0].setup()
-        except Exception:
-            return
-
-        info = mdraid.mdexamine(self.devices[0].path)
-        if self.level is None:
-            self.level = mdraid.raidLevel(info['level'])
-
-    def updateSysfsPath(self):
-        """ Update this device's sysfs path. """
-        log_method_call(self, self.name, status=self.status)
-        if not self.exists:
-            raise DeviceError("device has not been created", self.name)
-
-        if self.status:
-            self.sysfsPath = "/devices/virtual/block/%s" % self.name
-        else:
-            self.sysfsPath = ''
-
-    def _addDevice(self, device):
-        """ Add a new member device to the array.
-
-            XXX This is for use when probing devices, not for modification
-                of arrays.
-        """
-        log_method_call(self,
-                        self.name,
-                        device=device.name,
-                        status=self.status)
-        if not self.exists:
-            raise DeviceError("device has not been created", self.name)
-
-        if not isinstance(device.format, self.formatClass):
-            raise ValueError("invalid device format for mdraid member")
-
-        if self.uuid and device.format.mdUuid != self.uuid:
-            raise ValueError("cannot add member with non-matching UUID")
-
-        if device in self.devices:
-            raise ValueError("device is already a member of this array")
-
-        # we added it, so now set up the relations
-        self.devices.append(device)
-        device.addChild()
-
-        device.setup()
-        udev_settle()
-        try:
-            mdraid.mdadd(device.path, len(self.devices) < self.memberDevices)
-            # mdadd causes udev events
-            udev_settle()
-        except MDRaidError as e:
-            log.warning("failed to add member %s to md array %s: %s"
-                        % (device.path, self.path, e))
-
-        if self.status:
-            # we always probe since the device may not be set up when we want
-            # information about it
-            self._size = self.currentSize
-
-    def _removeDevice(self, device):
-        """ Remove a component device from the array.
-
-            XXX This is for use by clearpart, not for reconfiguration.
-        """
-        log_method_call(self,
-                        self.name,
-                        device=device.name,
-                        status=self.status)
-
-        if device not in self.devices:
-            raise ValueError("cannot remove non-member device from array")
-
-        self.devices.remove(device)
-        device.removeChild()
-
-    @property
-    def status(self):
-        """ This device's status.
-
-            For now, this should return a boolean:
-                True    the device is open and ready for use
-                False   the device is not open
-        """
-        # check the status in sysfs
-        status = False
-        if not self.exists:
-            return status
-
-        state_file = "/sys/%s/md/array_state" % self.sysfsPath
-        if os.access(state_file, os.R_OK):
-            state = open(state_file).read().strip()
-            log.debug("%s state is %s" % (self.name, state))
-            if state in ("clean", "active", "active-idle", "readonly", "read-auto"):
-                status = True
-            # mdcontainers have state inactive when started (clear if stopped)
-            if self.type == "mdcontainer" and state == "inactive":
-                status = True
-
-        return status
-
-    @property
-    def degraded(self):
-        """ Return True if the array is running in degraded mode. """
-        rc = False
-        degraded_file = "/sys/%s/md/degraded" % self.sysfsPath
-        if os.access(degraded_file, os.R_OK):
-            val = open(degraded_file).read().strip()
-            log.debug("%s degraded is %s" % (self.name, val))
-            if val == "1":
-                rc = True
-
-        return rc
-
-    @property
-    def devices(self):
-        """ Return a list of this array's member device instances. """
-        return self.parents
-
-    def setup(self, intf=None, orig=False):
-        """ Open, or set up, a device. """
-        log_method_call(self, self.name, orig=orig, status=self.status)
-        if not self.exists:
-            raise DeviceError("device has not been created", self.name)
-
-        if self.status:
-            return
-
-        disks = []
-        for member in self.devices:
-            member.setup(orig=orig)
-            disks.append(member.path)
-
-        update_super_minor = True
-        if self.type == "mdcontainer" or self.type == "mdbiosraidarray":
-            update_super_minor = False
-
-        mdraid.mdactivate(self.path,
-                          members=disks,
-                          super_minor=self.minor,
-                          update_super_minor=update_super_minor,
-                          uuid=self.uuid)
-
-        udev_settle()
-
-        # we always probe since the device may not be set up when we want
-        # information about it
-        self._size = self.currentSize
-
-    def teardown(self, recursive=None):
-        """ Close, or tear down, a device. """
-        log_method_call(self, self.name, status=self.status)
-        if not self.exists and not recursive:
-            raise DeviceError("device has not been created", self.name)
-
-        if self.status:
-            if self.originalFormat.exists:
-                self.originalFormat.teardown()
-            if self.format.exists:
-                self.format.teardown()
-            udev_settle()
-
-        # Since BIOS RAID sets (containers in mdraid terminology) never change
-        # there is no need to stop them and later restart them. Not stopping
-        # (and thus also not starting) them also works around bug 523334
-        if self.type == "mdcontainer" or self.type == "mdbiosraidarray":
-            return
-
-        # We don't really care what the array's state is. If the device
-        # file exists, we want to deactivate it. mdraid has too many
-        # states.
-        if self.exists and os.path.exists(self.path):
-            mdraid.mddeactivate(self.path)
-
-        if recursive:
-            self.teardownParents(recursive=recursive)
-
-    def preCommitFixup(self, *args, **kwargs):
-        """ Determine create parameters for this set """
-        mountpoints = kwargs.pop("mountpoints")
-        log_method_call(self, self.name, mountpoints)
-
-        if "/boot" in mountpoints:
-            bootmountpoint = "/boot"
-        else:
-            bootmountpoint = "/"
-
-        # If we are used to boot from we cannot use 1.1 metadata
-        if getattr(self.format, "mountpoint", None) == bootmountpoint or \
-           getattr(self.format, "mountpoint", None) == "/boot/efi" or \
-           self.format.type == "prepboot":
-            self.createMetadataVer = "1.0"
-
-        # Bitmaps are not useful for swap and small partitions
-        if self.size < 1000 or self.format.type == "swap":
-            self.createBitmap = False
-
-    def create(self, intf=None):
-        """ Create the device. """
-        log_method_call(self, self.name, status=self.status)
-        if self.exists:
-            raise DeviceError("device already exists", self.name)
-
-        w = None
-        if intf:
-            w = intf.progressWindow(_("Creating"),
-                                    _("Creating device %s")
-                                    % (self.path,),
-                                    100, pulse = True)
-        try:
-            self.createParents()
-            self.setupParents()
-
-            disks = [disk.path for disk in self.devices]
-            spares = len(self.devices) - self.memberDevices
-            mdraid.mdcreate(self.path,
-                            self.level,
-                            disks,
-                            spares,
-                            metadataVer=self.createMetadataVer,
-                            bitmap=self.createBitmap,
-                            progress=w)
-        except Exception:
-            raise
-        else:
-            self.exists = True
-            # the array is automatically activated upon creation, but...
-            self.setup()
-            udev_settle()
-            self.updateSysfsPath()
-            info = udev_get_block_device(self.sysfsPath)
-            self.uuid = udev_device_get_md_uuid(info)
-            for member in self.devices:
-                member.mdUuid = self.uuid
-        finally:
-            if w:
-                w.pop()
-
-    @property
-    def formatArgs(self):
-        formatArgs = []
-        if self.format.type == "ext2":
-            if self.level == mdraid.RAID5:
-                formatArgs = ['-R',
-                              'stride=%d' % ((self.memberDevices - 1) * 16)]
-            if self.level == mdraid.RAID4:
-                formatArgs = ['-R',
-                              'stride=%d' % ((self.memberDevices - 1) * 16)]
-            elif self.level == mdraid.RAID0:
-                formatArgs = ['-R',
-                              'stride=%d' % (self.memberDevices * 16)]
-
-    def destroy(self):
-        """ Destroy the device. """
-        log_method_call(self, self.name, status=self.status)
-        if not self.exists:
-            raise DeviceError("device has not been created", self.name)
-
-        self.teardown()
-
-        # The destruction of the formatting on the member devices does the
-        # real work, but it isn't our place to do it from here.
-        self.exists = False
-
-    @property
-    def mediaPresent(self):
-        # Containers should not get any format handling done
-        # (the device node does not allow read / write calls)
-        if self.type == "mdcontainer":
-            return False
-        # BIOS RAID sets should show as present even when teared down
-        elif self.type == "mdbiosraidarray":
-            return True
-        else:
-            return self.partedDevice is not None
-
-    @property
-    def model(self):
-        return self.description
-
-    @property
-    def partitionable(self):
-        return self.type == "mdbiosraidarray"
-
-    @property
-    def isDisk(self):
-        return self.type == "mdbiosraidarray"
-
-    def dracutSetupString(self):
-        return "rd_MD_UUID=%s" % self.uuid
-
-
-class DMRaidArrayDevice(DMDevice):
-    """ A dmraid (device-mapper RAID) device """
-    _type = "dm-raid array"
-    _packages = ["dmraid"]
-    _partitionable = True
-    _isDisk = True
-
-    def __init__(self, name, raidSet=None, format=None,
-                 size=None, parents=None, sysfsPath=''):
-        """ Create a DMRaidArrayDevice instance.
-
-            Arguments:
-
-                name -- the dmraid name also the device node's basename
-
-            Keyword Arguments:
-
-                raidSet -- the RaidSet object from block
-                parents -- a list of the member devices
-                sysfsPath -- sysfs device path
-                size -- the device's size
-                format -- a DeviceFormat instance
-        """
-        if isinstance(parents, list):
-            for parent in parents:
-                if not parent.format or parent.format.type != "dmraidmember":
-                    raise ValueError("parent devices must contain dmraidmember format")
-        DMDevice.__init__(self, name, format=format, size=size,
-                          parents=parents, sysfsPath=sysfsPath, exists=True)
-
-        self.formatClass = get_device_format_class("dmraidmember")
-        if not self.formatClass:
-            raise StorageError("cannot find class for 'dmraidmember'")
-
-        self._raidSet = raidSet
-
-    @property
-    def raidSet(self):
-        return self._raidSet
-
-    def _addDevice(self, device):
-        """ Add a new member device to the array.
-
-            XXX This is for use when probing devices, not for modification
-                of arrays.
-        """
-        log_method_call(self, self.name, device=device.name, status=self.status)
-
-        if not self.exists:
-            raise DeviceError("device has not been created", self.name)
-
-        if not isinstance(device.format, self.formatClass):
-            raise ValueError("invalid device format for dmraid member")
-
-        if device in self.members:
-            raise ValueError("device is already a member of this array")
-
-        # we added it, so now set up the relations
-        self.devices.append(device)
-        device.addChild()
-
-    @property
-    def members(self):
-        return self.parents
-
-    @property
-    def devices(self):
-        """ Return a list of this array's member device instances. """
-        return self.parents
-
-    def deactivate(self):
-        """ Deactivate the raid set. """
-        log_method_call(self, self.name, status=self.status)
-        # This call already checks if the set is not active.
-        self._raidSet.deactivate()
-
-    def activate(self):
-        """ Activate the raid set. """
-        log_method_call(self, self.name, status=self.status)
-        # This call already checks if the set is active.
-        self._raidSet.activate(mknod=True)
-        udev_settle()
-
-    def setup(self, intf=None, orig=False):
-        """ Open, or set up, a device. """
-        log_method_call(self, self.name, orig=orig, status=self.status)
-        StorageDevice.setup(self, intf=intf, orig=orig)
-        self.activate()
-
-    def teardown(self, recursive=None):
-        """ Close, or tear down, a device. """
-        log_method_call(self, self.name, status=self.status)
-        if not self.exists and not recursive:
-            raise DeviceError("device has not been created", self.name)
-
-        log.debug("not tearing down dmraid device %s" % self.name)
-
-    @property
-    def description(self):
-        return "BIOS RAID set (%s)" % self._raidSet.rs.set_type
-
-    @property
-    def model(self):
-        return self.description
-
-    def dracutSetupString(self):
-        return "rd_DM_UUID=%s" % self.name
-
-class MultipathDevice(DMDevice):
-    """ A multipath device """
-    _type = "dm-multipath"
-    _packages = ["device-mapper-multipath"]
-    _partitionable = True
-    _isDisk = True
-
-    def __init__(self, name, info, format=None, size=None,
-                 parents=None, sysfsPath=''):
-        """ Create a MultipathDevice instance.
-
-            Arguments:
-
-                name -- the device name (generally a device node's basename)
-                info -- the udev info for this device
-
-            Keyword Arguments:
-
-                sysfsPath -- sysfs device path
-                size -- the device's size
-                format -- a DeviceFormat instance
-                parents -- a list of the backing devices (Device instances)
-        """
-
-        self._info = info
-        self.setupIdentity()
-        DMDevice.__init__(self, name, format=format, size=size,
-                          parents=parents, sysfsPath=sysfsPath,
-                          exists=True)
-
-        self.config = {
-            'wwid' : self.identity,
-            'alias' : self.name,
-            'mode' : '0600',
-            'uid' : '0',
-            'gid' : '0',
-        }
-
-    def setupIdentity(self):
-        """ Adds identifying remarks to MultipathDevice object.
-        
-            May be overridden by a sub-class for e.g. RDAC handling.
-        """
-        self._identity_short = self._info['ID_SERIAL_SHORT']
-        self._identity = self._info['ID_SERIAL']
-
-    @property
-    def identity(self):
-        """ Get identity set with setupIdentityFromInfo()
-        
-            May be overridden by a sub-class for e.g. RDAC handling.
-        """
-        if not hasattr(self, "_identity"):
-            raise RuntimeError, "setupIdentityFromInfo() has not been called."
-        return self._identity
-
-    @property
-    def wwid(self):
-        identity = self._identity_short
-        ret = []
-        while identity:
-            ret.append(identity[:2])
-            identity = identity[2:]
-        return ":".join(ret)
-
-    @property
-    def model(self):
-        if not self.parents:
-            return ""
-        return self.parents[0].model
-
-    @property
-    def vendor(self):
-        if not self.parents:
-            return ""
-        return self.parents[0].vendor
-
-    @property
-    def description(self):
-        return "WWID %s" % (self.wwid,)
-
-    def addParent(self, parent):
-        """ Add a parent device to the mpath. """
-        log_method_call(self, self.name, status=self.status)
-        if self.status:
-            self.teardown()
-            self.parents.append(parent)
-            self.setup()
-        else:
-            self.parents.append(parent)
-
-    def setupPartitions(self):
-        log_method_call(self, name=self.name, kids=self.kids)
-        rc = iutil.execWithRedirect("kpartx",
-                                ["-a", "-p", "p", "/dev/mapper/%s" % self.name],
-                                stdout = "/dev/tty5",
-                                stderr = "/dev/tty5")
-        if rc:
-            raise MPathError("multipath partition activation failed for '%s'" %
-                            self.name)
-        udev_settle()
-
-    def teardown(self, recursive=None):
-        """ Tear down the mpath device. """
-        log_method_call(self, self.name, status=self.status)
-
-        if not self.exists and not recursive:
-            raise DeviceError("device has not been created", self.name)
-
-        if self.exists and os.path.exists(self.path):
-            #self.teardownPartitions()
-            #rc = iutil.execWithRedirect("multipath",
-            #                    ['-f', self.name],
-            #                    stdout = "/dev/tty5",
-            #                    stderr = "/dev/tty5")
-            #if rc:
-            #    raise MPathError("multipath deactivation failed for '%s'" %
-            #                    self.name)
-            bdev = block.getDevice(self.name)
-            devmap = block.getMap(major=bdev[0], minor=bdev[1])
-            if devmap.open_count:
-                return
-            try:
-                block.removeDeviceMap(devmap)
-            except Exception as e:
-                raise MPathError("failed to tear down multipath device %s: %s"
-                                % (self.name, e))
-
-        if recursive:
-            self.teardownParents(recursive=recursive)
-
-    def setup(self, intf=None, orig=False):
-        """ Open, or set up, a device. """
-        log_method_call(self, self.name, orig=orig, status=self.status)
-
-        if self.status:
-            return
-
-        StorageDevice.setup(self, intf=intf, orig=orig)
-        udev_settle()
-        rc = iutil.execWithRedirect("multipath",
-                            [self.name],
-                            stdout = "/dev/tty5",
-                            stderr = "/dev/tty5")
-        if rc:
-            raise MPathError("multipath activation failed for '%s'" %
-                            self.name)
-        udev_settle()
-        self.setupPartitions()
-        udev_settle()
-
-class NoDevice(StorageDevice):
-    """ A nodev device for nodev filesystems like tmpfs. """
-    _type = "nodev"
-
-    def __init__(self, format=None):
-        """ Create a NoDevice instance.
-
-            Arguments:
-
-            Keyword Arguments:
-
-                format -- a DeviceFormat instance
-        """
-        if format:
-            name = format.type
-        else:
-            name = "none"
-
-        StorageDevice.__init__(self, name, format=format)
-
-    @property
-    def path(self):
-        """ Device node representing this device. """
-        return self.name
-
-    def probe(self):
-        """ Probe for any missing information about this device. """
-        log_method_call(self, self.name, status=self.status)
-
-    def setup(self, intf=None, orig=False):
-        """ Open, or set up, a device. """
-        log_method_call(self, self.name, orig=orig, status=self.status)
-
-    def teardown(self, recursive=False):
-        """ Close, or tear down, a device. """
-        log_method_call(self, self.name, status=self.status)
-
-    def create(self, intf=None):
-        """ Create the device. """
-        log_method_call(self, self.name, status=self.status)
-        self.setupParents()
-
-    def destroy(self):
-        """ Destroy the device. """
-        log_method_call(self, self.name, status=self.status)
-
-
-class FileDevice(StorageDevice):
-    """ A file on a filesystem.
-
-        This exists because of swap files.
-    """
-    _type = "file"
-    _devDir = ""
-
-    def __init__(self, path, format=None, size=None,
-                 exists=None, parents=None):
-        """ Create a FileDevice instance.
-
-            Arguments:
-
-                path -- full path to the file
-
-            Keyword Arguments:
-
-                format -- a DeviceFormat instance
-                size -- the file size (units TBD)
-                parents -- a list of required devices (Device instances)
-                exists -- indicates whether this is an existing device
-        """
-        StorageDevice.__init__(self, path, format=format, size=size,
-                               exists=exists, parents=parents)
-
-    def probe(self):
-        """ Probe for any missing information about this device. """
-        pass
-
-    @property
-    def fstabSpec(self):
-        return self.name
-
-    @property
-    def path(self):
-        path = self.name
-        root = ""
-        try:
-            status = self.parents[0].format.status
-        except (AttributeError, IndexError):
-            status = False
-
-        if status: 
-            # this is the actual active mountpoint
-            root = self.parents[0].format._mountpoint
-            # trim the mountpoint down to the chroot since we already have
-            # the otherwise fully-qualified path
-            mountpoint = self.parents[0].format.mountpoint
-            if mountpoint.endswith("/"):
-                mountpoint = mountpoint[:-1]
-            if mountpoint:
-                root = root[:-len(mountpoint)]
-
-        return os.path.normpath("%s/%s" % (root, path))
-
-    def setup(self, intf=None, orig=False):
-        StorageDevice.setup(self, orig=orig)
-        if self.format and self.format.exists and not self.format.status:
-            self.format.device = self.path
-
-        for parent in self.parents:
-            if orig:
-                parent.originalFormat.setup()
-            else:
-                parent.format.setup()
-
-    def teardown(self, recursive=None):
-        StorageDevice.teardown(self)
-        if self.format and self.format.exists and not self.format.status:
-            self.format.device = self.path
-
-    def create(self, intf=None):
-        """ Create the device. """
-        log_method_call(self, self.name, status=self.status)
-        if self.exists:
-            raise DeviceError("device already exists", self.name)
-
-        w = None
-        if intf:
-            w = intf.waitWindow(_("Creating"),
-                                _("Creating file %s") % (self.path,))
-
-        try:
-            # this only checks that parents exist
-            self.createParents()
-            self.setupParents()
-
-            fd = os.open(self.path, os.O_RDWR)
-            buf = '\0' * 1024 * 1024 * self.size
-            os.write(fd, buf)
-        except (OSError, TypeError) as e:
-            log.error("error writing out %s: %s" % (self.path, e))
-            raise DeviceError(e, self.name)
-        else:
-            self.exists = True
-        finally:
-            os.close(fd)
-            if w:
-                w.pop()
-
-    def destroy(self):
-        """ Destroy the device. """
-        log_method_call(self, self.name, status=self.status)
-        if not self.exists:
-            raise DeviceError("device has not been created", self.name)
-
-        os.unlink(self.path)
-        self.exists = False
-
-
-class DirectoryDevice(FileDevice):
-    """ A directory on a filesystem.
-
-        This exists because of bind mounts.
-    """
-    _type = "directory"
-
-    def create(self):
-        """ Create the device. """
-        log_method_call(self, self.name, status=self.status)
-        if self.exists:
-            raise DeviceError("device already exists", self.name)
-
-        self.createParents()
-        self.setupParents()
-        try:
-            iutil.mkdirChain(self.path)
-        except Exception, e:
-            raise DeviceError(e, self.name)
-
-        self.exists = True
-
-    def destroy(self):
-        """ Destroy the device. """
-        log_method_call(self, self.name, status=self.status)
-        if not self.exists:
-            raise DeviceError("device has not been created", self.name)
-
-        os.unlink(self.path)
-        self.exists = False
-
-
-class iScsiDiskDevice(DiskDevice, NetworkStorageDevice):
-    """ An iSCSI disk. """
-    _type = "iscsi"
-    _packages = ["iscsi-initiator-utils", "dracut-network"]
-
-    def __init__(self, device, **kwargs):
-        self.node = kwargs.pop("node")
-        self.ibft = kwargs.pop("ibft")
-        self.initiator = kwargs.pop("initiator")
-        DiskDevice.__init__(self, device, **kwargs)
-        NetworkStorageDevice.__init__(self, host_address=self.node.address)
-        log.debug("created new iscsi disk %s %s:%d" % (self.node.name, self.node.address, self.node.port))
-
-    def dracutSetupString(self):
-        if self.ibft:
-            return "iscsi_firmware"
-
-        netroot="netroot=iscsi:"
-        auth = self.node.getAuth()
-        if auth:
-            netroot += "%s:%s" % (auth.username, auth.password)
-            if len(auth.reverse_username) or len(auth.reverse_password):
-                netroot += ":%s:%s" % (auth.reverse_username,
-                                       auth.reverse_password)
-
-        netroot += "@%s::%d::%s" % (self.node.address, self.node.port,
-                                    self.node.name)
-
-        netroot += " iscsi_initiator=%s" % self.initiator
-
-        return netroot
-
-class FcoeDiskDevice(DiskDevice, NetworkStorageDevice):
-    """ An FCoE disk. """
-    _type = "fcoe"
-    _packages = ["fcoe-utils", "dracut-network"]
-
-    def __init__(self, device, **kwargs):
-        self.nic = kwargs.pop("nic")
-        self.identifier = kwargs.pop("identifier")
-        DiskDevice.__init__(self, device, **kwargs)
-        NetworkStorageDevice.__init__(self, nic=self.nic)
-        log.debug("created new fcoe disk %s @ %s" % (device, self.nic))
-
-    def dracutSetupString(self):
-        dcb = True
-
-        from .fcoe import fcoe
-        for nic, dcb in fcoe().nics:
-            if nic == self.nic:
-                break
-
-        if dcb:
-            dcbOpt = "dcb"
-        else:
-            dcbOpt = "nodcb"
-
-        return "netroot=fcoe:%s:%s" % (self.nic, dcbOpt)
-
-
-class OpticalDevice(StorageDevice):
-    """ An optical drive, eg: cdrom, dvd+r, &c.
-
-        XXX Is this useful?
-    """
-    _type = "cdrom"
-
-    def __init__(self, name, major=None, minor=None, exists=None,
-                 format=None, parents=None, sysfsPath='', vendor="",
-                 model=""):
-        StorageDevice.__init__(self, name, format=format,
-                               major=major, minor=minor, exists=True,
-                               parents=parents, sysfsPath=sysfsPath,
-                               vendor=vendor, model=model)
-
-    @property
-    def mediaPresent(self):
-        """ Return a boolean indicating whether or not the device contains
-            media.
-        """
-        log_method_call(self, self.name, status=self.status)
-        if not self.exists:
-            raise DeviceError("device has not been created", self.name)
-
-        try:
-            fd = os.open(self.path, os.O_RDONLY)
-        except OSError as e:
-            # errno 123 = No medium found
-            if e.errno == 123:
-                return False
-            else:
-                return True
-        else:
-            os.close(fd)
-            return True
-
-    def eject(self):
-        """ Eject the drawer. """
-        import _isys
-
-        log_method_call(self, self.name, status=self.status)
-        if not self.exists:
-            raise DeviceError("device has not been created", self.name)
-
-        #try to umount and close device before ejecting
-        self.teardown()
-
-        # Make a best effort attempt to do the eject.  If it fails, it's not
-        # critical.
-        fd = os.open(self.path, os.O_RDONLY | os.O_NONBLOCK)
-
-        try:
-            _isys.ejectcdrom(fd)
-        except SystemError as e:
-            log.warning("error ejecting cdrom %s: %s" % (self.name, e))
-
-        os.close(fd)
-
-
-class ZFCPDiskDevice(DiskDevice):
-    """ A mainframe ZFCP disk. """
-    _type = "zfcp"
-
-    def __init__(self, device, **kwargs):
-        self.hba_id = kwargs.pop("hba_id")
-        self.wwpn = kwargs.pop("wwpn")
-        self.fcp_lun = kwargs.pop("fcp_lun")
-        DiskDevice.__init__(self, device, **kwargs)
-
-    def __str__(self):
-        s = DiskDevice.__str__(self)
-        s += ("  hba_id = %(hba_id)s  wwpn = %(wwpn)s  fcp_lun = %(fcp_lun)s" %
-              {"hba_id": self.hba_id,
-               "wwpn": self.wwpn,
-               "fcp_lun": self.fcp_lun})
-        return s
-
-    def dracutSetupString(self):
-        return "rd_ZFCP=%s,%s,%s" % (self.hba_id, self.wwpn, self.fcp_lun,)
-
-
-class DASDDevice(DiskDevice):
-    """ A mainframe DASD. """
-    _type = "dasd"
-
-    def __init__(self, device, **kwargs):
-        self.busid = kwargs.pop('busid')
-        self.opts = kwargs.pop('opts')
-        self.dasd = kwargs.pop('dasd')
-        DiskDevice.__init__(self, device, **kwargs)
-
-        if self.dasd:
-            self.dasd.addDASD(self)
-
-    def getOpts(self):
-        return map(lambda (k, v): "%s=%s" % (k, v,), self.opts.items())
-
-    def dracutSetupString(self):
-        args = ["rd_DASD=%s" % (self.busid,)] + self.getOpts()
-        return ",".join(args)
-
-
-class NFSDevice(StorageDevice, NetworkStorageDevice):
-    """ An NFS device """
-    _type = "nfs"
-    _packages = ["dracut-network"]
-
-    def __init__(self, device, format=None, parents=None):
-        # we could make host/ip, path, &c but will anything use it?
-        StorageDevice.__init__(self, device, format=format, parents=parents)
-        NetworkStorageDevice.__init__(self, device.split(":")[0])
-
-    @property
-    def path(self):
-        """ Device node representing this device. """
-        return self.name
-
-    def setup(self, intf=None, orig=False):
-        """ Open, or set up, a device. """
-        log_method_call(self, self.name, orig=orig, status=self.status)
-
-    def teardown(self, recursive=None):
-        """ Close, or tear down, a device. """
-        log_method_call(self, self.name, status=self.status)
-
-    def create(self, intf=None):
-        """ Create the device. """
-        log_method_call(self, self.name, status=self.status)
-        self.createParents()
-        self.setupParents()
-
-    def destroy(self):
-        """ Destroy the device. """
-        log_method_call(self, self.name, status=self.status)
diff --git a/storage/devicetree.py b/storage/devicetree.py
deleted file mode 100644
index 5c4df8e..0000000
--- a/storage/devicetree.py
+++ /dev/null
@@ -1,2278 +0,0 @@
-# devicetree.py
-# Device management for anaconda's storage configuration module.
-#
-# Copyright (C) 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, or (at your option) any later version.
-# 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.
-#
-# Red Hat Author(s): Dave Lehman <dlehman@xxxxxxxxxx>
-#
-
-import os
-import stat
-import block
-import re
-
-from errors import *
-from devices import *
-from deviceaction import *
-from partitioning import shouldClear
-from pykickstart.constants import *
-import formats
-import devicelibs.mdraid
-import devicelibs.dm
-import devicelibs.lvm
-import devicelibs.mpath
-from udev import *
-from .storage_log import log_method_call
-import iutil
-
-import gettext
-_ = lambda x: gettext.ldgettext("anaconda", x)
-
-import logging
-log = logging.getLogger("storage")
-
-def getLUKSPassphrase(intf, device, globalPassphrase):
-    """ Obtain a passphrase for a LUKS encrypted block device.
-
-        The format's mapping name must already be set and the backing
-        device must already be set up before calling this function.
-
-        If successful, this function leaves the device mapped.
-
-        Return value is a two-tuple: (passphrase, isglobal)
-
-        passphrase is the passphrase string, if obtained
-        isglobal is a boolean indicating whether the passphrase is global
-
-        Either or both can be None, depending on the outcome.
-    """
-    if device.format.type != "luks":
-        # this function only works on luks devices
-        raise ValueError("not a luks device")
-
-    if not device.status:
-        # the device should have already been set up
-        raise RuntimeError("device is not set up")
-
-    if device.format.status:
-        # the device is already mapped
-        raise RuntimeError("device is already mapped")
-
-    if not device.format.configured and globalPassphrase:
-        # try the given passphrase first
-        device.format.passphrase =  globalPassphrase
-    
-        try:
-            device.format.setup()
-        except CryptoError as e:
-            device.format.passphrase = None
-        else:
-            # we've opened the device so we're done.
-            return (globalPassphrase, False)
-
-    if not intf:
-        return (None, None)
-    
-    buttons = [_("Back"), _("Continue")]
-    passphrase_incorrect = False
-    while True:
-        if passphrase_incorrect:
-            # TODO: add a flag to passphraseEntryWindow to say the last
-            #       passphrase was incorrect so try again
-            passphrase_incorrect = False
-        (passphrase, isglobal) = intf.passphraseEntryWindow(device.name)
-        if not passphrase:
-            rc = intf.messageWindow(_("Confirm"),
-                                    _("Are you sure you want to skip "
-                                      "entering a passphrase for device "
-                                      "%s?\n\n"
-                                      "If you skip this step the "
-                                      "device's contents will not "
-                                      "be available during "
-                                      "installation.") % device.name,
-                                    type = "custom",
-                                    default = 0,
-                                    custom_buttons = buttons)
-            if rc == 0:
-                continue
-            else:
-                passphrase = None
-                isglobal = None
-                log.info("skipping passphrase for %s" % (device.name,))
-                break
-
-        device.format.passphrase = passphrase
-
-        try:
-            device.format.setup()
-        except CryptoError as e:
-            device.format.passphrase = None
-            passphrase_incorrect = True
-        else:
-            # we've opened the device so we're done.
-            break
-
-    return (passphrase, isglobal)
-
-
-class DeviceTree(object):
-    """ A quasi-tree that represents the devices in the system.
-
-        The tree contains a list of device instances, which does not
-        necessarily reflect the actual state of the system's devices.
-        DeviceActions are used to perform modifications to the tree,
-        except when initially populating the tree.
-
-        DeviceAction instances are registered, possibly causing the
-        addition or removal of Device instances to/from the tree. The
-        DeviceActions are all reversible up to the time their execute
-        method has been called.
-
-        Only one action of any given type/object pair should exist for
-        any given device at any given time.
-
-        DeviceAction instances can only be registered for leaf devices,
-        except for resize actions.
-    """
-
-    def __init__(self, intf=None, ignored=[], exclusive=[], type=CLEARPART_TYPE_NONE,
-                 clear=[], zeroMbr=None, reinitializeDisks=None, protected=[],
-                 passphrase=None, luksDict=None, iscsi=None, dasd=None):
-        # internal data members
-        self._devices = []
-        self._actions = []
-
-        # indicates whether or not the tree has been fully populated
-        self.populated = False
-
-        self.intf = intf
-        self.exclusiveDisks = exclusive
-        self.clearPartType = type
-        self.clearPartDisks = clear
-        self.zeroMbr = zeroMbr
-        self.reinitializeDisks = reinitializeDisks
-        self.iscsi = iscsi
-        self.dasd = dasd
-
-        # protected device specs as provided by the user
-        self.protectedDevSpecs = protected
-
-        # names of protected devices at the time of tree population
-        self.protectedDevNames = []
-
-        self.unusedRaidMembers = []
-
-        self.__multipaths = {}
-        self.__multipathConfigWriter = devicelibs.mpath.MultipathConfigWriter()
-
-        self.__passphrase = passphrase
-        self.__luksDevs = {}
-        if luksDict and isinstance(luksDict, dict):
-            self.__luksDevs = luksDict
-        self._ignoredDisks = []
-        for disk in ignored:
-            self.addIgnoredDisk(disk)
-        self.immutableDevices = []
-        lvm.lvm_cc_resetFilter()
-
-    def addIgnoredDisk(self, disk):
-        self._ignoredDisks.append(disk)
-        lvm.lvm_cc_addFilterRejectRegexp(disk)
-
-    def pruneActions(self):
-        """ Prune loops and redundant actions from the queue. """
-        # handle device destroy actions
-        actions = self.findActions(type="destroy", object="device")
-        for a in actions:
-            if a not in self._actions:
-                # we may have removed some of the actions in a previous
-                # iteration of this loop
-                continue
-
-            log.debug("action '%s' (%s)" % (a, id(a)))
-            destroys = self.findActions(devid=a.device.id,
-                                        type="destroy",
-                                        object="device")
-
-            creates = self.findActions(devid=a.device.id,
-                                       type="create",
-                                       object="device")
-            log.debug("found %d create and %d destroy actions for device id %d"
-                        % (len(creates), len(destroys), a.device.id))
-
-            # If the device is not preexisting, we remove all actions up
-            # to and including the last destroy action.
-            # If the device is preexisting, we remove all actions from
-            # after the first destroy action up to and including the last
-            # destroy action.
-            # If the device is preexisting and there is only one device
-            # destroy action we remove all resize and format create/migrate
-            # actions on that device that precede the destroy action.
-            loops = []
-            first_destroy_idx = None
-            first_create_idx = None
-            stop_action = None
-            start = None
-            if len(destroys) > 1:
-                # there are multiple destroy actions for this device
-                loops = destroys
-                first_destroy_idx = self._actions.index(loops[0])
-                start = self._actions.index(a) + 1
-                stop_action = destroys[-1]
-
-            if creates:
-                first_create_idx = self._actions.index(creates[0])
-                if not loops or first_destroy_idx > first_create_idx:
-                    # this device is not preexisting
-                    start = first_create_idx
-                    stop_action = destroys[-1]
-
-            dev_actions = self.findActions(devid=a.device.id)
-            if start is None:
-                # only one device destroy, so prune preceding resizes and
-                # format creates and migrates
-                for _a in dev_actions[:]:
-                    if _a.isResize() or (_a.isFormat() and not _a.isDestroy()):
-                        continue
-
-                    dev_actions.remove(_a)
-
-                if not dev_actions:
-                    # nothing to prune
-                    continue
-
-                start = self._actions.index(dev_actions[0])
-                stop_action = dev_actions[-1]
-
-            # now we remove all actions on this device between the start
-            # index (into self._actions) and stop_action.
-            for rem in dev_actions:
-                end = self._actions.index(stop_action)
-                if start <= self._actions.index(rem) <= end:
-                    log.debug(" removing action '%s' (%s)" % (rem, id(rem)))
-                    self._actions.remove(rem)
-
-                if rem == stop_action:
-                    break
-
-        # device create actions
-        actions = self.findActions(type="create", object="device")
-        for a in actions:
-            if a not in self._actions:
-                # we may have removed some of the actions in a previous
-                # iteration of this loop
-                continue
-
-            log.debug("action '%s' (%s)" % (a, id(a)))
-            creates = self.findActions(devid=a.device.id,
-                                       type="create",
-                                       object="device")
-
-            destroys = self.findActions(devid=a.device.id,
-                                        type="destroy",
-                                        object="device")
-
-            # If the device is preexisting, we remove everything between
-            # the first destroy and the last create.
-            # If the device is not preexisting, we remove everything up to
-            # the last create.
-            loops = []
-            first_destroy_idx = None
-            first_create_idx = None
-            stop_action = None
-            start = None
-            if len(creates) > 1:
-                # there are multiple create actions for this device
-                loops = creates
-                first_create_idx = self._actions.index(loops[0])
-                start = 0
-                stop_action = creates[-1]
-
-            if destroys:
-                first_destroy_idx = self._actions.index(destroys[0])
-                if not loops or first_create_idx > first_destroy_idx:
-                    # this device is preexisting
-                    start = first_destroy_idx + 1
-                    stop_action = creates[-1]
-
-            if start is None:
-                continue
-
-            # remove all actions on this from after the first destroy up
-            # to the last create
-            dev_actions = self.findActions(devid=a.device.id)
-            for rem in dev_actions:
-                if rem == stop_action:
-                    break
-
-                end = self._actions.index(stop_action)
-                if start <= self._actions.index(rem) < end:
-                    log.debug(" removing action '%s' (%s)" % (rem, id(rem)))
-                    self._actions.remove(rem)
-
-        # device resize actions
-        actions = self.findActions(type="resize", object="device")
-        for a in actions:
-            if a not in self._actions:
-                # we may have removed some of the actions in a previous
-                # iteration of this loop
-                continue
-
-            log.debug("action '%s' (%s)" % (a, id(a)))
-            loops = self.findActions(devid=a.device.id,
-                                     type="resize",
-                                     object="device")
-
-            if len(loops) == 1:
-                continue
-
-            # remove all but the last resize action on this device
-            for rem in loops[:-1]:
-                log.debug(" removing action '%s' (%s)" % (rem, id(rem)))
-                self._actions.remove(rem)
-
-        # format destroy
-        # XXX I don't think there's a way for these loops to happen
-        actions = self.findActions(type="destroy", object="format")
-        for a in actions:
-            if a not in self._actions:
-                # we may have removed some of the actions in a previous
-                # iteration of this loop
-                continue
-
-            log.debug("action '%s' (%s)" % (a, id(a)))
-            destroys = self.findActions(devid=a.device.id,
-                                        type="destroy",
-                                        object="format")
-
-            creates = self.findActions(devid=a.device.id,
-                                       type="create",
-                                       object="format")
-
-            # If the format is not preexisting, we remove all actions up
-            # to and including the last destroy action.
-            # If the format is preexisting, we remove all actions from
-            # after the first destroy action up to and including the last
-            # destroy action.
-            loops = []
-            first_destroy_idx = None
-            first_create_idx = None
-            stop_action = None
-            start = None
-            if len(destroys) > 1:
-                # there are multiple destroy actions for this format
-                loops = destroys
-                first_destroy_idx = self._actions.index(loops[0])
-                start = self._actions.index(a) + 1
-                stop_action = destroys[-1]
-
-            if creates:
-                first_create_idx = self._actions.index(creates[0])
-                if not loops or first_destroy_idx > first_create_idx:
-                    # this format is not preexisting
-                    start = first_create_idx
-                    stop_action = destroys[-1]
-
-            if start is None:
-                continue
-
-            # now we remove all actions on this device's format between
-            # the start index (into self._actions) and stop_action.
-            dev_actions = self.findActions(devid=a.device.id,
-                                           object="format")
-            for rem in dev_actions:
-                end = self._actions.index(stop_action)
-                if start <= self._actions.index(rem) <= end:
-                    log.debug(" removing action '%s' (%s)" % (rem, id(rem)))
-                    self._actions.remove(rem)
-
-                if rem == stop_action:
-                    break
-
-        # format create
-        # XXX I don't think there's a way for these loops to happen
-        actions = self.findActions(type="create", object="format")
-        for a in actions:
-            if a not in self._actions:
-                # we may have removed some of the actions in a previous
-                # iteration of this loop
-                continue
-
-            log.debug("action '%s' (%s)" % (a, id(a)))
-            creates = self.findActions(devid=a.device.id,
-                                       type="create",
-                                       object="format")
-
-            destroys = self.findActions(devid=a.device.id,
-                                        type="destroy",
-                                        object="format")
-
-            # If the format is preexisting, we remove everything between
-            # the first destroy and the last create.
-            # If the format is not preexisting, we remove everything up to
-            # the last create.
-            loops = []
-            first_destroy_idx = None
-            first_create_idx = None
-            stop_action = None
-            start = None
-            if len(creates) > 1:
-                # there are multiple create actions for this format
-                loops = creates
-                first_create_idx = self._actions.index(loops[0])
-                start = 0
-                stop_action = creates[-1]
-
-            if destroys:
-                first_destroy_idx = self._actions.index(destroys[0])
-                if not loops or first_create_idx > first_destroy_idx:
-                    # this format is preexisting
-                    start = first_destroy_idx + 1
-                    stop_action = creates[-1]
-
-            if start is None:
-                continue
-
-            # remove all actions on this from after the first destroy up
-            # to the last create
-            dev_actions = self.findActions(devid=a.device.id,
-                                           object="format")
-            for rem in dev_actions:
-                if rem == stop_action:
-                    break
-
-                end = self._actions.index(stop_action)
-                if start <= self._actions.index(rem) < end:
-                    log.debug(" removing action '%s' (%s)" % (rem, id(rem)))
-                    self._actions.remove(rem)
-
-        # format resize
-        actions = self.findActions(type="resize", object="format")
-        for a in actions:
-            if a not in self._actions:
-                # we may have removed some of the actions in a previous
-                # iteration of this loop
-                continue
-
-            log.debug("action '%s' (%s)" % (a, id(a)))
-            loops = self.findActions(devid=a.device.id,
-                                     type="resize",
-                                     object="format")
-
-            if len(loops) == 1:
-                continue
-
-            # remove all but the last resize action on this format
-            for rem in loops[:-1]:
-                log.debug(" removing action '%s' (%s)" % (rem, id(rem)))
-                self._actions.remove(rem)
-
-        # format migrate
-        # XXX I don't think there's away for these loops to occur
-        actions = self.findActions(type="migrate", object="format")
-        for a in actions:
-            if a not in self._actions:
-                # we may have removed some of the actions in a previous
-                # iteration of this loop
-                continue
-
-            log.debug("action '%s' (%s)" % (a, id(a)))
-            loops = self.findActions(devid=a.device.id,
-                                     type="migrate",
-                                     object="format")
-
-            if len(loops) == 1:
-                continue
-
-            # remove all but the last migrate action on this format
-            for rem in loops[:-1]:
-                log.debug(" removing action '%s' (%s)" % (rem, id(rem)))
-                self._actions.remove(rem)
-
-    def processActions(self, dryRun=None):
-        """ Execute all registered actions. """
-        # in most cases the actions will already be sorted because of the
-        # rules for registration, but let's not rely on that
-        def cmpActions(a1, a2):
-            ret = 0
-            if a1.isDestroy() and a2.isDestroy():
-                if a1.device.path == a2.device.path:
-                    # if it's the same device, destroy the format first
-                    if a1.isFormat() and a2.isFormat():
-                        ret = 0
-                    elif a1.isFormat() and not a2.isFormat():
-                        ret = -1
-                    elif not a1.isFormat() and a2.isFormat():
-                        ret = 1
-                elif a1.device.dependsOn(a2.device):
-                    ret = -1
-                elif a2.device.dependsOn(a1.device):
-                    ret = 1
-                # generally destroy partitions after lvs, vgs, &c
-                elif isinstance(a1.device, PartitionDevice) and \
-                     isinstance(a2.device, PartitionDevice):
-                    if a1.device.disk == a2.device.disk:
-                        ret = cmp(a2.device.partedPartition.number,
-                                  a1.device.partedPartition.number)
-                    else:
-                        ret = cmp(a2.device.name, a1.device.name)
-                elif isinstance(a1.device, PartitionDevice) and \
-                     a2.device.partitioned:
-                    ret = -1
-                elif isinstance(a2.device, PartitionDevice) and \
-                     a1.device.partitioned:
-                    ret = 1
-                # remove partitions before unpartitioned non-partition
-                # devices
-                elif isinstance(a1.device, PartitionDevice) and \
-                     not isinstance(a2.device, PartitionDevice):
-                    ret = 1
-                elif isinstance(a2.device, PartitionDevice) and \
-                     not isinstance(a1.device, PartitionDevice):
-                    ret = -1
-                else:
-                    ret = 0
-            elif a1.isDestroy():
-                ret = -1
-            elif a2.isDestroy():
-                ret = 1
-            elif a1.isResize() and a2.isResize():
-                if a1.device.path == a2.device.path:
-                    if a1.obj == a2.obj:
-                        ret = 0
-                    elif a1.isFormat() and not a2.isFormat():
-                        # same path, one device, one format
-                        if a1.isGrow():
-                            ret = 1
-                        else:
-                            ret = -1
-                    elif not a1.isFormat() and a2.isFormat():
-                        # same path, one device, one format
-                        if a1.isGrow():
-                            ret = -1
-                        else:
-                            ret = 1
-                    else:
-                        ret = cmp(a1.device.name, a2.device.name)
-                elif a1.device.dependsOn(a2.device):
-                    if a1.isGrow():
-                        ret = 1
-                    else:
-                        ret = -1
-                elif a2.device.dependsOn(a1.device):
-                    if a1.isGrow():
-                        ret = -1
-                    else:
-                        ret = 1
-                elif isinstance(a1.device, PartitionDevice) and \
-                     isinstance(a2.device, PartitionDevice):
-                    ret = cmp(a1.device.name, a2.device.name)
-                else:
-                    ret = 0
-            elif a1.isResize():
-                ret = -1
-            elif a2.isResize():
-                ret = 1
-            elif a1.isCreate() and a2.isCreate():
-                if a1.device.path == a2.device.path:
-                    if a1.obj == a2.obj:
-                        ret = 0
-                    if a1.isFormat():
-                        ret = 1
-                    elif a2.isFormat():
-                        ret = -1
-                    else:
-                        ret = 0
-                elif a1.device.dependsOn(a2.device):
-                    ret = 1
-                elif a2.device.dependsOn(a1.device):
-                    ret = -1
-                # generally create partitions before other device types
-                elif isinstance(a1.device, PartitionDevice) and \
-                     isinstance(a2.device, PartitionDevice):
-                    if a1.device.disk == a2.device.disk:
-                        ret = cmp(a1.device.partedPartition.number,
-                                  a2.device.partedPartition.number)
-                    else:
-                        ret = cmp(a1.device.name, a2.device.name)
-                elif isinstance(a1.device, PartitionDevice) and \
-                     a2.device.partitioned:
-                    ret = 1
-                elif isinstance(a2.device, PartitionDevice) and \
-                     a1.device.partitioned:
-                    ret = -1
-                elif isinstance(a1.device, PartitionDevice) and \
-                     not isinstance(a2.device, PartitionDevice):
-                    ret = -1
-                elif isinstance(a2.device, PartitionDevice) and \
-                     not isinstance(a1.device, PartitionDevice):
-                    ret = 1
-                else:
-                    ret = 0
-            elif a1.isCreate():
-                ret = -1
-            elif a2.isCreate():
-                ret = 1
-            elif a1.isMigrate() and a2.isMigrate():
-                if a1.device.path == a2.device.path:
-                    ret = 0
-                elif a1.device.dependsOn(a2.device):
-                    ret = 1
-                elif a2.device.dependsOn(a1.device):
-                    ret = -1
-                elif isinstance(a1.device, PartitionDevice) and \
-                     isinstance(a2.device, PartitionDevice):
-                    if a1.device.disk == a2.device.disk:
-                        ret = cmp(a1.device.partedPartition.number,
-                                  a2.device.partedPartition.number)
-                    else:
-                        ret = cmp(a1.device.name, a2.device.name)
-                else:
-                    ret = 0
-            else:
-                ret = 0
-
-            log.debug("cmp: %d -- %s | %s" % (ret, a1, a2))
-            return ret
-
-        log.debug("resetting parted disks...")
-        for device in self.devices:
-            if device.partitioned:
-                device.format.resetPartedDisk()
-                if device.originalFormat.type == "disklabel" and \
-                   device.originalFormat != device.format:
-                    device.originalFormat.resetPartedDisk()
-
-        # Call preCommitFixup on all devices
-        mpoints = [getattr(d.format, 'mountpoint', "") for d in self.devices]
-        for device in self.devices:
-            device.preCommitFixup(mountpoints=mpoints)
-
-        # Also call preCommitFixup on any devices we're going to
-        # destroy (these are already removed from the tree)
-        for action in self._actions:
-            if isinstance(action, ActionDestroyDevice):
-                action.device.preCommitFixup(mountpoints=mpoints)
-
-        # setup actions to create any extended partitions we added
-        #
-        # XXX At this point there can be duplicate partition paths in the
-        #     tree (eg: non-existent sda6 and previous sda6 that will become
-        #     sda5 in the course of partitioning), so we access the list
-        #     directly here.
-        for device in self._devices:
-            if isinstance(device, PartitionDevice) and \
-               device.isExtended and not device.exists:
-                # don't properly register the action since the device is
-                # already in the tree
-                self._actions.append(ActionCreateDevice(device))
-
-        for action in self._actions:
-            log.debug("action: %s" % action)
-
-        log.debug("pruning action queue...")
-        self.pruneActions()
-        for action in self._actions:
-            log.debug("action: %s" % action)
-
-        log.debug("sorting actions...")
-        self._actions.sort(cmp=cmpActions)
-        for action in self._actions:
-            log.debug("action: %s" % action)
-
-        for action in self._actions:
-            log.info("executing action: %s" % action)
-            if not dryRun:
-                try:
-                    action.execute(intf=self.intf)
-                except DiskLabelCommitError:
-                    # it's likely that a previous format destroy action
-                    # triggered setup of an lvm or md device.
-                    self.teardownAll()
-                    action.execute(intf=self.intf)
-
-                udev_settle()
-                for device in self._devices:
-                    # make sure we catch any renumbering parted does
-                    if device.exists and isinstance(device, PartitionDevice):
-                        device.updateName()
-                        device.format.device = device.path
-
-    def _addDevice(self, newdev):
-        """ Add a device to the tree.
-
-            Raise ValueError if the device's identifier is already
-            in the list.
-        """
-        if newdev.path in [d.path for d in self._devices] and \
-           not isinstance(newdev, NoDevice):
-            raise ValueError("device is already in tree")
-
-        # make sure this device's parent devices are in the tree already
-        for parent in newdev.parents:
-            if parent not in self._devices:
-                raise DeviceTreeError("parent device not in tree")
-
-        self._devices.append(newdev)
-        log.debug("added %s %s (id %d) to device tree" % (newdev.type,
-                                                          newdev.name,
-                                                          newdev.id))
-
-    def _removeDevice(self, dev, force=None, moddisk=True):
-        """ Remove a device from the tree.
-
-            Only leaves may be removed.
-        """
-        if dev not in self._devices:
-            raise ValueError("Device '%s' not in tree" % dev.name)
-
-        if not dev.isleaf and not force:
-            log.debug("%s has %d kids" % (dev.name, dev.kids))
-            raise ValueError("Cannot remove non-leaf device '%s'" % dev.name)
-
-        # if this is a partition we need to remove it from the parted.Disk
-        if moddisk and isinstance(dev, PartitionDevice) and \
-                dev.disk is not None:
-            # if this partition hasn't been allocated it could not have
-            # a disk attribute
-            if dev.partedPartition.type == parted.PARTITION_EXTENDED and \
-                    len(dev.disk.format.logicalPartitions) > 0:
-                raise ValueError("Cannot remove extended partition %s.  "
-                        "Logical partitions present." % dev.name)
-
-            dev.disk.format.removePartition(dev.partedPartition)
-
-            # adjust all other PartitionDevice instances belonging to the
-            # same disk so the device name matches the potentially altered
-            # name of the parted.Partition
-            for device in self._devices:
-                if isinstance(device, PartitionDevice) and \
-                   device.disk == dev.disk:
-                    device.updateName()
-
-        self._devices.remove(dev)
-        log.debug("removed %s %s (id %d) from device tree" % (dev.type,
-                                                              dev.name,
-                                                              dev.id))
-
-        for parent in dev.parents:
-            # Will this cause issues with garbage collection?
-            #   Do we care about garbage collection? At all?
-            parent.removeChild()
-
-    def registerAction(self, action):
-        """ Register an action to be performed at a later time.
-
-            Modifications to the Device instance are handled before we
-            get here.
-        """
-        if (action.isDestroy() or action.isResize() or \
-            (action.isCreate() and action.isFormat())) and \
-           action.device not in self._devices:
-            raise DeviceTreeError("device is not in the tree")
-        elif (action.isCreate() and action.isDevice()):
-            # this allows multiple create actions w/o destroy in between;
-            # we will clean it up before processing actions
-            #raise DeviceTreeError("device is already in the tree")
-            if action.device in self._devices:
-                self._removeDevice(action.device)
-            for d in self._devices:
-                if d.path == action.device.path:
-                    self._removeDevice(d)
-
-        if action.isCreate() and action.isDevice():
-            self._addDevice(action.device)
-        elif action.isDestroy() and action.isDevice():
-            self._removeDevice(action.device)
-        elif action.isCreate() and action.isFormat():
-            if isinstance(action.device.format, formats.fs.FS) and \
-               action.device.format.mountpoint in self.filesystems:
-                raise DeviceTreeError("mountpoint already in use")
-
-        log.debug("registered action: %s" % action)
-        self._actions.append(action)
-
-    def cancelAction(self, action):
-        """ Cancel a registered action.
-
-            This will unregister the action and do any required
-            modifications to the device list.
-
-            Actions all operate on a Device, so we can use the devices
-            to determine dependencies.
-        """
-        if action.isCreate() and action.isDevice():
-            # remove the device from the tree
-            self._removeDevice(action.device)
-        elif action.isDestroy() and action.isDevice():
-            # add the device back into the tree
-            self._addDevice(action.device)
-        elif action.isFormat() and \
-             (action.isCreate() or action.isMigrate() or action.isResize()):
-            action.cancel()
-
-        self._actions.remove(action)
-
-    def findActions(self, device=None, type=None, object=None, path=None,
-                    devid=None):
-        """ Find all actions that match all specified parameters.
-
-            Keyword arguments:
-
-                device -- device to match (Device, or None to match any)
-                type -- action type to match (string, or None to match any)
-                object -- operand type to match (string, or None to match any)
-                path -- device path to match (string, or None to match any)
-
-        """
-        if device is None and type is None and object is None and \
-           path is None and devid is None:
-            return self._actions[:]
-
-        # convert the string arguments to the types used in actions
-        _type = action_type_from_string(type)
-        _object = action_object_from_string(object)
-
-        actions = []
-        for action in self._actions:
-            if device is not None and action.device != device:
-                continue
-
-            if _type is not None and action.type != _type:
-                continue
-
-            if _object is not None and action.obj != _object:
-                continue
-
-            if path is not None and action.device.path != path:
-                continue
-
-            if devid is not None and action.device.id != devid:
-                continue
-                
-            actions.append(action)
-
-        return actions
-
-    def getDependentDevices(self, dep):
-        """ Return a list of devices that depend on dep.
-
-            The list includes both direct and indirect dependents.
-        """
-        dependents = []
-
-        # special handling for extended partitions since the logical
-        # partitions and their deps effectively depend on the extended
-        logicals = []
-        if isinstance(dep, PartitionDevice) and dep.partType and \
-           dep.isExtended:
-            # collect all of the logicals on the same disk
-            for part in self.getDevicesByInstance(PartitionDevice):
-                if part.partType and part.isLogical and part.disk == dep.disk:
-                    logicals.append(part)
-
-        for device in self.devices:
-            if device.dependsOn(dep):
-                dependents.append(device)
-            else:
-                for logical in logicals:
-                    if device.dependsOn(logical):
-                        dependents.append(device)
-                        break
-
-        return dependents
-
-    def isIgnored(self, info):
-        """ Return True if info is a device we should ignore.
-
-            Arguments:
-
-                info -- a dict representing a udev db entry
-
-            TODO:
-
-                - filtering of SAN/FC devices
-                - filtering by driver?
-
-        """
-        sysfs_path = udev_device_get_sysfs_path(info)
-        name = udev_device_get_name(info)
-        if not sysfs_path:
-            return None
-
-        if name in self._ignoredDisks:
-            return True
-
-        # Special handling for mdraid external metadata sets (mdraid BIOSRAID):
-        # 1) The containers are intermediate devices which will never be
-        # in exclusiveDisks
-        # 2) Sets get added to exclusive disks with their dmraid set name by
-        # the filter ui.  Note that making the ui use md names instead is not
-        # possible as the md names are simpy md# and we cannot predict the #
-        if udev_device_get_md_level(info) == "container":
-            return False
-
-        if udev_device_get_md_container(info) and \
-               udev_device_get_md_name(info):
-            md_name = udev_device_get_md_name(info)
-            for i in range(0, len(self.exclusiveDisks)):
-                if re.match("isw_[a-z]*_%s" % md_name, self.exclusiveDisks[i]):
-                    self.exclusiveDisks[i] = name
-                    return False
-
-        if udev_device_is_disk(info) and \
-                not udev_device_is_md(info) and \
-                not udev_device_is_dm(info) and \
-                not udev_device_is_biosraid(info) and \
-                not udev_device_is_multipath_member(info):
-            if self.exclusiveDisks and name not in self.exclusiveDisks:
-                self.addIgnoredDisk(name)
-                return True
-
-        # Ignore loop and ram devices, we normally already skip these in
-        # udev.py: enumerate_block_devices(), but we can still end up trying
-        # to add them to the tree when they are slaves of other devices, this
-        # happens for example with the livecd
-        if name.startswith("loop") or name.startswith("ram"):
-            return True
-
-        # FIXME: check for virtual devices whose slaves are on the ignore list
-
-    def addUdevDMDevice(self, info):
-        name = udev_device_get_name(info)
-        log_method_call(self, name=name)
-        uuid = udev_device_get_uuid(info)
-        sysfs_path = udev_device_get_sysfs_path(info)
-        device = None
-
-        for dmdev in self.devices:
-            if not isinstance(dmdev, DMDevice):
-                continue
-
-            try:
-                # there is a device in the tree already with the same
-                # major/minor as this one but with a different name
-                # XXX this is kind of racy
-                if dmdev.getDMNode() == os.path.basename(sysfs_path):
-                    # XXX should we take the name already in use?
-                    device = dmdev
-                    break
-            except DMError:
-                # This is a little lame, but the VG device is a DMDevice
-                # and it won't have a dm node. At any rate, this is not
-                # important enough to crash the install.
-                log.debug("failed to find dm node for %s" % dmdev.name)
-                continue
-
-        if device is None:
-            # we couldn't find it, so create it
-            # first, get a list of the slave devs and look them up
-            slaves = []
-            dir = os.path.normpath("/sys/%s/slaves" % sysfs_path)
-            slave_names = os.listdir(dir)
-            for slave_name in slave_names:
-                # if it's a dm-X name, resolve it to a map name first
-                if slave_name.startswith("dm-"):
-                    dev_name = dm.name_from_dm_node(slave_name)
-                else:
-                    dev_name = slave_name
-                slave_dev = self.getDeviceByName(dev_name)
-                if slave_dev:
-                    slaves.append(slave_dev)
-                else:
-                    # we haven't scanned the slave yet, so do it now
-                    path = os.path.normpath("%s/%s" % (dir, slave_name))
-                    new_info = udev_get_block_device(os.path.realpath(path)[4:])
-                    if new_info:
-                        self.addUdevDevice(new_info)
-                        if self.getDeviceByName(dev_name) is None:
-                            # if the current slave is still not in
-                            # the tree, something has gone wrong
-                            log.error("failure scanning device %s: could not add slave %s" % (name, dev_name))
-                            return
-
-            # try to get the device again now that we've got all the slaves
-            device = self.getDeviceByName(name)
-
-            if device is None:
-                if udev_device_is_multipath_partition(info, self):
-                    diskname = udev_device_get_multipath_partition_disk(info)
-                    disk = self.getDeviceByName(diskname)
-                    return self.addUdevPartitionDevice(info, disk=disk)
-                elif udev_device_is_dmraid_partition(info, self):
-                    diskname = udev_device_get_dmraid_partition_disk(info)
-                    disk = self.getDeviceByName(diskname)
-                    return self.addUdevPartitionDevice(info, disk=disk)
-
-            # if we get here, we found all of the slave devices and
-            # something must be wrong -- if all of the slaves are in
-            # the tree, this device should be as well
-            if device is None:
-                log.warning("ignoring dm device %s" % name)
-
-        return device
-
-    def addUdevMDDevice(self, info):
-        name = udev_device_get_name(info)
-        log_method_call(self, name=name)
-        uuid = udev_device_get_uuid(info)
-        sysfs_path = udev_device_get_sysfs_path(info)
-        device = None
-
-        slaves = []
-        dir = os.path.normpath("/sys/%s/slaves" % sysfs_path)
-        slave_names = os.listdir(dir)
-        for slave_name in slave_names:
-            # if it's a dm-X name, resolve it to a map name
-            if slave_name.startswith("dm-"):
-                dev_name = dm.name_from_dm_node(slave_name)
-            else:
-                dev_name = slave_name
-            slave_dev = self.getDeviceByName(dev_name)
-            if slave_dev:
-                slaves.append(slave_dev)
-            else:
-                # we haven't scanned the slave yet, so do it now
-                path = os.path.normpath("%s/%s" % (dir, slave_name))
-                new_info = udev_get_block_device(os.path.realpath(path)[4:])
-                if new_info:
-                    self.addUdevDevice(new_info)
-                    if self.getDeviceByName(dev_name) is None:
-                        # if the current slave is still not in
-                        # the tree, something has gone wrong
-                        log.error("failure scanning device %s: could not add slave %s" % (name, dev_name))
-                        return
-
-        # try to get the device again now that we've got all the slaves
-        device = self.getDeviceByName(name)
-
-        # if we get here, we found all of the slave devices and
-        # something must be wrong -- if all of the slaves we in
-        # the tree, this device should be as well
-        if device is None:
-            log.warning("using MD RAID device for %s" % name)
-            try:
-                # level is reported as, eg: "raid1"
-                md_level = udev_device_get_md_level(info)
-                md_devices = int(udev_device_get_md_devices(info))
-                md_uuid = udev_device_get_md_uuid(info)
-            except (KeyError, IndexError, ValueError) as e:
-                log.warning("invalid data for %s: %s" % (name, e))
-                return
-
-            device = MDRaidArrayDevice(name,
-                                       level=md_level,
-                                       memberDevices=md_devices,
-                                       uuid=md_uuid,
-                                       exists=True,
-                                       parents=slaves)
-            self._addDevice(device)
-
-        return device
-
-    def addUdevPartitionDevice(self, info, disk=None):
-        name = udev_device_get_name(info)
-        log_method_call(self, name=name)
-        uuid = udev_device_get_uuid(info)
-        sysfs_path = udev_device_get_sysfs_path(info)
-        device = None
-
-        if disk is None:
-            disk_name = os.path.basename(os.path.dirname(sysfs_path))
-            disk_name = disk_name.replace('!','/')
-            disk = self.getDeviceByName(disk_name)
-
-        if disk is None:
-            # create a device instance for the disk
-            new_info = udev_get_block_device(os.path.dirname(sysfs_path))
-            if new_info:
-                self.addUdevDevice(new_info)
-                disk = self.getDeviceByName(disk_name)
-
-            if disk is None:
-                # if the current device is still not in
-                # the tree, something has gone wrong
-                log.error("failure scanning device %s" % disk_name)
-                lvm.lvm_cc_addFilterRejectRegexp(name)
-                return
-
-        # Check that the disk has partitions. If it does not, we must have
-        # reinitialized the disklabel.
-        #
-        # Also ignore partitions on devices we do not support partitioning
-        # of, like logical volumes.
-        if not getattr(disk.format, "partitions", None) or \
-           not disk.partitionable:
-            # When we got here because the disk does not have a disklabel
-            # format (ie a biosraid member), or because it is not
-            # partitionable we want LVM to ignore this partition too
-            if disk.format.type != "disklabel" or not disk.partitionable:
-                lvm.lvm_cc_addFilterRejectRegexp(name)
-            log.debug("ignoring partition %s" % name)
-            return
-
-        try:
-            device = PartitionDevice(name, sysfsPath=sysfs_path,
-                                     major=udev_device_get_major(info),
-                                     minor=udev_device_get_minor(info),
-                                     exists=True, parents=[disk])
-        except DeviceError:
-            # corner case sometime the kernel accepts a partition table
-            # which gets rejected by parted, in this case we will
-            # prompt to re-initialize the disk, so simply skip the
-            # faulty partitions.
-            return
-
-        self._addDevice(device)
-        return device
-
-    def addUdevDiskDevice(self, info):
-        name = udev_device_get_name(info)
-        log_method_call(self, name=name)
-        uuid = udev_device_get_uuid(info)
-        sysfs_path = udev_device_get_sysfs_path(info)
-        serial = udev_device_get_serial(info)
-        bus = udev_device_get_bus(info)
-
-        # udev doesn't always provide a vendor.
-        vendor = udev_device_get_vendor(info)
-        if not vendor:
-            vendor = ""
-
-        device = None
-
-        kwargs = { "serial": serial, "vendor": vendor, "bus": bus }
-        if udev_device_is_iscsi(info):
-            diskType = iScsiDiskDevice
-            kwargs["node"] = self.iscsi.getNode(
-                                   udev_device_get_iscsi_name(info),
-                                   udev_device_get_iscsi_address(info),
-                                   udev_device_get_iscsi_port(info))
-            kwargs["ibft"] = kwargs["node"] in self.iscsi.ibftNodes
-            kwargs["initiator"] = self.iscsi.initiator
-            log.debug("%s is an iscsi disk" % name)
-        elif udev_device_is_fcoe(info):
-            diskType = FcoeDiskDevice
-            kwargs["nic"]        = udev_device_get_fcoe_nic(info)
-            kwargs["identifier"] = udev_device_get_fcoe_identifier(info)
-            log.debug("%s is an fcoe disk" % name)
-        elif udev_device_get_md_container(info):
-            diskType = MDRaidArrayDevice
-            parentName = devicePathToName(udev_device_get_md_container(info))
-            kwargs["parents"] = [ self.getDeviceByName(parentName) ]
-            kwargs["level"]  = udev_device_get_md_level(info)
-            kwargs["memberDevices"] = int(udev_device_get_md_devices(info))
-            kwargs["uuid"] = udev_device_get_md_uuid(info)
-            kwargs["exists"]  = True
-            del kwargs["serial"]
-            del kwargs["vendor"]
-            del kwargs["bus"]
-        elif udev_device_is_dasd(info):
-            diskType = DASDDevice
-            kwargs["dasd"] = self.dasd
-            kwargs["busid"] = udev_device_get_dasd_bus_id(info)
-            kwargs["opts"] = {}
-
-            for attr in ['readonly', 'use_diag', 'erplog', 'failfast']:
-                kwargs["opts"][attr] = udev_device_get_dasd_flag(info, attr)
-
-            log.debug("%s is a dasd device" % name)
-        elif udev_device_is_zfcp(info):
-            diskType = ZFCPDiskDevice
-
-            for attr in ['hba_id', 'wwpn', 'fcp_lun']:
-                kwargs[attr] = udev_device_get_zfcp_attribute(info, attr=attr)
-
-            log.debug("%s is a zfcp device" % name)
-        else:
-            diskType = DiskDevice
-            log.debug("%s is a disk" % name)
-
-        device = diskType(name,
-                          major=udev_device_get_major(info),
-                          minor=udev_device_get_minor(info),
-                          sysfsPath=sysfs_path, **kwargs)
-        self._addDevice(device)
-        return device
-
-    def addUdevOpticalDevice(self, info):
-        log_method_call(self)
-        # XXX should this be RemovableDevice instead?
-        #
-        # Looks like if it has ID_INSTANCE=0:1 we can ignore it.
-        device = OpticalDevice(udev_device_get_name(info),
-                               major=udev_device_get_major(info),
-                               minor=udev_device_get_minor(info),
-                               sysfsPath=udev_device_get_sysfs_path(info),
-                               vendor=udev_device_get_vendor(info),
-                               model=udev_device_get_model(info))
-        self._addDevice(device)
-        return device
-
-    def addUdevDevice(self, info):
-        name = udev_device_get_name(info)
-        log_method_call(self, name=name, info=info)
-        uuid = udev_device_get_uuid(info)
-        sysfs_path = udev_device_get_sysfs_path(info)
-
-        if self.isIgnored(info):
-            log.debug("ignoring %s (%s)" % (name, sysfs_path))
-            return
-
-        log.debug("scanning %s (%s)..." % (name, sysfs_path))
-        device = self.getDeviceByName(name)
-
-        #
-        # The first step is to either look up or create the device
-        #
-        if udev_device_is_multipath_member(info):
-            device = DiskDevice(name,
-                            major=udev_device_get_major(info),
-                            minor=udev_device_get_minor(info),
-                            sysfsPath=sysfs_path, exists=True,
-                            serial=udev_device_get_serial(info),
-                            vendor=udev_device_get_vendor(info),
-                            model=udev_device_get_model(info))
-            self._addDevice(device)
-        elif udev_device_is_dm(info) and \
-               devicelibs.dm.dm_is_multipath(info):
-            log.debug("%s is a multipath device" % name)
-            self.addUdevDMDevice(info)
-        elif udev_device_is_dm(info):
-            log.debug("%s is a device-mapper device" % name)
-            # try to look up the device
-            if device is None and uuid:
-                # try to find the device by uuid
-                device = self.getDeviceByUuid(uuid)
-
-            if device is None:
-                device = self.addUdevDMDevice(info)
-        elif udev_device_is_md(info):
-            log.debug("%s is an md device" % name)
-            if device is None and uuid:
-                # try to find the device by uuid
-                device = self.getDeviceByUuid(uuid)
-
-            if device is None:
-                device = self.addUdevMDDevice(info)
-        elif udev_device_is_cdrom(info):
-            log.debug("%s is a cdrom" % name)
-            if device is None:
-                device = self.addUdevOpticalDevice(info)
-        elif udev_device_is_biosraid(info) and udev_device_is_disk(info):
-            log.debug("%s is part of a biosraid" % name)
-            if device is None:
-                device = DiskDevice(name,
-                                major=udev_device_get_major(info),
-                                minor=udev_device_get_minor(info),
-                                sysfsPath=sysfs_path, exists=True)
-                self._addDevice(device)
-        elif udev_device_is_disk(info):
-            if device is None:
-                device = self.addUdevDiskDevice(info)
-        elif udev_device_is_partition(info):
-            log.debug("%s is a partition" % name)
-            if device is None:
-                device = self.addUdevPartitionDevice(info)
-        else:
-            log.error("Unknown block device type for: %s" % name)
-            return
-
-        # If this device is protected, mark it as such now. Once the tree
-        # has been populated, devices' protected attribute is how we will
-        # identify protected devices.
-        if device and device.name in self.protectedDevNames:
-            device.protected = True
-
-        # Don't try to do format handling on drives without media or
-        # if we didn't end up with a device somehow.
-        if not device or not device.mediaPresent:
-            return
-
-        # now handle the device's formatting
-        self.handleUdevDeviceFormat(info, device)
-        log.debug("got device: %s" % device)
-        if device.format.type:
-            log.debug("got format: %s" % device.format)
-        device.originalFormat = device.format
-
-    def handleUdevDiskLabelFormat(self, info, device):
-        log_method_call(self, device=device.name)
-        if device.partitioned:
-            # this device is already set up
-            log.debug("disklabel format on %s already set up" % device.name)
-            return
-
-        try:
-            device.setup()
-        except Exception as e:
-            log.debug("setup of %s failed: %s" % (device.name, e))
-            log.warning("aborting disklabel handler for %s" % device.name)
-            return
-
-        # special handling for unsupported partitioned devices
-        if not device.partitionable:
-            try:
-                format = getFormat("disklabel",
-                                   device=device.path,
-                                   exists=True)
-            except InvalidDiskLabelError:
-                pass
-            else:
-                if format.partitions:
-                    # parted's checks for disklabel presence are less than
-                    # rigorous, so we will assume that detected disklabels
-                    # with no partitions are spurious
-                    device.format = format
-            return
-
-        # if the disk contains protected partitions we will not wipe the
-        # disklabel even if clearpart --initlabel was specified
-        if not self.clearPartDisks or device.name in self.clearPartDisks:
-            initlabel = self.reinitializeDisks
-            sysfs_path = udev_device_get_sysfs_path(info)
-            for protected in self.protectedDevNames:
-                # check for protected partition
-                _p = "/sys/%s/%s" % (sysfs_path, protected)
-                if os.path.exists(os.path.normpath(_p)):
-                    initlabel = False
-                    break
-
-                # check for protected partition on a device-mapper disk
-                disk_name = re.sub(r'p\d+$', '', protected)
-                if disk_name != protected and disk_name == device.name:
-                    initlabel = False
-                    break
-        else:
-            initlabel = False
-
-
-        if self.zeroMbr:
-            initcb = lambda: True
-        else:
-            description = device.description or device.model
-            bypath = deviceNameToDiskByPath(device.name)
-            if bypath:
-                bypath = os.path.basename(bypath)
-                details = "\n\nDevice details:\n%s" % (bypath,)
-            else:
-                bypath = device.name
-                details = ""
-
-            initcb = lambda: self.intf.questionInitializeDisk(bypath,
-                                                              description,
-                                                              device.size,
-                                                              details)
-
-        try:
-            format = getFormat("disklabel",
-                               device=device.path,
-                               exists=not initlabel)
-        except InvalidDiskLabelError:
-            # if there is preexisting formatting on the device we will
-            # use it instead of ignoring the device
-            if not self.zeroMbr and \
-               getFormat(udev_device_get_format(info)).type is not None:
-                return
-            # if we have a cb function use it. else we ignore the device.
-            if initcb is not None and initcb():
-                format = getFormat("disklabel",
-                                   device=device.path,
-                                   exists=False)
-            else:
-                self._removeDevice(device)
-                self.addIgnoredDisk(device.name)
-                return
-
-        if not format.exists:
-            # if we just initialized a disklabel we should schedule
-            # actions for destruction of the previous format and creation
-            # of the new one
-            self.registerAction(ActionDestroyFormat(device))
-            self.registerAction(ActionCreateFormat(device, format))
-
-            # If this is a mac-formatted disk we just initialized, make
-            # sure the partition table partition gets added to the device
-            # tree.
-            if device.format.partedDisk.type == "mac" and \
-               len(device.format.partitions) == 1:
-                name = device.format.partitions[0].getDeviceNodeName()
-                if not self.getDeviceByName(name):
-                    partDevice = PartitionDevice(name, exists=True,
-                                                 parents=[device])
-                    self._addDevice(partDevice)
-
-        else:
-            device.format = format
-
-    def handleUdevLUKSFormat(self, info, device):
-        log_method_call(self, name=device.name, type=device.format.type)
-        if not device.format.uuid:
-            log.info("luks device %s has no uuid" % device.path)
-            return
-
-        # look up or create the mapped device
-        if not self.getDeviceByName(device.format.mapName):
-            passphrase = self.__luksDevs.get(device.format.uuid)
-            if passphrase:
-                device.format.passphrase = passphrase
-            else:
-                (passphrase, isglobal) = getLUKSPassphrase(self.intf,
-                                                    device,
-                                                    self.__passphrase)
-                if isglobal and device.format.status:
-                    self.__passphrase = passphrase
-
-            luks_device = LUKSDevice(device.format.mapName,
-                                     parents=[device],
-                                     exists=True)
-            try:
-                luks_device.setup()
-            except (LUKSError, CryptoError, DeviceError) as e:
-                log.info("setup of %s failed: %s" % (device.format.mapName,
-                                                     e))
-                device.removeChild()
-            else:
-                self._addDevice(luks_device)
-        else:
-            log.warning("luks device %s already in the tree"
-                        % device.format.mapName)
-
-    def handleUdevLVMPVFormat(self, info, device):
-        log_method_call(self, name=device.name, type=device.format.type)
-        # lookup/create the VG and LVs
-        try:
-            vg_name = udev_device_get_vg_name(info)
-        except KeyError:
-            # no vg name means no vg -- we're done with this pv
-            return
-
-        vg_device = self.getDeviceByName(vg_name)
-        if vg_device:
-            vg_device._addDevice(device)
-            for lv in vg_device.lvs:
-                try:
-                    lv.setup()
-                except DeviceError as (msg, name):
-                    log.info("setup of %s failed: %s" % (lv.name, msg))
-        else:
-            try:
-                vg_uuid = udev_device_get_vg_uuid(info)
-                vg_size = udev_device_get_vg_size(info)
-                vg_free = udev_device_get_vg_free(info)
-                pe_size = udev_device_get_vg_extent_size(info)
-                pe_count = udev_device_get_vg_extent_count(info)
-                pe_free = udev_device_get_vg_free_extents(info)
-                pv_count = udev_device_get_vg_pv_count(info)
-            except (KeyError, ValueError) as e:
-                log.warning("invalid data for %s: %s" % (device.name, e))
-                return
-
-            vg_device = LVMVolumeGroupDevice(vg_name,
-                                             device,
-                                             uuid=vg_uuid,
-                                             size=vg_size,
-                                             free=vg_free,
-                                             peSize=pe_size,
-                                             peCount=pe_count,
-                                             peFree=pe_free,
-                                             pvCount=pv_count,
-                                             exists=True)
-            self._addDevice(vg_device)
-
-            try:
-                lv_names = udev_device_get_lv_names(info)
-                lv_uuids = udev_device_get_lv_uuids(info)
-                lv_sizes = udev_device_get_lv_sizes(info)
-                lv_attr = udev_device_get_lv_attr(info)
-            except KeyError as e:
-                log.warning("invalid data for %s: %s" % (device.name, e))
-                return
-
-            if not lv_names:
-                log.debug("no LVs listed for VG %s" % device.name)
-                return
-
-            # make a list of indices with snapshots at the end
-            indices = range(len(lv_names))
-            indices.sort(key=lambda i: lv_attr[i][0] in 'Ss')
-            for index in indices:
-                lv_name = lv_names[index]
-                name = "%s-%s" % (vg_name, lv_name)
-                if lv_attr[index][0] in 'Ss':
-                    log.debug("found lvm snapshot volume '%s'" % name)
-                    origin_name = devicelibs.lvm.lvorigin(vg_name, lv_name)
-                    if not origin_name:
-                        log.error("lvm snapshot '%s-%s' has unknown origin"
-                                    % (vg_name, lv_name))
-                        continue
-
-                    origin = self.getDeviceByName("%s-%s" % (vg_name,
-                                                             origin_name))
-                    if not origin:
-                        log.warning("snapshot lv '%s' origin lv '%s-%s' "
-                                    "not found" % (name,
-                                                   vg_name, origin_name))
-                        continue
-
-                    log.debug("adding %dMB to %s snapshot total"
-                                % (lv_sizes[index], origin.name))
-                    origin.snapshotSpace += lv_sizes[index]
-                    continue
-                elif lv_attr[index][0] in 'Iil':
-                    # skip mirror images and log volumes
-                    continue
-
-                log_size = 0
-                if lv_attr[index][0] in 'Mm':
-                    stripes = 0
-                    # identify mirror stripes/copies and mirror logs
-                    for (j, _lvname) in enumerate(lv_names):
-                        if lv_attr[j][0] not in 'Iil':
-                            continue
-
-                        if _lvname == "[%s_mlog]" % lv_name:
-                            log_size = lv_sizes[j]
-                        elif _lvname.startswith("[%s_mimage_" % lv_name):
-                            stripes += 1
-                else:
-                    stripes = 1
-
-                lv_dev = self.getDeviceByName(name)
-                if lv_dev is None:
-                    lv_uuid = lv_uuids[index]
-                    lv_size = lv_sizes[index]
-                    lv_device = LVMLogicalVolumeDevice(lv_name,
-                                                       vg_device,
-                                                       uuid=lv_uuid,
-                                                       size=lv_size,
-                                                       stripes=stripes,
-                                                       logSize=log_size,
-                                                       exists=True)
-                    self._addDevice(lv_device)
-
-                    try:
-                        lv_device.setup()
-                    except DeviceError as (msg, name):
-                        log.info("setup of %s failed: %s"
-                                            % (lv_device.name, msg))
-
-    def handleUdevMDMemberFormat(self, info, device):
-        log_method_call(self, name=device.name, type=device.format.type)
-        # either look up or create the array device
-        name = udev_device_get_name(info)
-        sysfs_path = udev_device_get_sysfs_path(info)
-
-        if udev_device_is_biosraid(info):
-            # this will prevent display of the member devices in the UI
-            device.format.biosraid = True
-
-        md_array = self.getDeviceByUuid(device.format.mdUuid)
-        if device.format.mdUuid and md_array:
-            md_array._addDevice(device)
-        else:
-            # create the array with just this one member
-            # FIXME: why does this exact block appear twice?
-            try:
-                # level is reported as, eg: "raid1"
-                md_level = udev_device_get_md_level(info)
-                md_devices = int(udev_device_get_md_devices(info))
-                md_uuid = udev_device_get_md_uuid(info)
-            except (KeyError, ValueError) as e:
-                log.warning("invalid data for %s: %s" % (name, e))
-                return
-
-            # try to name the array based on the preferred minor
-            md_info = devicelibs.mdraid.mdexamine(device.path)
-            md_path = md_info.get("device", "")
-            md_name = devicePathToName(md_info.get("device", ""))
-            if md_name:
-                try:
-                    minor = int(md_name[2:])     # strip off leading "md"
-                except (IndexError, ValueError):
-                    minor = None
-                    md_name = None
-                else:
-                    array = self.getDeviceByName(md_name)
-                    if array and array.uuid != md_uuid:
-                        md_name = None
-
-            if not md_name:
-                # if we don't have a name yet, find the first unused minor
-                minor = 0
-                while True:
-                    if self.getDeviceByName("md%d" % minor):
-                        minor += 1
-                    else:
-                        break
-
-                md_name = "md%d" % minor
-
-            log.debug("using name %s for md array containing member %s"
-                        % (md_name, device.name))
-            md_array = MDRaidArrayDevice(md_name,
-                                         level=md_level,
-                                         minor=minor,
-                                         memberDevices=md_devices,
-                                         uuid=md_uuid,
-                                         sysfsPath=sysfs_path,
-                                         exists=True)
-            md_array._addDevice(device)
-            self._addDevice(md_array)
-
-    def handleMultipathMemberFormat(self, info, device):
-        log_method_call(self, name=device.name, type=device.format.type)
-
-        name = udev_device_get_multipath_name(info)
-        if self.__multipaths.has_key(name):
-            mp = self.__multipaths[name]
-            mp.addParent(device)
-        else:
-            mp = MultipathDevice(name, info, parents=[device])
-            self.__multipaths[name] = mp
-
-    def handleUdevDMRaidMemberFormat(self, info, device):
-        log_method_call(self, name=device.name, type=device.format.type)
-        name = udev_device_get_name(info)
-        sysfs_path = udev_device_get_sysfs_path(info)
-        uuid = udev_device_get_uuid(info)
-        major = udev_device_get_major(info)
-        minor = udev_device_get_minor(info)
-
-        def _all_ignored(rss):
-            retval = True
-            for rs in rss:
-                if rs.name not in self._ignoredDisks:
-                    retval = False
-                    break
-            return retval
-
-        # Have we already created the DMRaidArrayDevice?
-        rss = block.getRaidSetFromRelatedMem(uuid=uuid, name=name,
-                                            major=major, minor=minor)
-        if len(rss) == 0:
-            # we ignore the device in the hope that all the devices
-            # from this set will be ignored.
-            self.unusedRaidMembers.append(device.name)
-            self.addIgnoredDisk(device.name)
-            return
-
-        # We ignore the device if all the rss are in self._ignoredDisks
-        if _all_ignored(rss):
-            self.addIgnoredDisk(device.name)
-            return
-
-        for rs in rss:
-            dm_array = self.getDeviceByName(rs.name)
-            if dm_array is not None:
-                # We add the new device.
-                dm_array._addDevice(device)
-            else:
-                # Activate the Raid set.
-                rs.activate(mknod=True)
-                dm_array = DMRaidArrayDevice(rs.name,
-                                             raidSet=rs,
-                                             parents=[device])
-
-                self._addDevice(dm_array)
-
-                # Wait for udev to scan the just created nodes, to avoid a race
-                # with the udev_get_block_device() call below.
-                udev_settle()
-
-                # Get the DMRaidArrayDevice a DiskLabel format *now*, in case
-                # its partitions get scanned before it does.
-                dm_array.updateSysfsPath()
-                dm_array_info = udev_get_block_device(dm_array.sysfsPath)
-                self.handleUdevDiskLabelFormat(dm_array_info, dm_array)
-
-                # Use the rs's object on the device.
-                # pyblock can return the memebers of a set and the
-                # device has the attribute to hold it.  But ATM we
-                # are not really using it. Commenting this out until
-                # we really need it.
-                #device.format.raidmem = block.getMemFromRaidSet(dm_array,
-                #        major=major, minor=minor, uuid=uuid, name=name)
-
-    def handleUdevDeviceFormat(self, info, device):
-        log_method_call(self, name=getattr(device, "name", None))
-        name = udev_device_get_name(info)
-        sysfs_path = udev_device_get_sysfs_path(info)
-        uuid = udev_device_get_uuid(info)
-        label = udev_device_get_label(info)
-        format_type = udev_device_get_format(info)
-        serial = udev_device_get_serial(info)
-
-        # Now, if the device is a disk, see if there is a usable disklabel.
-        # If not, see if the user would like to create one.
-        # XXX ignore disklabels on multipath or biosraid member disks
-        if not udev_device_is_biosraid(info) and \
-           not udev_device_is_multipath_member(info):
-            self.handleUdevDiskLabelFormat(info, device)
-            if device.partitioned or self.isIgnored(info) or \
-               (not device.partitionable and
-                device.format.type == "disklabel"):
-                # If the device has a disklabel, or the user chose not to
-                # create one, we are finished with this device. Otherwise
-                # it must have some non-disklabel formatting, in which case
-                # we fall through to handle that.
-                return
-
-        format = None
-        if (not device) or (not format_type) or device.format.type:
-            # this device has no formatting or it has already been set up
-            # FIXME: this probably needs something special for disklabels
-            log.debug("no type or existing type for %s, bailing" % (name,))
-            return
-
-        # set up the common arguments for the format constructor
-        args = [format_type]
-        kwargs = {"uuid": uuid,
-                  "label": label,
-                  "device": device.path,
-                  "serial": serial,
-                  "exists": True}
-
-        # set up type-specific arguments for the format constructor
-        if format_type == "multipath_member":
-            kwargs["multipath_members"] = self.getDevicesBySerial(serial)
-        elif format_type == "crypto_LUKS":
-            # luks/dmcrypt
-            kwargs["name"] = "luks-%s" % uuid
-        elif format_type in formats.mdraid.MDRaidMember._udevTypes:
-            # mdraid
-            try:
-                kwargs["mdUuid"] = udev_device_get_md_uuid(info)
-            except KeyError:
-                log.debug("mdraid member %s has no md uuid" % name)
-        elif format_type == "LVM2_member":
-            # lvm
-            try:
-                kwargs["vgName"] = udev_device_get_vg_name(info)
-            except KeyError as e:
-                log.debug("PV %s has no vg_name" % name)
-            try:
-                kwargs["vgUuid"] = udev_device_get_vg_uuid(info)
-            except KeyError:
-                log.debug("PV %s has no vg_uuid" % name)
-            try:
-                kwargs["peStart"] = udev_device_get_pv_pe_start(info)
-            except KeyError:
-                log.debug("PV %s has no pe_start" % name)
-        elif format_type == "vfat":
-            # efi magic
-            if isinstance(device, PartitionDevice) and device.bootable:
-                efi = formats.getFormat("efi")
-                if efi.minSize <= device.size <= efi.maxSize:
-                    args[0] = "efi"
-        elif format_type == "hfs":
-            # apple bootstrap magic
-            if isinstance(device, PartitionDevice) and device.bootable:
-                apple = formats.getFormat("appleboot")
-                if apple.minSize <= device.size <= apple.maxSize:
-                    args[0] = "appleboot"
-
-        try:
-            log.debug("type detected on '%s' is '%s'" % (name, format_type,))
-            device.format = formats.getFormat(*args, **kwargs)
-        except FSError:
-            log.debug("type '%s' on '%s' invalid, assuming no format" %
-                      (format_type, name,))
-            device.format = formats.DeviceFormat()
-            return
-
-        if shouldClear(device, self.clearPartType,
-                       clearPartDisks=self.clearPartDisks):
-            # if this is a device that will be cleared by clearpart,
-            # don't bother with format-specific processing
-            return
-
-        #
-        # now do any special handling required for the device's format
-        #
-        if device.format.type == "luks":
-            self.handleUdevLUKSFormat(info, device)
-        elif device.format.type == "mdmember":
-            self.handleUdevMDMemberFormat(info, device)
-        elif device.format.type == "dmraidmember":
-            self.handleUdevDMRaidMemberFormat(info, device)
-        elif device.format.type == "lvmpv":
-            self.handleUdevLVMPVFormat(info, device)
-        elif device.format.type == "multipath_member":
-            self.handleMultipathMemberFormat(info, device)
-
-    def updateDeviceFormat(self, device):
-        log.debug("updating format of device: %s" % device)
-        iutil.notify_kernel("/sys%s" % device.sysfsPath)
-        udev_settle()
-        info = udev_get_device(device.sysfsPath)
-        self.handleUdevDeviceFormat(info, device)
-        if device.format.type:
-            log.debug("got format: %s" % device.format)
-
-    def _handleInconsistencies(self):
-        def reinitializeVG(vg):
-            # First we remove VG data
-            try:
-                vg.destroy()
-            except DeviceError:
-                # the pvremoves will finish the job.
-                log.debug("There was an error destroying the VG %s." % vg.name)
-
-            # remove VG device from list.
-            self._removeDevice(vg)
-
-            for parent in vg.parents:
-                parent.format.destroy()
-
-                # Give the vg the a default format
-                kwargs = {"device": parent.path,
-                          "exists": parent.exists}
-                parent.format = formats.getFormat(*[""], **kwargs)
-
-        def leafInconsistencies(device):
-            if device.type == "lvmvg":
-                if device.complete:
-                    return
-
-                paths = []
-                for parent in device.parents:
-                    paths.append(parent.path)
-
-                # if zeroMbr is true don't ask.
-                if (self.zeroMbr or
-                    self.intf.questionReinitInconsistentLVM(pv_names=paths,
-                                                            vg_name=device.name)):
-                    reinitializeVG(device)
-                else:
-                    # The user chose not to reinitialize.
-                    # hopefully this will ignore the vg components too.
-                    self._removeDevice(device)
-                    lvm.lvm_cc_addFilterRejectRegexp(device.name)
-                    lvm.blacklistVG(device.name)
-                    for parent in device.parents:
-                        if parent.type == "partition":
-                            self.immutableDevices.append([parent.name,
-                                _("This partition is part of an inconsistent LVM Volume Group.")])
-                        else:
-                            self._removeDevice(parent, moddisk=False)
-                            self.addIgnoredDisk(parent.name)
-                        lvm.lvm_cc_addFilterRejectRegexp(parent.name)
-
-            elif device.type == "lvmlv":
-                # we might have already fixed this.
-                if device not in self._devices or \
-                        device.name in self._ignoredDisks:
-                    return
-                if device.complete:
-                    return
-
-                paths = []
-                for parent in device.vg.parents:
-                    paths.append(parent.path)
-
-                if (self.zeroMbr or
-                    self.intf.questionReinitInconsistentLVM(pv_names=paths,
-                                                            lv_name=device.name)):
-
-                    # destroy all lvs.
-                    for lv in device.vg.lvs:
-                        try:
-                            # reinitializeVG should clean up if necessary
-                            lv.destroy()
-                        except StorageError as e:
-                            log.info("error removing lv %s from "
-                                     "inconsistent/incomplete vg %s"
-                                     % (lv.lvname, device.vg.name))
-                        device.vg._removeLogVol(lv)
-                        self._removeDevice(lv)
-
-                    reinitializeVG(device.vg)
-                else:
-                    # ignore all the lvs.
-                    for lv in device.vg.lvs:
-                        self._removeDevice(lv)
-                        lvm.lvm_cc_addFilterRejectRegexp(lv.name)
-                    # ignore the vg
-                    self._removeDevice(device.vg)
-                    lvm.lvm_cc_addFilterRejectRegexp(device.vg.name)
-                    lvm.blacklistVG(device.vg.name)
-                    # ignore all the pvs
-                    for parent in device.vg.parents:
-                        if parent.type == "partition":
-                            self.immutableDevices.append([parent.name,
-                                _("This partition is part of an inconsistent LVM Volume Group.")])
-                        else:
-                            self._removeDevice(parent, moddisk=False)
-                            self.addIgnoredDisk(parent.name)
-                        lvm.lvm_cc_addFilterRejectRegexp(parent.name)
-
-        # Address the inconsistencies present in the tree leaves.
-        for leaf in self.leaves:
-            leafInconsistencies(leaf)
-
-        # Check for unused BIOS raid members, unused dmraid members are added
-        # to self.unusedRaidMembers as they are processed, extend this list
-        # with unused mdraid BIOS raid members
-        for c in self.getDevicesByType("mdcontainer"):
-            if c.kids == 0:
-                self.unusedRaidMembers.extend(map(lambda m: m.name, c.devices))
-
-        self.intf.unusedRaidMembersWarning(self.unusedRaidMembers)
-
-    def populate(self):
-        """ Locate all storage devices. """
-
-        # mark the tree as unpopulated so exception handlers can tell the
-        # exception originated while finding storage devices
-        self.populated = False
-
-        # resolve the protected device specs to device names
-        for spec in self.protectedDevSpecs:
-            name = udev_resolve_devspec(spec)
-            if name:
-                self.protectedDevNames.append(name)
-
-        # FIXME: the backing dev for the live image can't be used as an
-        # install target.  note that this is a little bit of a hack
-        # since we're assuming that /dev/live will exist
-        if os.path.exists("/dev/live") and \
-           stat.S_ISBLK(os.stat("/dev/live")[stat.ST_MODE]):
-            livetarget = devicePathToName(os.path.realpath("/dev/live"))
-            log.info("%s looks to be the live device; marking as protected"
-                     % (livetarget,))
-            self.protectedDevNames.append(livetarget)
-
-        # First iteration - let's just look for disks.
-        old_devices = {}
-
-        devices = udev_get_block_devices()
-        for dev in devices:
-            old_devices[dev['name']] = dev
-
-        cfg = self.__multipathConfigWriter.write()
-        open("/etc/multipath.conf", "w+").write(cfg)
-        del cfg
-
-        (singles, mpaths, partitions) = devicelibs.mpath.identifyMultipaths(devices)
-        devices = singles + reduce(list.__add__, mpaths, []) + partitions
-        log.info("devices to scan: %s" % [d['name'] for d in devices])
-        for dev in devices:
-            self.addUdevDevice(dev)
-
-        # Having found all the disks, we can now find all the multipaths built
-        # upon them.
-        whitelist = []
-        mpaths = self.__multipaths.values()
-        mpaths.sort(key=lambda d: d.name)
-        for mp in mpaths:
-            log.info("adding mpath device %s" % mp.name)
-            mp.setup()
-            whitelist.append(mp.name)
-            for p in mp.parents:
-                whitelist.append(p.name)
-            self.__multipathConfigWriter.addMultipathDevice(mp)
-            self._addDevice(mp)
-        for d in self.devices:
-            if not d.name in whitelist:
-                self.__multipathConfigWriter.addBlacklistDevice(d)
-        cfg = self.__multipathConfigWriter.write()
-        open("/etc/multipath.conf", "w+").write(cfg)
-        del cfg
-
-        # Now, loop and scan for devices that have appeared since the two above
-        # blocks or since previous iterations.
-        while True:
-            devices = []
-            new_devices = udev_get_block_devices()
-
-            for new_device in new_devices:
-                if not old_devices.has_key(new_device['name']):
-                    old_devices[new_device['name']] = new_device
-                    devices.append(new_device)
-
-            if len(devices) == 0:
-                # nothing is changing -- we are finished building devices
-                break
-
-            log.info("devices to scan: %s" % [d['name'] for d in devices])
-            for dev in devices:
-                self.addUdevDevice(dev)
-
-        self.populated = True
-
-        # After having the complete tree we make sure that the system
-        # inconsistencies are ignored or resolved.
-        self._handleInconsistencies()
-
-        self.teardownAll()
-        try:
-            os.unlink("/etc/mdadm.conf")
-        except OSError:
-            log.info("failed to unlink /etc/mdadm.conf")
-
-    def teardownAll(self):
-        """ Run teardown methods on all devices. """
-        for device in self.leaves:
-            try:
-                device.teardown(recursive=True)
-            except StorageError as e:
-                log.info("teardown of %s failed: %s" % (device.name, e))
-
-    def setupAll(self):
-        """ Run setup methods on all devices. """
-        for device in self.leaves:
-            try:
-                device.setup()
-            except DeviceError as (msg, name):
-                log.debug("setup of %s failed: %s" % (device.name, msg))
-
-    def getDeviceBySysfsPath(self, path):
-        if not path:
-            return None
-
-        found = None
-        for device in self._devices:
-            if device.sysfsPath == path:
-                found = device
-                break
-
-        return found
-
-    def getDeviceByUuid(self, uuid):
-        if not uuid:
-            return None
-
-        found = None
-        for device in self._devices:
-            if device.uuid == uuid:
-                found = device
-                break
-            elif device.format.uuid == uuid:
-                found = device
-                break
-
-        return found
-
-    def getDevicesBySerial(self, serial):
-        devices = []
-        for device in self._devices:
-            if not hasattr(device, "serial"):
-                log.warning("device %s has no serial attr" % device.name)
-                continue
-            if device.serial == serial:
-                devices.append(device)
-        return devices
-
-    def getDeviceByLabel(self, label):
-        if not label:
-            return None
-
-        found = None
-        for device in self._devices:
-            _label = getattr(device.format, "label", None)
-            if not _label:
-                continue
-
-            if _label == label:
-                found = device
-                break
-
-        return found
-
-    def getDeviceByName(self, name):
-        log.debug("looking for device '%s'..." % name)
-        if not name:
-            return None
-
-        found = None
-        for device in self._devices:
-            if device.name == name:
-                found = device
-                break
-            elif (device.type == "lvmlv" or device.type == "lvmvg") and \
-                    device.name == name.replace("--","-"):
-                found = device
-                break
-
-        log.debug("found %s" % found)
-        return found
-
-    def getDeviceByPath(self, path):
-        log.debug("looking for device '%s'..." % path)
-        if not path:
-            return None
-
-        found = None
-        for device in self._devices:
-            if device.path == path:
-                found = device
-                break
-            elif (device.type == "lvmlv" or device.type == "lvmvg") and \
-                    device.path == path.replace("--","-"):
-                found = device
-                break
-
-        log.debug("found %s" % found)
-        return found
-
-    def getDevicesByType(self, device_type):
-        # TODO: expand this to catch device format types
-        return [d for d in self._devices if d.type == device_type]
-
-    def getDevicesByInstance(self, device_class):
-        return [d for d in self._devices if isinstance(d, device_class)]
-
-    @property
-    def devices(self):
-        """ List of device instances """
-        devices = []
-        for device in self._devices:
-            if device.path in [d.path for d in devices] and \
-               not isinstance(device, NoDevice):
-                raise DeviceTreeError("duplicate paths in device tree")
-
-            devices.append(device)
-
-        return devices
-
-    @property
-    def filesystems(self):
-        """ List of filesystems. """
-        #""" Dict with mountpoint keys and filesystem values. """
-        filesystems = []
-        for dev in self.leaves:
-            if dev.format and getattr(dev.format, 'mountpoint', None):
-                filesystems.append(dev.format)
-
-        return filesystems
-
-    @property
-    def uuids(self):
-        """ Dict with uuid keys and Device values. """
-        uuids = {}
-        for dev in self._devices:
-            try:
-                uuid = dev.uuid
-            except AttributeError:
-                uuid = None
-
-            if uuid:
-                uuids[uuid] = dev
-
-            try:
-                uuid = dev.format.uuid
-            except AttributeError:
-                uuid = None
-
-            if uuid:
-                uuids[uuid] = dev
-
-        return uuids
-
-    @property
-    def labels(self):
-        """ Dict with label keys and Device values.
-
-            FIXME: duplicate labels are a possibility
-        """
-        labels = {}
-        for dev in self._devices:
-            if dev.format and getattr(dev.format, "label", None):
-                labels[dev.format.label] = dev
-
-        return labels
-
-    @property
-    def leaves(self):
-        """ List of all devices upon which no other devices exist. """
-        leaves = [d for d in self._devices if d.isleaf]
-        return leaves
-
-    def getChildren(self, device):
-        """ Return a list of a device's children. """
-        return [c for c in self._devices if device in c.parents]
-
-    def resolveDevice(self, devspec, blkidTab=None, cryptTab=None):
-        # find device in the tree
-        device = None
-        if devspec.startswith("UUID="):
-            # device-by-uuid
-            uuid = devspec.partition("=")[2]
-            device = self.uuids.get(uuid)
-            if device is None:
-                log.error("failed to resolve device %s" % devspec)
-        elif devspec.startswith("LABEL="):
-            # device-by-label
-            label = devspec.partition("=")[2]
-            device = self.labels.get(label)
-            if device is None:
-                log.error("failed to resolve device %s" % devspec)
-        elif devspec.startswith("/dev/"):
-            # device path
-            device = self.getDeviceByPath(devspec)
-            if device is None:
-                if blkidTab:
-                    # try to use the blkid.tab to correlate the device
-                    # path with a UUID
-                    blkidTabEnt = blkidTab.get(devspec)
-                    if blkidTabEnt:
-                        log.debug("found blkid.tab entry for '%s'" % devspec)
-                        uuid = blkidTabEnt.get("UUID")
-                        if uuid:
-                            device = self.getDeviceByUuid(uuid)
-                            if device:
-                                devstr = device.name
-                            else:
-                                devstr = "None"
-                            log.debug("found device '%s' in tree" % devstr)
-                        if device and device.format and \
-                           device.format.type == "luks":
-                            map_name = device.format.mapName
-                            log.debug("luks device; map name is '%s'" % map_name)
-                            mapped_dev = self.getDeviceByName(map_name)
-                            if mapped_dev:
-                                device = mapped_dev
-
-                if device is None and cryptTab and \
-                   devspec.startswith("/dev/mapper/"):
-                    # try to use a dm-crypt mapping name to 
-                    # obtain the underlying device, possibly
-                    # using blkid.tab
-                    cryptTabEnt = cryptTab.get(devspec.split("/")[-1])
-                    if cryptTabEnt:
-                        luks_dev = cryptTabEnt['device']
-                        try:
-                            device = self.getChildren(luks_dev)[0]
-                        except IndexError as e:
-                            pass
-                elif device is None:
-                    # dear lvm: can we please have a few more device nodes
-                    #           for each logical volume?
-                    #           three just doesn't seem like enough.
-                    name = devspec[5:]      # strip off leading "/dev/"
-                    (vg_name, slash, lv_name) = name.partition("/")
-                    if lv_name and not "/" in lv_name:
-                        # looks like we may have one
-                        lv = "%s-%s" % (vg_name, lv_name)
-                        device = self.getDeviceByName(lv)
-
-        if device:
-            log.debug("resolved '%s' to '%s' (%s)" % (devspec, device.name, device.type))
-        else:
-            log.debug("failed to resolve '%s'" % devspec)
-        return device
diff --git a/storage/errors.py b/storage/errors.py
deleted file mode 100644
index c4d4313..0000000
--- a/storage/errors.py
+++ /dev/null
@@ -1,153 +0,0 @@
-# errors.py
-# Exception classes for anaconda's storage configuration module.
-#
-# Copyright (C) 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, or (at your option) any later version.
-# 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.
-#
-# Red Hat Author(s): Dave Lehman <dlehman@xxxxxxxxxx>
-#
-
-class StorageError(Exception):
-    pass
-
-# Device
-class DeviceError(StorageError):
-    pass
-
-class DeviceCreateError(DeviceError):
-    pass
-
-class DeviceDestroyError(DeviceError):
-    pass
-
-class DeviceResizeError(DeviceError):
-    pass
-
-class DeviceSetupError(DeviceError):
-    pass
-
-class DeviceTeardownError(DeviceError):
-    pass
-
-class DeviceUserDeniedFormatError(DeviceError):
-    pass
-
-# DeviceFormat
-class DeviceFormatError(StorageError):
-    pass
-
-class FormatCreateError(DeviceFormatError):
-    pass
-
-class FormatDestroyError(DeviceFormatError):
-    pass
-
-class FormatSetupError(DeviceFormatError):
-    pass
-
-class FormatTeardownError(DeviceFormatError):
-    pass
-
-class DMRaidMemberError(DeviceFormatError):
-    pass
-
-class MultipathMemberError(DeviceFormatError):
-    pass
-
-class FSError(DeviceFormatError):
-    pass
-
-class FSResizeError(FSError):
-    pass
-
-class FSMigrateError(FSError):
-    pass
-
-class LUKSError(DeviceFormatError):
-    pass
-
-class MDMemberError(DeviceFormatError):
-    pass
-
-class PhysicalVolumeError(DeviceFormatError):
-    pass
-
-class SwapSpaceError(DeviceFormatError):
-    pass
-
-class DiskLabelError(DeviceFormatError):
-    pass
-
-class InvalidDiskLabelError(DiskLabelError):
-    pass
-
-class DiskLabelCommitError(DiskLabelError):
-    pass
-
-# devicelibs
-class SwapError(StorageError):
-    pass
-
-class SuspendError(SwapError):
-    pass
-
-class OldSwapError(SwapError):
-    pass
-
-class UnknownSwapError(SwapError):
-    pass
-
-class MDRaidError(StorageError):
-    pass
-
-class DMError(StorageError):
-    pass
-
-class LVMError(StorageError):
-    pass
-
-class CryptoError(StorageError):
-    pass
-
-class MPathError(StorageError):
-    pass
-
-# DeviceTree
-class DeviceTreeError(StorageError):
-    pass
-
-# DeviceAction
-class DeviceActionError(StorageError):
-    pass
-
-# partitioning
-class PartitioningError(StorageError):
-    pass
-
-class PartitioningWarning(StorageError):
-    pass
-
-# udev
-class UdevError(StorageError):
-    pass
-
-# fstab
-class UnrecognizedFSTabEntryError(StorageError):
-    pass
-
-# dasd
-class DasdFormatError(StorageError):
-    pass
diff --git a/storage/fcoe.py b/storage/fcoe.py
deleted file mode 100644
index e77caba..0000000
--- a/storage/fcoe.py
+++ /dev/null
@@ -1,164 +0,0 @@
-#
-# fcoe.py - fcoe class
-#
-# Copyright (C) 2009  Red Hat, Inc.  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 as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# 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, see <http://www.gnu.org/licenses/>.
-#
-
-import os
-import iutil
-import isys
-import logging
-import time
-from flags import flags
-log = logging.getLogger("anaconda")
-
-import gettext
-_ = lambda x: gettext.ldgettext("anaconda", x)
-
-_fcoe_module_loaded = False
-
-def has_fcoe():
-    global _fcoe_module_loaded
-    if not _fcoe_module_loaded:
-        iutil.execWithRedirect("modprobe", [ "fcoe" ],
-                               stdout = "/dev/tty5", stderr="/dev/tty5")
-        _fcoe_module_loaded = True
-
-    return os.access("/sys/module/fcoe", os.X_OK)
-
-class fcoe(object):
-    """ FCoE utility class.
-
-        This class will automatically discover and connect to EDD configured
-        FCoE SAN's when the startup() method gets called. It can also be
-        used to manually configure FCoE SAN's through the addSan() method.
-
-        As this class needs to make sure certain things like starting fcoe
-        daemons and connecting to firmware discovered SAN's only happens once
-        and as it keeps a global list of all FCoE devices it is
-        implemented as a Singleton.
-    """
-
-    def __init__(self):
-        self.started = False
-        self.lldpadStarted = False
-        self.nics = []
-
-    # So that users can write fcoe() to get the singleton instance
-    def __call__(self):
-        return self
-
-    def _stabilize(self, intf = None):
-        if intf:
-            w = intf.waitWindow(_("Connecting to FCoE SAN"),
-                                _("Connecting to FCoE SAN"))
-
-        # I have no clue how long we need to wait, this ought to do the trick
-        time.sleep(10)
-        iutil.execWithRedirect("udevadm", [ "settle" ],
-                               stdout = "/dev/tty5", stderr="/dev/tty5")
-        if intf:
-            w.pop()
-
-    def _startEDD(self, intf = None):
-        rc = iutil.execWithCapture("/usr/libexec/fcoe/fcoe_edd.sh", [ "-i" ],
-                                   stderr="/dev/tty5")
-        if not rc.startswith("NIC="):
-            log.info("No FCoE EDD info found: %s" % rc)
-            return
-
-        (key, val) = rc.split("=", 1)
-        if val not in isys.getDeviceProperties():
-            log.error("Unknown FCoE NIC found in EDD: %s, ignoring" % val)
-            return
-
-        log.info("FCoE NIC found in EDD: %s" % val)
-        self.addSan(val, dcb=True, intf=intf)
-
-    def startup(self, intf = None):
-        if self.started:
-            return
-
-        if not has_fcoe():
-            return
-
-        self._startEDD(intf)
-        self.started = True
-
-    def _startLldpad(self):
-        if self.lldpadStarted:
-            return
-
-        iutil.execWithRedirect("lldpad", [ "-d" ],
-                               stdout = "/dev/tty5", stderr="/dev/tty5")
-        self.lldpadStarted = True
-
-    def addSan(self, nic, dcb=False, intf=None):
-        if not has_fcoe():
-            raise IOError, _("FCoE not available")
-
-        log.info("Activating FCoE SAN attached to %s, dcb: %s" % (nic, dcb))
-
-        iutil.execWithRedirect("ip", [ "link", "set", nic, "up" ],
-                               stdout = "/dev/tty5", stderr="/dev/tty5")
-
-        if dcb:
-            self._startLldpad()
-            iutil.execWithRedirect("dcbtool", [ "sc", nic, "dcb", "on" ],
-                               stdout = "/dev/tty5", stderr="/dev/tty5")
-            iutil.execWithRedirect("dcbtool", [ "sc", nic, "app:fcoe",
-                               "e:1", "a:1", "w:1" ],
-                               stdout = "/dev/tty5", stderr="/dev/tty5")
-            iutil.execWithRedirect("fipvlan", [ nic, "-c", "-s" ],
-                               stdout = "/dev/tty5", stderr="/dev/tty5")
-        else:
-            f = open("/sys/module/fcoe/parameters/create", "w")
-            f.write(nic)
-            f.close()
-
-        self._stabilize(intf)
-        self.nics.append((nic, dcb))
-
-    def writeKS(self, f):
-        # fixme plenty (including add ks support for fcoe in general)
-        return
-
-    def write(self, instPath, anaconda):
-        if not self.nics:
-            return
-
-        if not os.path.isdir(instPath + "/etc/fcoe"):
-            os.makedirs(instPath + "/etc/fcoe", 0755)
-
-        for nic, dcb in self.nics:
-            fd = os.open(instPath + "/etc/fcoe/cfg-" + nic,
-                         os.O_RDWR | os.O_CREAT)
-            os.write(fd, '# Created by anaconda\n')
-            os.write(fd, '# Enable/Disable FCoE service at the Ethernet port\n')
-            os.write(fd, 'FCOE_ENABLE="yes"\n')
-            os.write(fd, '# Indicate if DCB service is required at the Ethernet port\n')
-            if dcb:
-                os.write(fd, 'DCB_REQUIRED="yes"\n')
-            else:
-                os.write(fd, 'DCB_REQUIRED="no"\n')
-            os.close(fd)
-
-        return
-
-# Create FCoE singleton
-fcoe = fcoe()
-
-# vim:tw=78:ts=4:et:sw=4
diff --git a/storage/formats/Makefile.am b/storage/formats/Makefile.am
deleted file mode 100644
index 7ecaf07..0000000
--- a/storage/formats/Makefile.am
+++ /dev/null
@@ -1,24 +0,0 @@
-# storage/formats/Makefile.am for anaconda
-#
-# Copyright (C) 2009  Red Hat, Inc.
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU Lesser General Public License as published
-# by the Free Software Foundation; either version 2.1 of the License, or
-# (at your option) any later version.
-#
-# 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 Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public License
-# along with this program.  If not, see <http://www.gnu.org/licenses/>.
-#
-# Author: David Cantrell <dcantrell@xxxxxxxxxx>
-
-pkgpyexecdir = $(pyexecdir)/py$(PACKAGE_NAME)
-storageformatsdir = $(pkgpyexecdir)/storage/formats
-storageformats_PYTHON = *.py
-
-MAINTAINERCLEANFILES = Makefile.in
diff --git a/storage/formats/__init__.py b/storage/formats/__init__.py
deleted file mode 100644
index 2decf4c..0000000
--- a/storage/formats/__init__.py
+++ /dev/null
@@ -1,403 +0,0 @@
-# __init__.py
-# Entry point for anaconda storage formats subpackage.
-#
-# Copyright (C) 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, or (at your option) any later version.
-# 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.
-#
-# Red Hat Author(s): Dave Lehman <dlehman@xxxxxxxxxx>
-#
-
-import os
-
-from iutil import notify_kernel, get_sysfs_path_by_name
-from ..storage_log import log_method_call
-from ..errors import *
-from ..devicelibs.dm import dm_node_from_name
-
-import gettext
-_ = lambda x: gettext.ldgettext("anaconda", x)
-
-import logging
-log = logging.getLogger("storage")
-
-
-device_formats = {}
-def register_device_format(fmt_class):
-    if not issubclass(fmt_class, DeviceFormat):
-        raise ValueError("arg1 must be a subclass of DeviceFormat")
-
-    device_formats[fmt_class._type] = fmt_class
-    log.debug("registered device format class %s as %s" % (fmt_class.__name__,
-                                                           fmt_class._type))
-
-default_fstypes = ("ext4", "ext3", "ext2")
-def get_default_filesystem_type(boot=None):
-    import platform
-
-    if boot:
-        fstypes = [platform.getPlatform(None).defaultBootFSType]
-    else:
-        fstypes = default_fstypes
-
-    for fstype in fstypes:
-        try:
-            supported = get_device_format_class(fstype).supported
-        except AttributeError:
-            supported = None
-
-        if supported:
-            return fstype
-
-    raise DeviceFormatError("None of %s is supported by your kernel" % ",".join(fstypes))
-
-def getFormat(fmt_type, *args, **kwargs):
-    """ Return a DeviceFormat instance based on fmt_type and args.
-
-        Given a device format type and a set of constructor arguments,
-        return a DeviceFormat instance.
-
-        Return None if no suitable format class is found.
-
-        Arguments:
-
-            fmt_type -- the name of the format type (eg: 'ext3', 'swap')
-
-        Keyword Arguments:
-
-            The keyword arguments may vary according to the format type,
-            but here is the common set:
-
-            device -- path to the device on which the format resides
-            uuid -- the UUID of the (preexisting) formatted device
-            exists -- whether or not the format exists on the device            
-            
-    """
-    fmt_class = get_device_format_class(fmt_type)
-    fmt = None
-    if fmt_class:
-        fmt = fmt_class(*args, **kwargs)
-    try:
-        className = fmt.__class__.__name__
-    except AttributeError:
-        className = None
-    log.debug("getFormat('%s') returning %s instance" % (fmt_type, className))
-    return fmt
-
-def collect_device_format_classes():
-    """ Pick up all device format classes from this directory.
-
-        Note: Modules must call register_device_format(FormatClass) in
-              order for the format class to be picked up.
-    """
-    dir = os.path.dirname(__file__)
-    for module_file in os.listdir(dir):
-        # make sure we're not importing this module
-        if module_file.endswith(".py") and module_file != __file__:
-            mod_name = module_file[:-3]
-            # imputil is deprecated in python 2.6
-            try:
-                globals()[mod_name] = __import__(mod_name, globals(), locals(), [], -1)
-            except ImportError, e:
-                log.debug("import of device format module '%s' failed" % mod_name)
-
-def get_device_format_class(fmt_type):
-    """ Return an appropriate format class based on fmt_type. """
-    if not device_formats:
-        collect_device_format_classes()
-
-    fmt = device_formats.get(fmt_type)
-    if not fmt:
-        for fmt_class in device_formats.values():
-            if fmt_type and fmt_type == fmt_class._name:
-                fmt = fmt_class
-                break
-            elif fmt_type in fmt_class._udevTypes:
-                fmt = fmt_class
-                break
-
-    # default to no formatting, AKA "Unknown"
-    if not fmt:
-        fmt = DeviceFormat
-
-    return fmt
-
-class DeviceFormat(object):
-    """ Generic device format. """
-    _type = None
-    _name = "Unknown"
-    _udevTypes = []
-    partedFlag = None
-    partedSystem = None
-    _formattable = False                # can be formatted
-    _supported = False                  # is supported
-    _linuxNative = False                # for clearpart
-    _packages = []                      # required packages
-    _resizable = False                  # can be resized
-    _bootable = False                   # can be used as boot
-    _migratable = False                 # can be migrated
-    _maxSize = 0                        # maximum size in MB
-    _minSize = 0                        # minimum size in MB
-    _dump = False
-    _check = False
-    _hidden = False                     # hide devices with this formatting?
-
-    def __init__(self, *args, **kwargs):
-        """ Create a DeviceFormat instance.
-
-            Keyword Arguments:
-
-                device -- path to the underlying device
-                uuid -- this format's UUID
-                exists -- indicates whether this is an existing format
-
-        """
-        self.device = kwargs.get("device")
-        self.uuid = kwargs.get("uuid")
-        self.exists = kwargs.get("exists")
-        self.options = kwargs.get("options")
-        self._migrate = False
-
-        # don't worry about existence if this is a DeviceFormat instance
-        #if self.__class__ is DeviceFormat:
-        #    self.exists = True
-
-    def __str__(self):
-        s = ("%(classname)s instance (%(id)s) --\n"
-             "  type = %(type)s  name = %(name)s  status = %(status)s\n"
-             "  device = %(device)s  uuid = %(uuid)s  exists = %(exists)s\n"
-             "  options = %(options)s  supported = %(supported)s"
-             "  formattable = %(format)s  resizable = %(resize)s\n" %
-             {"classname": self.__class__.__name__, "id": "%#x" % id(self),
-              "type": self.type, "name": self.name, "status": self.status,
-              "device": self.device, "uuid": self.uuid, "exists": self.exists,
-              "options": self.options, "supported": self.supported,
-              "format": self.formattable, "resize": self.resizable})
-        return s
-
-    @property
-    def dict(self):
-        d = {"type": self.type, "name": self.name, "device": self.device,
-             "uuid": self.uuid, "exists": self.exists,
-             "options": self.options, "supported": self.supported,
-             "resizable": self.resizable}
-        return d
-
-    def _setOptions(self, options):
-        self._options = options
-
-    def _getOptions(self):
-        return self._options
-
-    options = property(_getOptions, _setOptions)
-
-    def _setDevice(self, devspec):
-        if devspec and not devspec.startswith("/"):
-            raise ValueError("device must be a fully qualified path")
-        self._device = devspec
-
-    def _getDevice(self):
-        return self._device
-
-    device = property(lambda f: f._getDevice(),
-                      lambda f,d: f._setDevice(d),
-                      doc="Full path the device this format occupies")
-
-    @property
-    def name(self):
-        if self._name:
-            name = self._name
-        else:
-            name = self.type
-        return name
-
-    @property
-    def type(self):
-        return self._type
-
-    def probe(self):
-        log_method_call(self, device=self.device,
-                        type=self.type, status=self.status)
-
-    def notifyKernel(self):
-        log_method_call(self, device=self.device,
-                        type=self.type)
-        if not self.device:
-            return
-
-        if self.device.startswith("/dev/mapper/"):
-            try:
-                name = dm_node_from_name(os.path.basename(self.device))
-            except Exception, e:
-                log.warning("failed to get dm node for %s" % self.device)
-                return
-        elif self.device:
-            name = os.path.basename(self.device)
-
-        path = get_sysfs_path_by_name(name)
-        try:
-            notify_kernel(path, action="change")
-        except Exception, e:
-            log.warning("failed to notify kernel of change: %s" % e)
-
-
-    def create(self, *args, **kwargs):
-        log_method_call(self, device=self.device,
-                        type=self.type, status=self.status)
-        # allow late specification of device path
-        device = kwargs.get("device")
-        if device:
-            self.device = device
-
-        if not os.path.exists(self.device):
-            raise FormatCreateError("invalid device specification", self.device)
-
-    def destroy(self, *args, **kwargs):
-        log_method_call(self, device=self.device,
-                        type=self.type, status=self.status)
-        # zero out the 1MB at the beginning and end of the device in the
-        # hope that it will wipe any metadata from filesystems that
-        # previously occupied this device
-        log.debug("zeroing out beginning and end of %s..." % self.device)
-        fd = None
-
-        try:
-            fd = os.open(self.device, os.O_RDWR)
-            buf = '\0' * 1024 * 1024
-            os.write(fd, buf)
-            os.lseek(fd, -1024 * 1024, 2)
-            os.write(fd, buf)
-            os.close(fd)
-        except OSError as e:
-            if getattr(e, "errno", None) == 28: # No space left in device
-                pass
-            else:
-                log.error("error zeroing out %s: %s" % (self.device, e))
-
-            if fd:
-                os.close(fd)
-        except Exception as e:
-            log.error("error zeroing out %s: %s" % (self.device, e))
-            if fd:
-                os.close(fd)
-
-        self.exists = False
-
-    def setup(self, *args, **kwargs):
-        log_method_call(self, device=self.device,
-                        type=self.type, status=self.status)
-
-        if not self.exists:
-            raise FormatSetupError("format has not been created")
-
-        if self.status:
-            return
-
-        # allow late specification of device path
-        device = kwargs.get("device")
-        if device:
-            self.device = device
-
-        if not self.device or not os.path.exists(self.device):
-            raise FormatSetupError("invalid device specification")
-
-    def teardown(self, *args, **kwargs):
-        log_method_call(self, device=self.device,
-                        type=self.type, status=self.status)
-
-    @property
-    def status(self):
-        return (self.exists and
-                self.__class__ is not DeviceFormat and
-                isinstance(self.device, str) and
-                self.device and 
-                os.path.exists(self.device))
-
-    @property
-    def formattable(self):
-        """ Can we create formats of this type? """
-        return self._formattable
-
-    @property
-    def supported(self):
-        """ Is this format a supported type? """
-        return self._supported
-
-    @property
-    def packages(self):
-        """ Packages required to manage formats of this type. """
-        return self._packages
-
-    @property
-    def resizable(self):
-        """ Can formats of this type be resized? """
-        return self._resizable and self.exists
-
-    @property
-    def bootable(self):
-        """ Is this format type suitable for a boot partition? """
-        return self._bootable
-
-    @property
-    def migratable(self):
-        """ Can formats of this type be migrated? """
-        return self._migratable
-
-    @property
-    def migrate(self):
-        return self._migrate
-
-    @property
-    def linuxNative(self):
-        """ Is this format type native to linux? """
-        return self._linuxNative
-
-    @property
-    def mountable(self):
-        """ Is this something we can mount? """
-        return False
-
-    @property
-    def dump(self):
-        """ Whether or not this format will be dumped by dump(8). """
-        return self._dump
-
-    @property
-    def check(self):
-        """ Whether or not this format is checked on boot. """
-        return self._check
-
-    @property
-    def maxSize(self):
-        """ Maximum size (in MB) for this format type. """
-        return self._maxSize
-
-    @property
-    def minSize(self):
-        """ Minimum size (in MB) for this format type. """
-        return self._minSize
-
-    @property
-    def hidden(self):
-        """ Whether devices with this formatting should be hidden in UIs. """
-        return self._hidden
-
-    def writeKS(self, f):
-        return
-
-
-collect_device_format_classes()
-
-
diff --git a/storage/formats/disklabel.py b/storage/formats/disklabel.py
deleted file mode 100644
index a76e452..0000000
--- a/storage/formats/disklabel.py
+++ /dev/null
@@ -1,356 +0,0 @@
-# disklabel.py
-# Device format classes for anaconda's storage configuration module.
-#
-# Copyright (C) 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, or (at your option) any later version.
-# 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.
-#
-# Red Hat Author(s): Dave Lehman <dlehman@xxxxxxxxxx>
-#
-
-import os
-import copy
-
-from ..storage_log import log_method_call
-import parted
-import _ped
-import platform
-from ..errors import *
-from ..udev import udev_settle
-from . import DeviceFormat, register_device_format
-
-import gettext
-_ = lambda x: gettext.ldgettext("anaconda", x)
-
-import logging
-log = logging.getLogger("storage")
-
-
-class DiskLabel(DeviceFormat):
-    """ Disklabel """
-    _type = "disklabel"
-    _name = "partition table"
-    _formattable = True                # can be formatted
-    _supported = False                 # is supported
-
-    def __init__(self, *args, **kwargs):
-        """ Create a DiskLabel instance.
-
-            Keyword Arguments:
-
-                device -- path to the underlying device
-                exists -- indicates whether this is an existing format
-
-        """
-        log_method_call(self, *args, **kwargs)
-        DeviceFormat.__init__(self, *args, **kwargs)
-
-        self._size = None
-
-        self._partedDevice = None
-        self._partedDisk = None
-        self._origPartedDisk = None
-        self._alignment = None
-        self._endAlignment = None
-
-        if self.partedDevice:
-            # set up the parted objects and raise exception on failure
-            self._origPartedDisk = self.partedDisk.duplicate()
-
-    def __deepcopy__(self, memo):
-        """ Create a deep copy of a Disklabel instance.
-
-            We can't do copy.deepcopy on parted objects, which is okay.
-            For these parted objects, we just do a shallow copy.
-        """
-        new = self.__class__.__new__(self.__class__)
-        memo[id(self)] = new
-        shallow_copy_attrs = ('_partedDevice', '_partedDisk', '_origPartedDisk')
-        for (attr, value) in self.__dict__.items():
-            if attr in shallow_copy_attrs:
-                setattr(new, attr, copy.copy(value))
-            else:
-                setattr(new, attr, copy.deepcopy(value, memo))
-
-        return new
-
-    def __str__(self):
-        s = DeviceFormat.__str__(self)
-        s += ("  type = %(type)s  partition count = %(count)s"
-              "  sectorSize = %(sectorSize)s\n"
-              "  align_offset = %(offset)s  align_grain = %(grain)s\n"
-              "  partedDisk = %(disk)r\n"
-              "  origPartedDisk = %(orig_disk)r\n"
-              "  partedDevice = %(dev)r\n" %
-              {"type": self.labelType, "count": len(self.partitions),
-               "sectorSize": self.partedDevice.sectorSize,
-               "offset": self.alignment.offset,
-               "grain": self.alignment.grainSize,
-               "disk": self.partedDisk, "orig_disk": self._origPartedDisk,
-               "dev": self.partedDevice})
-        return s
-
-    @property
-    def dict(self):
-        d = super(DiskLabel, self).dict
-        d.update({"labelType": self.labelType,
-                  "partitionCount": len(self.partitions),
-                  "sectorSize": self.partedDevice.sectorSize,
-                  "offset": self.alignment.offset,
-                  "grainSize": self.alignment.grainSize})
-        return d
-
-    def resetPartedDisk(self):
-        """ Set this instance's partedDisk to reflect the disk's contents. """
-        log_method_call(self, device=self.device)
-        self._partedDisk = self._origPartedDisk
-
-    def freshPartedDisk(self):
-        """ Return a new, empty parted.Disk instance for this device. """
-        log_method_call(self, device=self.device)
-        platf = platform.getPlatform(None)
-        labelType = platf.diskLabelType(self.partedDevice.type)
-        return parted.freshDisk(device=self.partedDevice, ty=labelType)
-
-    @property
-    def partedDisk(self):
-        if not self._partedDisk:
-            if self.exists:
-                try:
-                    self._partedDisk = parted.Disk(device=self.partedDevice)
-                except (_ped.DiskLabelException, _ped.IOException,
-                        NotImplementedError) as e:
-                    raise InvalidDiskLabelError()
-
-                if self._partedDisk.type == "loop":
-                    # When the device has no partition table but it has a FS,
-                    # it will be created with label type loop.  Treat the
-                    # same as if the device had no label (cause it really
-                    # doesn't).
-                    raise InvalidDiskLabelError()
-            else:
-                self._partedDisk = self.freshPartedDisk()
-
-            # turn off cylinder alignment
-            if self._partedDisk.isFlagAvailable(parted.DISK_CYLINDER_ALIGNMENT):
-                self._partedDisk.unsetFlag(parted.DISK_CYLINDER_ALIGNMENT)
-
-        return self._partedDisk
-
-    @property
-    def partedDevice(self):
-        if not self._partedDevice and self.device and \
-           os.path.exists(self.device):
-            # We aren't guaranteed to be able to get a device.  In
-            # particular, built-in USB flash readers show up as devices but
-            # do not always have any media present, so parted won't be able
-            # to find a device.
-            try:
-                 self._partedDevice = parted.Device(path=self.device)
-            except (_ped.IOException, _ped.DeviceException):
-                 pass
-
-        return self._partedDevice
-
-    @property
-    def labelType(self):
-        """ The disklabel type (eg: 'gpt', 'msdos') """
-        return self.partedDisk.type
-
-    @property
-    def name(self):
-        return "%s (%s)" % (self._name, self.labelType.upper())
-
-    @property
-    def size(self):
-        size = self._size
-        if not size:
-            try:
-                size = self.partedDevice.getSize(unit="MB")
-            except Exception:
-                size = 0
-
-        return size
-
-    @property
-    def status(self):
-        """ Device status. """
-        return False
-
-    def setup(self, *args, **kwargs):
-        """ Open, or set up, a device. """
-        log_method_call(self, device=self.device,
-                        type=self.type, status=self.status)
-        if not self.exists:
-            raise DeviceFormatError("format has not been created")
-
-        if self.status:
-            return
-
-        DeviceFormat.setup(self, *args, **kwargs)
-
-    def teardown(self, *args, **kwargs):
-        """ Close, or tear down, a device. """
-        log_method_call(self, device=self.device,
-                        type=self.type, status=self.status)
-        if not self.exists:
-            raise DeviceFormatError("format has not been created")
-
-    def create(self, *args, **kwargs):
-        """ Create the device. """
-        log_method_call(self, device=self.device,
-                        type=self.type, status=self.status)
-        if self.exists:
-            raise DeviceFormatError("format already exists")
-
-        if self.status:
-            raise DeviceFormatError("device exists and is active")
-
-        DeviceFormat.create(self, *args, **kwargs)
-
-        # We're relying on someone having called resetPartedDisk -- we
-        # could ensure a fresh disklabel by setting self._partedDisk to
-        # None right before calling self.commit(), but that might hide
-        # other problems.
-        self.commit()
-        self.exists = True
-
-    def destroy(self, *args, **kwargs):
-        """ Wipe the disklabel from the device. """
-        log_method_call(self, device=self.device,
-                        type=self.type, status=self.status)
-        if not self.exists:
-            raise DeviceFormatError("format does not exist")
-
-        if not os.access(self.device, os.W_OK):
-            raise DeviceFormatError("device path does not exist")
-
-        self.partedDevice.clobber()
-        self.exists = False
-
-    def commit(self):
-        """ Commit the current partition table to disk and notify the OS. """
-        log_method_call(self, device=self.device,
-                        numparts=len(self.partitions))
-        try:
-            self.partedDisk.commit()
-        except parted.DiskException as msg:
-            raise DiskLabelCommitError(msg)
-        else:
-            udev_settle()
-
-    def commitToDisk(self):
-        """ Commit the current partition table to disk. """
-        log_method_call(self, device=self.device,
-                        numparts=len(self.partitions))
-        try:
-            self.partedDisk.commitToDevice()
-        except parted.DiskException as msg:
-            raise DiskLabelCommitError(msg)
-
-    def addPartition(self, *args, **kwargs):
-        partition = kwargs.get("partition", None)
-        if not partition:
-            partition = args[0]
-        geometry = partition.geometry
-        constraint = kwargs.get("constraint", None)
-        if not constraint and len(args) > 1:
-            constraint = args[1]
-        elif not constraint:
-            constraint = parted.Constraint(exactGeom=geometry)
-
-        new_partition = parted.Partition(disk=self.partedDisk,
-                                         type=partition.type,
-                                         geometry=geometry)
-        self.partedDisk.addPartition(partition=new_partition,
-                                     constraint=constraint)
-
-    def removePartition(self, partition):
-        self.partedDisk.removePartition(partition)
-
-    @property
-    def extendedPartition(self):
-        try:
-            extended = self.partedDisk.getExtendedPartition()
-        except Exception:
-            extended = None
-        return extended
-
-    @property
-    def logicalPartitions(self):
-        try:
-            logicals = self.partedDisk.getLogicalPartitions()
-        except Exception:
-            logicals = []
-        return logicals
-
-    @property
-    def firstPartition(self):
-        try:
-            part = self.partedDisk.getFirstPartition()
-        except Exception:
-            part = None
-        return part
-
-    @property
-    def partitions(self):
-        try:
-            parts = self.partedDisk.partitions
-        except Exception:
-            parts = []
-        return parts
-
-    @property
-    def alignment(self):
-        """ Alignment requirements for this device. """
-        if not self._alignment:
-            try:
-                disklabel_alignment = self.partedDisk.partitionAlignment
-            except _ped.CreateException:
-                disklabel_alignment = parted.Alignment(offset=0, grainSize=1)
-
-            try:
-                optimum_device_alignment = self.partedDevice.optimumAlignment
-            except _ped.CreateException:
-                optimum_device_alignment = None
-
-            try:
-                minimum_device_alignment = self.partedDevice.minimumAlignment
-            except _ped.CreateException:
-                minimum_device_alignment = None
-
-            try:
-                a = optimum_device_alignment.intersect(disklabel_alignment)
-            except (ArithmeticError, AttributeError):
-                try:
-                    a = minimum_device_alignment.intersect(disklabel_alignment)
-                except (ArithmeticError, AttributeError):
-                    a = disklabel_alignment
-
-            self._alignment = a
-
-        return self._alignment
-
-    @property
-    def endAlignment(self):
-        if not self._endAlignment:
-            self._endAlignment = parted.Alignment(
-                                        offset = self.alignment.offset - 1,
-                                        grainSize = self.alignment.grainSize)
-
-        return self._endAlignment
-
-register_device_format(DiskLabel)
-
diff --git a/storage/formats/dmraid.py b/storage/formats/dmraid.py
deleted file mode 100644
index 3d2ee86..0000000
--- a/storage/formats/dmraid.py
+++ /dev/null
@@ -1,114 +0,0 @@
-# dmraid.py
-# dmraid device formats
-#
-# Copyright (C) 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, or (at your option) any later version.
-# 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.
-#
-# Red Hat Author(s): Dave Lehman <dlehman@xxxxxxxxxx>
-#
-
-from ..storage_log import log_method_call
-from flags import flags
-from ..errors import *
-from . import DeviceFormat, register_device_format
-
-import gettext
-_ = lambda x: gettext.ldgettext("anaconda", x)
-
-import logging
-log = logging.getLogger("storage")
-
-
-class DMRaidMember(DeviceFormat):
-    """ A dmraid member disk. """
-    _type = "dmraidmember"
-    _name = "dm-raid member device"
-    # XXX This looks like trouble.
-    #
-    #     Maybe a better approach is a RaidMember format with subclass
-    #     for MDRaidMember, letting all *_raid_member types fall through
-    #     to the generic RaidMember format, which is basically read-only.
-    #
-    #     One problem that presents is the possibility of someone passing
-    #     a dmraid member to the MDRaidArrayDevice constructor.
-    _udevTypes = ["adaptec_raid_member", "ddf_raid_member",
-                 "highpoint_raid_member", "isw_raid_member",
-                 "jmicron_raid_member", "lsi_mega_raid_member",
-                 "nvidia_raid_member", "promise_fasttrack_raid_member",
-                 "silicon_medley_raid_member", "via_raid_member"]
-    _formattable = False                # can be formatted
-    _supported = True                   # is supported
-    _linuxNative = False                # for clearpart
-    _packages = ["dmraid"]              # required packages
-    _resizable = False                  # can be resized
-    _bootable = False                   # can be used as boot 
-    _maxSize = 0                        # maximum size in MB
-    _minSize = 0                        # minimum size in MB
-    _hidden = True                      # hide devices with this formatting?
-
-    def __init__(self, *args, **kwargs):
-        """ Create a DeviceFormat instance.
-
-            Keyword Arguments:
-
-                device -- path to the underlying device
-                uuid -- this format's UUID
-                exists -- indicates whether this is an existing format
-
-            On initialization this format is like DeviceFormat
-
-        """
-        log_method_call(self, *args, **kwargs)
-        DeviceFormat.__init__(self, *args, **kwargs)
-
-        # Initialize the attribute that will hold the block object.
-        self._raidmem = None
-
-    def __str__(self):
-        s = DeviceFormat.__str__(self)
-        s += ("  raidmem = %(raidmem)r" % {"raidmem": self.raidmem})
-        return s
-
-    def _getRaidmem(self):
-        return self._raidmem
-
-    def _setRaidmem(self, raidmem):
-        self._raidmem = raidmem
-
-    raidmem = property(lambda d: d._getRaidmem(),
-                       lambda d,r: d._setRaidmem(r))
-
-    def create(self, *args, **kwargs):
-        log_method_call(self, device=self.device,
-                        type=self.type, status=self.status)
-        raise DMRaidMemberError("creation of dmraid members is non-sense")
-
-    def destroy(self, *args, **kwargs):
-        log_method_call(self, device=self.device,
-                        type=self.type, status=self.status)
-        raise DMRaidMemberError("destruction of dmraid members is non-sense")
-
-
-if not flags.cmdline.has_key("noiswmd"):
-    DMRaidMember._udevTypes.remove("isw_raid_member")
-
-# The anaconda cmdline has not been parsed yet when we're first imported,
-# so we can not use flags.dmraid here
-if flags.cmdline.has_key("nodmraid"):
-    DMRaidMember._udevTypes = []
-
-register_device_format(DMRaidMember)
-
diff --git a/storage/formats/fs.py b/storage/formats/fs.py
deleted file mode 100644
index 7377471..0000000
--- a/storage/formats/fs.py
+++ /dev/null
@@ -1,1488 +0,0 @@
-# filesystems.py
-# Filesystem classes for anaconda's storage configuration module.
-#
-# Copyright (C) 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, or (at your option) any later version.
-# 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.
-#
-# Red Hat Author(s): Dave Lehman <dlehman@xxxxxxxxxx>
-#                    David Cantrell <dcantrell@xxxxxxxxxx>
-#
-
-""" Filesystem classes for use by anaconda.
-
-    TODO:
-        - migration
-        - bug 472127: allow creation of tmpfs filesystems (/tmp, /var/tmp, &c)
-"""
-import math
-import os
-import sys
-import tempfile
-import selinux
-import isys
-
-from ..errors import *
-from . import DeviceFormat, register_device_format
-import iutil
-from flags import flags
-from parted import fileSystemType
-from ..storage_log import log_method_call
-
-import logging
-log = logging.getLogger("storage")
-
-import gettext
-_ = lambda x: gettext.ldgettext("anaconda", x)
-
-try:
-    lost_and_found_context = selinux.matchpathcon("/lost+found", 0)[1]
-except OSError:
-    lost_and_found_context = None
-
-fs_configs = {}
-
-def get_kernel_filesystems():
-    fs_list = []
-    for line in open("/proc/filesystems").readlines():
-        fs_list.append(line.split()[-1])
-    return fs_list
-
-global kernel_filesystems
-kernel_filesystems = get_kernel_filesystems()
-
-def fsConfigFromFile(config_file):
-    """ Generate a set of attribute name/value pairs with which a
-        filesystem type can be defined.
-
-        The following config file would define a filesystem identical to
-        the static Ext3FS class definition:
-
-            type = ext3
-            mkfs = "mke2fs"
-            resizefs = "resize2fs"
-            labelfs = "e2label"
-            fsck = "e2fsck"
-            packages = ["e2fsprogs"]
-            formattable = True
-            supported = True
-            resizable = True
-            bootable = True
-            linuxNative = True
-            maxSize = 8 * 1024 * 1024
-            minSize = 0
-            defaultFormatOptions = "-t ext3"
-            defaultMountOptions = "defaults"
-
-    """
-    # XXX NOTUSED
-    lines = open(config_file).readlines()
-    fs_attrs = {}
-    for line in lines:
-        (key, value) = [t.strip() for t in line.split("=")]
-        if not hasattr(FS, "_" + key):
-            print "invalid key: %s" % key
-            continue
-
-        fs_attrs[key] = value
-
-    if not fs_attrs.has_key("type"):
-        raise ValueError, _("filesystem configuration missing a type")
-
-    # XXX what's the policy about multiple configs for a given type?
-    fs_configs[fs_attrs['type']] = fs_attrs
-
-class FS(DeviceFormat):
-    """ Filesystem class. """
-    _type = "Abstract Filesystem Class"  # fs type name
-    _mountType = None                    # like _type but for passing to mount
-    _name = None
-    _mkfs = ""                           # mkfs utility
-    _modules = []                        # kernel modules required for support
-    _resizefs = ""                       # resize utility
-    _labelfs = ""                        # labeling utility
-    _fsck = ""                           # fs check utility
-    _fsckErrors = {}                     # fs check command error codes & msgs
-    _migratefs = ""                      # fs migration utility
-    _infofs = ""                         # fs info utility
-    _defaultFormatOptions = []           # default options passed to mkfs
-    _defaultMountOptions = ["defaults"]  # default options passed to mount
-    _defaultLabelOptions = []
-    _defaultCheckOptions = []
-    _defaultMigrateOptions = []
-    _defaultInfoOptions = []
-    _migrationTarget = None
-    _existingSizeFields = []
-    _fsProfileSpecifier = None           # mkfs option specifying fsprofile
-
-    def __init__(self, *args, **kwargs):
-        """ Create a FS instance.
-
-            Keyword Args:
-
-                device -- path to the device containing the filesystem
-                mountpoint -- the filesystem's mountpoint
-                label -- the filesystem label
-                uuid -- the filesystem UUID
-                mountopts -- mount options for the filesystem
-                size -- the filesystem's size in MiB
-                exists -- indicates whether this is an existing filesystem
-                
-        """
-        if self.__class__ is FS:
-            raise TypeError("FS is an abstract class.")
-
-        DeviceFormat.__init__(self, *args, **kwargs)
-        self.mountpoint = kwargs.get("mountpoint")
-        self.mountopts = kwargs.get("mountopts")
-        self.label = kwargs.get("label")
-        self.fsprofile = kwargs.get("fsprofile")
-
-        # filesystem size does not necessarily equal device size
-        self._size = kwargs.get("size", 0)
-        self._minInstanceSize = None    # min size of this FS instance
-        self._mountpoint = None     # the current mountpoint when mounted
-        if self.exists and self.supported:
-            self._size = self._getExistingSize()
-            foo = self.minSize      # force calculation of minimum size
-
-        self._targetSize = self._size
-
-        if self.supported:
-            self.loadModule()
-
-    def __str__(self):
-        s = DeviceFormat.__str__(self)
-        s += ("  mountpoint = %(mountpoint)s  mountopts = %(mountopts)s\n"
-              "  label = %(label)s  size = %(size)s"
-              "  targetSize = %(targetSize)s\n" %
-              {"mountpoint": self.mountpoint, "mountopts": self.mountopts,
-               "label": self.label, "size": self._size,
-               "targetSize": self.targetSize})
-        return s
-
-    @property
-    def dict(self):
-        d = super(FS, self).dict
-        d.update({"mountpoint": self.mountpoint, "size": self._size,
-                  "label": self.label, "targetSize": self.targetSize,
-                  "mountable": self.mountable,
-                  "migratable": self.migratable})
-        return d
-
-    def _setTargetSize(self, newsize):
-        """ Set a target size for this filesystem. """
-        if not self.exists:
-            raise FSError("filesystem has not been created")
-
-        if newsize is None:
-            # unset any outstanding resize request
-            self._targetSize = self._size
-            return
-
-        if not self.minSize <= newsize < self.maxSize:
-            raise ValueError("invalid target size request")
-
-        self._targetSize = newsize
-
-    def _getTargetSize(self):
-        """ Get this filesystem's target size. """
-        return self._targetSize
-
-    targetSize = property(_getTargetSize, _setTargetSize,
-                          doc="Target size for this filesystem")
-
-    def _getSize(self):
-        """ Get this filesystem's size. """
-        size = self._size
-        if self.resizable and self.targetSize != size:
-            size = self.targetSize
-        return size
-
-    size = property(_getSize, doc="This filesystem's size, accounting "
-                                  "for pending changes")
-
-    def _getExistingSize(self):
-        """ Determine the size of this filesystem.  Filesystem must
-            exist.  Each filesystem varies, but the general procedure
-            is to run the filesystem dump or info utility and read
-            the block size and number of blocks for the filesystem
-            and compute megabytes from that.
-
-            The loop that reads the output from the infofsProg is meant
-            to be simple, but take in to account variations in output.
-            The general procedure:
-                1) Capture output from infofsProg.
-                2) Iterate over each line of the output:
-                       a) Trim leading and trailing whitespace.
-                       b) Break line into fields split on ' '
-                       c) If line begins with any of the strings in
-                          _existingSizeFields, start at the end of
-                          fields and take the first one that converts
-                          to a long.  Store this in the values list.
-                       d) Repeat until the values list length equals
-                          the _existingSizeFields length.
-                3) If the length of the values list equals the length
-                   of _existingSizeFields, compute the size of this
-                   filesystem by multiplying all of the values together
-                   to get bytes, then convert to megabytes.  Return
-                   this value.
-                4) If we were unable to capture all fields, return 0.
-
-            The caller should catch exceptions from this method.  Any
-            exception raised indicates a need to change the fields we
-            are looking for, the command to run and arguments, or
-            something else.  If you catch an exception from this method,
-            assume the filesystem cannot be resized.
-        """
-        size = self._size
-
-        if self.infofsProg and self.mountable and self.exists and not size:
-            try:
-                values = []
-                argv = self._defaultInfoOptions + [ self.device ]
-
-                buf = iutil.execWithCapture(self.infofsProg, argv,
-                                            stderr="/dev/tty5")
-
-                for line in buf.splitlines():
-                    found = False
-
-                    line = line.strip()
-                    tmp = line.split(' ')
-                    tmp.reverse()
-
-                    for field in self._existingSizeFields:
-                        if line.startswith(field):
-                            for subfield in tmp:
-                                try:
-                                    values.append(long(subfield))
-                                    found = True
-                                    break
-                                except ValueError:
-                                    continue
-
-                        if found:
-                            break
-
-                    if len(values) == len(self._existingSizeFields):
-                        break
-
-                if len(values) != len(self._existingSizeFields):
-                    return 0
-
-                size = 1
-                for value in values:
-                    size *= value
-
-                # report current size as megabytes
-                size = math.floor(size / 1024.0 / 1024.0)
-            except Exception as e:
-                log.error("failed to obtain size of filesystem on %s: %s"
-                          % (self.device, e))
-
-        return size
-
-    @property
-    def currentSize(self):
-        """ The filesystem's current actual size. """
-        size = 0
-        if self.exists:
-            size = self._size
-        return float(size)
-
-    def _getFormatOptions(self, options=None):
-        argv = []
-        if options and isinstance(options, list):
-            argv.extend(options)
-        argv.extend(self.defaultFormatOptions)
-        if self._fsProfileSpecifier and self.fsprofile:
-            argv.extend([self._fsProfileSpecifier, self.fsprofile])
-        argv.append(self.device)
-        return argv
-    
-    def doFormat(self, *args, **kwargs):
-        """ Create the filesystem.
-
-            Arguments:
-
-                None
-
-            Keyword Arguments:
-
-                intf -- InstallInterface instance
-                options -- list of options to pass to mkfs
-
-        """
-        log_method_call(self, type=self.mountType, device=self.device,
-                        mountpoint=self.mountpoint)
-
-        intf = kwargs.get("intf")
-        options = kwargs.get("options")
-
-        if self.exists:
-            raise FormatCreateError("filesystem already exists", self.device)
-
-        if not self.formattable:
-            return
-
-        if not self.mkfsProg:
-            return
-
-        if self.exists:
-            return
-
-        if not os.path.exists(self.device):
-            raise FormatCreateError("device does not exist", self.device)
-
-        argv = self._getFormatOptions(options=options)
-
-        w = None
-        if intf:
-            w = intf.progressWindow(_("Formatting"),
-                                    _("Creating %s filesystem on %s")
-                                    % (self.type, self.device),
-                                    100, pulse = True)
-
-        try:
-            rc = iutil.execWithPulseProgress(self.mkfsProg,
-                                             argv,
-                                             stdout="/dev/tty5",
-                                             stderr="/dev/tty5",
-                                             progress=w)
-        except Exception as e:
-            raise FormatCreateError(e, self.device)
-        finally:
-            if w:
-                w.pop()
-
-        if rc:
-            raise FormatCreateError("format failed: %s" % rc, self.device)
-
-        self.exists = True
-        self.notifyKernel()
-
-        if self.label:
-            self.writeLabel(self.label)
-
-    def doMigrate(self, intf=None):
-        if not self.exists:
-            raise FSError("filesystem has not been created")
-
-        if not self.migratable or not self.migrate:
-            return
-
-        if not os.path.exists(self.device):
-            raise FSError("device does not exist")
-
-        # if journal already exists skip
-        if isys.ext2HasJournal(self.device):
-            log.info("Skipping migration of %s, has a journal already."
-                     % self.device)
-            return
-
-        argv = self._defaultMigrateOptions[:]
-        argv.append(self.device)
-        try:
-            rc = iutil.execWithRedirect(self.migratefsProg,
-                                        argv,
-                                        stdout = "/dev/tty5",
-                                        stderr = "/dev/tty5")
-        except Exception as e:
-            raise FSMigrateError("filesystem migration failed: %s" % e,
-                                 self.device)
-
-        if rc:
-            raise FSMigrateError("filesystem migration failed: %s" % rc,
-                                 self.device)
-
-        # the other option is to actually replace this instance with an
-        # instance of the new filesystem type.
-        self._type = self.migrationTarget
-
-    @property
-    def resizeArgs(self):
-        argv = [self.device, "%d" % (self.targetSize,)]
-        return argv
-
-    def doResize(self, *args, **kwargs):
-        """ Resize this filesystem to new size @newsize.
-
-            Arguments:
-
-                None
-
-            Keyword Arguments:
-
-                intf -- InstallInterface instance
-
-        """
-        intf = kwargs.get("intf")
-
-        if not self.exists:
-            raise FSResizeError("filesystem does not exist", self.device)
-
-        if not self.resizable:
-            raise FSResizeError("filesystem not resizable", self.device)
-
-        if self.targetSize == self.currentSize:
-            return
-
-        if not self.resizefsProg:
-            return
-
-        if not os.path.exists(self.device):
-            raise FSResizeError("device does not exist", self.device)
-
-        self.doCheck(intf=intf)
-
-        # The first minimum size can be incorrect if the fs was not
-        # properly unmounted. After doCheck the minimum size will be correct
-        # so run the check one last time and bump up the size if it was too
-        # small.
-        self._minInstanceSize = None
-        if self.targetSize < self.minSize:
-            self.targetSize = self.minSize
-            log.info("Minimum size changed, setting targetSize on %s to %s" \
-                     % (self.device, self.targetSize))
-
-        w = None
-        if intf:
-            w = intf.progressWindow(_("Resizing"),
-                                    _("Resizing filesystem on %s")
-                                    % (self.device,),
-                                    100, pulse = True)
-
-        try:
-            rc = iutil.execWithPulseProgress(self.resizefsProg,
-                                             self.resizeArgs,
-                                             stdout="/dev/tty5",
-                                             stderr="/dev/tty5",
-                                             progress=w)
-        except Exception as e:
-            raise FSResizeError(e, self.device)
-        finally:
-            if w:
-                w.pop()
-
-        if rc:
-            raise FSResizeError("resize failed: %s" % rc, self.device)
-
-        self.doCheck(intf=intf)
-
-        # XXX must be a smarter way to do this
-        self._size = self.targetSize
-        self.notifyKernel()
-
-    def _getCheckArgs(self):
-        argv = []
-        argv.extend(self.defaultCheckOptions)
-        argv.append(self.device)
-        return argv
-
-    def _fsckFailed(self, rc):
-        return False
-
-    def _fsckErrorMessage(self, rc):
-        return _("Unknown return code: %d.") % (rc,)
-
-    def doCheck(self, intf=None):
-        if not self.exists:
-            raise FSError("filesystem has not been created")
-
-        if not self.fsckProg:
-            return
-
-        if not os.path.exists(self.device):
-            raise FSError("device does not exist")
-
-        w = None
-        if intf:
-            w = intf.progressWindow(_("Checking"),
-                                    _("Checking filesystem on %s")
-                                    % (self.device),
-                                    100, pulse = True)
-
-        try:
-            rc = iutil.execWithPulseProgress(self.fsckProg,
-                                             self._getCheckArgs(),
-                                             stdout="/dev/tty5",
-                                             stderr="/dev/tty5",
-                                             progress = w)
-        except Exception as e:
-            raise FSError("filesystem check failed: %s" % e)
-        finally:
-            if w:
-                w.pop()
-
-        if self._fsckFailed(rc):
-            hdr = _("%(type)s filesystem check failure on %(device)s: ") % \
-                    {"type": self.type, "device": self.device}
-
-            msg = self._fsckErrorMessage(rc)
-
-            if intf:
-                help = _("Errors like this usually mean there is a problem "
-                         "with the filesystem that will require user "
-                         "interaction to repair.  Before restarting "
-                         "installation, reboot to rescue mode or another "
-                         "system that allows you to repair the filesystem "
-                         "interactively.  Restart installation after you "
-                         "have corrected the problems on the filesystem.")
-
-                intf.messageWindow(_("Unrecoverable Error"),
-                                   hdr + "\n\n" + msg + "\n\n" + help,
-                                   custom_icon='error')
-                sys.exit(0)
-            else:
-                raise FSError(hdr + msg)
-
-    def loadModule(self):
-        """Load whatever kernel module is required to support this filesystem."""
-        global kernel_filesystems
-
-        if not self._modules or self.mountType in kernel_filesystems:
-            return
-
-        for module in self._modules:
-            try:
-                rc = iutil.execWithRedirect("modprobe", [module],
-                                            stdout="/dev/tty5",
-                                            stderr="/dev/tty5")
-            except Exception as e:
-                log.error("Could not load kernel module %s: %s" % (module, e))
-                self._supported = False
-                return
-
-            if rc:
-                log.error("Could not load kernel module %s" % module)
-                self._supported = False
-                return
-
-        # If we successfully loaded a kernel module, for this filesystem, we
-        # also need to update the list of supported filesystems.
-        kernel_filesystems = get_kernel_filesystems()
-
-    def mount(self, *args, **kwargs):
-        """ Mount this filesystem.
-
-            Arguments:
-
-                None
-
-            Keyword Arguments:
-
-                options -- mount options (overrides all other option strings)
-                chroot -- prefix to apply to mountpoint
-                mountpoint -- mountpoint (overrides self.mountpoint)
-        """
-        options = kwargs.get("options", "")
-        chroot = kwargs.get("chroot", "/")
-        mountpoint = kwargs.get("mountpoint")
-
-        if not self.exists:
-            raise FSError("filesystem has not been created")
-
-        if not mountpoint:
-            mountpoint = self.mountpoint
-
-        if not mountpoint:
-            raise FSError("no mountpoint given")
-
-        if self.status:
-            return
-
-        if not isinstance(self, NoDevFS) and not os.path.exists(self.device):
-            raise FSError("device %s does not exist" % self.device)
-
-        # XXX os.path.join is FUBAR:
-        #
-        #         os.path.join("/mnt/foo", "/") -> "/"
-        #
-        #mountpoint = os.path.join(chroot, mountpoint)
-        chrootedMountpoint = os.path.normpath("%s/%s" % (chroot, mountpoint))
-        iutil.mkdirChain(chrootedMountpoint)
-        if flags.selinux:
-            ret = isys.resetFileContext(mountpoint, chroot)
-            log.info("set SELinux context for mountpoint %s to %s" \
-                     % (mountpoint, ret))
-
-        # passed in options override default options
-        if not options or not isinstance(options, str):
-            options = self.options
-
-        try: 
-            rc = isys.mount(self.device, chrootedMountpoint, 
-                            fstype=self.mountType,
-                            options=options,
-                            bindMount=isinstance(self, BindFS))
-        except Exception as e:
-            raise FSError("mount failed: %s" % e)
-
-        if rc:
-            raise FSError("mount failed: %s" % rc)
-
-        if flags.selinux and "ro" not in options.split(","):
-            ret = isys.resetFileContext(mountpoint, chroot)
-            log.info("set SELinux context for newly mounted filesystem "
-                     "root at %s to %s" %(mountpoint, ret))
-            isys.setFileContext("%s/lost+found" % mountpoint,
-                                lost_and_found_context, chroot)
-
-        self._mountpoint = chrootedMountpoint
-
-    def unmount(self):
-        """ Unmount this filesystem. """
-        if not self.exists:
-            raise FSError("filesystem has not been created")
-
-        if not self._mountpoint:
-            # not mounted
-            return
-
-        if not os.path.exists(self._mountpoint):
-            raise FSError("mountpoint does not exist")
-
-        rc = isys.umount(self._mountpoint, removeDir = False)
-        if rc:
-            raise FSError("umount failed")
-
-        self._mountpoint = None
-
-    def _getLabelArgs(self, label):
-        argv = []
-        argv.extend(self.defaultLabelOptions)
-        argv.extend([self.device, label])
-        return argv 
-
-    def writeLabel(self, label):
-        """ Create a label for this filesystem. """
-        if not self.exists:
-            raise FSError("filesystem has not been created")
-
-        if not self.labelfsProg:
-            return
-
-        if not os.path.exists(self.device):
-            raise FSError("device does not exist")
-
-        argv = self._getLabelArgs(label)
-        rc = iutil.execWithRedirect(self.labelfsProg,
-                                    argv,
-                                    stderr="/dev/tty5")
-        if rc:
-            raise FSError("label failed")
-
-        self.label = label
-        self.notifyKernel()
-
-    @property
-    def isDirty(self):
-        return False
-
-    @property
-    def mkfsProg(self):
-        """ Program used to create filesystems of this type. """
-        return self._mkfs
-
-    @property
-    def fsckProg(self):
-        """ Program used to check filesystems of this type. """
-        return self._fsck
-
-    @property
-    def resizefsProg(self):
-        """ Program used to resize filesystems of this type. """
-        return self._resizefs
-
-    @property
-    def labelfsProg(self):
-        """ Program used to manage labels for this filesystem type. """
-        return self._labelfs
-
-    @property
-    def migratefsProg(self):
-        """ Program used to migrate filesystems of this type. """
-        return self._migratefs
-
-    @property
-    def infofsProg(self):
-        """ Program used to get information for this filesystem type. """
-        return self._infofs
-
-    @property
-    def migrationTarget(self):
-        return self._migrationTarget
-
-    @property
-    def utilsAvailable(self):
-        # we aren't checking for fsck because we shouldn't need it
-        for prog in [self.mkfsProg, self.resizefsProg, self.labelfsProg,
-                     self.infofsProg]:
-            if not prog:
-                continue
-
-            if not filter(lambda d: os.access("%s/%s" % (d, prog), os.X_OK),
-                          os.environ["PATH"].split(":")):
-                return False
-
-        return True
-
-    @property
-    def supported(self):
-        log_method_call(self, supported=self._supported)
-        return self._supported and self.utilsAvailable
-
-    @property
-    def mountable(self):
-        canmount = (self.mountType in kernel_filesystems) or \
-                   (os.access("/sbin/mount.%s" % (self.mountType,), os.X_OK))
-        modpath = os.path.realpath(os.path.join("/lib/modules", os.uname()[2]))
-        modname = "%s.ko" % self.mountType
-
-        if not canmount and os.path.isdir(modpath):
-            for root, dirs, files in os.walk(modpath):
-                have = filter(lambda x: x.startswith(modname), files)
-                if len(have) == 1 and have[0].startswith(modname):
-                    return True
-
-        return canmount
-
-    @property
-    def resizable(self):
-        """ Can formats of this filesystem type be resized? """
-        return super(FS, self).resizable and self.utilsAvailable
-
-    @property
-    def defaultFormatOptions(self):
-        """ Default options passed to mkfs for this filesystem type. """
-        # return a copy to prevent modification
-        return self._defaultFormatOptions[:]
-
-    @property
-    def defaultMountOptions(self):
-        """ Default options passed to mount for this filesystem type. """
-        # return a copy to prevent modification
-        return self._defaultMountOptions[:]
-
-    @property
-    def defaultLabelOptions(self):
-        """ Default options passed to labeler for this filesystem type. """
-        # return a copy to prevent modification
-        return self._defaultLabelOptions[:]
-
-    @property
-    def defaultCheckOptions(self):
-        """ Default options passed to checker for this filesystem type. """
-        # return a copy to prevent modification
-        return self._defaultCheckOptions[:]
-
-    def _getOptions(self):
-        options = ",".join(self.defaultMountOptions)
-        if self.mountopts:
-            # XXX should we clobber or append?
-            options = self.mountopts
-        return options
-
-    def _setOptions(self, options):
-        self.mountopts = options
-
-    options = property(_getOptions, _setOptions)
-
-    def _isMigratable(self):
-        """ Can filesystems of this type be migrated? """
-        return bool(self._migratable and self.migratefsProg and
-                    filter(lambda d: os.access("%s/%s"
-                                               % (d, self.migratefsProg,),
-                                               os.X_OK),
-                           os.environ["PATH"].split(":")) and
-                    self.migrationTarget)
-
-    migratable = property(_isMigratable)
-
-    def _setMigrate(self, migrate):
-        if not migrate:
-            self._migrate = migrate
-            return
-
-        if self.migratable and self.exists:
-            self._migrate = migrate
-        else:
-            raise ValueError("cannot set migrate on non-migratable filesystem")
-
-    migrate = property(lambda f: f._migrate, lambda f,m: f._setMigrate(m))
-
-    @property
-    def type(self):
-        _type = self._type
-        if self.migrate:
-            _type = self.migrationTarget
-
-        return _type
-
-    @property
-    def mountType(self):
-        if not self._mountType:
-            self._mountType = self._type
-
-        return self._mountType
-
-    # These methods just wrap filesystem-specific methods in more
-    # generically named methods so filesystems and formatted devices
-    # like swap and LVM physical volumes can have a common API.
-    def create(self, *args, **kwargs):
-        if self.exists:
-            raise FSError("filesystem already exists")
-
-        DeviceFormat.create(self, *args, **kwargs)
-
-        return self.doFormat(*args, **kwargs)
-
-    def setup(self, *args, **kwargs):
-        """ Mount the filesystem.
-
-            The filesystem will be mounted at the directory indicated by
-            self.mountpoint.
-        """
-        return self.mount(**kwargs)
-
-    def teardown(self, *args, **kwargs):
-        return self.unmount(*args, **kwargs)
-
-    @property
-    def status(self):
-        # FIXME check /proc/mounts or similar
-        if not self.exists:
-            return False
-        return self._mountpoint is not None
-
-    def writeKS(self, f):
-        f.write("%s --fstype=%s" % (self.mountpoint, self.type))
-
-        if self.label:
-            f.write(" --label=\"%s\"" % self.label)
-
-
-class Ext2FS(FS):
-    """ ext2 filesystem. """
-    _type = "ext2"
-    _mkfs = "mke2fs"
-    _modules = ["ext2"]
-    _resizefs = "resize2fs"
-    _labelfs = "e2label"
-    _fsck = "e2fsck"
-    _fsckErrors = {4: _("File system errors left uncorrected."),
-                   8: _("Operational error."),
-                   16: _("Usage or syntax error."),
-                   32: _("e2fsck cancelled by user request."),
-                   128: _("Shared library error.")}
-    _packages = ["e2fsprogs"]
-    _formattable = True
-    _supported = True
-    _resizable = True
-    _bootable = True
-    _linuxNative = True
-    _maxSize = 8 * 1024 * 1024
-    _minSize = 0
-    _defaultFormatOptions = []
-    _defaultMountOptions = ["defaults"]
-    _defaultCheckOptions = ["-f", "-p", "-C", "0"]
-    _dump = True
-    _check = True
-    _migratable = True
-    _migrationTarget = "ext3"
-    _migratefs = "tune2fs"
-    _defaultMigrateOptions = ["-j"]
-    _infofs = "dumpe2fs"
-    _defaultInfoOptions = ["-h"]
-    _existingSizeFields = ["Block count:", "Block size:"]
-    _fsProfileSpecifier = "-T"
-    partedSystem = fileSystemType["ext2"]
-
-    def _fsckFailed(self, rc):
-        for errorCode in self._fsckErrors.keys():
-            if rc & errorCode:
-                return True
-        return False
-
-    def _fsckErrorMessage(self, rc):
-        msg = ''
-
-        for errorCode in self._fsckErrors.keys():
-            if rc & errorCode:
-                msg += "\n" + self._fsckErrors[errorCode]
-
-        return msg.strip()
-
-    def doMigrate(self, intf=None):
-        FS.doMigrate(self, intf=intf)
-        self.tuneFS()
-
-    def doFormat(self, *args, **kwargs):
-        FS.doFormat(self, *args, **kwargs)
-        self.tuneFS()
-
-    def tuneFS(self):
-        if not isys.ext2HasJournal(self.device):
-            # only do this if there's a journal
-            return
-
-        try:
-            rc = iutil.execWithRedirect("tune2fs",
-                                        ["-c0", "-i0",
-                                         "-ouser_xattr,acl", self.device],
-                                        stdout = "/dev/tty5",
-                                        stderr = "/dev/tty5")
-        except Exception as e:
-            log.error("failed to run tune2fs on %s: %s" % (self.device, e))
-
-    @property
-    def minSize(self):
-        """ Minimum size for this filesystem in MB. """
-        if self._minInstanceSize is None:
-            # try once in the beginning to get the minimum size for an
-            # existing filesystem.
-            size = self._minSize
-            blockSize = None
-
-            if self.exists and os.path.exists(self.device):
-                # get block size
-                buf = iutil.execWithCapture(self.infofsProg,
-                                            ["-h", self.device],
-                                            stderr="/dev/tty5")
-                for line in buf.splitlines():
-                    if line.startswith("Block size:"):
-                        blockSize = int(line.split(" ")[-1])
-                        break
-
-                if blockSize is None:
-                    raise FSError("failed to get block size for %s filesystem "
-                                  "on %s" % (self.mountType, self.device))
-
-                # get minimum size according to resize2fs
-                buf = iutil.execWithCapture(self.resizefsProg,
-                                            ["-P", self.device],
-                                            stderr="/dev/tty5")
-                for line in buf.splitlines():
-                    if "minimum size of the filesystem:" not in line:
-                        continue
-
-                    # line will look like:
-                    # Estimated minimum size of the filesystem: 1148649
-                    #
-                    # NOTE: The minimum size reported is in blocks.  Convert
-                    # to bytes, then megabytes, and finally round up.
-                    (text, sep, minSize) = line.partition(": ")
-                    size = long(minSize) * blockSize
-                    size = math.ceil(size / 1024.0 / 1024.0)
-                    break
-
-                if size is None:
-                    log.warning("failed to get minimum size for %s filesystem "
-                                "on %s" % (self.mountType, self.device))
-
-            self._minInstanceSize = size
-
-        return self._minInstanceSize
-
-    @property
-    def isDirty(self):
-        return isys.ext2IsDirty(self.device)
-
-    @property
-    def resizeArgs(self):
-        argv = ["-p", self.device, "%dM" % (self.targetSize,)]
-        return argv
-
-register_device_format(Ext2FS)
-
-
-class Ext3FS(Ext2FS):
-    """ ext3 filesystem. """
-    _type = "ext3"
-    _defaultFormatOptions = ["-t", "ext3"]
-    _migrationTarget = "ext4"
-    _modules = ["ext3"]
-    _defaultMigrateOptions = ["-O", "extents"]
-    partedSystem = fileSystemType["ext3"]
-
-    def _isMigratable(self):
-        """ Can filesystems of this type be migrated? """
-        return (flags.cmdline.has_key("ext4migrate") and
-                Ext2FS._isMigratable(self))
-
-    migratable = property(_isMigratable)
-
-register_device_format(Ext3FS)
-
-
-class Ext4FS(Ext3FS):
-    """ ext4 filesystem. """
-    _type = "ext4"
-    _defaultFormatOptions = ["-t", "ext4"]
-    _migratable = False
-    _modules = ["ext4"]
-    partedSystem = fileSystemType["ext4"]
-
-register_device_format(Ext4FS)
-
-
-class FATFS(FS):
-    """ FAT filesystem. """
-    _type = "vfat"
-    _mkfs = "mkdosfs"
-    _modules = ["vfat"]
-    _labelfs = "dosfslabel"
-    _fsck = "dosfsck"
-    _fsckErrors = {1: _("Recoverable errors have been detected or dosfsck has "
-                        "discovered an internal inconsistency."),
-                   2: _("Usage error.")}
-    _supported = True
-    _formattable = True
-    _maxSize = 1024 * 1024
-    _packages = [ "dosfstools" ]
-    _defaultMountOptions = ["umask=0077", "shortname=winnt"]
-    # FIXME this should be fat32 in some cases
-    partedSystem = fileSystemType["fat16"]
-
-    def _fsckFailed(self, rc):
-        if rc >= 1:
-            return True
-        return False
-
-    def _fsckErrorMessage(self, rc):
-        return self._fsckErrors[rc]
-
-register_device_format(FATFS)
-
-
-class EFIFS(FATFS):
-    _type = "efi"
-    _mountType = "vfat"
-    _modules = ["vfat"]
-    _name = "EFI System Partition"
-    _minSize = 50
-    _maxSize = 256
-    _bootable = True
-
-    @property
-    def supported(self):
-        import platform
-        p = platform.getPlatform(None)
-        return (isinstance(p, platform.EFI) and
-                p.isEfi and
-                self.utilsAvailable)
-
-register_device_format(EFIFS)
-
-
-class BTRFS(FS):
-    """ btrfs filesystem """
-    _type = "btrfs"
-    _mkfs = "mkfs.btrfs"
-    _modules = ["btrfs"]
-    _resizefs = "btrfsctl"
-    _formattable = True
-    _linuxNative = True
-    _bootable = False
-    _maxLabelChars = 256
-    _supported = False
-    _dump = True
-    _check = True
-    _packages = ["btrfs-progs"]
-    _maxSize = 16 * 1024 * 1024
-    # FIXME parted needs to be thaught about btrfs so that we can set the
-    # partition table type correctly for btrfs partitions
-    # partedSystem = fileSystemType["btrfs"]
-
-    def _getFormatOptions(self, options=None):
-        argv = []
-        if options and isinstance(options, list):
-            argv.extend(options)
-        argv.extend(self.defaultFormatOptions)
-        if self.label:
-            argv.extend(["-L", self.label])
-        argv.append(self.device)
-        return argv
-
-    @property
-    def resizeArgs(self):
-        argv = ["-r", "%dm" % (self.targetSize,), self.device]
-        return argv
-
-    @property
-    def supported(self):
-        """ Is this filesystem a supported type? """
-        supported = self._supported
-        if flags.cmdline.has_key("btrfs"):
-            supported = self.utilsAvailable
-
-        return supported
-
-register_device_format(BTRFS)
-
-
-class GFS2(FS):
-    """ gfs2 filesystem. """
-    _type = "gfs2"
-    _mkfs = "mkfs.gfs2"
-    _modules = ["dlm", "gfs2"]
-    _formattable = True
-    _defaultFormatOptions = ["-j", "1", "-p", "lock_nolock", "-O"]
-    _linuxNative = True
-    _supported = False
-    _dump = True
-    _check = True
-    _packages = ["gfs2-utils"]
-    # FIXME parted needs to be thaught about btrfs so that we can set the
-    # partition table type correctly for btrfs partitions
-    # partedSystem = fileSystemType["gfs2"]
-
-    @property
-    def supported(self):
-        """ Is this filesystem a supported type? """
-        supported = self._supported
-        if flags.cmdline.has_key("gfs2"):
-            supported = self.utilsAvailable
-
-        return supported
-
-register_device_format(GFS2)
-
-
-class JFS(FS):
-    """ JFS filesystem """
-    _type = "jfs"
-    _mkfs = "mkfs.jfs"
-    _modules = ["jfs"]
-    _labelfs = "jfs_tune"
-    _defaultFormatOptions = ["-q"]
-    _defaultLabelOptions = ["-L"]
-    _maxLabelChars = 16
-    _maxSize = 8 * 1024 * 1024
-    _formattable = True
-    _linuxNative = True
-    _supported = False
-    _dump = True
-    _check = True
-    _infofs = "jfs_tune"
-    _defaultInfoOptions = ["-l"]
-    _existingSizeFields = ["Aggregate block size:", "Aggregate size:"]
-    partedSystem = fileSystemType["jfs"]
-
-    @property
-    def supported(self):
-        """ Is this filesystem a supported type? """
-        supported = self._supported
-        if flags.cmdline.has_key("jfs"):
-            supported = self.utilsAvailable
-
-        return supported
-
-register_device_format(JFS)
-
-
-class ReiserFS(FS):
-    """ reiserfs filesystem """
-    _type = "reiserfs"
-    _mkfs = "mkreiserfs"
-    _resizefs = "resize_reiserfs"
-    _labelfs = "reiserfstune"
-    _modules = ["reiserfs"]
-    _defaultFormatOptions = ["-f", "-f"]
-    _defaultLabelOptions = ["-l"]
-    _maxLabelChars = 16
-    _maxSize = 16 * 1024 * 1024
-    _formattable = True
-    _linuxNative = True
-    _supported = False
-    _dump = True
-    _check = True
-    _packages = ["reiserfs-utils"]
-    _infofs = "debugreiserfs"
-    _defaultInfoOptions = []
-    _existingSizeFields = ["Count of blocks on the device:", "Blocksize:"]
-    partedSystem = fileSystemType["reiserfs"]
-
-    @property
-    def supported(self):
-        """ Is this filesystem a supported type? """
-        supported = self._supported
-        if flags.cmdline.has_key("reiserfs"):
-            supported = self.utilsAvailable
-
-        return supported
-
-    @property
-    def resizeArgs(self):
-        argv = ["-s", "%dM" % (self.targetSize,), self.device]
-        return argv
-
-register_device_format(ReiserFS)
-
-
-class XFS(FS):
-    """ XFS filesystem """
-    _type = "xfs"
-    _mkfs = "mkfs.xfs"
-    _modules = ["xfs"]
-    _labelfs = "xfs_admin"
-    _defaultFormatOptions = ["-f"]
-    _defaultLabelOptions = ["-L"]
-    _maxLabelChars = 16
-    _maxSize = 16 * 1024 * 1024
-    _formattable = True
-    _linuxNative = True
-    _supported = True
-    _dump = True
-    _check = True
-    _packages = ["xfsprogs"]
-    _infofs = "xfs_db"
-    _defaultInfoOptions = ["-c", "\"sb 0\"", "-c", "\"p dblocks\"",
-                           "-c", "\"p blocksize\""]
-    _existingSizeFields = ["dblocks =", "blocksize ="]
-    partedSystem = fileSystemType["xfs"]
-
-    def _getLabelArgs(self, label):
-        argv = []
-        argv.extend(self.defaultLabelOptions)
-        argv.extend([label, self.device])
-        return argv
-
-register_device_format(XFS)
-
-
-class HFS(FS):
-    _type = "hfs"
-    _mkfs = "hformat"
-    _modules = ["hfs"]
-    _formattable = True
-    partedSystem = fileSystemType["hfs"]
-
-register_device_format(HFS)
-
-
-class AppleBootstrapFS(HFS):
-    _type = "appleboot"
-    _mountType = "hfs"
-    _name = "Apple Bootstrap"
-    _bootable = True
-    _minSize = 800.00 / 1024.00
-    _maxSize = 1
-
-    @property
-    def supported(self):
-        import platform
-        return (isinstance(platform.getPlatform(None), platform.NewWorldPPC)
-                and self.utilsAvailable)
-
-    def writeKS(self, f):
-        f.write("appleboot --fstype=%s" % self.type)
-
-register_device_format(AppleBootstrapFS)
-
-
-# this doesn't need to be here
-class HFSPlus(FS):
-    _type = "hfs+"
-    _modules = ["hfsplus"]
-    _udevTypes = ["hfsplus"]
-    partedSystem = fileSystemType["hfs+"]
-
-register_device_format(HFSPlus)
-
-
-class NTFS(FS):
-    """ ntfs filesystem. """
-    _type = "ntfs"
-    _resizefs = "ntfsresize"
-    _fsck = "ntfsresize"
-    _resizable = True
-    _minSize = 1
-    _maxSize = 16 * 1024 * 1024
-    _defaultMountOptions = ["defaults", "ro"]
-    _defaultCheckOptions = ["-c"]
-    _packages = ["ntfsprogs"]
-    _infofs = "ntfsinfo"
-    _defaultInfoOptions = ["-m"]
-    _existingSizeFields = ["Cluster Size:", "Volume Size in Clusters:"]
-    partedSystem = fileSystemType["ntfs"]
-
-    def _fsckFailed(self, rc):
-        if rc != 0:
-            return True
-        return False
-
-    @property
-    def minSize(self):
-        """ The minimum filesystem size in megabytes. """
-        if self._minInstanceSize is None:
-            # we try one time to determine the minimum size.
-            size = self._minSize
-            if self.exists and os.path.exists(self.device):
-                minSize = None
-                buf = iutil.execWithCapture(self.resizefsProg,
-                                            ["-m", self.device],
-                                            stderr = "/dev/tty5")
-                for l in buf.split("\n"):
-                    if not l.startswith("Minsize"):
-                        continue
-                    try:
-                        min = l.split(":")[1].strip()
-                        minSize = int(min) + 250
-                    except Exception, e:
-                        minSize = None
-                        log.warning("Unable to parse output for minimum size on %s: %s" %(self.device, e))
-
-                if minSize is None:
-                    log.warning("Unable to discover minimum size of filesystem "
-                                "on %s" %(self.device,))
-                else:
-                    size = minSize
-
-            self._minInstanceSize = size
-
-        return self._minInstanceSize
-
-    @property
-    def resizeArgs(self):
-        # You must supply at least two '-f' options to ntfsresize or
-        # the proceed question will be presented to you.
-        argv = ["-ff", "-s", "%dM" % (self.targetSize,), self.device]
-        return argv
-
-
-register_device_format(NTFS)
-
-
-# if this isn't going to be mountable it might as well not be here
-class NFS(FS):
-    """ NFS filesystem. """
-    _type = "nfs"
-    _modules = ["nfs"]
-
-    def _deviceCheck(self, devspec):
-        if devspec is not None and ":" not in devspec:
-            raise ValueError("device must be of the form <host>:<path>")
-
-    @property
-    def mountable(self):
-        return False
-
-    def _setDevice(self, devspec):
-        self._deviceCheck(devspec)
-        self._device = devspec
-
-    def _getDevice(self):
-        return self._device
-
-    device = property(lambda f: f._getDevice(),
-                      lambda f,d: f._setDevice(d),
-                      doc="Full path the device this format occupies")
- 
-register_device_format(NFS)
-
-
-class NFSv4(NFS):
-    """ NFSv4 filesystem. """
-    _type = "nfs4"
-    _modules = ["nfs4"]
-
-register_device_format(NFSv4)
-
-
-class Iso9660FS(FS):
-    """ ISO9660 filesystem. """
-    _type = "iso9660"
-    _formattable = False
-    _supported = True
-    _resizable = False
-    _bootable = False
-    _linuxNative = False
-    _dump = False
-    _check = False
-    _migratable = False
-    _defaultMountOptions = ["ro"]
-
-    def writeKS(self, f):
-        return
-
-register_device_format(Iso9660FS)
-
-
-class NoDevFS(FS):
-    """ nodev filesystem base class """
-    _type = "nodev"
-
-    def __init__(self, *args, **kwargs):
-        FS.__init__(self, *args, **kwargs)
-        self.exists = True
-        self.device = self.type
-
-    def _setDevice(self, devspec):
-        self._device = devspec
-
-    def _getExistingSize(self):
-        pass
-
-    def writeKS(self, f):
-        return
-
-register_device_format(NoDevFS)
-
-
-class DevPtsFS(NoDevFS):
-    """ devpts filesystem. """
-    _type = "devpts"
-    _defaultMountOptions = ["gid=5", "mode=620"]
-
-register_device_format(DevPtsFS)
-
-
-# these don't really need to be here
-class ProcFS(NoDevFS):
-    _type = "proc"
-
-register_device_format(ProcFS)
-
-
-class SysFS(NoDevFS):
-    _type = "sysfs"
-
-register_device_format(SysFS)
-
-
-class TmpFS(NoDevFS):
-    _type = "tmpfs"
-
-register_device_format(TmpFS)
-
-
-class BindFS(FS):
-    _type = "bind"
-
-    @property
-    def mountable(self):
-        return True
-
-    def _getExistingSize(self):
-        pass
-
-    def writeKS(self, f):
-        return
-
-register_device_format(BindFS)
-
-
diff --git a/storage/formats/luks.py b/storage/formats/luks.py
deleted file mode 100644
index b164f14..0000000
--- a/storage/formats/luks.py
+++ /dev/null
@@ -1,352 +0,0 @@
-# luks.py
-# Device format classes for anaconda's storage configuration module.
-#
-# Copyright (C) 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, or (at your option) any later version.
-# 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.
-#
-# Red Hat Author(s): Dave Lehman <dlehman@xxxxxxxxxx>
-#
-
-
-
-import os
-
-try:
-    import volume_key
-except ImportError:
-    volume_key = None
-
-from ..storage_log import log_method_call
-from ..errors import *
-from ..devicelibs import crypto
-from . import DeviceFormat, register_device_format
-
-import gettext
-_ = lambda x: gettext.ldgettext("anaconda", x)
-
-import logging
-log = logging.getLogger("storage")
-
-
-class LUKS(DeviceFormat):
-    """ A LUKS device. """
-    _type = "luks"
-    _name = "LUKS"
-    _lockedName = _("Encrypted")
-    _udevTypes = ["crypto_LUKS"]
-    _formattable = True                 # can be formatted
-    _supported = False                  # is supported
-    _linuxNative = True                 # for clearpart
-    _packages = ["cryptsetup-luks"]     # required packages
-
-    def __init__(self, *args, **kwargs):
-        """ Create a LUKS instance.
-
-            Keyword Arguments:
-
-                device -- the path to the underlying device
-                name -- the name of the mapped device
-                uuid -- this device's UUID
-                passphrase -- device passphrase (string)
-                key_file -- path to a file containing a key (string)
-                cipher -- cipher mode string
-                key_size -- key size in bits
-                exists -- indicates whether this is an existing format
-                escrow_cert -- certificate to use for key escrow
-                add_backup_passphrase -- generate a backup passphrase?
-        """
-        log_method_call(self, *args, **kwargs)
-        DeviceFormat.__init__(self, *args, **kwargs)
-        self.cipher = kwargs.get("cipher")
-        self.key_size = kwargs.get("key_size")
-        self.mapName = kwargs.get("name")
-
-        if not self.exists and not self.cipher:
-            self.cipher = "aes-xts-plain"
-            if not self.key_size:
-                # default to the max (512 bits) for aes-xts
-                self.key_size = 512
-
-        # FIXME: these should both be lists, but managing them will be a pain
-        self.__passphrase = kwargs.get("passphrase")
-        self._key_file = kwargs.get("key_file")
-        self.escrow_cert = kwargs.get("escrow_cert")
-        self.add_backup_passphrase = kwargs.get("add_backup_passphrase", False)
-
-        if not self.mapName and self.exists and self.uuid:
-            self.mapName = "luks-%s" % self.uuid
-        elif not self.mapName and self.device:
-            self.mapName = "luks-%s" % os.path.basename(self.device)
-
-    def __str__(self):
-        s = DeviceFormat.__str__(self)
-        if self.__passphrase:
-            passphrase = "(set)"
-        else:
-            passphrase = "(not set)"
-        s += ("  cipher = %(cipher)s  keySize = %(keySize)s"
-              "  mapName = %(mapName)s\n"
-              "  keyFile = %(keyFile)s  passphrase = %(passphrase)s\n"
-              "  escrowCert = %(escrowCert)s  addBackup = %(backup)s" %
-              {"cipher": self.cipher, "keySize": self.key_size,
-               "mapName": self.mapName, "keyFile": self._key_file,
-               "passphrase": passphrase, "escrowCert": self.escrow_cert,
-               "backup": self.add_backup_passphrase})
-        return s
-
-    @property
-    def dict(self):
-        d = super(LUKS, self).dict
-        d.update({"cipher": self.cipher, "keySize": self.key_size,
-                  "mapName": self.mapName, "hasKey": self.hasKey,
-                  "escrowCert": self.escrow_cert,
-                  "backup": self.add_backup_passphrase})
-        return d
-
-    @property
-    def name(self):
-        name = self._name
-        # for existing locked devices, show "Encrypted" instead of LUKS
-        if self.hasKey or not self.exists:
-            name = self._name
-        else:
-            name = "%s (%s)" % (self._lockedName, self._name)
-        return name
-
-    def _setPassphrase(self, passphrase):
-        """ Set the passphrase used to access this device. """
-        self.__passphrase = passphrase
-
-    passphrase = property(fset=_setPassphrase)
-
-    @property
-    def hasKey(self):
-        return ((self.__passphrase not in ["", None]) or
-                (self._key_file and os.access(self._key_file, os.R_OK)))
-
-    @property
-    def configured(self):
-        """ To be ready we need a key or passphrase and a map name. """
-        return self.hasKey and self.mapName
-
-    @property
-    def status(self):
-        if not self.exists or not self.mapName:
-            return False
-        return os.path.exists("/dev/mapper/%s" % self.mapName)
-
-    def probe(self):
-        """ Probe for any missing information about this format.
-
-            cipher mode, key size
-        """
-        raise NotImplementedError("probe method not defined for LUKS")
-
-    def setup(self, *args, **kwargs):
-        """ Open, or set up, the format. """
-        log_method_call(self, device=self.device, mapName=self.mapName,
-                        type=self.type, status=self.status)
-        if not self.configured:
-            raise LUKSError("luks device not configured")
-
-        if self.status:
-            return
-
-        DeviceFormat.setup(self, *args, **kwargs)
-        crypto.luks_open(self.device, self.mapName,
-                       passphrase=self.__passphrase,
-                       key_file=self._key_file)
-
-    def teardown(self, *args, **kwargs):
-        """ Close, or tear down, the format. """
-        log_method_call(self, device=self.device,
-                        type=self.type, status=self.status)
-        if not self.exists:
-            raise LUKSError("format has not been created")
-
-        if self.status:
-            log.debug("unmapping %s" % self.mapName)
-            crypto.luks_close(self.mapName)
-
-    def create(self, *args, **kwargs):
-        """ Create the format. """
-        log_method_call(self, device=self.device,
-                        type=self.type, status=self.status)
-        if not self.hasKey:
-            raise LUKSError("luks device has no key/passphrase")
-
-        intf = kwargs.get("intf")
-        w = None
-        if intf:
-            w = intf.waitWindow(_("Formatting"),
-                                _("Encrypting %s") % kwargs.get("device",
-                                                                self.device))
-
-        try:
-            DeviceFormat.create(self, *args, **kwargs)
-            crypto.luks_format(self.device,
-                             passphrase=self.__passphrase,
-                             key_file=self._key_file,
-                             cipher=self.cipher,
-                             key_size=self.key_size)
-        except Exception:
-            raise
-        else:
-            self.uuid = crypto.luks_uuid(self.device)
-            self.exists = True
-            self.mapName = "luks-%s" % self.uuid
-            self.notifyKernel()
-        finally:
-            if w:
-                w.pop()
-
-    def destroy(self, *args, **kwargs):
-        """ Create the format. """
-        log_method_call(self, device=self.device,
-                        type=self.type, status=self.status)
-        self.teardown()
-        DeviceFormat.destroy(self, *args, **kwargs)
-
-    @property
-    def keyFile(self):
-        """ Path to key file to be used in /etc/crypttab """
-        return self._key_file
-
-    def addKeyFromFile(self, keyfile):
-        """ Add a new key from a file.
-
-            Add the contents of the specified key file to an available key
-            slot in the LUKS header.
-        """
-        log_method_call(self, device=self.device,
-                        type=self.type, status=self.status, file=keyfile)
-        if not self.exists:
-            raise LUKSError("format has not been created")
-
-        crypto.luks_add_key(self.device,
-                          passphrase=self.__passphrase,
-                          key_file=self._key_file,
-                          new_key_file=keyfile)
-
-    def addPassphrase(self, passphrase):
-        """ Add a new passphrase.
-
-            Add the specified passphrase to an available key slot in the
-            LUKS header.
-        """
-        log_method_call(self, device=self.device,
-                        type=self.type, status=self.status)
-        if not self.exists:
-            raise LUKSError("format has not been created")
-
-        crypto.luks_add_key(self.device,
-                          passphrase=self.__passphrase,
-                          key_file=self._key_file,
-                          new_passphrase=passphrase)
-
-    def removeKeyFromFile(self, keyfile):
-        """ Remove a key contained in a file.
-
-            Remove key contained in the specified key file from the LUKS
-            header.
-        """
-        log_method_call(self, device=self.device,
-                        type=self.type, status=self.status, file=keyfile)
-        if not self.exists:
-            raise LUKSError("format has not been created")
-
-        crypto.luks_remove_key(self.device,
-                             passphrase=self.__passphrase,
-                             key_file=self._key_file,
-                             del_key_file=keyfile)
-
-
-    def removePassphrase(self, passphrase):
-        """ Remove the specified passphrase from the LUKS header. """
-        log_method_call(self, device=self.device,
-                        type=self.type, status=self.status)
-        if not self.exists:
-            raise LUKSError("format has not been created")
-
-        crypto.luks_remove_key(self.device,
-                             passphrase=self.__passphrase,
-                             key_file=self._key_file,
-                             del_passphrase=passphrase)
-
-    def _escrowVolumeIdent(self, vol):
-        """ Return an escrow packet filename prefix for a volume_key.Volume. """
-        label = vol.label
-        if label is not None:
-            label = label.replace("/", "_")
-        uuid = vol.uuid
-        if uuid is not None:
-            uuid = uuid.replace("/", "_")
-        # uuid is never None on LUKS volumes
-        if label is not None and uuid is not None:
-            volume_ident = "%s-%s" % (label, uuid)
-        elif uuid is not None:
-            volume_ident = uuid
-        elif label is not None:
-            volume_ident = label
-        else:
-            volume_ident = "_unknown"
-        return volume_ident
-
-    def escrow(self, directory, backupPassphrase):
-        log.debug("escrow: escrowVolume start for %s" % self.device)
-        if volume_key is None:
-            raise LUKSError("Missing key escrow support libraries")
-
-        vol = volume_key.Volume.open(self.device)
-        volume_ident = self._escrowVolumeIdent(vol)
-
-        ui = volume_key.UI()
-        # This callback is not expected to be used, let it always fail
-        ui.generic_cb = lambda unused_prompt, unused_echo: None
-        def known_passphrase_cb(unused_prompt, failed_attempts):
-            if failed_attempts == 0:
-                return self.__passphrase
-            return None
-        ui.passphrase_cb = known_passphrase_cb
-
-        log.debug("escrow: getting secret")
-        vol.get_secret(volume_key.SECRET_DEFAULT, ui)
-        log.debug("escrow: creating packet")
-        default_packet = vol.create_packet_assymetric_from_cert_data \
-            (volume_key.SECRET_DEFAULT, self.escrow_cert, ui)
-        log.debug("escrow: packet created")
-        with open("%s/%s-escrow" % (directory, volume_ident), "wb") as f:
-            f.write(default_packet)
-        log.debug("escrow: packet written")
-
-        if self.add_backup_passphrase:
-            log.debug("escrow: adding backup passphrase")
-            vol.add_secret(volume_key.SECRET_PASSPHRASE, backupPassphrase)
-            log.debug("escrow: creating backup packet")
-            backup_passphrase_packet = \
-                vol.create_packet_assymetric_from_cert_data \
-                (volume_key.SECRET_PASSPHRASE, self.escrow_cert, ui)
-            log.debug("escrow: backup packet created")
-            with open("%s/%s-escrow-backup-passphrase" %
-                      (directory, volume_ident), "wb") as f:
-                f.write(backup_passphrase_packet)
-            log.debug("escrow: backup packet written")
-
-        log.debug("escrow: escrowVolume done for %s" % repr(self.device))
-
-
-register_device_format(LUKS)
-
diff --git a/storage/formats/lvmpv.py b/storage/formats/lvmpv.py
deleted file mode 100644
index 9fe9ba3..0000000
--- a/storage/formats/lvmpv.py
+++ /dev/null
@@ -1,156 +0,0 @@
-# lvmpv.py
-# Device format classes for anaconda's storage configuration module.
-#
-# Copyright (C) 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, or (at your option) any later version.
-# 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.
-#
-# Red Hat Author(s): Dave Lehman <dlehman@xxxxxxxxxx>
-#
-
-import os
-
-from ..storage_log import log_method_call
-from parted import PARTITION_LVM
-from ..errors import *
-from ..devicelibs import lvm
-from . import DeviceFormat, register_device_format
-
-import gettext
-_ = lambda x: gettext.ldgettext("anaconda", x)
-
-import logging
-log = logging.getLogger("storage")
-
-
-class LVMPhysicalVolume(DeviceFormat):
-    """ An LVM physical volume. """
-    _type = "lvmpv"
-    _name = "physical volume (LVM)"
-    _udevTypes = ["LVM2_member"]
-    partedFlag = PARTITION_LVM
-    _formattable = True                 # can be formatted
-    _supported = True                   # is supported
-    _linuxNative = True                 # for clearpart
-    _packages = ["lvm2"]                # required packages
-
-    def __init__(self, *args, **kwargs):
-        """ Create an LVMPhysicalVolume instance.
-
-            Keyword Arguments:
-
-                device -- path to the underlying device
-                uuid -- this PV's uuid (not the VG uuid)
-                vgName -- the name of the VG this PV belongs to
-                vgUuid -- the UUID of the VG this PV belongs to
-                peStart -- offset of first physical extent
-                exists -- indicates whether this is an existing format
-
-        """
-        log_method_call(self, *args, **kwargs)
-        DeviceFormat.__init__(self, *args, **kwargs)
-        self.vgName = kwargs.get("vgName")
-        self.vgUuid = kwargs.get("vgUuid")
-        # liblvm may be able to tell us this at some point, even
-        # for not-yet-created devices
-        self.peStart = kwargs.get("peStart", 0.1875)    # in MB
-
-    def __str__(self):
-        s = DeviceFormat.__str__(self)
-        s += ("  vgName = %(vgName)s  vgUUID = %(vgUUID)s"
-              "  peStart = %(peStart)s" %
-              {"vgName": self.vgName, "vgUUID": self.vgUuid,
-               "peStart": self.peStart})
-        return s
-
-    @property
-    def dict(self):
-        d = super(LVMPhysicalVolume, self).dict
-        d.update({"vgName": self.vgName, "vgUUID": self.vgUuid,
-                  "peStart": self.peStart})
-        return d
-
-    def probe(self):
-        """ Probe for any missing information about this device. """
-        log_method_call(self, device=self.device,
-                        type=self.type, status=self.status)
-        if not self.exists:
-            raise PhysicalVolumeError("format has not been created")
-
-        #info = lvm.pvinfo(self.device)
-        #self.vgName = info['vg_name']
-        #self.vgUuid = info['vg_uuid']
-
-    def create(self, *args, **kwargs):
-        """ Create the format. """
-        log_method_call(self, device=self.device,
-                        type=self.type, status=self.status)
-        intf = kwargs.get("intf")
-        w = None
-        if intf:
-            w = intf.progressWindow(_("Formatting"),
-                                    _("Creating %s on %s")
-                                    % (self.name, self.device),
-                                    100, pulse = True)
-
-        try:
-            DeviceFormat.create(self, *args, **kwargs)
-            # Consider use of -Z|--zero
-            # -f|--force or -y|--yes may be required
-
-            # lvm has issues with persistence of metadata, so here comes the
-            # hammer...
-            DeviceFormat.destroy(self, *args, **kwargs)
-
-            lvm.pvcreate(self.device, progress=w)
-        except Exception:
-            raise
-        else:
-            self.exists = True
-            self.notifyKernel()
-        finally:
-            if w:
-                w.pop()
-
-    def destroy(self, *args, **kwargs):
-        """ Destroy the format. """
-        log_method_call(self, device=self.device,
-                        type=self.type, status=self.status)
-        if not self.exists:
-            raise PhysicalVolumeError("format has not been created")
-
-        if self.status:
-            raise PhysicalVolumeError("device is active")
-
-        # FIXME: verify path exists?
-        try:
-            lvm.pvremove(self.device)
-        except LVMError:
-            DeviceFormat.destroy(self, *args, **kwargs)
-
-        self.exists = False
-        self.notifyKernel()
-
-    @property
-    def status(self):
-        # XXX hack
-        return (self.exists and self.vgName and
-                os.path.isdir("/dev/mapper/%s" % self.vgName))
-
-    def writeKS(self, f):
-        f.write("pv.%s" % self.uuid)
-
-register_device_format(LVMPhysicalVolume)
-
diff --git a/storage/formats/mdraid.py b/storage/formats/mdraid.py
deleted file mode 100644
index d153807..0000000
--- a/storage/formats/mdraid.py
+++ /dev/null
@@ -1,124 +0,0 @@
-# mdraid.py
-# Device format classes for anaconda's storage configuration module.
-#
-# Copyright (C) 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, or (at your option) any later version.
-# 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.
-#
-# Red Hat Author(s): Dave Lehman <dlehman@xxxxxxxxxx>
-#
-
-import os
-
-from ..storage_log import log_method_call
-from flags import flags
-from parted import PARTITION_RAID
-from ..errors import *
-from ..devicelibs import mdraid
-from . import DeviceFormat, register_device_format
-
-import gettext
-_ = lambda x: gettext.ldgettext("anaconda", x)
-
-import logging
-log = logging.getLogger("storage")
-
-
-class MDRaidMember(DeviceFormat):
-    """ An mdraid member disk. """
-    _type = "mdmember"
-    _name = "software RAID"
-    _udevTypes = ["linux_raid_member"]
-    partedFlag = PARTITION_RAID
-    _formattable = True                 # can be formatted
-    _supported = True                   # is supported
-    _linuxNative = True                 # for clearpart
-    _packages = ["mdadm"]               # required packages
-    
-    def __init__(self, *args, **kwargs):
-        """ Create a MDRaidMember instance.
-
-            Keyword Arguments:
-
-                device -- path to underlying device
-                uuid -- this member device's uuid
-                mdUuid -- the uuid of the array this device belongs to
-                exists -- indicates whether this is an existing format
-
-        """
-        log_method_call(self, *args, **kwargs)
-        DeviceFormat.__init__(self, *args, **kwargs)
-        self.mdUuid = kwargs.get("mdUuid")
-        self.raidMinor = None
-
-        #self.probe()
-        self.biosraid = False
-
-    def __str__(self):
-        s = DeviceFormat.__str__(self)
-        s += ("  mdUUID = %(mdUUID)s  biosraid = %(biosraid)s" %
-              {"mdUUID": self.mdUuid, "biosraid": self.biosraid})
-        return s
-
-    @property
-    def dict(self):
-        d = super(MDRaidMember, self).dict
-        d.update({"mdUUID": self.mdUuid, "biosraid": self.biosraid})
-        return d
-
-    def probe(self):
-        """ Probe for any missing information about this format. """
-        log_method_call(self, device=self.device,
-                        type=self.type, status=self.status)
-        if not self.exists:
-            raise MDMemberError("format does not exist")
-
-        info = mdraid.mdexamine(self.device)
-        if self.uuid is None:
-            self.uuid = info['uuid']
-        if self.raidMinor is None:
-            self.raidMinor = info['mdMinor']
-
-    def destroy(self, *args, **kwargs):
-        if not self.exists:
-            raise MDMemberError("format does not exist")
-
-        if not os.access(self.device, os.W_OK):
-            raise MDMemberError("device path does not exist")
-
-        mdraid.mddestroy(self.device)
-        self.exists = False
-
-    @property
-    def status(self):
-        # XXX hack -- we don't have a nice way to see if the array is active
-        return False
-
-    @property
-    def hidden(self):
-        return (self._hidden or self.biosraid)
-
-    def writeKS(self, f):
-        f.write("raid.%s" % self.mdUuid)
-
-# nodmraid -> Wether to use BIOS RAID or not
-# Note the anaconda cmdline has not been parsed yet when we're first imported,
-# so we can not use flags.dmraid here
-if not flags.cmdline.has_key("noiswmd") and \
-   not flags.cmdline.has_key("nodmraid"):
-    MDRaidMember._udevTypes.append("isw_raid_member")
-
-register_device_format(MDRaidMember)
-
diff --git a/storage/formats/multipath.py b/storage/formats/multipath.py
deleted file mode 100644
index 86c05d6..0000000
--- a/storage/formats/multipath.py
+++ /dev/null
@@ -1,95 +0,0 @@
-# multipath.py
-# multipath device formats
-#
-# Copyright (C) 2009  Red Hat, 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; either version 2 of the License, or
-# (at your option) any later version.
-#
-# 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, see <http://www.gnu.org/licenses/>.
-#
-# 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.
-#
-# Red Hat Author(s): Peter Jones <pjones@xxxxxxxxxx>
-#
-
-from ..storage_log import log_method_call
-from ..errors import *
-from . import DeviceFormat, register_device_format
-
-import gettext
-_ = lambda x: gettext.ldgettext("anaconda", x)
-
-import logging
-log = logging.getLogger("storage")
-
-class MultipathMember(DeviceFormat):
-    """ A multipath member disk. """
-    _type = "multipath_member"
-    _name = "multipath member device"
-    _udev_types = ["multipath_member"]
-    _formattable = False                # can be formatted
-    _supported = True                   # is supported
-    _linuxNative = False                # for clearpart
-    _packages = ["device-mapper-multipath"] # required packages
-    _resizable = False                  # can be resized
-    _bootable = False                   # can be used as boot
-    _maxSize = 0                        # maximum size in MB
-    _minSize = 0                        # minimum size in MB
-    _hidden = True                      # hide devices with this formatting?
-
-    def __init__(self, *args, **kwargs):
-        """ Create a DeviceFormat instance.
-
-            Keyword Arguments:
-
-                device -- path to the underlying device
-                uuid -- this format's UUID
-                exists -- indicates whether this is an existing format
-
-            On initialization this format is like DeviceFormat
-
-        """
-        log_method_call(self, *args, **kwargs)
-        DeviceFormat.__init__(self, *args, **kwargs)
-
-        # Initialize the attribute that will hold the block object.
-        self._member = None
-
-    def __str__(self):
-        s = DeviceFormat.__str__(self)
-        s += ("  member = %(member)r" % {"member": self.member})
-        return s
-
-    def _getMember(self):
-        return self._member
-
-    def _setMember(self, member):
-        self._member = member
-
-    member = property(lambda s: s._getMember(),
-                      lambda s,m: s._setMember(m))
-
-    def create(self, *args, **kwargs):
-        log_method_call(self, device=self.device,
-                        type=self.type, status=self.status)
-        raise MultipathMemberError("creation of multipath members is non-sense")
-
-    def destroy(self, *args, **kwargs):
-        log_method_call(self, device=self.device,
-                        type=self.type, status=self.status)
-        raise MultipathMemberError("destruction of multipath members is non-sense")
-
-register_device_format(MultipathMember)
-
diff --git a/storage/formats/prepboot.py b/storage/formats/prepboot.py
deleted file mode 100644
index 2191b81..0000000
--- a/storage/formats/prepboot.py
+++ /dev/null
@@ -1,64 +0,0 @@
-# prepboot.py
-# Format class for PPC PReP Boot.
-#
-# Copyright (C) 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, or (at your option) any later version.
-# 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.
-#
-# Red Hat Author(s): Dave Lehman <dlehman@xxxxxxxxxx>
-#
-
-from ..errors import *
-from . import DeviceFormat, register_device_format
-from parted import PARTITION_PREP
-
-class PPCPRePBoot(DeviceFormat):
-    """ Generic device format. """
-    _type = "prepboot"
-    _name = "PPC PReP Boot"
-    _udevTypes = []
-    partedFlag = PARTITION_PREP
-    _formattable = True                 # can be formatted
-    _linuxNative = True                 # for clearpart
-    _bootable = True                    # can be used as boot
-    _maxSize = 4                        # maximum size in MB
-    _minSize = 10                       # minimum size in MB
-
-    def __init__(self, *args, **kwargs):
-        """ Create a PRePBoot instance.
-
-            Keyword Arguments:
-
-                device -- path to the underlying device
-                exists -- indicates whether this is an existing format
-
-        """
-        DeviceFormat.__init__(self, *args, **kwargs)
-
-    @property
-    def status(self):
-        return False
-
-    @property
-    def supported(self):
-        import platform
-        return isinstance(platform.getPlatform(None), platform.IPSeriesPPC)
-
-    def writeKS(self, f):
-        f.write("prepboot --fstype=%s" % self.type)
-
-
-register_device_format(PPCPRePBoot)
-
diff --git a/storage/formats/swap.py b/storage/formats/swap.py
deleted file mode 100644
index 362f6d5..0000000
--- a/storage/formats/swap.py
+++ /dev/null
@@ -1,186 +0,0 @@
-# swap.py
-# Device format classes for anaconda's storage configuration module.
-#
-# Copyright (C) 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, or (at your option) any later version.
-# 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.
-#
-# Red Hat Author(s): Dave Lehman <dlehman@xxxxxxxxxx>
-#
-
-from iutil import numeric_type
-from parted import PARTITION_SWAP, fileSystemType
-from ..storage_log import log_method_call
-from ..errors import *
-from ..devicelibs import swap
-from . import DeviceFormat, register_device_format
-
-import gettext
-_ = lambda x: gettext.ldgettext("anaconda", x)
-
-import logging
-log = logging.getLogger("storage")
-
-
-class SwapSpace(DeviceFormat):
-    """ Swap space """
-    _type = "swap"
-    _name = None
-    _udevTypes = ["swap"]
-    partedFlag = PARTITION_SWAP
-    partedSystem = fileSystemType["linux-swap(v1)"]
-    _formattable = True                # can be formatted
-    _supported = True                  # is supported
-    _linuxNative = True                # for clearpart
-
-    def __init__(self, *args, **kwargs):
-        """ Create a SwapSpace instance.
-
-            Keyword Arguments:
-
-                device -- path to the underlying device
-                uuid -- this swap space's uuid
-                label -- this swap space's label
-                priority -- this swap space's priority
-                exists -- indicates whether this is an existing format
-
-        """
-        log_method_call(self, *args, **kwargs)
-        DeviceFormat.__init__(self, *args, **kwargs)
-
-        self.priority = kwargs.get("priority")
-        self.label = kwargs.get("label")
-
-    def __str__(self):
-        s = DeviceFormat.__str__(self)
-        s += ("  priority = %(priority)s  label = %(label)s" %
-              {"priority": self.priority, "label": self.label})
-        return s
-
-    @property
-    def dict(self):
-        d = super(SwapSpace, self).dict
-        d.update({"priority": self.priority, "label": self.label})
-        return d
-
-    def _setPriority(self, priority):
-        if priority is None:
-            self._priority = None
-            return
-
-        if not isinstance(priority, int) or not 0 <= priority <= 32767:
-            raise ValueError("swap priority must be an integer between 0 and 32767")
-
-        self._priority = priority
-
-    def _getPriority(self):
-        return self._priority
-
-    priority = property(_getPriority, _setPriority,
-                        doc="The priority of the swap device")
-
-    def _getOptions(self):
-        opts = ""
-        if self.priority is not None:
-            opts += "pri=%d" % self.priority
-
-        return opts
-
-    def _setOptions(self, opts):
-        if not opts:
-            self.priority = None
-            return
-
-        for option in opts.split(","):
-            (opt, equals, arg) = option.partition("=")
-            if equals and opt == "pri":
-                try:
-                    self.priority = int(arg)
-                except ValueError:
-                    log.info("invalid value for swap priority: %s" % arg)
-
-    options = property(_getOptions, _setOptions,
-                       doc="The swap device's fstab options string")
-
-    @property
-    def status(self):
-        """ Device status. """
-        return self.exists and swap.swapstatus(self.device)
-
-    def setup(self, *args, **kwargs):
-        """ Open, or set up, a device. """
-        log_method_call(self, device=self.device,
-                        type=self.type, status=self.status)
-        if not self.exists:
-            raise SwapSpaceError("format has not been created")
-
-        if self.status:
-            return
-
-        DeviceFormat.setup(self, *args, **kwargs)
-        swap.swapon(self.device, priority=self.priority)
-
-    def teardown(self, *args, **kwargs):
-        """ Close, or tear down, a device. """
-        log_method_call(self, device=self.device,
-                        type=self.type, status=self.status)
-        if not self.exists:
-            raise SwapSpaceError("format has not been created")
-
-        if self.status:
-            swap.swapoff(self.device)
-
-    def create(self, *args, **kwargs):
-        """ Create the device. """
-        log_method_call(self, device=self.device,
-                        type=self.type, status=self.status)
-        intf = kwargs.get("intf")
-        force = kwargs.get("force")
-        if not force and self.exists:
-            raise SwapSpaceError("format already exists")
-
-        if force:
-            self.teardown()
-        elif self.status:
-            raise SwapSpaceError("device exists and is active")
-
-        w = None
-        if intf:
-            w = intf.progressWindow(_("Formatting"),
-                                    _("Creating %s on %s")
-                                    % (self.type,
-                                       kwargs.get("device", self.device)),
-                                    100, pulse = True)
-
-        try:
-            DeviceFormat.create(self, *args, **kwargs)
-            swap.mkswap(self.device, label=self.label, progress=w)
-        except Exception:
-            raise
-        else:
-            self.exists = True
-        finally:
-            if w:
-                w.pop()
-
-    def writeKS(self, f):
-        f.write("swap")
-
-        if self.label:
-            f.write(" --label=\"%s\"" % self.label)
-
-
-register_device_format(SwapSpace)
-
diff --git a/storage/iscsi.py b/storage/iscsi.py
deleted file mode 100644
index 55caa17..0000000
--- a/storage/iscsi.py
+++ /dev/null
@@ -1,333 +0,0 @@
-#
-# iscsi.py - iscsi class
-#
-# Copyright (C) 2005, 2006  IBM, Inc.  All rights reserved.
-# Copyright (C) 2006  Red Hat, Inc.  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 as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# 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, see <http://www.gnu.org/licenses/>.
-#
-
-from constants import *
-from udev import *
-import os
-import iutil
-from flags import flags
-import logging
-import shutil
-import time
-import hashlib
-import random
-log = logging.getLogger("anaconda")
-
-import gettext
-_ = lambda x: gettext.ldgettext("anaconda", x)
-
-has_libiscsi = True
-try:
-    import libiscsi
-except ImportError:
-    has_libiscsi = False
-
-# Note that stage2 copies all files under /sbin to /usr/sbin
-ISCSID=""
-INITIATOR_FILE="/etc/iscsi/initiatorname.iscsi"
-
-def find_iscsi_files():
-    global ISCSID
-    if ISCSID == "":
-        for dir in ("/usr/sbin", "/tmp/updates", "/mnt/source/RHupdates"):
-            path="%s/iscsid" % (dir,)
-            if os.access(path, os.X_OK):
-                ISCSID=path
-
-def has_iscsi():
-    find_iscsi_files()
-    if ISCSID == "" or not has_libiscsi:
-        return False
-
-    log.info("ISCSID is %s" % (ISCSID,))
-
-    # make sure the module is loaded
-    if not os.access("/sys/module/iscsi_tcp", os.X_OK):
-        return False
-    return True
-
-def randomIname():
-    """Generate a random initiator name the same way as iscsi-iname"""
-    
-    s = "iqn.1994-05.com.fedora:01."
-    m = hashlib.md5()
-    u = os.uname()
-    for i in u:
-        m.update(i)
-    dig = m.hexdigest()
-    
-    for i in range(0, 6):
-        s += dig[random.randrange(0, 32)]
-    return s
-
-def stabilize(intf = None):
-    # Wait for udev to create the devices for the just added disks
-    if intf:
-        w = intf.waitWindow(_("Scanning iSCSI nodes"),
-                            _("Scanning iSCSI nodes"))
-    # It is possible when we get here the events for the new devices
-    # are not send yet, so sleep to make sure the events are fired
-    time.sleep(2)
-    udev_settle()
-    if intf:
-        w.pop()
-
-class iscsi(object):
-    """ iSCSI utility class.
-
-        This class will automatically discover and login to iBFT (or
-        other firmware) configured iscsi devices when the startup() method
-        gets called. It can also be used to manually configure iscsi devices
-        through the addTarget() method.
-
-        As this class needs to make sure certain things like starting iscsid
-        and logging in to firmware discovered disks only happens once 
-        and as it keeps a global list of all iSCSI devices it is implemented as
-        a Singleton.
-    """
-
-    def __init__(self):
-        # This list contains all nodes
-        self.nodes = []
-        # This list contains nodes discovered through iBFT (or other firmware)
-        self.ibftNodes = []
-        self._initiator = ""
-        self.initiatorSet = False
-        self.started = False
-
-        if flags.ibft:
-            try:
-                initiatorname = libiscsi.get_firmware_initiator_name()
-                self._initiator = initiatorname
-                self.initiatorSet = True
-            except:
-                pass
-
-    # So that users can write iscsi() to get the singleton instance
-    def __call__(self):
-        return self
-
-    def _getInitiator(self):
-        if self._initiator != "":
-            return self._initiator
-
-        return randomIname()
-
-    def _setInitiator(self, val):
-        if self.initiatorSet and val != self._initiator:
-            raise ValueError, "Unable to change iSCSI initiator name once set"
-        if len(val) == 0:
-            raise ValueError, "Must provide a non-zero length string"
-        self._initiator = val
-
-    initiator = property(_getInitiator, _setInitiator)
-
-    def _startIBFT(self, intf = None):
-        if not flags.ibft:
-            return
-
-        try:
-            found_nodes = libiscsi.discover_firmware()
-        except:
-            # an exception here means there is no ibft firmware, just return
-            return
-
-        for node in found_nodes:
-            try:
-                node.login()
-                log.info("iscsi._startIBFT logged in to %s %s %s" % (node.name, node.address, node.port))
-                self.nodes.append(node)
-                self.ibftNodes.append(node)
-            except IOError, e:
-                log.error("Could not log into ibft iscsi target %s: %s" %
-                          (node.name, str(e)))
-                pass
-
-        stabilize(intf)
-
-    def startup(self, intf = None):
-        if self.started:
-            return
-
-        if not has_iscsi():
-            return
-
-        if self._initiator == "":
-            log.info("no initiator set")
-            return
-
-        if intf:
-            w = intf.waitWindow(_("Initializing iSCSI initiator"),
-                                _("Initializing iSCSI initiator"))
-
-        log.debug("Setting up %s" % (INITIATOR_FILE, ))
-        log.info("iSCSI initiator name %s", self.initiator)
-        if os.path.exists(INITIATOR_FILE):
-            os.unlink(INITIATOR_FILE)
-        if not os.path.isdir("/etc/iscsi"):
-            os.makedirs("/etc/iscsi", 0755)
-        fd = os.open(INITIATOR_FILE, os.O_RDWR | os.O_CREAT)
-        os.write(fd, "InitiatorName=%s\n" %(self.initiator))
-        os.close(fd)
-        self.initiatorSet = True
-
-        for dir in ['ifaces','isns','nodes','send_targets','slp','static']:
-            fulldir = "/var/lib/iscsi/%s" % (dir,)
-            if not os.path.isdir(fulldir):
-                os.makedirs(fulldir, 0755)
-
-        log.info("iSCSI startup")
-        iutil.execWithRedirect(ISCSID, [],
-                               stdout="/dev/tty5", stderr="/dev/tty5")
-        time.sleep(1)
-
-        if intf:
-            w.pop()
-
-        self._startIBFT(intf)
-        self.started = True
-
-    def addTarget(self, ipaddr, port="3260", user=None, pw=None,
-                  user_in=None, pw_in=None, intf=None):
-        authinfo = None
-        found = 0
-        logged_in = 0
-
-        if not has_iscsi():
-            raise IOError, _("iSCSI not available")
-        if self._initiator == "":
-            raise ValueError, _("No initiator name set")
-
-        if user or pw or user_in or pw_in:
-            # Note may raise a ValueError
-            authinfo = libiscsi.chapAuthInfo(username=user, password=pw,
-                                             reverse_username=user_in,
-                                             reverse_password=pw_in)
-        self.startup(intf)
-
-        # Note may raise an IOError
-        found_nodes = libiscsi.discover_sendtargets(address=ipaddr,
-                                                    port=int(port),
-                                                    authinfo=authinfo)
-        if found_nodes == None:
-            raise IOError, _("No iSCSI nodes discovered")
-
-        if intf:
-            w = intf.waitWindow(_("Logging in to iSCSI nodes"),
-                                _("Logging in to iSCSI nodes"))
-
-        for node in found_nodes:
-            # skip nodes we already have
-            if node in self.nodes:
-                continue
-
-            found = found + 1
-            try:
-                if (authinfo):
-                    node.setAuth(authinfo)
-                node.login()
-                log.info("iscsi.addTarget logged in to %s %s %s" % (node.name, node.address, node.port))
-                self.nodes.append(node)
-                logged_in = logged_in + 1
-            except IOError, e:
-                log.warning(
-                    "Could not log into discovered iscsi target %s: %s" %
-                    (node.name, str(e)))
-                # some nodes may require different credentials
-                pass
-
-        if intf:
-            w.pop()
-
-        if found == 0:
-            raise IOError, _("No new iSCSI nodes discovered")
-
-        if logged_in == 0:
-            raise IOError, _("Could not log in to any of the discovered nodes")
-
-        stabilize(intf)
-
-    def writeKS(self, f):
-        if not self.initiatorSet:
-            return
-        f.write("iscsiname %s\n" %(self.initiator,))
-        for n in self.nodes:
-            f.write("iscsi --ipaddr %s --port %s" %(n.address, n.port))
-            auth = n.getAuth()
-            if auth:
-                f.write(" --user %s" % auth.username)
-                f.write(" --password %s" % auth.password)
-                if len(auth.reverse_username):
-                    f.write(" --reverse-user %s" % auth.reverse_username)
-                if len(auth.reverse_password):
-                    f.write(" --reverse-password %s" % auth.reverse_password)
-            f.write("\n")
-
-    def write(self, instPath, anaconda):
-        if not self.initiatorSet:
-            return
-
-        # set iscsi nodes to autostart
-        root = anaconda.storage.rootDevice
-        for node in self.nodes:
-            autostart = True
-            disks = self.getNodeDisks(node, anaconda.storage)
-            for disk in disks:
-                # nodes used for root get started by the initrd
-                if root.dependsOn(disk):
-                    autostart = False
-
-            if autostart:
-                node.setParameter("node.startup", "automatic")
-
-        if not os.path.isdir(instPath + "/etc/iscsi"):
-            os.makedirs(instPath + "/etc/iscsi", 0755)
-        fd = os.open(instPath + INITIATOR_FILE, os.O_RDWR | os.O_CREAT)
-        os.write(fd, "InitiatorName=%s\n" %(self.initiator))
-        os.close(fd)
-
-        # copy "db" files.  *sigh*
-        if os.path.isdir(instPath + "/var/lib/iscsi"):
-            shutil.rmtree(instPath + "/var/lib/iscsi")
-        if os.path.isdir("/var/lib/iscsi"):
-            shutil.copytree("/var/lib/iscsi", instPath + "/var/lib/iscsi",
-                            symlinks=True)
-
-    def getNode(self, name, address, port):
-        for node in self.nodes:
-            if node.name == name and node.address == address and \
-               node.port == int(port):
-                return node
-
-        return None
-
-    def getNodeDisks(self, node, storage):
-        nodeDisks = []
-        iscsiDisks = storage.devicetree.getDevicesByType("iscsi")
-        for disk in iscsiDisks:
-            if disk.node == node:
-                nodeDisks.append(disk)
-
-        return nodeDisks
-
-# Create iscsi singleton
-iscsi = iscsi()
-
-# vim:tw=78:ts=4:et:sw=4
diff --git a/storage/miscutils.py b/storage/miscutils.py
deleted file mode 100644
index e577497..0000000
--- a/storage/miscutils.py
+++ /dev/null
@@ -1,57 +0,0 @@
-# iutil.py stubs
-import os
-
-import logging
-log = logging.getLogger("storage")
-
-def notify_kernel(path, action="change"):
-    """ Signal the kernel that the specified device has changed. """
-    log.debug("notifying kernel of '%s' event on device %s" % (action, path))
-    path = os.path.join(path, "uevent")
-    if not path.startswith("/sys/") or not os.access(path, os.W_OK):
-        log.debug("sysfs path '%s' invalid" % path)
-        raise ValueError("invalid sysfs path")
-
-    f = open(path, "a")
-    f.write("%s\n" % action)
-    f.close()
-
-def get_sysfs_path_by_name(dev_name, class_name="block"):
-    dev_name = os.path.basename(dev_name)
-    sysfs_class_dir = "/sys/class/%s" % class_name
-    dev_path = os.path.join(sysfs_class_dir, dev_name)
-    if os.path.exists(dev_path):
-        return dev_path
-
-import inspect
-def log_method_call(d, *args, **kwargs):
-    classname = d.__class__.__name__
-    methodname = inspect.stack()[1][3]
-    fmt = "%s.%s:"
-    fmt_args = [classname, methodname]
-    for arg in args:
-        fmt += " %s ;"
-        fmt_args.append(arg)
-
-    for k, v in kwargs.items():
-        fmt += " %s: %s ;"
-        fmt_args.extend([k, v])
-
-    log.debug(fmt % tuple(fmt_args))
-
-def numeric_type(num):
-    """ Verify that a value is given as a numeric data type.
-
-        Return the number if the type is sensible or raise ValueError
-        if not.
-    """
-    if num is None:
-        num = 0
-    elif not (isinstance(num, int) or \
-              isinstance(num, long) or \
-              isinstance(num, float)):
-        raise ValueError("value (%s) must be either a number or None" % num)
-
-    return num
-
-
diff --git a/storage/partitioning.py b/storage/partitioning.py
deleted file mode 100644
index 00c1986..0000000
--- a/storage/partitioning.py
+++ /dev/null
@@ -1,1707 +0,0 @@
-# partitioning.py
-# Disk partitioning functions.
-#
-# Copyright (C) 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, or (at your option) any later version.
-# 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.
-#
-# Red Hat Author(s): Dave Lehman <dlehman@xxxxxxxxxx>
-#
-
-import sys
-import os
-from operator import add, sub, gt, lt
-
-import parted
-from pykickstart.constants import *
-
-from constants import *
-
-from errors import *
-from deviceaction import *
-from devices import PartitionDevice, LUKSDevice, devicePathToName
-from formats import getFormat
-
-import gettext
-_ = lambda x: gettext.ldgettext("anaconda", x)
-
-import logging
-log = logging.getLogger("storage")
-
-def _createFreeSpacePartitions(anaconda):
-    # get a list of disks that have at least one free space region of at
-    # least 100MB
-    disks = []
-    for disk in anaconda.storage.partitioned:
-        if anaconda.storage.clearPartDisks and \
-           (disk.name not in anaconda.storage.clearPartDisks):
-            continue
-
-        part = disk.format.firstPartition
-        while part:
-            if not part.type & parted.PARTITION_FREESPACE:
-                part = part.nextPartition()
-                continue
-
-            if part.getSize(unit="MB") > 100:
-                disks.append(disk)
-                break
-
-            part = part.nextPartition()
-
-    # create a separate pv partition for each disk with free space
-    devs = []
-    for disk in disks:
-        if anaconda.storage.encryptedAutoPart:
-            fmt_type = "luks"
-            fmt_args = {"escrow_cert": anaconda.storage.autoPartEscrowCert,
-                        "add_backup_passphrase": anaconda.storage.autoPartAddBackupPassphrase}
-        else:
-            fmt_type = "lvmpv"
-            fmt_args = {}
-        part = anaconda.storage.newPartition(fmt_type=fmt_type,
-                                                fmt_args=fmt_args,
-                                                grow=True,
-                                                disks=[disk])
-        anaconda.storage.createDevice(part)
-        devs.append(part)
-
-    return (disks, devs)
-
-def _schedulePartitions(anaconda, disks):
-    #
-    # Convert storage.autoPartitionRequests into Device instances and
-    # schedule them for creation
-    #
-    # First pass is for partitions only. We'll do LVs later.
-    #
-    for request in anaconda.storage.autoPartitionRequests:
-        if request.asVol:
-            continue
-
-        if request.fstype is None:
-            request.fstype = anaconda.storage.defaultFSType
-        # This is a little unfortunate but let the backend dictate the rootfstype
-        # so that things like live installs can do the right thing
-        if request.mountpoint == "/" and anaconda.backend.rootFsType != None:
-            request.fstype = anaconda.backend.rootFsType
-
-        dev = anaconda.storage.newPartition(fmt_type=request.fstype,
-                                            size=request.size,
-                                            grow=request.grow,
-                                            maxsize=request.maxSize,
-                                            mountpoint=request.mountpoint,
-                                            disks=disks,
-                                            weight=request.weight)
-
-        # schedule the device for creation
-        anaconda.storage.createDevice(dev)
-
-    # make sure preexisting broken lvm/raid configs get out of the way
-    return
-
-def _scheduleLVs(anaconda, devs):
-    if anaconda.storage.encryptedAutoPart:
-        pvs = []
-        for dev in devs:
-            pv = LUKSDevice("luks-%s" % dev.name,
-                            format=getFormat("lvmpv", device=dev.path),
-                            size=dev.size,
-                            parents=dev)
-            pvs.append(pv)
-            anaconda.storage.createDevice(pv)
-    else:
-        pvs = devs
-
-    # create a vg containing all of the autopart pvs
-    vg = anaconda.storage.newVG(pvs=pvs)
-    anaconda.storage.createDevice(vg)
-
-    initialVGSize = vg.size
-
-    #
-    # Convert storage.autoPartitionRequests into Device instances and
-    # schedule them for creation.
-    #
-    # Second pass, for LVs only.
-    for request in anaconda.storage.autoPartitionRequests:
-        if not request.asVol:
-            continue
-
-        if request.requiredSpace and request.requiredSpace > initialVGSize:
-            continue
-
-        if request.fstype is None:
-            request.fstype = anaconda.storage.defaultFSType
-
-        # This is a little unfortunate but let the backend dictate the rootfstype
-        # so that things like live installs can do the right thing
-        if request.mountpoint == "/" and anaconda.backend.rootFsType != None:
-            request.fstype = anaconda.backend.rootFsType
-
-        # FIXME: move this to a function and handle exceptions
-        dev = anaconda.storage.newLV(vg=vg,
-                                     fmt_type=request.fstype,
-                                     mountpoint=request.mountpoint,
-                                     grow=request.grow,
-                                     maxsize=request.maxSize,
-                                     size=request.size)
-
-        # schedule the device for creation
-        anaconda.storage.createDevice(dev)
-
-
-def doAutoPartition(anaconda):
-    log.debug("doAutoPartition(%s)" % anaconda)
-    log.debug("doAutoPart: %s" % anaconda.storage.doAutoPart)
-    log.debug("clearPartType: %s" % anaconda.storage.clearPartType)
-    log.debug("clearPartDisks: %s" % anaconda.storage.clearPartDisks)
-    log.debug("autoPartitionRequests: %s" % anaconda.storage.autoPartitionRequests)
-    log.debug("storage.disks: %s" % [d.name for d in anaconda.storage.disks])
-    log.debug("storage.partitioned: %s" % [d.name for d in anaconda.storage.partitioned])
-    log.debug("all names: %s" % [d.name for d in anaconda.storage.devices])
-    if anaconda.dir == DISPATCH_BACK:
-        anaconda.storage.reset()
-        return
-
-    disks = []
-    devs = []
-
-    if anaconda.storage.doAutoPart:
-        clearPartitions(anaconda.storage)
-
-    if anaconda.storage.doAutoPart:
-        (disks, devs) = _createFreeSpacePartitions(anaconda)
-
-        if disks == []:
-            if anaconda.ksdata:
-                msg = _("Could not find enough free space for automatic "
-                        "partitioning.  Press 'OK' to exit the installer.")
-            else:
-                msg = _("Could not find enough free space for automatic "
-                        "partitioning, please use another partitioning method.")
-
-            anaconda.intf.messageWindow(_("Error Partitioning"), msg,
-                                        custom_icon='error')
-
-            if anaconda.ksdata:
-                sys.exit(0)
-
-            anaconda.storage.reset()
-            return DISPATCH_BACK
-
-        _schedulePartitions(anaconda, disks)
-
-    # sanity check the individual devices
-    log.warning("not sanity checking devices because I don't know how yet")
-
-    # run the autopart function to allocate and grow partitions
-    try:
-        doPartitioning(anaconda.storage,
-                       exclusiveDisks=anaconda.storage.clearPartDisks)
-
-        if anaconda.storage.doAutoPart:
-            _scheduleLVs(anaconda, devs)
-
-        # grow LVs
-        growLVM(anaconda.storage)
-    except PartitioningWarning as msg:
-        if not anaconda.ksdata:
-            anaconda.intf.messageWindow(_("Warnings During Automatic "
-                                          "Partitioning"),
-                           _("Following warnings occurred during automatic "
-                           "partitioning:\n\n%s") % (msg,),
-                           custom_icon='warning')
-        else:
-            log.warning(msg)
-    except PartitioningError as msg:
-        # restore drives to original state
-        anaconda.storage.reset()
-        if not anaconda.ksdata:
-            extra = ""
-
-            if anaconda.displayMode != "t":
-                anaconda.dispatch.skipStep("partition", skip = 0)
-        else:
-            extra = _("\n\nPress 'OK' to exit the installer.")
-        anaconda.intf.messageWindow(_("Error Partitioning"),
-               _("Could not allocate requested partitions: \n\n"
-                 "%(msg)s.%(extra)s") % {'msg': msg, 'extra': extra},
-               custom_icon='error')
-
-        if anaconda.ksdata:
-            sys.exit(0)
-        else:
-            return
-
-    # sanity check the collection of devices
-    log.warning("not sanity checking storage config because I don't know how yet")
-    # now do a full check of the requests
-    (errors, warnings) = anaconda.storage.sanityCheck()
-    if warnings:
-        for warning in warnings:
-            log.warning(warning)
-    if errors:
-        errortxt = "\n".join(errors)
-        if anaconda.ksdata:
-            extra = _("\n\nPress 'OK' to exit the installer.")
-        else:
-            extra = _("\n\nPress 'OK' to choose a different partitioning option.")
-
-        anaconda.intf.messageWindow(_("Automatic Partitioning Errors"),
-                           _("The following errors occurred with your "
-                             "partitioning:\n\n%(errortxt)s\n\n"
-                             "This can happen if there is not enough "
-                             "space on your hard drive(s) for the "
-                             "installation. %(extra)s")
-                           % {'errortxt': errortxt, 'extra': extra},
-                           custom_icon='error')
-        #
-        # XXX if in kickstart we reboot
-        #
-        if anaconda.ksdata:
-            anaconda.intf.messageWindow(_("Unrecoverable Error"),
-                               _("The system will now reboot."))
-            sys.exit(0)
-        anaconda.storage.reset()
-        return DISPATCH_BACK
-
-def shouldClear(device, clearPartType, clearPartDisks=None):
-    if clearPartType not in [CLEARPART_TYPE_LINUX, CLEARPART_TYPE_ALL]:
-        return False
-
-    if isinstance(device, PartitionDevice):
-        # Never clear the special first partition on a Mac disk label, as that
-        # holds the partition table itself.
-        if device.disk.format.partedDisk.type == "mac" and \
-           device.partedPartition.number == 1 and \
-           device.partedPartition.name == "Apple":
-            return False
-
-        # If we got a list of disks to clear, make sure this one's on it
-        if clearPartDisks and device.disk.name not in clearPartDisks:
-            return False
-
-        # We don't want to fool with extended partitions, freespace, &c
-        if device.partType not in [parted.PARTITION_NORMAL,
-                                   parted.PARTITION_LOGICAL]:
-            return False
-
-        if clearPartType == CLEARPART_TYPE_LINUX and \
-           not device.format.linuxNative and \
-           not device.getFlag(parted.PARTITION_LVM) and \
-           not device.getFlag(parted.PARTITION_RAID) and \
-           not device.getFlag(parted.PARTITION_SWAP):
-            return False
-    elif device.isDisk and not device.partitioned:
-        # If we got a list of disks to clear, make sure this one's on it
-        if clearPartDisks and device.name not in clearPartDisks:
-            return False
-
-        # Never clear disks with hidden formats
-        if device.format.hidden:
-            return False
-
-        if clearPartType == CLEARPART_TYPE_LINUX and \
-           not device.format.linuxNative:
-            return False
-
-    # Don't clear devices holding install media.
-    if device.protected:
-        return False
-
-    # TODO: do platform-specific checks on ia64, pSeries, iSeries, mac
-
-    return True
-
-def clearPartitions(storage):
-    """ Clear partitions and dependent devices from disks.
-
-        Arguments:
-
-            storage -- a storage.Storage instance
-
-        Keyword arguments:
-
-            None
-
-        NOTES:
-
-            - Needs some error handling, especially for the parted bits.
-
-    """
-    if storage.clearPartType is None or storage.clearPartType == CLEARPART_TYPE_NONE:
-        # not much to do
-        return
-
-    # we are only interested in partitions that physically exist
-    partitions = [p for p in storage.partitions if p.exists]
-    # Sort partitions by descending partition number to minimize confusing
-    # things like multiple "destroy sda5" actions due to parted renumbering
-    # partitions. This can still happen through the UI but it makes sense to
-    # avoid it where possible.
-    partitions.sort(key=lambda p: p.partedPartition.number, reverse=True)
-    for part in partitions:
-        log.debug("clearpart: looking at %s" % part.name)
-        if not shouldClear(part, storage.clearPartType, storage.clearPartDisks):
-            continue
-
-        log.debug("clearing %s" % part.name)
-
-        # XXX is there any argument for not removing incomplete devices?
-        #       -- maybe some RAID devices
-        devices = storage.deviceDeps(part)
-        while devices:
-            log.debug("devices to remove: %s" % ([d.name for d in devices],))
-            leaves = [d for d in devices if d.isleaf]
-            log.debug("leaves to remove: %s" % ([d.name for d in leaves],))
-            for leaf in leaves:
-                storage.destroyDevice(leaf)
-                devices.remove(leaf)
-
-        log.debug("partitions: %s" % [p.getDeviceNodeName() for p in part.partedPartition.disk.partitions])
-        storage.destroyDevice(part)
-
-    # now remove any empty extended partitions
-    removeEmptyExtendedPartitions(storage)
-
-    _platform = storage.anaconda.platform
-
-    # make sure that the the boot device has the correct disklabel type if
-    # we're going to completely clear it.
-    for disk in storage.partitioned:
-        if not storage.anaconda.bootloader.drivelist:
-            break
-
-        if disk.name != storage.anaconda.bootloader.drivelist[0]:
-            continue
-
-        if storage.clearPartType != CLEARPART_TYPE_ALL or \
-           (storage.clearPartDisks and disk.name not in storage.clearPartDisks):
-            continue
-
-        # don't reinitialize the disklabel if the disk contains install media
-        if filter(lambda p: p.dependsOn(disk), storage.protectedDevices):
-            continue
-
-        nativeLabelType = _platform.diskLabelType(disk.partedDevice.type)
-        if disk.format.labelType == nativeLabelType:
-            continue
-
-        if disk.format.labelType == "mac":
-            # remove the magic apple partition
-            for part in storage.partitions:
-                if part.disk == disk and part.partedPartition.number == 1:
-                    log.debug("clearing %s" % part.name)
-                    # We can't schedule the apple map partition for removal
-                    # because parted will not allow us to remove it from the
-                    # disk. Still, we need it out of the devicetree.
-                    storage.devicetree._removeDevice(part, moddisk=False)
-
-        destroy_action = ActionDestroyFormat(disk)
-        newLabel = getFormat("disklabel", device=disk.path)
-        create_action = ActionCreateFormat(disk, format=newLabel)
-        storage.devicetree.registerAction(destroy_action)
-        storage.devicetree.registerAction(create_action)
-
-def removeEmptyExtendedPartitions(storage):
-    for disk in storage.partitioned:
-        log.debug("checking whether disk %s has an empty extended" % disk.name)
-        extended = disk.format.extendedPartition
-        logical_parts = disk.format.logicalPartitions
-        log.debug("extended is %s ; logicals is %s" % (extended, [p.getDeviceNodeName() for p in logical_parts]))
-        if extended and not logical_parts:
-            log.debug("removing empty extended partition from %s" % disk.name)
-            extended_name = devicePathToName(extended.getDeviceNodeName())
-            extended = storage.devicetree.getDeviceByName(extended_name)
-            storage.destroyDevice(extended)
-            #disk.partedDisk.removePartition(extended.partedPartition)
-
-    for disk in [d for d in storage.disks if d not in storage.partitioned]:
-        # clear any whole-disk formats that need clearing
-        if shouldClear(disk, storage.clearPartType, storage.clearPartDisks):
-            log.debug("clearing %s" % disk.name)
-            devices = storage.deviceDeps(disk)
-            while devices:
-                log.debug("devices to remove: %s" % ([d.name for d in devices],))
-                leaves = [d for d in devices if d.isleaf]
-                log.debug("leaves to remove: %s" % ([d.name for d in leaves],))
-                for leaf in leaves:
-                    storage.destroyDevice(leaf)
-                    devices.remove(leaf)
-
-            destroy_action = ActionDestroyFormat(disk)
-            newLabel = getFormat("disklabel", device=disk.path)
-            create_action = ActionCreateFormat(disk, format=newLabel)
-            storage.devicetree.registerAction(destroy_action)
-            storage.devicetree.registerAction(create_action)
-
-def partitionCompare(part1, part2):
-    """ More specifically defined partitions come first.
-
-        < 1 => x < y
-          0 => x == y
-        > 1 => x > y
-    """
-    ret = 0
-
-    if part1.req_base_weight:
-        ret -= part1.req_base_weight
-
-    if part2.req_base_weight:
-        ret += part2.req_base_weight
-
-    # bootable partitions to the front
-    ret -= cmp(part1.req_bootable, part2.req_bootable) * 1000
-
-    # more specific disk specs to the front of the list
-    # req_disks being empty is equivalent to it being an infinitely long list
-    if part1.req_disks and not part2.req_disks:
-        ret -= 500
-    elif not part1.req_disks and part2.req_disks:
-        ret += 500
-    else:
-        ret += cmp(len(part1.req_disks), len(part2.req_disks)) * 500
-
-    # primary-only to the front of the list
-    ret -= cmp(part1.req_primary, part2.req_primary) * 200
-
-    # fixed size requests to the front
-    ret += cmp(part1.req_grow, part2.req_grow) * 100
-
-    # larger requests go to the front of the list
-    ret -= cmp(part1.req_base_size, part2.req_base_size) * 50
-
-    # potentially larger growable requests go to the front
-    if part1.req_grow and part2.req_grow:
-        if not part1.req_max_size and part2.req_max_size:
-            ret -= 25
-        elif part1.req_max_size and not part2.req_max_size:
-            ret += 25
-        else:
-            ret -= cmp(part1.req_max_size, part2.req_max_size) * 25
-
-    # give a little bump based on mountpoint
-    if hasattr(part1.format, "mountpoint") and \
-       hasattr(part2.format, "mountpoint"):
-        ret += cmp(part1.format.mountpoint, part2.format.mountpoint) * 10
-
-    if ret > 0:
-        ret = 1
-    elif ret < 0:
-        ret = -1
-
-    return ret
-
-def getNextPartitionType(disk, no_primary=None):
-    """ Find the type of partition to create next on a disk.
-
-        Return a parted partition type value representing the type of the
-        next partition we will create on this disk.
-
-        If there is only one free primary partition and we can create an
-        extended partition, we do that.
-
-        If there are free primary slots and an extended partition we will
-        recommend creating a primary partition. This can be overridden
-        with the keyword argument no_primary.
-
-        Arguments:
-
-            disk -- a parted.Disk instance representing the disk
-
-        Keyword arguments:
-
-            no_primary -- given a choice between primary and logical
-                          partitions, prefer logical
-
-    """
-    part_type = None
-    extended = disk.getExtendedPartition()
-    supports_extended = disk.supportsFeature(parted.DISK_TYPE_EXTENDED)
-    logical_count = len(disk.getLogicalPartitions())
-    max_logicals = disk.getMaxLogicalPartitions()
-    primary_count = disk.primaryPartitionCount
-
-    if primary_count < disk.maxPrimaryPartitionCount:
-        if primary_count == disk.maxPrimaryPartitionCount - 1:
-            # can we make an extended partition? now's our chance.
-            if not extended and supports_extended:
-                part_type = parted.PARTITION_EXTENDED
-            elif not extended:
-                # extended partitions not supported. primary or nothing.
-                if not no_primary:
-                    part_type = parted.PARTITION_NORMAL
-            else:
-                # there is an extended and a free primary
-                if not no_primary:
-                    part_type = parted.PARTITION_NORMAL
-                elif logical_count < max_logicals:
-                    # we have an extended with logical slots, so use one.
-                    part_type = parted.PARTITION_LOGICAL
-        else:
-            # there are two or more primary slots left. use one unless we're
-            # not supposed to make primaries.
-            if not no_primary:
-                part_type = parted.PARTITION_NORMAL
-            elif extended and logical_count < max_logicals:
-                part_type = parted.PARTITION_LOGICAL
-    elif extended and logical_count < max_logicals:
-        part_type = parted.PARTITION_LOGICAL
-
-    return part_type
-
-def getBestFreeSpaceRegion(disk, part_type, req_size,
-                           boot=None, best_free=None, grow=None):
-    """ Return the "best" free region on the specified disk.
-
-        For non-boot partitions, we return the largest free region on the
-        disk. For boot partitions, we return the first region that is
-        large enough to hold the partition.
-
-        Partition type (parted's PARTITION_NORMAL, PARTITION_LOGICAL) is
-        taken into account when locating a suitable free region.
-
-        For locating the best region from among several disks, the keyword
-        argument best_free allows the specification of a current "best"
-        free region with which to compare the best from this disk. The
-        overall best region is returned.
-
-        Arguments:
-
-            disk -- the disk (a parted.Disk instance)
-            part_type -- the type of partition we want to allocate
-                         (one of parted's partition type constants)
-            req_size -- the requested size of the partition (in MB)
-
-        Keyword arguments:
-
-            boot -- indicates whether this will be a bootable partition
-                    (boolean)
-            best_free -- current best free region for this partition
-            grow -- indicates whether this is a growable request
-
-    """
-    log.debug("getBestFreeSpaceRegion: disk=%s part_type=%d req_size=%dMB "
-              "boot=%s best=%s grow=%s" %
-              (disk.device.path, part_type, req_size, boot, best_free, grow))
-    extended = disk.getExtendedPartition()
-
-    for _range in disk.getFreeSpaceRegions():
-        if extended:
-            # find out if there is any overlap between this region and the
-            # extended partition
-            log.debug("looking for intersection between extended (%d-%d) and free (%d-%d)" %
-                    (extended.geometry.start, extended.geometry.end, _range.start, _range.end))
-
-            # parted.Geometry.overlapsWith can handle this
-            try:
-                free_geom = extended.geometry.intersect(_range)
-            except ArithmeticError, e:
-                # this freespace region does not lie within the extended
-                # partition's geometry
-                free_geom = None
-
-            if (free_geom and part_type == parted.PARTITION_NORMAL) or \
-               (not free_geom and part_type == parted.PARTITION_LOGICAL):
-                log.debug("free region not suitable for request")
-                continue
-
-            if part_type == parted.PARTITION_NORMAL:
-                # we're allocating a primary and the region is not within
-                # the extended, so we use the original region
-                free_geom = _range
-        else:
-            free_geom = _range
-
-        log.debug("current free range is %d-%d (%dMB)" % (free_geom.start,
-                                                          free_geom.end,
-                                                          free_geom.getSize()))
-        free_size = free_geom.getSize()
-
-        # For boot partitions, we want the first suitable region we find.
-        # For growable or extended partitions, we want the largest possible
-        # free region.
-        # For all others, we want the smallest suitable free region.
-        if grow or part_type == parted.PARTITION_EXTENDED:
-            op = gt
-        else:
-            op = lt
-        if req_size <= free_size:
-            if not best_free or op(free_geom.length, best_free.length):
-                best_free = free_geom
-
-                if boot:
-                    # if this is a bootable partition we want to
-                    # use the first freespace region large enough
-                    # to satisfy the request
-                    break
-
-    return best_free
-
-def sectorsToSize(sectors, sectorSize):
-    """ Convert length in sectors to size in MB.
-
-        Arguments:
-
-            sectors     -   sector count
-            sectorSize  -   sector size for the device, in bytes
-    """
-    return (sectors * sectorSize) / (1024.0 * 1024.0)
-
-def sizeToSectors(size, sectorSize):
-    """ Convert size in MB to length in sectors.
-
-        Arguments:
-
-            size        -   size in MB
-            sectorSize  -   sector size for the device, in bytes
-    """
-    return (size * 1024.0 * 1024.0) / sectorSize
-
-def removeNewPartitions(disks, partitions):
-    """ Remove newly added input partitions from input disks.
-
-        Arguments:
-
-            disks -- list of StorageDevice instances with DiskLabel format
-            partitions -- list of PartitionDevice instances
-
-    """
-    log.debug("removing all non-preexisting partitions %s from disk(s) %s"
-                % (["%s(id %d)" % (p.name, p.id) for p in partitions
-                                                    if not p.exists],
-                   [d.name for d in disks]))
-    for part in partitions:
-        if part.partedPartition and part.disk in disks:
-            if part.exists:
-                # we're only removing partitions that don't physically exist
-                continue
-
-            if part.isExtended:
-                # these get removed last
-                continue
-
-            part.disk.format.partedDisk.removePartition(part.partedPartition)
-            part.partedPartition = None
-            part.disk = None
-
-    for disk in disks:
-        # remove empty extended so it doesn't interfere
-        extended = disk.format.extendedPartition
-        if extended and not disk.format.logicalPartitions:
-            log.debug("removing empty extended partition from %s" % disk.name)
-            disk.format.partedDisk.removePartition(extended)
-
-def addPartition(disklabel, free, part_type, size):
-    """ Return new partition after adding it to the specified disk.
-
-        Arguments:
-
-            disklabel -- disklabel instance to add partition to
-            free -- where to add the partition (parted.Geometry instance)
-            part_type -- partition type (parted.PARTITION_* constant)
-            size -- size (in MB) of the new partition
-
-        The new partition will be aligned.
-
-        Return value is a parted.Partition instance.
-
-    """
-    start = free.start
-    if not disklabel.alignment.isAligned(free, start):
-        start = disklabel.alignment.alignNearest(free, start)
-
-    if part_type == parted.PARTITION_LOGICAL:
-        # make room for logical partition's metadata
-        start += disklabel.alignment.grainSize
-
-    if start != free.start:
-        log.debug("adjusted start sector from %d to %d" % (free.start, start))
-
-    if part_type == parted.PARTITION_EXTENDED:
-        end = free.end
-        length = end - start + 1
-    else:
-        # size is in MB
-        length = sizeToSectors(size, disklabel.partedDevice.sectorSize)
-        end = start + length - 1
-
-    if not disklabel.endAlignment.isAligned(free, end):
-        end = disklabel.endAlignment.alignNearest(free, end)
-        log.debug("adjusted length from %d to %d" % (length, end - start + 1))
-
-    new_geom = parted.Geometry(device=disklabel.partedDevice,
-                               start=start,
-                               end=end)
-
-    max_length = disklabel.partedDisk.maxPartitionLength
-    if max_length and new_geom.length > max_length:
-        raise PartitioningError("requested size exceeds maximum allowed")
-
-    # create the partition and add it to the disk
-    partition = parted.Partition(disk=disklabel.partedDisk,
-                                 type=part_type,
-                                 geometry=new_geom)
-    constraint = parted.Constraint(exactGeom=new_geom)
-    disklabel.partedDisk.addPartition(partition=partition,
-                                      constraint=constraint)
-    return partition
-
-def getFreeRegions(disks):
-    """ Return a list of free regions on the specified disks.
-
-        Arguments:
-
-            disks -- list of parted.Disk instances
-
-        Return value is a list of unaligned parted.Geometry instances.
-
-    """
-    free = []
-    for disk in disks:
-        for f in disk.format.partedDisk.getFreeSpaceRegions():
-            if f.length > 0:
-                free.append(f)
-
-    return free
-
-def doPartitioning(storage, exclusiveDisks=None):
-    """ Allocate and grow partitions.
-
-        When this function returns without error, all PartitionDevice
-        instances must have their parents set to the disk they are
-        allocated on, and their partedPartition attribute set to the
-        appropriate parted.Partition instance from their containing
-        disk. All req_xxxx attributes must be unchanged.
-
-        Arguments:
-
-            storage - Main anaconda Storage instance
-
-        Keyword arguments:
-
-            exclusiveDisks -- list of names of disks to use
-
-    """
-    anaconda = storage.anaconda
-    disks = storage.partitioned
-    if exclusiveDisks:
-        disks = [d for d in disks if d.name in exclusiveDisks]
-
-    for disk in disks:
-        disk.setup()
-
-    partitions = storage.partitions[:]
-    for part in storage.partitions:
-        part.req_bootable = False
-
-        if part.exists or \
-           (storage.deviceImmutable(part) and part.partedPartition):
-            # if the partition is preexisting or part of a complex device
-            # then we shouldn't modify it
-            partitions.remove(part)
-            continue
-
-        if not part.exists:
-            # start over with flexible-size requests
-            part.req_size = part.req_base_size
-
-    # FIXME: isn't there a better place for this to happen?
-    try:
-        bootDev = anaconda.platform.bootDevice()
-    except DeviceError:
-        bootDev = None
-
-    if bootDev:
-        bootDev.req_bootable = True
-
-    removeNewPartitions(disks, partitions)
-    free = getFreeRegions(disks)
-    allocatePartitions(storage, disks, partitions, free)
-    growPartitions(disks, partitions, free)
-
-    # The number and thus the name of partitions may have changed now,
-    # allocatePartitions() takes care of this for new partitions, but not
-    # for pre-existing ones, so we update the name of all partitions here
-    for part in storage.partitions:
-        # needed because of XXX hack below
-        if part.isExtended:
-            continue
-        part.updateName()
-
-    # XXX hack -- if we created any extended partitions we need to add
-    #             them to the tree now
-    for disk in disks:
-        extended = disk.format.extendedPartition
-        if not extended:
-            # remove any obsolete extended partitions
-            for part in storage.partitions:
-                if part.disk == disk and part.isExtended:
-                    if part.exists:
-                        storage.destroyDevice(part)
-                    else:
-                        storage.devicetree._removeDevice(part, moddisk=False)
-            continue
-
-        extendedName = devicePathToName(extended.getDeviceNodeName())
-        # remove any obsolete extended partitions
-        for part in storage.partitions:
-            if part.disk == disk and part.isExtended and \
-               part.partedPartition not in disk.format.partitions:
-                if part.exists:
-                    storage.destroyDevice(part)
-                else:
-                    storage.devicetree._removeDevice(part, moddisk=False)
-
-        device = storage.devicetree.getDeviceByName(extendedName)
-        if device:
-            if not device.exists:
-                # created by us, update partedPartition
-                device.partedPartition = extended
-            continue
-
-        # This is a little odd because normally instantiating a partition
-        # that does not exist means leaving self.parents empty and instead
-        # populating self.req_disks. In this case, we need to skip past
-        # that since this partition is already defined.
-        device = PartitionDevice(extendedName, parents=disk)
-        device.parents = [disk]
-        device.partedPartition = extended
-        # just add the device for now -- we'll handle actions at the last
-        # moment to simplify things
-        storage.devicetree._addDevice(device)
-
-def allocatePartitions(storage, disks, partitions, freespace):
-    """ Allocate partitions based on requested features.
-
-        Non-existing partitions are sorted according to their requested
-        attributes, and then allocated.
-
-        The basic approach to sorting is that the more specifically-
-        defined a request is, the earlier it will be allocated. See
-        the function partitionCompare for details on the sorting
-        criteria.
-
-        The PartitionDevice instances will have their name and parents
-        attributes set once they have been allocated.
-    """
-    log.debug("allocatePartitions: disks=%s ; partitions=%s" %
-                ([d.name for d in disks],
-                 ["%s(id %d)" % (p.name, p.id) for p in partitions]))
-
-    new_partitions = [p for p in partitions if not p.exists]
-    new_partitions.sort(cmp=partitionCompare)
-
-    # the following dicts all use device path strings as keys
-    disklabels = {}     # DiskLabel instances for each disk
-    all_disks = {}      # StorageDevice for each disk
-    for disk in disks:
-        if disk.path not in disklabels.keys():
-            disklabels[disk.path] = disk.format
-            all_disks[disk.path] = disk
-
-    removeNewPartitions(disks, new_partitions)
-
-    for _part in new_partitions:
-        if _part.partedPartition and _part.isExtended:
-            # ignore new extendeds as they are implicit requests
-            continue
-
-        # obtain the set of candidate disks
-        req_disks = []
-        if _part.disk:
-            # we have a already selected a disk for this request
-            req_disks = [_part.disk]
-        elif _part.req_disks:
-            # use the requested disk set
-            req_disks = _part.req_disks
-        else:
-            # no disks specified means any disk will do
-            req_disks = disks
-
-        # sort the disks, making sure the boot disk is first
-        req_disks.sort(key=lambda d: d.name, cmp=storage.compareDisks)
-        boot_index = None
-        for disk in req_disks:
-            if disk.name == storage.anaconda.bootloader.drivelist[0]:
-                boot_index = req_disks.index(disk)
-
-        if boot_index is not None and len(req_disks) > 1:
-            boot_disk = req_disks.pop(boot_index)
-            req_disks.insert(0, boot_disk)
-
-        log.debug("allocating partition: %s ; id: %d ; disks: %s ;\n"
-                  "boot: %s ; primary: %s ; size: %dMB ; grow: %s ; "
-                  "max_size: %s" % (_part.name, _part.id,
-                                    [d.name for d in req_disks],
-                                    _part.req_bootable, _part.req_primary,
-                                    _part.req_size, _part.req_grow,
-                                    _part.req_max_size))
-        free = None
-        use_disk = None
-        part_type = None
-        growth = 0
-        # loop through disks
-        for _disk in req_disks:
-            disklabel = disklabels[_disk.path]
-            sectorSize = disklabel.partedDevice.sectorSize
-            best = None
-            current_free = free
-
-            # for growable requests, we don't want to pass the current free
-            # geometry to getBestFreeRegion -- this allows us to try the
-            # best region from each disk and choose one based on the total
-            # growth it allows
-            if _part.req_grow:
-                current_free = None
-
-            log.debug("checking freespace on %s" % _disk.name)
-
-            new_part_type = getNextPartitionType(disklabel.partedDisk)
-            if new_part_type is None:
-                # can't allocate any more partitions on this disk
-                log.debug("no free partition slots on %s" % _disk.name)
-                continue
-
-            if _part.req_primary and new_part_type != parted.PARTITION_NORMAL:
-                if (disklabel.partedDisk.primaryPartitionCount <
-                    disklabel.partedDisk.maxPrimaryPartitionCount):
-                    # don't fail to create a primary if there are only three
-                    # primary partitions on the disk (#505269)
-                    new_part_type = parted.PARTITION_NORMAL
-                else:
-                    # we need a primary slot and none are free on this disk
-                    log.debug("no primary slots available on %s" % _disk.name)
-                    continue
-
-            best = getBestFreeSpaceRegion(disklabel.partedDisk,
-                                          new_part_type,
-                                          _part.req_size,
-                                          best_free=current_free,
-                                          boot=_part.req_bootable,
-                                          grow=_part.req_grow)
-
-            if best == free and not _part.req_primary and \
-               new_part_type == parted.PARTITION_NORMAL:
-                # see if we can do better with a logical partition
-                log.debug("not enough free space for primary -- trying logical")
-                new_part_type = getNextPartitionType(disklabel.partedDisk,
-                                                     no_primary=True)
-                if new_part_type:
-                    best = getBestFreeSpaceRegion(disklabel.partedDisk,
-                                                  new_part_type,
-                                                  _part.req_size,
-                                                  best_free=current_free,
-                                                  boot=_part.req_bootable,
-                                                  grow=_part.req_grow)
-
-            if best and free != best:
-                update = True
-                if _part.req_grow:
-                    log.debug("evaluating growth potential for new layout")
-                    new_growth = 0
-                    for disk_path in disklabels.keys():
-                        log.debug("calculating growth for disk %s" % disk_path)
-                        # Now we check, for growable requests, which of the two
-                        # free regions will allow for more growth.
-
-                        # set up chunks representing the disks' layouts
-                        temp_parts = []
-                        for _p in new_partitions[:new_partitions.index(_part)]:
-                            if _p.disk.path == disk_path:
-                                temp_parts.append(_p)
-
-                        # add the current request to the temp disk to set up
-                        # its partedPartition attribute with a base geometry
-                        if disk_path == _disk.path:
-                            temp_part = addPartition(disklabel,
-                                                     best,
-                                                     new_part_type,
-                                                     _part.req_size)
-                            _part.partedPartition = temp_part
-                            _part.disk = _disk
-                            temp_parts.append(_part)
-
-                        chunks = getDiskChunks(all_disks[disk_path],
-                                               temp_parts, freespace)
-
-                        # grow all growable requests
-                        disk_growth = 0
-                        disk_sector_size = disklabels[disk_path].partedDevice.sectorSize
-                        for chunk in chunks:
-                            chunk.growRequests()
-                            # record the growth for this layout
-                            new_growth += chunk.growth
-                            disk_growth += chunk.growth
-                            for req in chunk.requests:
-                                log.debug("request %d (%s) growth: %d (%dMB) "
-                                          "size: %dMB" %
-                                          (req.partition.id,
-                                           req.partition.name,
-                                           req.growth,
-                                           sectorsToSize(req.growth,
-                                                         disk_sector_size),
-                                           sectorsToSize(req.growth + req.base,
-                                                         disk_sector_size)))
-                        log.debug("disk %s growth: %d (%dMB)" %
-                                        (disk_path, disk_growth,
-                                         sectorsToSize(disk_growth,
-                                                       disk_sector_size)))
-
-                    disklabel.partedDisk.removePartition(temp_part)
-                    _part.partedPartition = None
-                    _part.disk = None
-
-                    log.debug("total growth: %d sectors" % new_growth)
-
-                    # update the chosen free region unless the previous
-                    # choice yielded greater total growth
-                    if new_growth < growth:
-                        log.debug("keeping old free: %d < %d" % (new_growth,
-                                                                 growth))
-                        update = False
-                    else:
-                        growth = new_growth
-
-                if update:
-                    # now we know we are choosing a new free space,
-                    # so update the disk and part type
-                    log.debug("updating use_disk to %s (%s), type: %s"
-                                % (_disk, _disk.name, new_part_type))
-                    part_type = new_part_type
-                    use_disk = _disk
-                    log.debug("new free: %s (%d-%d / %dMB)" % (best,
-                                                               best.start,
-                                                               best.end,
-                                                               best.getSize()))
-                    log.debug("new free allows for %d sectors of growth" %
-                                growth)
-                    free = best
-
-            # For platforms with a fake boot partition (like Apple Bootstrap or
-            # PReP) and multiple disks, we need to ensure the /boot partition
-            # ends up on the same disk as the fake one.
-            mountpoint = getattr(_part.format, "mountpoint", "")
-            if not mountpoint:
-                mountpoint = ""
-
-            if free and (_part.req_bootable or mountpoint.startswith("/boot")):
-                # if this is a bootable partition we want to
-                # use the first freespace region large enough
-                # to satisfy the request
-                log.debug("found free space for bootable request")
-                break
-
-        if free is None:
-            raise PartitioningError("not enough free space on disks")
-
-        _disk = use_disk
-        disklabel = _disk.format
-
-        # create the extended partition if needed
-        if part_type == parted.PARTITION_EXTENDED:
-            log.debug("creating extended partition")
-            addPartition(disklabel, free, part_type, None)
-
-            # now the extended partition exists, so set type to logical
-            part_type = parted.PARTITION_LOGICAL
-
-            # recalculate freespace
-            log.debug("recalculating free space")
-            free = getBestFreeSpaceRegion(disklabel.partedDisk,
-                                          part_type,
-                                          _part.req_size,
-                                          boot=_part.req_bootable,
-                                          grow=_part.req_grow)
-            if not free:
-                raise PartitioningError("not enough free space after "
-                                        "creating extended partition")
-
-        partition = addPartition(disklabel, free, part_type, _part.req_size)
-        log.debug("created partition %s of %dMB and added it to %s" %
-                (partition.getDeviceNodeName(), partition.getSize(),
-                 disklabel.device))
-
-        # this one sets the name
-        _part.partedPartition = partition
-        _part.disk = _disk
-
-        # parted modifies the partition in the process of adding it to
-        # the disk, so we need to grab the latest version...
-        _part.partedPartition = disklabel.partedDisk.getPartitionByPath(_part.path)
-
-
-class Request(object):
-    """ A partition request.
-
-        Request instances are used for calculating how much to grow
-        partitions.
-    """
-    def __init__(self, partition):
-        """ Create a Request instance.
-
-            Arguments:
-
-                partition -- a PartitionDevice instance
-
-        """
-        self.partition = partition          # storage.devices.PartitionDevice
-        self.growth = 0                     # growth in sectors
-        self.max_growth = 0                 # max growth in sectors
-        self.done = not partition.req_grow  # can we grow this request more?
-        self.base = partition.partedPartition.geometry.length   # base sectors
-
-        sector_size = partition.partedPartition.disk.device.sectorSize
-
-        if partition.req_grow:
-            limits = filter(lambda l: l > 0,
-                        [sizeToSectors(partition.req_max_size, sector_size),
-                         sizeToSectors(partition.format.maxSize, sector_size),
-                         partition.partedPartition.disk.maxPartitionLength])
-
-            if limits:
-                max_sectors = min(limits)
-                self.max_growth = max_sectors - self.base
-
-    @property
-    def growable(self):
-        """ True if this request is growable. """
-        return self.partition.req_grow
-
-    @property
-    def id(self):
-        """ The id of the PartitionDevice this request corresponds to. """
-        return self.partition.id
-
-    def __str__(self):
-        s = ("%(type)s instance --\n"
-             "id = %(id)s  name = %(name)s  growable = %(growable)s\n"
-             "base = %(base)d  growth = %(growth)d  max_grow = %(max_grow)d\n"
-             "done = %(done)s" %
-             {"type": self.__class__.__name__, "id": self.id,
-              "name": self.partition.name, "growable": self.growable,
-              "base": self.base, "growth": self.growth,
-              "max_grow": self.max_growth, "done": self.done})
-        return s
-
-
-class Chunk(object):
-    """ A free region on disk from which partitions will be allocated """
-    def __init__(self, geometry, requests=None):
-        """ Create a Chunk instance.
-
-            Arguments:
-
-                geometry -- parted.Geometry instance describing the free space
-
-
-            Keyword Arguments:
-
-                requests -- list of Request instances allocated from this chunk
-
-        """
-        self.geometry = geometry            # parted.Geometry
-        self.pool = self.geometry.length    # free sector count
-        self.sectorSize = self.geometry.device.sectorSize
-        self.base = 0                       # sum of growable requests' base
-                                            # sizes, in sectors
-        self.requests = []                  # list of Request instances
-        if isinstance(requests, list):
-            for req in requests:
-                self.addRequest(req)
-
-    def __str__(self):
-        s = ("%(type)s instance --\n"
-             "device = %(device)s  start = %(start)d  end = %(end)d\n"
-             "length = %(length)d  size = %(size)d pool = %(pool)d\n"
-             "remaining = %(rem)d  sectorSize = %(sectorSize)d" %
-             {"type": self.__class__.__name__,
-              "device": self.geometry.device.path,
-              "start": self.geometry.start, "end": self.geometry.end,
-              "length": self.geometry.length, "size": self.geometry.getSize(),
-              "pool": self.pool, "rem": self.remaining,
-              "sectorSize": self.sectorSize})
-
-        return s
-
-    def addRequest(self, req):
-        """ Add a Request to this chunk. """
-        log.debug("adding request %d to chunk %s" % (req.partition.id, self))
-        self.requests.append(req)
-        self.pool -= req.base
-
-        if not req.done:
-            self.base += req.base
-
-    def getRequestByID(self, id):
-        """ Retrieve a request from this chunk based on its id. """
-        for request in self.requests:
-            if request.id == id:
-                return request
-
-    @property
-    def growth(self):
-        """ Sum of growth in sectors for all requests in this chunk. """
-        return sum(r.growth for r in self.requests)
-
-    @property
-    def hasGrowable(self):
-        """ True if this chunk contains at least one growable request. """
-        for req in self.requests:
-            if req.growable:
-                return True
-        return False
-
-    @property
-    def remaining(self):
-        """ Number of requests still being grown in this chunk. """
-        return len([d for d in self.requests if not d.done])
-
-    @property
-    def done(self):
-        """ True if we are finished growing all requests in this chunk. """
-        return self.remaining == 0
-
-    def trimOverGrownRequest(self, req, base=None):
-        """ Enforce max growth and return extra sectors to the pool. """
-        if req.max_growth and req.growth >= req.max_growth:
-            if req.growth > req.max_growth:
-                # we've grown beyond the maximum. put some back.
-                extra = req.growth - req.max_growth
-                log.debug("taking back %d (%dMB) from %d (%s)" %
-                            (extra,
-                             sectorsToSize(extra, self.sectorSize),
-                             req.partition.id, req.partition.name))
-                self.pool += extra
-                req.growth = req.max_growth
-
-            # We're done growing this partition, so it no longer
-            # factors into the growable base used to determine
-            # what fraction of the pool each request gets.
-            if base is not None:
-                base -= req.base
-            req.done = True
-
-        return base
-
-    def growRequests(self):
-        """ Calculate growth amounts for requests in this chunk. """
-        log.debug("Chunk.growRequests: %s" % self)
-
-        # sort the partitions by start sector
-        self.requests.sort(key=lambda r: r.partition.partedPartition.geometry.start)
-
-        # we use this to hold the base for the next loop through the
-        # chunk's requests since we want the base to be the same for
-        # all requests in any given growth iteration
-        new_base = self.base
-        last_pool = 0 # used to track changes to the pool across iterations
-        while not self.done and self.pool and last_pool != self.pool:
-            last_pool = self.pool    # to keep from getting stuck
-            self.base = new_base
-            log.debug("%d partitions and %d (%dMB) left in chunk" %
-                        (self.remaining, self.pool,
-                         sectorsToSize(self.pool, self.sectorSize)))
-            for p in self.requests:
-                if p.done:
-                    continue
-
-                # Each partition is allocated free sectors from the pool
-                # based on the relative _base_ sizes of the remaining
-                # growable partitions.
-                share = p.base / float(self.base)
-                growth = int(share * last_pool) # truncate, don't round
-                p.growth += growth
-                self.pool -= growth
-                log.debug("adding %d (%dMB) to %d (%s)" %
-                            (growth,
-                             sectorsToSize(growth, self.sectorSize),
-                             p.partition.id, p.partition.name))
-
-                new_base = self.trimOverGrownRequest(p, base=new_base)
-                log.debug("new grow amount for partition %d (%s) is %d "
-                          "sectors, or %dMB" %
-                            (p.partition.id, p.partition.name, p.growth,
-                             sectorsToSize(p.growth, self.sectorSize)))
-
-        if self.pool:
-            # allocate any leftovers in pool to the first partition
-            # that can still grow
-            for p in self.requests:
-                if p.done:
-                    continue
-
-                p.growth += self.pool
-                self.pool = 0
-
-                self.trimOverGrownRequest(p)
-                if self.pool == 0:
-                    break
-
-
-def getDiskChunks(disk, partitions, free):
-    """ Return a list of Chunk instances representing a disk.
-
-        Arguments:
-
-            disk -- a StorageDevice with a DiskLabel format
-            partitions -- list of PartitionDevice instances
-            free -- list of parted.Geometry instances representing free space
-
-        Partitions and free regions not on the specified disk are ignored.
-
-    """
-    # list of all new partitions on this disk
-    disk_parts = [p for p in partitions if p.disk == disk and not p.exists]
-    disk_free = [f for f in free if f.device.path == disk.path]
-
-
-    chunks = [Chunk(f) for f in disk_free]
-
-    for p in disk_parts:
-        if p.isExtended:
-            # handle extended partitions specially since they are
-            # indeed very special
-            continue
-
-        for i, f in enumerate(disk_free):
-            if f.contains(p.partedPartition.geometry):
-                chunks[i].addRequest(Request(p))
-                break
-
-    return chunks
-
-def growPartitions(disks, partitions, free):
-    """ Grow all growable partition requests.
-
-        Partitions have already been allocated from chunks of free space on
-        the disks. This function does not modify the ordering of partitions
-        or the free chunks from which they are allocated.
-
-        Free space within a given chunk is allocated to each growable
-        partition allocated from that chunk in an amount corresponding to
-        the ratio of that partition's base size to the sum of the base sizes
-        of all growable partitions allocated from the chunk.
-
-        Arguments:
-
-            disks -- a list of all usable disks (DiskDevice instances)
-            partitions -- a list of all partitions (PartitionDevice instances)
-            free -- a list of all free regions (parted.Geometry instances)
-    """
-    log.debug("growPartitions: disks=%s, partitions=%s" %
-            ([d.name for d in disks],
-             ["%s(id %d)" % (p.name, p.id) for p in partitions]))
-    all_growable = [p for p in partitions if p.req_grow]
-    if not all_growable:
-        log.debug("no growable partitions")
-        return
-
-    log.debug("growable partitions are %s" % [p.name for p in all_growable])
-
-    for disk in disks:
-        log.debug("growing partitions on %s" % disk.name)
-        sector_size = disk.format.partedDevice.sectorSize
-
-        # find any extended partition on this disk
-        extended_geometry = getattr(disk.format.extendedPartition,
-                                    "geometry",
-                                    None)  # parted.Geometry
-
-        # list of free space regions on this disk prior to partition allocation
-        disk_free = [f for f in free if f.device.path == disk.path]
-        if not disk_free:
-            log.debug("no free space on %s" % disk.name)
-            continue
-
-        chunks = getDiskChunks(disk, partitions, disk_free)
-        log.debug("disk %s has %d chunks" % (disk.name, len(chunks)))
-        # grow the partitions in each chunk as a group
-        for chunk in chunks:
-            if not chunk.hasGrowable:
-                # no growable partitions in this chunk
-                continue
-
-            chunk.growRequests()
-
-            # recalculate partition geometries
-            disklabel = disk.format
-            start = chunk.geometry.start
-            # align start sector as needed
-            if not disklabel.alignment.isAligned(chunk.geometry, start):
-                start = disklabel.alignment.alignUp(chunk.geometry, start)
-            new_partitions = []
-            for p in chunk.requests:
-                ptype = p.partition.partedPartition.type
-                log.debug("partition %s (%d): %s" % (p.partition.name,
-                                                     p.partition.id, ptype))
-                if ptype == parted.PARTITION_EXTENDED:
-                    continue
-
-                # XXX since we need one metadata sector before each
-                #     logical partition we burn one logical block to
-                #     safely align the start of each logical partition
-                if ptype == parted.PARTITION_LOGICAL:
-                    start += disklabel.alignment.grainSize
-
-                old_geometry = p.partition.partedPartition.geometry
-                new_length = p.base + p.growth
-                end = start + new_length - 1
-                # align end sector as needed
-                if not disklabel.endAlignment.isAligned(chunk.geometry, end):
-                    end = disklabel.endAlignment.alignDown(chunk.geometry, end)
-                new_geometry = parted.Geometry(device=disklabel.partedDevice,
-                                               start=start,
-                                               end=end)
-                log.debug("new geometry for %s: %s" % (p.partition.name,
-                                                       new_geometry))
-                start = end + 1
-                new_partition = parted.Partition(disk=disklabel.partedDisk,
-                                                 type=ptype,
-                                                 geometry=new_geometry)
-                new_partitions.append((new_partition, p.partition))
-
-            # remove all new partitions from this chunk
-            removeNewPartitions([disk], [r.partition for r in chunk.requests])
-            log.debug("back from removeNewPartitions")
-
-            # adjust the extended partition as needed
-            # we will ony resize an extended partition that we created
-            log.debug("extended: %s" % extended_geometry)
-            if extended_geometry and \
-               chunk.geometry.contains(extended_geometry):
-                log.debug("setting up new geometry for extended on %s" % disk.name)
-                ext_start = 0
-                ext_end = 0
-                for (partition, device) in new_partitions:
-                    if partition.type != parted.PARTITION_LOGICAL:
-                        continue
-
-                    if not ext_start or partition.geometry.start < ext_start:
-                        # account for the logical block difference in start
-                        # sector for the extended -v- first logical
-                        # (partition.geometry.start is already aligned)
-                        ext_start = partition.geometry.start - disklabel.alignment.grainSize
-
-                    if not ext_end or partition.geometry.end > ext_end:
-                        ext_end = partition.geometry.end
-
-                new_geometry = parted.Geometry(device=disklabel.partedDevice,
-                                               start=ext_start,
-                                               end=ext_end)
-                log.debug("new geometry for extended: %s" % new_geometry)
-                new_extended = parted.Partition(disk=disklabel.partedDisk,
-                                                type=parted.PARTITION_EXTENDED,
-                                                geometry=new_geometry)
-                ptypes = [p.type for (p, d) in new_partitions]
-                for pt_idx, ptype in enumerate(ptypes):
-                    if ptype == parted.PARTITION_LOGICAL:
-                        new_partitions.insert(pt_idx, (new_extended, None))
-                        break
-
-            # add the partitions with their new geometries to the disk
-            for (partition, device) in new_partitions:
-                if device:
-                    name = device.name
-                else:
-                    # If there was no extended partition on this disk when
-                    # doPartitioning was called we won't have a
-                    # PartitionDevice instance for it.
-                    name = partition.getDeviceNodeName()
-
-                log.debug("setting %s new geometry: %s" % (name,
-                                                           partition.geometry))
-                constraint = parted.Constraint(exactGeom=partition.geometry)
-                disklabel.partedDisk.addPartition(partition=partition,
-                                                  constraint=constraint)
-                path = partition.path
-                if device:
-                    # set the device's name
-                    device.partedPartition = partition
-                    # without this, the path attr will be a basename. eek.
-                    device.disk = disk
-
-                    # make sure we store the disk's version of the partition
-                    newpart = disklabel.partedDisk.getPartitionByPath(path)
-                    device.partedPartition = newpart
-
-
-def hasFreeDiskSpace(storage, exclusiveDisks=None):
-    """Returns True if there is at least 100Mb of free usable space in any of
-       the disks.  False otherwise.
-
-    """
-    # FIXME: This function needs to be implemented.  It is used, at least, by
-    # iw/partition_gui.py.  It should be implemented after the new
-    # doPartitioning code is commited for fedora 13.  Since it returns True
-    # the user will always be able to access the create partition screen. If
-    # no partition can be created, the user will go back to the previous
-    # storage state after seeing a warning message.
-    return True
-
-
-def lvCompare(lv1, lv2):
-    """ More specifically defined lvs come first.
-
-        < 1 => x < y
-          0 => x == y
-        > 1 => x > y
-    """
-    ret = 0
-
-    # larger requests go to the front of the list
-    ret -= cmp(lv1.size, lv2.size) * 100
-
-    # fixed size requests to the front
-    ret += cmp(lv1.req_grow, lv2.req_grow) * 50
-
-    # potentially larger growable requests go to the front
-    if lv1.req_grow and lv2.req_grow:
-        if not lv1.req_max_size and lv2.req_max_size:
-            ret -= 25
-        elif lv1.req_max_size and not lv2.req_max_size:
-            ret += 25
-        else:
-            ret -= cmp(lv1.req_max_size, lv2.req_max_size) * 25
-
-    if ret > 0:
-        ret = 1
-    elif ret < 0:
-        ret = -1
-
-    return ret
-
-def growLVM(storage):
-    """ Grow LVs according to the sizes of the PVs. """
-    for vg in storage.vgs:
-        total_free = vg.freeSpace
-        if total_free < 0:
-            # by now we have allocated the PVs so if there isn't enough
-            # space in the VG we have a real problem
-            raise PartitioningError("not enough space for LVM requests")
-        elif not total_free:
-            log.debug("vg %s has no free space" % vg.name)
-            continue
-
-        log.debug("vg %s: %dMB free ; lvs: %s" % (vg.name, vg.freeSpace,
-                                                  [l.lvname for l in vg.lvs]))
-
-        # figure out how much to grow each LV
-        grow_amounts = {}
-        lv_total = vg.size - total_free
-        log.debug("used: %dMB ; vg.size: %dMB" % (lv_total, vg.size))
-
-        # This first loop is to calculate percentage-based growth
-        # amounts. These are based on total free space.
-        lvs = vg.lvs
-        lvs.sort(cmp=lvCompare)
-        for lv in lvs:
-            if not lv.req_grow or not lv.req_percent:
-                continue
-
-            portion = (lv.req_percent * 0.01)
-            grow = portion * vg.vgFree
-            new_size = lv.req_size + grow
-            if lv.req_max_size and new_size > lv.req_max_size:
-                grow -= (new_size - lv.req_max_size)
-
-            if lv.format.maxSize and lv.format.maxSize < new_size:
-                grow -= (new_size - lv.format.maxSize)
-
-            # clamp growth amount to a multiple of vg extent size
-            grow_amounts[lv.name] = vg.align(grow)
-            total_free -= grow
-            lv_total += grow
-
-        # This second loop is to calculate non-percentage-based growth
-        # amounts. These are based on free space remaining after
-        # calculating percentage-based growth amounts.
-
-        # keep a tab on space not allocated due to format or requested
-        # maximums -- we'll dole it out to subsequent requests
-        leftover = 0
-        for lv in lvs:
-            log.debug("checking lv %s: req_grow: %s ; req_percent: %s"
-                      % (lv.name, lv.req_grow, lv.req_percent))
-            if not lv.req_grow or lv.req_percent:
-                continue
-
-            portion = float(lv.req_size) / float(lv_total)
-            grow = portion * total_free
-            log.debug("grow is %dMB" % grow)
-
-            todo = lvs[lvs.index(lv):]
-            unallocated = reduce(lambda x,y: x+y,
-                                 [l.req_size for l in todo
-                                  if l.req_grow and not l.req_percent])
-            extra_portion = float(lv.req_size) / float(unallocated)
-            extra = extra_portion * leftover
-            log.debug("%s getting %dMB (%d%%) of %dMB leftover space"
-                      % (lv.name, extra, extra_portion * 100, leftover))
-            leftover -= extra
-            grow += extra
-            log.debug("grow is now %dMB" % grow)
-            max_size = lv.req_size + grow
-            if lv.req_max_size and max_size > lv.req_max_size:
-                max_size = lv.req_max_size
-
-            if lv.format.maxSize and max_size > lv.format.maxSize:
-                max_size = lv.format.maxSize
-
-            log.debug("max size is %dMB" % max_size)
-            max_size = max_size
-            leftover += (lv.req_size + grow) - max_size
-            grow = max_size - lv.req_size
-            log.debug("lv %s gets %dMB" % (lv.name, vg.align(grow)))
-            grow_amounts[lv.name] = vg.align(grow)
-
-        if not grow_amounts:
-            log.debug("no growable lvs in vg %s" % vg.name)
-            continue
-
-        # now grow the lvs by the amounts we've calculated above
-        for lv in lvs:
-            if lv.name not in grow_amounts.keys():
-                continue
-            lv.size += grow_amounts[lv.name]
-
-        # now there shouldn't be any free space left, but if there is we
-        # should allocate it to one of the LVs
-        vg_free = vg.freeSpace
-        log.debug("vg %s has %dMB free" % (vg.name, vg_free))
-        if vg_free:
-            for lv in lvs:
-                if not lv.req_grow:
-                    continue
-
-                if lv.req_max_size and lv.size == lv.req_max_size:
-                    continue
-
-                if lv.format.maxSize and lv.size == lv.format.maxSize:
-                    continue
-
-                # first come, first served
-                projected = lv.size + vg.freeSpace
-                if lv.req_max_size and projected > lv.req_max_size:
-                    projected = lv.req_max_size
-
-                if lv.format.maxSize and projected > lv.format.maxSize:
-                    projected = lv.format.maxSize
-
-                log.debug("giving leftover %dMB to %s" % (projected - lv.size,
-                                                          lv.name))
-                lv.size = projected
-
diff --git a/storage/partspec.py b/storage/partspec.py
deleted file mode 100644
index 8ad81ca..0000000
--- a/storage/partspec.py
+++ /dev/null
@@ -1,66 +0,0 @@
-# partspec.py
-#
-# Copyright (C) 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, or (at your option) any later version.
-# 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.
-#
-# Red Hat Author(s): Chris Lumens <clumens@xxxxxxxxxx>
-#
-
-class PartSpec(object):
-    def __init__(self, mountpoint=None, fstype=None, size=None, maxSize=None,
-                 grow=False, asVol=False, weight=0, requiredSpace=0):
-        """ Create a new storage specification.  These are used to specify
-            the default partitioning layout as an object before we have the
-            storage system up and running.  The attributes are obvious
-            except for the following:
-
-            asVol -- Should this be allocated as a logical volume?  If not,
-                     it will be allocated as a partition.
-            weight -- An integer that modifies the sort algorithm for partition
-                      requests.  A larger value means the partition will end up
-                      closer to the front of the disk.  This is mainly used to
-                      make sure /boot ends up in front, and any special (PReP,
-                      appleboot, etc.) partitions end up in front of /boot.
-                      This value means nothing if asVol=False.
-            requiredSpace -- This value is only taken into account if
-                             asVol=True, and specifies the size in MB that the
-                             containing VG must be for this PartSpec to even
-                             get used.  The VG's size is calculated before any
-                             other LVs are created inside it.  If not enough
-                             space exists, this PartSpec will never get turned
-                             into an LV.
-        """
-
-        self.mountpoint = mountpoint
-        self.fstype = fstype
-        self.size = size
-        self.maxSize = maxSize
-        self.grow = grow
-        self.asVol = asVol
-        self.weight = weight
-        self.requiredSpace = requiredSpace
-
-    def __str__(self):
-        s = ("%(type)s instance (%(id)s) -- \n"
-             "  mountpoint = %(mountpoint)s  asVol = %(asVol)s\n"
-             "  weight = %(weight)s  fstype = %(fstype)s\n"
-             "  size = %(size)s  maxSize = %(maxSize)s  grow = %(grow)s\n" %
-             {"type": self.__class__.__name__, "id": "%#x" % id(self),
-              "mountpoint": self.mountpoint, "asVol": self.asVol,
-              "weight": self.weight, "fstype": self.fstype, "size": self.size,
-              "maxSize": self.maxSize, "grow": self.grow})
-
-        return s
diff --git a/storage/storage_log.py b/storage/storage_log.py
deleted file mode 100644
index a52513d..0000000
--- a/storage/storage_log.py
+++ /dev/null
@@ -1,32 +0,0 @@
-import logging
-import anaconda_log
-import inspect
-
-def log_method_call(d, *args, **kwargs):
-    classname = d.__class__.__name__
-    stack = inspect.stack()
-    methodname = stack[1][3]
-
-    spaces = len(stack) * ' '
-    fmt = "%s%s.%s:"
-    fmt_args = [spaces, classname, methodname]
-
-    for arg in args:
-        fmt += " %s ;"
-        fmt_args.append(arg)
-
-    for k, v in kwargs.items():
-        fmt += " %s: %s ;"
-        fmt_args.extend([k, v])
-
-    logger.debug(fmt % tuple(fmt_args))
-
-
-logger = logging.getLogger("storage")
-logger.setLevel(logging.DEBUG)
-anaconda_log.logger.addFileHandler("/tmp/storage.log", logger, logging.DEBUG)
-anaconda_log.logger.addFileHandler("/dev/tty3", logger,
-                                   anaconda_log.DEFAULT_TTY_LEVEL,
-                                   anaconda_log.TTY_FORMAT,
-                                   autoLevel=True)
-anaconda_log.logger.forwardToSyslog(logger)
diff --git a/storage/udev.py b/storage/udev.py
deleted file mode 100644
index c8ccfbf..0000000
--- a/storage/udev.py
+++ /dev/null
@@ -1,523 +0,0 @@
-# udev.py
-# Python module for querying the udev database for device information.
-#
-# Copyright (C) 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, or (at your option) any later version.
-# 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.
-#
-# Red Hat Author(s): Dave Lehman <dlehman@xxxxxxxxxx>
-#
-
-import os
-
-import iutil
-from errors import *
-from baseudev import *
-
-import logging
-log = logging.getLogger("storage")
-
-def udev_resolve_devspec(devspec):
-    if not devspec:
-        return None
-
-    import devices as _devices
-    ret = None
-    for dev in udev_get_block_devices():
-        if devspec.startswith("LABEL="):
-            if udev_device_get_label(dev) == devspec[6:]:
-                ret = dev
-                break
-        elif devspec.startswith("UUID="):
-            if udev_device_get_uuid(dev) == devspec[5:]:
-                ret = dev
-                break
-        elif udev_device_get_name(dev) == _devices.devicePathToName(devspec):
-            ret = dev
-            break
-        else:
-            for link in dev["symlinks"]:
-                if devspec == link:
-                    ret = dev
-                    break
-
-    del _devices
-    if ret:
-        return udev_device_get_name(ret)
-
-def udev_resolve_glob(glob):
-    import fnmatch
-    ret = []
-
-    if not glob:
-        return ret
-
-    for dev in udev_get_block_devices():
-        name = udev_device_get_name(dev)
-
-        if fnmatch.fnmatch(name, glob):
-            ret.append(name)
-        else:
-            for link in dev["symlinks"]:
-                if fnmatch.fnmatch(link, glob):
-                    ret.append(name)
-
-    return ret
-
-def udev_get_block_devices():
-    # Wait for scsi adapters to be done with scanning their busses (#583143)
-    iutil.execWithRedirect("modprobe", [ "scsi_wait_scan" ],
-                               stdout = "/dev/tty5", stderr="/dev/tty5")
-    iutil.execWithRedirect("rmmod", [ "scsi_wait_scan" ],
-                               stdout = "/dev/tty5", stderr="/dev/tty5")
-    udev_settle()
-    entries = []
-    for path in udev_enumerate_block_devices():
-        entry = udev_get_block_device(path)
-        if entry:
-            if entry["name"].startswith("md"):
-                # mdraid is really braindead, when a device is stopped
-                # it is no longer usefull in anyway (and we should not
-                # probe it) yet it still sticks around, see bug rh523387
-                state = None
-                state_file = "/sys/%s/md/array_state" % entry["sysfs_path"]
-                if os.access(state_file, os.R_OK):
-                    state = open(state_file).read().strip()
-                if state == "clear":
-                    continue
-            entries.append(entry)
-    return entries
-
-def __is_blacklisted_blockdev(dev_name):
-    """Is this a blockdev we never want for an install?"""
-    if dev_name.startswith("loop") or dev_name.startswith("ram") or dev_name.startswith("fd"):
-        return True
-
-    if os.path.exists("/sys/class/block/%s/device/model" %(dev_name,)):
-        model = open("/sys/class/block/%s/device/model" %(dev_name,)).read()
-        for bad in ("IBM *STMF KERNEL", "SCEI Flash-5", "DGC LUNZ"):
-            if model.find(bad) != -1:
-                log.info("ignoring %s with model %s" %(dev_name, model))
-                return True
-
-    return False
-
-def udev_enumerate_block_devices():
-    import os.path
-
-    return filter(lambda d: not __is_blacklisted_blockdev(os.path.basename(d)),
-                  udev_enumerate_devices(deviceClass="block"))
-
-def udev_get_block_device(sysfs_path):
-    dev = udev_get_device(sysfs_path)
-    if not dev or not dev.has_key("name"):
-        return None
-    else:
-        return dev
-
-
-# These are functions for retrieving specific pieces of information from
-# udev database entries.
-def udev_device_get_name(udev_info):
-    """ Return the best name for a device based on the udev db data. """
-    return udev_info.get("DM_NAME", udev_info["name"])
-
-def udev_device_get_format(udev_info):
-    """ Return a device's format type as reported by udev. """
-    return udev_info.get("ID_FS_TYPE")
-
-def udev_device_get_uuid(udev_info):
-    """ Get the UUID from the device's format as reported by udev. """
-    md_uuid = udev_info.get("MD_UUID")
-    uuid = udev_info.get("ID_FS_UUID")
-    # we don't want to return the array's uuid as a member's uuid
-    if uuid and not md_uuid == uuid:
-        return udev_info.get("ID_FS_UUID")
-
-def udev_device_get_label(udev_info):
-    """ Get the label from the device's format as reported by udev. """
-    return udev_info.get("ID_FS_LABEL")
-
-def udev_device_is_dm(info):
-    """ Return True if the device is a device-mapper device. """
-    return info.has_key("DM_NAME")
-
-def udev_device_is_md(info):
-    """ Return True if the device is a mdraid array device. """
-    # Don't identify partitions on mdraid arrays as raid arrays
-    if udev_device_is_partition(info):
-        return False
-    # isw raid set *members* have MD_METADATA set, but are not arrays!
-    return info.has_key("MD_METADATA") and \
-           info.get("ID_FS_TYPE") != "isw_raid_member"
-
-def udev_device_is_cciss(info):
-    """ Return True if the device is a CCISS device. """
-    return udev_device_get_name(info).startswith("cciss")
-
-def udev_device_is_dasd(info):
-    """ Return True if the device is a dasd device. """
-    devname = info.get("DEVNAME")
-    if devname:
-        return devname.startswith("dasd")
-    else:
-        return False
-
-def udev_device_is_zfcp(info):
-    """ Return True if the device is a zfcp device. """
-    if info.get("DEVTYPE") != "disk":
-        return False
-
-    subsystem = "/sys" + info.get("sysfs_path")
-
-    while True:
-        topdir = os.path.realpath(os.path.dirname(subsystem))
-        driver = "%s/driver" % (topdir,)
-
-        if os.path.islink(driver):
-            subsystemname = os.path.basename(os.readlink(subsystem))
-            drivername = os.path.basename(os.readlink(driver))
-
-            if subsystemname == 'ccw' and drivername == 'zfcp':
-                return True
-
-        newsubsystem = os.path.dirname(topdir)
-
-        if newsubsystem == topdir:
-            break
-
-        subsystem = newsubsystem + "/subsystem"
-
-    return False
-
-def udev_device_get_zfcp_attribute(info, attr=None):
-    """ Return the value of the specified attribute of the zfcp device. """
-    if not attr:
-        log.debug("udev_device_get_zfcp_attribute() called with attr=None")
-        return None
-
-    attribute = "/sys%s/device/%s" % (info.get("sysfs_path"), attr,)
-    attribute = os.path.realpath(attribute)
-
-    if not os.path.isfile(attribute):
-        log.warning("%s is not a valid zfcp attribute" % (attribute,))
-        return None
-
-    return open(attribute, "r").read().strip()
-
-def udev_device_get_dasd_bus_id(info):
-    """ Return the CCW bus ID of the dasd device. """
-    return info.get("sysfs_path").split("/")[-3]
-
-def udev_device_get_dasd_flag(info, flag=None):
-    """ Return the specified flag for the dasd device. """
-    if flag is None:
-        return None
-
-    path = "/sys" + info.get("sysfs_path") + "/device/" + flag
-    if not os.path.isfile(path):
-        return None
-
-    return open(path, 'r').read().strip()
-
-def udev_device_is_cdrom(info):
-    """ Return True if the device is an optical drive. """
-    # FIXME: how can we differentiate USB drives from CD-ROM drives?
-    #         -- USB drives also generate a sdX device.
-    return info.get("ID_CDROM") == "1"
-
-def udev_device_is_disk(info):
-    """ Return True is the device is a disk. """
-    if udev_device_is_cdrom(info):
-        return False
-    has_range = os.path.exists("/sys/%s/range" % info['sysfs_path'])
-    return info.get("DEVTYPE") == "disk" or has_range
-
-def udev_device_is_partition(info):
-    has_start = os.path.exists("/sys/%s/start" % info['sysfs_path'])
-    return info.get("DEVTYPE") == "partition" or has_start
-
-def udev_device_get_serial(udev_info):
-    """ Get the serial number/UUID from the device as reported by udev. """
-    return udev_info.get("ID_SERIAL_SHORT", udev_info.get("ID_SERIAL"))
-
-def udev_device_get_wwid(udev_info):
-    """ The WWID of a device is typically just its serial number, but with
-        colons in the name to make it more readable. """
-    serial = udev_device_get_serial(udev_info)
-
-    if serial and len(serial) == 32:
-        retval = ""
-        for i in range(0, 16):
-            retval += serial[i*2:i*2+2] + ":"
-
-        return retval[0:-1]
-
-    return ""
-
-def udev_device_get_vendor(udev_info):
-    """ Get the vendor of the device as reported by udev. """
-    return udev_info.get("ID_VENDOR_FROM_DATABASE", udev_info.get("ID_VENDOR"))
-
-def udev_device_get_model(udev_info):
-    """ Get the model of the device as reported by udev. """
-    return udev_info.get("ID_MODEL_FROM_DATABASE", udev_info.get("ID_MODEL"))
-
-def udev_device_get_bus(udev_info):
-    """ Get the bus a device is connected to the system by. """
-    return udev_info.get("ID_BUS", "").upper()
-
-def udev_device_get_path(info):
-    return info["ID_PATH"]
-
-def udev_device_get_by_path(info):
-    if info.has_key('symlinks'):
-        for link in info['symlinks']:
-            if link.startswith('/dev/disk/by-path/'):
-                return link
-
-    return None
-
-def udev_device_get_sysfs_path(info):
-    return info['sysfs_path']
-
-def udev_device_get_major(info):
-    return int(info["MAJOR"])
-
-def udev_device_get_minor(info):
-    return int(info["MINOR"])
-
-def udev_device_get_md_level(info):
-    return info.get("MD_LEVEL")
-
-def udev_device_get_md_devices(info):
-    return int(info["MD_DEVICES"])
-
-def udev_device_get_md_uuid(info):
-    return info["MD_UUID"]
-
-def udev_device_get_md_container(info):
-    return info.get("MD_CONTAINER")
-
-def udev_device_get_md_name(info):
-    return info.get("MD_DEVNAME")
-
-def udev_device_get_vg_name(info):
-    return info['LVM2_VG_NAME']
-
-def udev_device_get_vg_uuid(info):
-    return info['LVM2_VG_UUID']
-
-def udev_device_get_vg_size(info):
-    # lvm's decmial precision is not configurable, so we tell it to use
-    # KB and convert to MB here
-    return float(info['LVM2_VG_SIZE']) / 1024
-
-def udev_device_get_vg_free(info):
-    # lvm's decmial precision is not configurable, so we tell it to use
-    # KB and convert to MB here
-    return float(info['LVM2_VG_FREE']) / 1024
-
-def udev_device_get_vg_extent_size(info):
-    # lvm's decmial precision is not configurable, so we tell it to use
-    # KB and convert to MB here
-    return float(info['LVM2_VG_EXTENT_SIZE']) / 1024
-
-def udev_device_get_vg_extent_count(info):
-    return int(info['LVM2_VG_EXTENT_COUNT'])
-
-def udev_device_get_vg_free_extents(info):
-    return int(info['LVM2_VG_FREE_COUNT'])
-
-def udev_device_get_vg_pv_count(info):
-    return int(info['LVM2_PV_COUNT'])
-
-def udev_device_get_pv_pe_start(info):
-    # lvm's decmial precision is not configurable, so we tell it to use
-    # KB and convert to MB here
-    return float(info['LVM2_PE_START']) / 1024
-
-def udev_device_get_lv_names(info):
-    names = info['LVM2_LV_NAME']
-    if not names:
-        names = []
-    elif not isinstance(names, list):
-        names = [names]
-    return names
-
-def udev_device_get_lv_uuids(info):
-    uuids = info['LVM2_LV_UUID']
-    if not uuids:
-        uuids = []
-    elif not isinstance(uuids, list):
-        uuids = [uuids]
-    return uuids
-
-def udev_device_get_lv_sizes(info):
-    # lvm's decmial precision is not configurable, so we tell it to use
-    # KB and convert to MB here
-    sizes = info['LVM2_LV_SIZE']
-    if not sizes:
-        sizes = []
-    elif not isinstance(sizes, list):
-        sizes = [sizes]
-
-    return [float(s) / 1024 for s in sizes]
-
-def udev_device_get_lv_attr(info):
-    attr = info['LVM2_LV_ATTR']
-    if not attr:
-        attr = []
-    elif not isinstance(attr, list):
-        attr = [attr]
-    return attr
-
-def udev_device_is_biosraid(info):
-    # Note that this function does *not* identify raid sets.
-    # Tests to see if device is parto of a dmraid set.
-    # dmraid and mdraid have the same ID_FS_USAGE string, ID_FS_TYPE has a
-    # string that describes the type of dmraid (isw_raid_member...),  I don't
-    # want to maintain a list and mdraid's ID_FS_TYPE='linux_raid_member', so
-    # dmraid will be everything that is raid and not linux_raid_member
-    from formats.dmraid import DMRaidMember
-    from formats.mdraid import MDRaidMember
-    if info.has_key("ID_FS_TYPE") and \
-            (info["ID_FS_TYPE"] in DMRaidMember._udevTypes or \
-             info["ID_FS_TYPE"] in MDRaidMember._udevTypes) and \
-            info["ID_FS_TYPE"] != "linux_raid_member":
-        return True
-
-    return False
-
-def udev_device_get_dmraid_partition_disk(info):
-    try:
-        p_index = info["DM_NAME"].rindex("p")
-    except (KeyError, AttributeError, ValueError):
-        return None
-
-    if not info["DM_NAME"][p_index+1:].isdigit():
-        return None
-
-    return info["DM_NAME"][:p_index]
-
-def udev_device_is_dmraid_partition(info, devicetree):
-    diskname = udev_device_get_dmraid_partition_disk(info)
-    dmraid_devices = devicetree.getDevicesByType("dm-raid array")
-
-    for device in dmraid_devices:
-        if diskname == device.name:
-            return True
-
-    return False
-
-def udev_device_is_multipath_partition(info, devicetree):
-    """ Return True if the device is a partition of a multipath device. """
-    if not udev_device_is_dm(info):
-        return False
-    if not info["DM_NAME"].startswith("mpath"):
-        return False
-    diskname = udev_device_get_dmraid_partition_disk(info)
-    if diskname is None:
-        return False
-
-    # this is sort of a lame check, but basically, if diskname gave us "mpath0"
-    # and we start with "mpath" but we're not "mpath0", then we must be
-    # "mpath0" plus some non-numeric crap.
-    if diskname != info["DM_NAME"]:
-        return True
-
-    return False
-
-def udev_device_get_multipath_partition_disk(info):
-    """ Return True if the device is a partition of a multipath device. """
-    # XXX PJFIX This whole function is crap.
-    if not udev_device_is_dm(info):
-        return False
-    if not info["DM_NAME"].startswith("mpath"):
-        return False
-    diskname = udev_device_get_dmraid_partition_disk(info)
-    return diskname
-
-def udev_device_is_multipath_member(info):
-    """ Return True if the device is part of a multipath. """
-    return info.get("ID_FS_TYPE") == "multipath_member"
-
-def udev_device_get_multipath_name(info):
-    """ Return the name of the multipath that the device is a member of. """
-    if udev_device_is_multipath_member(info):
-        return info['ID_MPATH_NAME']
-    return None
-
-# iscsi disks have ID_PATH in the form of:
-# ip-${iscsi_address}:${iscsi_port}-iscsi-${iscsi_tgtname}-lun-${lun}
-# Note that in the case of IPV6 iscsi_address itself can contain :
-# too, but iscsi_port never contains :
-def udev_device_is_iscsi(info):
-    try:
-        path_components = udev_device_get_path(info).split("-")
-
-        if info["ID_BUS"] == "scsi" and len(path_components) >= 6 and \
-           path_components[0] == "ip" and path_components[2] == "iscsi":
-            return True
-    except KeyError:
-        pass
-
-    return False
-
-def udev_device_get_iscsi_name(info):
-    path_components = udev_device_get_path(info).split("-")
-
-    # Tricky, the name itself contains atleast 1 - char
-    return "-".join(path_components[3:len(path_components)-2])
-
-def udev_device_get_iscsi_address(info):
-    path_components = udev_device_get_path(info).split("-")
-
-    # IPV6 addresses contain : within the address, so take everything
-    # before the last : as address
-    return ":".join(path_components[1].split(":")[:-1])
-
-def udev_device_get_iscsi_port(info):
-    path_components = udev_device_get_path(info).split("-")
-
-    # IPV6 contains : within the address, the part after the last : is the port
-    return path_components[1].split(":")[-1]
-
-# fcoe disks have ID_PATH in the form of:
-# pci-eth#-fc-${id}
-# fcoe parts look like this:
-# pci-eth#-fc-${id}-part#
-def udev_device_is_fcoe(info):
-    try:
-        path_components = udev_device_get_path(info).split("-")
-
-        if info["ID_BUS"] == "scsi" and len(path_components) >= 4 and \
-           path_components[0] == "pci" and path_components[2] == "fc" and \
-           path_components[1][0:3] == "eth":
-            return True
-    except LookupError:
-        pass
-
-    return False
-
-def udev_device_get_fcoe_nic(info):
-    path_components = udev_device_get_path(info).split("-")
-
-    return path_components[1]
-
-def udev_device_get_fcoe_identifier(info):
-    path_components = udev_device_get_path(info).split("-")
-
-    return path_components[3]
diff --git a/storage/zfcp.py b/storage/zfcp.py
deleted file mode 100644
index 7692cad..0000000
--- a/storage/zfcp.py
+++ /dev/null
@@ -1,441 +0,0 @@
-#
-# zfcp.py - mainframe zfcp configuration install data
-#
-# Copyright (C) 2001, 2002, 2003, 2004  Red Hat, Inc.  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 as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# 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, see <http://www.gnu.org/licenses/>.
-#
-# Author(s): Karsten Hopp <karsten@xxxxxxxxxx>
-#
-
-import string
-import os
-from constants import *
-from udev import udev_settle
-
-import gettext
-_ = lambda x: gettext.ldgettext("anaconda", x)
-
-import logging
-log = logging.getLogger("anaconda")
-import warnings
-
-def loggedWriteLineToFile(fn, value):
-    f = open(fn, "w")
-    log.debug("echo %s > %s" % (value, fn))
-    f.write("%s\n" % (value))
-    f.close()
-
-zfcpsysfs = "/sys/bus/ccw/drivers/zfcp"
-scsidevsysfs = "/sys/bus/scsi/devices"
-
-class ZFCPDevice:
-    def __init__(self, devnum, wwpn, fcplun):
-        self.devnum = self.sanitizeDeviceInput(devnum)
-        self.wwpn = self.sanitizeWWPNInput(wwpn)
-        self.fcplun = self.sanitizeFCPLInput(fcplun)
-
-        if not self.checkValidDevice(self.devnum):
-            raise ValueError, _("You have not specified a device number or the number is invalid")
-        if not self.checkValidWWPN(self.wwpn):
-            raise ValueError, _("You have not specified a worldwide port name or the name is invalid.")
-        if not self.checkValidFCPLun(self.fcplun):
-            raise ValueError, _("You have not specified a FCP LUN or the number is invalid.")
-
-    def __str__(self):
-        return "%s %s %s" %(self.devnum, self.wwpn, self.fcplun)
-
-    def sanitizeDeviceInput(self, dev):
-        if dev is None or dev == "":
-            return None
-        dev = dev.lower()
-        bus = dev[:string.rfind(dev, ".") + 1]
-        dev = dev[string.rfind(dev, ".") + 1:]
-        dev = "0" * (4 - len(dev)) + dev
-        if not len(bus):
-            return "0.0." + dev
-        else:
-            return bus + dev
-
-    def sanitizeWWPNInput(self, id):
-        if id is None or id == "":
-            return None
-        id = id.lower()
-        if id[:2] != "0x":
-            return "0x" + id
-        return id
-
-    # ZFCP LUNs are usually entered as 16 bit, sysfs accepts only 64 bit 
-    # (#125632), expand with zeroes if necessary
-    def sanitizeFCPLInput(self, lun):
-        if lun is None or lun == "":
-            return None
-        lun = lun.lower()
-        if lun[:2] == "0x":
-            lun = lun[2:]
-        lun = "0x" + "0" * (4 - len(lun)) + lun
-        lun = lun + "0" * (16 - len(lun) + 2)
-        return lun
-
-    def _hextest(self, hex):
-        try:
-            int(hex, 16)
-            return True
-        except TypeError:
-            return False
-
-    def checkValidDevice(self, id):
-        if id is None or id == "":
-            return False
-        if len(id) != 8:             # p.e. 0.0.0600
-            return False
-        if id[0] not in string.digits or id[2] not in string.digits:
-            return False
-        if id[1] != "." or id[3] != ".":
-            return False
-        return self._hextest(id[4:])
-
-    def checkValid64BitHex(self, hex):
-        if hex is None or hex == "":
-            return False
-        if len(hex) != 18:
-            return False
-        return self._hextest(hex)
-    checkValidWWPN = checkValidFCPLun = checkValid64BitHex
-
-    def onlineDevice(self):
-        online = "%s/%s/online" %(zfcpsysfs, self.devnum)
-        portadd = "%s/%s/port_add" %(zfcpsysfs, self.devnum)
-        portdir = "%s/%s/%s" %(zfcpsysfs, self.devnum, self.wwpn)
-        unitadd = "%s/unit_add" %(portdir)
-        unitdir = "%s/%s" %(portdir, self.fcplun)
-        failed = "%s/failed" %(unitdir)
-
-        try:
-            if not os.path.exists(online):
-                loggedWriteLineToFile("/proc/cio_ignore",
-                                      "free %s" %(self.devnum,))
-                udev_settle()
-        except IOError as e:
-            raise ValueError, _("Could not free zFCP device %(devnum)s from "
-                                "device ignore list (%(e)s).") \
-                              % {'devnum': self.devnum, 'e': e}
-
-        if not os.path.exists(online):
-            raise ValueError, _(
-                "zFCP device %s not found, not even in device ignore list."
-                %(self.devnum,))
-
-        try:
-            f = open(online, "r")
-            devonline = f.readline().strip()
-            f.close()
-            if devonline != "1":
-                loggedWriteLineToFile(online, "1")
-            else:
-                log.info("zFCP device %s already online." %(self.devnum,))
-        except IOError as e:
-            raise ValueError, _("Could not set zFCP device %(devnum)s "
-                                "online (%(e)s).") \
-                              % {'devnum': self.devnum, 'e': e}
-
-        if not os.path.exists(portdir):
-            if os.path.exists(portadd):
-                # older zfcp sysfs interface
-                try:
-                    loggedWriteLineToFile(portadd, self.wwpn)
-                    udev_settle()
-                except IOError as e:
-                    raise ValueError, _("Could not add WWPN %(wwpn)s to zFCP "
-                                        "device %(devnum)s (%(e)s).") \
-                                      % {'wwpn': self.wwpn,
-                                         'devnum': self.devnum,
-                                         'e': e}
-            else:
-                # newer zfcp sysfs interface with auto port scan
-                raise ValueError, _("WWPN %(wwpn)s not found at zFCP device "
-                                    "%(devnum)s.") % {'wwpn': self.wwpn,
-                                                      'devnum': self.devnum}
-        else:
-            if os.path.exists(portadd):
-                # older zfcp sysfs interface
-                log.info("WWPN %(wwpn)s at zFCP device %(devnum)s already "
-                         "there.") % {'wwpn': self.wwpn,
-                                      'devnum': self.devnum}
-
-        if not os.path.exists(unitdir):
-            try:
-                loggedWriteLineToFile(unitadd, self.fcplun)
-                udev_settle()
-            except IOError as e:
-                raise ValueError, _("Could not add LUN %(fcplun)s to WWPN "
-                                    "%(wwpn)s on zFCP device %(devnum)s "
-                                    "(%(e)s).") \
-                                  % {'fcplun': self.fcplun, 'wwpn': self.wwpn,
-                                     'devnum': self.devnum, 'e': e}
-        else:
-            raise ValueError, _("LUN %(fcplun)s at WWPN %(wwpn)s on zFCP "
-                                "device %(devnum)s already configured.") \
-                              % {'fcplun': self.fcplun,
-                                 'wwpn': self.wwpn,
-                                 'devnum': self.devnum}
-
-        fail = "0"
-        try:
-            f = open(failed, "r")
-            fail = f.readline().strip()
-            f.close()
-        except IOError as e:
-            raise ValueError, _("Could not read failed attribute of LUN "
-                                "%(fcplun)s at WWPN %(wwpn)s on zFCP device "
-                                "%(devnum)s (%(e)s).") \
-                              % {'fcplun': self.fcplun,
-                                 'wwpn': self.wwpn,
-                                 'devnum': self.devnum,
-                                 'e': e}
-        if fail != "0":
-            self.offlineDevice()
-            raise ValueError, _("Failed LUN %(fcplun)s at WWPN %(wwpn)s on "
-                                "zFCP device %(devnum)s removed again.") \
-                              % {'fcplun': self.fcplun,
-                                 'wwpn': self.wwpn,
-                                 'devnum': self.devnum}
-
-        return True
-
-    def offlineSCSIDevice(self):
-        f = open("/proc/scsi/scsi", "r")
-        lines = f.readlines()
-        f.close()
-        # alternatively iterate over /sys/bus/scsi/devices/*:0:*:*/
-
-        for line in lines:
-            if not line.startswith("Host"):
-                continue
-            scsihost = string.split(line)
-            host = scsihost[1]
-            channel = "0"
-            id = scsihost[5]
-            lun = scsihost[7]
-            scsidev = "%s:%s:%s:%s" % (host[4:], channel, id, lun)
-            fcpsysfs = "%s/%s" % (scsidevsysfs, scsidev)
-            scsidel = "%s/%s/delete" % (scsidevsysfs, scsidev)
-
-            f = open("%s/hba_id" %(fcpsysfs), "r")
-            fcphbasysfs = f.readline().strip()
-            f.close()
-            f = open("%s/wwpn" %(fcpsysfs), "r")
-            fcpwwpnsysfs = f.readline().strip()
-            f.close()
-            f = open("%s/fcp_lun" %(fcpsysfs), "r")
-            fcplunsysfs = f.readline().strip()
-            f.close()
-
-            if fcphbasysfs == self.devnum \
-                    and fcpwwpnsysfs == self.wwpn \
-                    and fcplunsysfs == self.fcplun:
-                loggedWriteLineToFile(scsidel, "1")
-                udev_settle()
-                return
-
-        log.warn("no scsi device found to delete for zfcp %s %s %s"
-                 %(self.devnum, self.wwpn, self.fcplun))
-
-    def offlineDevice(self):
-        offline = "%s/%s/online" %(zfcpsysfs, self.devnum)
-        portadd = "%s/%s/port_add" %(zfcpsysfs, self.devnum)
-        portremove = "%s/%s/port_remove" %(zfcpsysfs, self.devnum)
-        unitremove = "%s/%s/%s/unit_remove" %(zfcpsysfs, self.devnum, self.wwpn)
-        portdir = "%s/%s/%s" %(zfcpsysfs, self.devnum, self.wwpn)
-        devdir = "%s/%s" %(zfcpsysfs, self.devnum)
-
-        try:
-            self.offlineSCSIDevice()
-        except IOError as e:
-            raise ValueError, _("Could not correctly delete SCSI device of "
-                                "zFCP %(devnum)s %(wwpn)s %(fcplun)s "
-                                "(%(e)s).") \
-                              % {'devnum': self.devnum, 'wwpn': self.wwpn,
-                                 'fcplun': self.fcplun, 'e': e}
-
-        try:
-            loggedWriteLineToFile(unitremove, self.fcplun)
-        except IOError as e:
-            raise ValueError, _("Could not remove LUN %(fcplun)s at WWPN "
-                                "%(wwpn)s on zFCP device %(devnum)s "
-                                "(%(e)s).") \
-                              % {'fcplun': self.fcplun, 'wwpn': self.wwpn,
-                                 'devnum': self.devnum, 'e': e}
-
-        if os.path.exists(portadd):
-            # only try to remove ports with older zfcp sysfs interface
-            for lun in os.listdir(portdir):
-                if lun.startswith("0x") and \
-                        os.path.isdir(os.path.join(portdir, lun)):
-                    log.info("Not removing WWPN %s at zFCP device %s since port still has other LUNs, e.g. %s."
-                             %(self.wwpn, self.devnum, lun))
-                    return True
-
-            try:
-                loggedWriteLineToFile(portremove, self.wwpn)
-            except IOError as e:
-                raise ValueError, _("Could not remove WWPN %(wwpn)s on zFCP "
-                                    "device %(devnum)s (%(e)s).") \
-                                  % {'wwpn': self.wwpn,
-                                     'devnum': self.devnum, 'e': e}
-
-        if os.path.exists(portadd):
-            # older zfcp sysfs interface
-            for port in os.listdir(devdir):
-                if port.startswith("0x") and \
-                        os.path.isdir(os.path.join(devdir, port)):
-                    log.info("Not setting zFCP device %s offline since it still has other ports, e.g. %s."
-                             %(self.devnum, port))
-                    return True
-        else:
-            # newer zfcp sysfs interface with auto port scan
-            import glob
-            luns = glob.glob("%s/0x????????????????/0x????????????????"
-                          %(devdir,))
-            if len(luns) != 0:
-                log.info("Not setting zFCP device %s offline since it still has other LUNs, e.g. %s."
-                         %(self.devnum, luns[0]))
-                return True
-
-        try:
-            loggedWriteLineToFile(offline, "0")
-        except IOError as e:
-            raise ValueError, _("Could not set zFCP device %(devnum)s "
-                                "offline (%(e)s).") \
-                              % {'devnum': self.devnum, 'e': e}
-
-        return True
-
-class ZFCP:
-    """ ZFCP utility class.
-
-        This class will automatically online to ZFCP drives configured in
-        /tmp/fcpconfig when the startup() method gets called. It can also be
-        used to manually configure ZFCP devices through the addFCP() method.
-
-        As this class needs to make sure that /tmp/fcpconfig configured
-        drives are only onlined once and as it keeps a global list of all ZFCP
-        devices it is implemented as a Singleton.
-    """
-
-    def __init__(self):
-        self.fcpdevs = []
-        self.hasReadConfig = False
-        self.down = True
-
-    # So that users can write zfcp() to get the singleton instance
-    def __call__(self):
-        return self
-
-    def readConfig(self):
-        try:
-            f = open("/tmp/fcpconfig", "r")
-        except IOError:
-            log.info("no /tmp/fcpconfig; not configuring zfcp")
-            return
-
-        lines = f.readlines()
-        f.close()
-        for line in lines:
-            # each line is a string separated list of values to describe a dev
-            # there are two valid formats for the line:
-            #   devnum scsiid wwpn scsilun fcplun    (scsiid + scsilun ignored)
-            #   devnum wwpn fcplun
-            line = string.strip(line).lower()
-            if line.startswith("#"):
-                continue
-            fcpconf = string.split(line)
-            if len(fcpconf) == 3:
-                devnum = fcpconf[0]
-                wwpn = fcpconf[1]
-                fcplun = fcpconf[2]
-            elif len(fcpconf) == 5:
-                warnings.warn("SCSI ID and SCSI LUN values for ZFCP devices are ignored and deprecated.", DeprecationWarning)
-                devnum = fcpconf[0]
-                wwpn = fcpconf[2]
-                fcplun = fcpconf[4]
-            else:
-                log.warn("Invalid line found in /tmp/fcpconfig!")
-                continue
-
-            try:
-                self.addFCP(devnum, wwpn, fcplun)
-            except ValueError, e:
-                log.warn(str(e))
-                continue
-
-    def addFCP(self, devnum, wwpn, fcplun):
-        d = ZFCPDevice(devnum, wwpn, fcplun)
-        if d.onlineDevice():
-            self.fcpdevs.append(d)
-
-    def shutdown(self):
-        if self.down:
-            return
-        self.down = True
-        if len(self.fcpdevs) == 0:
-            return
-        for d in self.fcpdevs:
-            try:
-                d.offlineDevice()
-            except ValueError, e:
-                log.warn(str(e))
-
-    def startup(self):
-        if not self.down:
-            return
-        self.down = False
-        if not self.hasReadConfig:
-            self.readConfig()
-            self.hasReadConfig = True
-            # readConfig calls addFCP which calls onlineDevice already
-            return
-            
-        if len(self.fcpdevs) == 0:
-            return
-        for d in self.fcpdevs:
-            try:
-                d.onlineDevice()
-            except ValueError, e:
-                log.warn(str(e))
-
-    def writeKS(self, f):
-        if len(self.fcpdevs) == 0:
-            return
-        for d in self.fcpdevs:
-            f.write("zfcp --devnum %s --wwpn %s --fcplun %s\n" %(d.devnum,
-                                                                 d.wwpn,
-                                                                 d.fcplun))
-
-    def write(self, instPath):
-        if len(self.fcpdevs) == 0:
-            return
-        f = open(instPath + "/etc/zfcp.conf", "w")
-        for d in self.fcpdevs:
-            f.write("%s\n" %(d,))
-        f.close()
-        
-        f = open(instPath + "/etc/modprobe.conf", "a")
-        f.write("alias scsi_hostadapter zfcp\n")
-        f.close()
-
-# Create ZFCP singleton
-ZFCP = ZFCP()
-
-# vim:tw=78:ts=4:et:sw=4
diff --git a/stubs/.gitignore b/stubs/.gitignore
deleted file mode 100644
index 6f8003e..0000000
--- a/stubs/.gitignore
+++ /dev/null
@@ -1,2 +0,0 @@
-*.so.*
-*.so
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 1c7d661..a348364 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -17,7 +17,7 @@
 #
 # Author: David Cantrell <dcantrell@xxxxxxxxxx>
 
-SUBDIRS = kickstart storage
+SUBDIRS = mock kickstart_test storage_test
 
 EXTRA_DIST = *.py
 
diff --git a/tests/__init__.py b/tests/__init__.py
deleted file mode 100644
index 784c932..0000000
--- a/tests/__init__.py
+++ /dev/null
@@ -1,31 +0,0 @@
-import os
-
-def getAvailableSuites():
-    root_dir, tests_dir = os.path.split(os.path.dirname(__file__))
-    modules = []
-
-    for root, dirs, files in os.walk(tests_dir):
-        if os.path.exists(os.path.join(root, ".disabled")):
-            continue
-        for filename in files:
-            if filename.endswith(".py") and filename != "__init__.py":
-                basename, extension = os.path.splitext(filename)
-                modules.append(os.path.join(root, basename).replace("/", "."))
-
-    available_suites = {}
-    for module in modules:
-        imported = __import__(module, globals(), locals(), [module], -1)
-        try:
-            suite = getattr(imported, "suite")
-        except AttributeError as e:
-            continue
-
-        if callable(suite):
-            available_suites[module] = suite()
-
-    return available_suites
-
-if __name__ == '__main__':
-    s = getAvailableSuites()
-    unittest.TextTestRunner(verbosity=2).run(s)
-    
diff --git a/tests/kickstart/Makefile.am b/tests/kickstart/Makefile.am
deleted file mode 100644
index 2483f65..0000000
--- a/tests/kickstart/Makefile.am
+++ /dev/null
@@ -1,26 +0,0 @@
-# tests/kickstart/Makefile.am for anaconda
-#
-# Copyright (C) 2010  Red Hat, Inc.
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU Lesser General Public License as published
-# by the Free Software Foundation; either version 2.1 of the License, or
-# (at your option) any later version.
-#
-# 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 Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public License
-# along with this program.  If not, see <http://www.gnu.org/licenses/>.
-#
-# Author: Chris Lumens <clumens@xxxxxxxxxx>
-
-EXTRA_DIST = *.py
-
-MAINTAINERCLEANFILES = Makefile.in
-
-TESTS_ENVIRONMENT = PYTHONPATH=$(top_builddir)/isys/.libs:$(top_builddir)/isys:$(top_builddir)
-
-TESTS = commands.py
diff --git a/tests/kickstart/__init__.py b/tests/kickstart/__init__.py
deleted file mode 100644
index e69de29..0000000
diff --git a/tests/kickstart/commands.py b/tests/kickstart/commands.py
deleted file mode 100755
index 63de209..0000000
--- a/tests/kickstart/commands.py
+++ /dev/null
@@ -1,61 +0,0 @@
-#!/usr/bin/python
-#
-# Copyright (C) 2010  Red Hat, Inc.
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU Lesser General Public License as published
-# by the Free Software Foundation; either version 2.1 of the License, or
-# (at your option) any later version.
-#
-# 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 Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public License
-# along with this program.  If not, see <http://www.gnu.org/licenses/>.
-#
-# Author: Chris Lumens <clumens@xxxxxxxxxx>
-import unittest
-
-# Verify that each kickstart command in anaconda uses the correct version of
-# that command as provided by pykickstart.  That is, if there's an FC3 and an
-# F10 version of a command, make sure anaconda >= F10 uses the F10 version.
-class CommandVersionTestCase(unittest.TestCase):
-    def setUp(self):
-        import kickstart
-        import pykickstart.version
-
-        self.handler = pykickstart.version.makeVersion(kickstart.ver)
-
-    def runTest(self):
-        for (commandName, commandObj) in kickstart.commandMap.iteritems():
-            baseClass = commandObj().__class__.__bases__[0]
-            pykickstartClass = self.handler.commands[commandName].__class__
-            self.assertEqual(baseClass.__name__, pykickstartClass.__name__)
-
-# Do the same thing as CommandVersionTestCase, but for data objects.
-class DataVersionTestCase(unittest.TestCase):
-    def setUp(self):
-        import kickstart
-        import pykickstart.version
-
-        self.handler = pykickstart.version.makeVersion(kickstart.ver)
-
-    def runTest(self):
-        for (dataName, dataObj) in kickstart.dataMap.iteritems():
-            baseClass = dataObj().__class__.__bases__[0]
-
-            # pykickstart does not expose data objects a mapping the way it
-            # does command objects.
-            pykickstartClass = eval("self.handler.%s" % dataName)
-
-            self.assertEqual(baseClass.__name__, pykickstartClass.__name__)
-def suite():
-    suite = unittest.TestSuite()
-    suite.addTest(CommandVersionTestCase())
-    suite.addTest(DataVersionTestCase())
-    return suite
-
-s = suite()
-unittest.TextTestRunner(verbosity=2).run(s)
diff --git a/tests/kickstart_test/Makefile.am b/tests/kickstart_test/Makefile.am
new file mode 100644
index 0000000..2483f65
--- /dev/null
+++ b/tests/kickstart_test/Makefile.am
@@ -0,0 +1,26 @@
+# tests/kickstart/Makefile.am for anaconda
+#
+# Copyright (C) 2010  Red Hat, Inc.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License as published
+# by the Free Software Foundation; either version 2.1 of the License, or
+# (at your option) any later version.
+#
+# 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 Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+#
+# Author: Chris Lumens <clumens@xxxxxxxxxx>
+
+EXTRA_DIST = *.py
+
+MAINTAINERCLEANFILES = Makefile.in
+
+TESTS_ENVIRONMENT = PYTHONPATH=$(top_builddir)/isys/.libs:$(top_builddir)/isys:$(top_builddir)
+
+TESTS = commands.py
diff --git a/tests/kickstart_test/commands_test.py b/tests/kickstart_test/commands_test.py
new file mode 100644
index 0000000..fcddced
--- /dev/null
+++ b/tests/kickstart_test/commands_test.py
@@ -0,0 +1,90 @@
+#!/usr/bin/python
+#
+# Copyright (C) 2010  Red Hat, Inc.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License as published
+# by the Free Software Foundation; either version 2.1 of the License, or
+# (at your option) any later version.
+#
+# 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 Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+#
+# Author: Chris Lumens <clumens@xxxxxxxxxx>
+import unittest
+import sys
+from mock import Mock, patch, TestCase
+
+class O(object):
+    pass
+
+# Verify that each kickstart command in anaconda uses the correct version of
+# that command as provided by pykickstart.  That is, if there's an FC3 and an
+# F10 version of a command, make sure anaconda >= F10 uses the F10 version.
+class CommandVersionTestCase(TestCase):
+    def setUp(self):
+        self.setupModules([
+            'pyanaconda.isys',
+            'pyanaconda.storage',
+            'pyanaconda.storage.isys',
+            'pyanaconda.storage.devices',
+            'pyanaconda.storage.formats',
+            'pyanaconda.storage.partitioning',
+            'pyanaconda.storage.deviceaction',
+            'pyanaconda.storage.devicelibs',
+            'pyanaconda.storage.devicelibs.lvm',
+            'pyanaconda.storage.iscsi',
+            'pyanaconda.storage.fcoe',
+            'pyanaconda.storage.zfcp',
+            'iutil',
+            'constants',
+            'flags',
+            'anaconda_log',
+            'parted',
+            'block',
+            'baseudev'])
+        
+        import pyanaconda.kickstart
+        import pykickstart.version
+
+        self.handler = pykickstart.version.makeVersion(kickstart.ver)
+
+    def tearDown(self):
+        self.tearDownModules()
+
+    def runTest(self):
+        for (commandName, commandObj) in kickstart.commandMap.iteritems():
+            baseClass = commandObj().__class__.__bases__[0]
+            pykickstartClass = self.handler.commands[commandName].__class__
+            self.assertEqual(baseClass.__name__, pykickstartClass.__name__)
+
+# Do the same thing as CommandVersionTestCase, but for data objects.
+class DataVersionTestCase(unittest.TestCase):
+    def setUp(self):
+        import pyanaconda.kickstart
+        import pykickstart.version
+
+        self.handler = pykickstart.version.makeVersion(kickstart.ver)
+
+    def runTest(self):
+        for (dataName, dataObj) in kickstart.dataMap.iteritems():
+            baseClass = dataObj().__class__.__bases__[0]
+
+            # pykickstart does not expose data objects a mapping the way it
+            # does command objects.
+            pykickstartClass = eval("self.handler.%s" % dataName)
+
+            self.assertEqual(baseClass.__name__, pykickstartClass.__name__)
+def suite():
+    suite = unittest.TestSuite()
+    suite.addTest(CommandVersionTestCase())
+    suite.addTest(DataVersionTestCase())
+    return suite
+
+s = suite()
+unittest.TextTestRunner(verbosity=2).run(s)
diff --git a/tests/mock/Makefile.am b/tests/mock/Makefile.am
new file mode 100644
index 0000000..ce35c64
--- /dev/null
+++ b/tests/mock/Makefile.am
@@ -0,0 +1,24 @@
+# tests/Makefile.am for anaconda
+#
+# Copyright (C) 2009  Red Hat, Inc.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License as published
+# by the Free Software Foundation; either version 2.1 of the License, or
+# (at your option) any later version.
+#
+# 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 Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+#
+# Author: David Cantrell <dcantrell@xxxxxxxxxx>
+
+SUBDIRS = 
+
+EXTRA_DIST = *.py
+
+MAINTAINERCLEANFILES = Makefile.in
diff --git a/tests/mock/__init__.py b/tests/mock/__init__.py
index 5e2c84d..7c1ab9f 100644
--- a/tests/mock/__init__.py
+++ b/tests/mock/__init__.py
@@ -1,2 +1,19 @@
 from disk import *
 from mock import *
+import unittest
+
+class TestCase(unittest.TestCase):
+    def __init__(self, *args, **kwargs):
+        unittest.TestCase.__init__(self, *args, **kwargs)
+        self.injectedModules = {}
+        
+    def setupModules(self, a):
+        import sys
+        for m in a:
+            sys.modules[m] = Mock()
+            self.injectedModules[m] = sys.modules[m]
+
+    def tearDownModules(self):
+        import sys
+        for k in self.injectedModules.keys():
+            del sys.modules[k]
diff --git a/tests/storage/Makefile.am b/tests/storage/Makefile.am
deleted file mode 100644
index e3e520c..0000000
--- a/tests/storage/Makefile.am
+++ /dev/null
@@ -1,24 +0,0 @@
-# tests/storage/Makefile.am for anaconda
-#
-# Copyright (C) 2009  Red Hat, Inc.
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU Lesser General Public License as published
-# by the Free Software Foundation; either version 2.1 of the License, or
-# (at your option) any later version.
-#
-# 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 Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public License
-# along with this program.  If not, see <http://www.gnu.org/licenses/>.
-#
-# Author: David Cantrell <dcantrell@xxxxxxxxxx>
-
-SUBDIRS = devicelibs
-
-EXTRA_DIST = *.py
-
-MAINTAINERCLEANFILES = Makefile.in
diff --git a/tests/storage/__init__.py b/tests/storage/__init__.py
deleted file mode 100644
index e69de29..0000000
diff --git a/tests/storage/devicelibs/Makefile.am b/tests/storage/devicelibs/Makefile.am
deleted file mode 100644
index fe45306..0000000
--- a/tests/storage/devicelibs/Makefile.am
+++ /dev/null
@@ -1,30 +0,0 @@
-# tests/storage/devicelibs/Makefile.am for anaconda
-#
-# Copyright (C) 2009  Red Hat, Inc.
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU Lesser General Public License as published
-# by the Free Software Foundation; either version 2.1 of the License, or
-# (at your option) any later version.
-#
-# 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 Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public License
-# along with this program.  If not, see <http://www.gnu.org/licenses/>.
-#
-# Author: David Cantrell <dcantrell@xxxxxxxxxx>
-
-EXTRA_DIST = *.py
-
-MAINTAINERCLEANFILES = Makefile.in
-
-TESTS_ENVIRONMENT = PYTHONPATH=$(top_builddir)/isys/.libs:$(top_builddir)/isys:$(top_builddir)
-
-TESTS = crypto.py \
-	lvm.py \
-	mdraid.py \
-	mpath.py \
-	swap.py
diff --git a/tests/storage/devicelibs/__init__.py b/tests/storage/devicelibs/__init__.py
deleted file mode 100644
index e69de29..0000000
diff --git a/tests/storage/devicelibs/baseclass.py b/tests/storage/devicelibs/baseclass.py
deleted file mode 100644
index c19bfc3..0000000
--- a/tests/storage/devicelibs/baseclass.py
+++ /dev/null
@@ -1,55 +0,0 @@
-import unittest
-import os
-import subprocess
-
-
-def makeLoopDev(device_name, file_name):
-    proc = subprocess.Popen(["dd", "if=/dev/zero", "of=%s" % file_name,
-                             "bs=1024", "count=102400"],
-                            stdout=subprocess.PIPE, stderr=subprocess.PIPE)
-    while True:
-        proc.communicate()
-        if proc.returncode is not None:
-            rc = proc.returncode
-            break
-    if rc:
-        raise OSError, "dd failed creating the file %s" % file_name
-
-    proc = subprocess.Popen(["losetup", device_name, file_name],
-                            stdout=subprocess.PIPE, stderr=subprocess.PIPE)
-    while True:
-        proc.communicate()
-        if proc.returncode is not None:
-            rc = proc.returncode
-            break
-    if rc:
-        raise OSError, "losetup failed setting up the loop device %s" % device_name
-
-def removeLoopDev(device_name, file_name):
-    proc = subprocess.Popen(["losetup", "-d", device_name],
-                            stdout=subprocess.PIPE, stderr=subprocess.PIPE)
-    while True:
-        proc.communicate()
-        if proc.returncode is not None:
-            rc = proc.returncode
-            break
-    if rc:
-        raise OSError, "losetup failed removing the loop device %s" % device_name
-
-    os.unlink(file_name)
-
-
-class DevicelibsTestCase(unittest.TestCase):
-
-    _LOOP_DEVICES = (("/dev/loop0", "/tmp/test-virtdev0"),
-                     ("/dev/loop1", "/tmp/test-virtdev1"))
-
-    ((_LOOP_DEV0, _LOOP_FILE0), (_LOOP_DEV1, _LOOP_FILE1)) = _LOOP_DEVICES
-
-    def setUp(self):
-        for dev, file in self._LOOP_DEVICES:
-            makeLoopDev(dev, file)
-
-    def tearDown(self):
-        for dev, file in self._LOOP_DEVICES:
-            removeLoopDev(dev, file)
diff --git a/tests/storage/devicelibs/crypto.py b/tests/storage/devicelibs/crypto.py
deleted file mode 100755
index 434fdcb..0000000
--- a/tests/storage/devicelibs/crypto.py
+++ /dev/null
@@ -1,131 +0,0 @@
-#!/usr/bin/python
-import baseclass
-import unittest
-
-import tempfile
-import os
-
-class CryptoTestCase(baseclass.DevicelibsTestCase):
-
-    def setUp(self):
-        baseclass.DevicelibsTestCase.setUp(self)
-        import storage.devicelibs.crypto as crypto
-
-
-    def testCrypto(self):
-        ##
-        ## is_luks
-        ##
-        # pass
-        self.assertEqual(crypto.is_luks(self._LOOP_DEV0), -22)
-        self.assertEqual(crypto.is_luks("/not/existing/device"), -22)
-
-        ##
-        ## luks_format
-        ##
-        # pass
-        self.assertEqual(crypto.luks_format(self._LOOP_DEV0, passphrase="secret", cipher="aes-cbc-essiv:sha256", key_size=256), None)
-
-        # make a key file
-        handle, keyfile = tempfile.mkstemp(prefix="key", text=False)
-        os.write(handle, "nobodyknows")
-        os.close(handle)
-
-        # format with key file
-        self.assertEqual(crypto.luks_format(self._LOOP_DEV1, key_file=keyfile), None)
-
-        # fail
-        self.assertRaises(crypto.CryptoError, crypto.luks_format, "/not/existing/device", passphrase="secret", cipher="aes-cbc-essiv:sha256", key_size=256)
-        # no passhprase or key file
-        self.assertRaises(ValueError, crypto.luks_format, self._LOOP_DEV1, cipher="aes-cbc-essiv:sha256", key_size=256)
-
-        ##
-        ## is_luks
-        ##
-        # pass
-        self.assertEqual(crypto.is_luks(self._LOOP_DEV0), 0)    # 0 = is luks
-        self.assertEqual(crypto.is_luks(self._LOOP_DEV1), 0)
-
-        ##
-        ## luks_add_key
-        ##
-        # pass
-        self.assertEqual(crypto.luks_add_key(self._LOOP_DEV0, new_passphrase="another-secret", passphrase="secret"), None)
-
-        # make another key file
-        handle, new_keyfile = tempfile.mkstemp(prefix="key", text=False)
-        os.write(handle, "area51")
-        os.close(handle)
-
-        # add new key file
-        self.assertEqual(crypto.luks_add_key(self._LOOP_DEV1, new_key_file=new_keyfile, key_file=keyfile), None)
-
-        # fail
-        self.assertRaises(RuntimeError, crypto.luks_add_key, self._LOOP_DEV0, new_passphrase="another-secret", passphrase="wrong-passphrase")
-
-        ##
-        ## luks_remove_key
-        ##
-        # fail
-        self.assertRaises(RuntimeError, crypto.luks_remove_key, self._LOOP_DEV0, del_passphrase="another-secret", passphrase="wrong-pasphrase")
-
-        # pass
-        self.assertEqual(crypto.luks_remove_key(self._LOOP_DEV0, del_passphrase="another-secret", passphrase="secret"), None)
-
-        # remove key file
-        self.assertEqual(crypto.luks_remove_key(self._LOOP_DEV1, del_key_file=new_keyfile, key_file=keyfile), None)
-
-        ##
-        ## luks_open
-        ##
-        # pass
-        self.assertEqual(crypto.luks_open(self._LOOP_DEV0, "crypted", passphrase="secret"), None)
-        self.assertEqual(crypto.luks_open(self._LOOP_DEV1, "encrypted", key_file=keyfile), None)
-
-        # fail
-        self.assertRaises(crypto.CryptoError, crypto.luks_open, "/not/existing/device", "another-crypted", passphrase="secret")
-        self.assertRaises(crypto.CryptoError, crypto.luks_open, "/not/existing/device", "another-crypted", key_file=keyfile)
-        # no passhprase or key file
-        self.assertRaises(ValueError, crypto.luks_open, self._LOOP_DEV1, "another-crypted")
-
-        ##
-        ## luks_status
-        ##
-        # pass
-        self.assertEqual(crypto.luks_status("crypted"), True)
-        self.assertEqual(crypto.luks_status("encrypted"), True)
-        self.assertEqual(crypto.luks_status("another-crypted"), False)
-
-        ##
-        ## luks_uuid
-        ##
-        # pass
-        uuid = crypto.luks_uuid(self._LOOP_DEV0)
-        self.assertEqual(crypto.luks_uuid(self._LOOP_DEV0), uuid)
-        uuid = crypto.luks_uuid(self._LOOP_DEV1)
-        self.assertEqual(crypto.luks_uuid(self._LOOP_DEV1), uuid)
-
-        ##
-        ## luks_close
-        ##
-        # pass
-        self.assertEqual(crypto.luks_close("crypted"), None)
-        self.assertEqual(crypto.luks_close("encrypted"), None)
-
-        # fail
-        self.assertRaises(crypto.CryptoError, crypto.luks_close, "wrong-name")
-        # already closed
-        self.assertRaises(crypto.CryptoError, crypto.luks_close, "crypted")
-        self.assertRaises(crypto.CryptoError, crypto.luks_close, "encrypted")
-
-        # cleanup
-        os.unlink(keyfile)
-        os.unlink(new_keyfile)
-
-
-def suite():
-    return unittest.TestLoader().loadTestsFromTestCase(CryptoTestCase)
-
-
-if __name__ == "__main__":
-    unittest.main()
diff --git a/tests/storage/devicelibs/lvm.py b/tests/storage/devicelibs/lvm.py
deleted file mode 100755
index 734644d..0000000
--- a/tests/storage/devicelibs/lvm.py
+++ /dev/null
@@ -1,234 +0,0 @@
-#!/usr/bin/python
-import baseclass
-import unittest
-
-class LVMTestCase(baseclass.DevicelibsTestCase):
-
-    def setUp(self):
-        baseclass.DevicelibsTestCase.setUp(self)
-        import storage.devicelibs.lvm as lvm
-
-    def testLVM(self):
-        ##
-        ## pvcreate
-        ##
-        # pass
-        for dev, file in self._LOOP_DEVICES:
-            self.assertEqual(lvm.pvcreate(dev), None)
-
-        # fail
-        self.assertRaises(lvm.LVMError, lvm.pvcreate, "/not/existing/device")
-
-        ##
-        ## pvresize
-        ##
-        # pass
-        for dev, file in self._LOOP_DEVICES:
-            self.assertEqual(lvm.pvresize(dev, 50), None)
-            self.assertEqual(lvm.pvresize(dev, 100), None)
-
-        # fail
-        self.assertRaises(lvm.LVMError, lvm.pvresize, "/not/existing/device", 50)
-
-        ##
-        ## vgcreate
-        ##
-        # pass
-        self.assertEqual(lvm.vgcreate("test-vg", [self._LOOP_DEV0, self._LOOP_DEV1], 4), None)
-
-        # fail
-        self.assertRaises(lvm.LVMError, lvm.vgcreate, "another-vg", ["/not/existing/device"], 4)
-        # vg already exists
-        self.assertRaises(lvm.LVMError, lvm.vgcreate, "test-vg", [self._LOOP_DEV0], 4)
-        # pe size must be power of 2
-        self.assertRaises(lvm.LVMError, lvm.vgcreate, "another-vg", [self._LOOP_DEV0], 5)
-
-        ##
-        ## pvremove
-        ##
-        # fail
-        # cannot remove pv now with vg created
-        self.assertRaises(lvm.LVMError, lvm.pvremove, self._LOOP_DEV0)
-
-        ##
-        ## vgdeactivate
-        ##
-        # pass
-        self.assertEqual(lvm.vgdeactivate("test-vg"), None)
-        
-        # fail
-        self.assertRaises(lvm.LVMError, lvm.vgdeactivate, "wrong-vg-name")
-        
-        ##
-        ## vgreduce
-        ##
-        # pass
-        self.assertEqual(lvm.vgreduce("test-vg", [self._LOOP_DEV1]), None)
-
-        # fail
-        self.assertRaises(lvm.LVMError, lvm.vgreduce, "wrong-vg-name", [self._LOOP_DEV1])
-        self.assertRaises(lvm.LVMError, lvm.vgreduce, "test-vg", ["/not/existing/device"])
-
-        ##
-        ## vgactivate
-        ##
-        # pass
-        self.assertEqual(lvm.vgactivate("test-vg"), None)
-
-        # fail
-        self.assertRaises(lvm.LVMError, lvm.vgactivate, "wrong-vg-name")
-        
-        ##
-        ## pvinfo
-        ##
-        # pass
-        self.assertEqual(lvm.pvinfo(self._LOOP_DEV0)["pv_name"], self._LOOP_DEV0)
-        # no vg
-        self.assertEqual(lvm.pvinfo(self._LOOP_DEV1)["pv_name"], self._LOOP_DEV1)
-
-        # fail
-        self.assertRaises(lvm.LVMError, lvm.pvinfo, "/not/existing/device")
-
-        ##
-        ## vginfo
-        ##
-        # pass
-        self.assertEqual(lvm.vginfo("test-vg")["pe_size"], "4.00")
-
-        # fail
-        self.assertRaises(lvm.LVMError, lvm.vginfo, "wrong-vg-name")
-
-        ##
-        ## lvcreate
-        ##
-        # pass
-        self.assertEqual(lvm.lvcreate("test-vg", "test-lv", 10), None)
-
-        # fail
-        self.assertRaises(lvm.LVMError, lvm.lvcreate, "wrong-vg-name", "another-lv", 10)
-
-        ##
-        ## lvdeactivate
-        ##
-        # pass
-        self.assertEqual(lvm.lvdeactivate("test-vg", "test-lv"), None)
-
-        # fail
-        self.assertRaises(lvm.LVMError, lvm.lvdeactivate, "test-vg", "wrong-lv-name")
-        self.assertRaises(lvm.LVMError, lvm.lvdeactivate, "wrong-vg-name", "test-lv")
-        self.assertRaises(lvm.LVMError, lvm.lvdeactivate, "wrong-vg-name", "wrong-lv-name")
-
-        ##
-        ## lvresize
-        ##
-        # pass
-        self.assertEqual(lvm.lvresize("test-vg", "test-lv", 60), None)
-
-        # fail
-        self.assertRaises(lvm.LVMError, lvm.lvresize, "test-vg", "wrong-lv-name", 80)
-        self.assertRaises(lvm.LVMError, lvm.lvresize, "wrong-vg-name", "test-lv", 80)
-        self.assertRaises(lvm.LVMError, lvm.lvresize, "wrong-vg-name", "wrong-lv-name", 80)
-        # changing to same size
-        self.assertRaises(lvm.LVMError, lvm.lvresize, "test-vg", "test-lv", 60)
-
-        ##
-        ## lvactivate
-        ##
-        # pass
-        self.assertEqual(lvm.lvactivate("test-vg", "test-lv"), None)
-
-        # fail
-        self.assertRaises(lvm.LVMError, lvm.lvactivate, "test-vg", "wrong-lv-name")
-        self.assertRaises(lvm.LVMError, lvm.lvactivate, "wrong-vg-name", "test-lv")
-        self.assertRaises(lvm.LVMError, lvm.lvactivate, "wrong-vg-name", "wrong-lv-name")
-
-        ##
-        ## lvs
-        ##
-        # pass
-        self.assertEqual(lvm.lvs("test-vg")["test-lv"]["size"], "60.00")
-
-        # fail
-        self.assertRaises(lvm.LVMError, lvm.lvs, "wrong-vg-name")
-
-        ##
-        ## has_lvm
-        ##
-        # pass
-        self.assertEqual(lvm.has_lvm(), True)
-
-        # fail
-        # TODO
-
-        ##
-        ## lvremove
-        ##
-        # pass
-        self.assertEqual(lvm.lvdeactivate("test-vg", "test-lv"), None)      # is deactivation needed?
-        self.assertEqual(lvm.lvremove("test-vg", "test-lv"), None)
-
-        # fail
-        self.assertRaises(lvm.LVMError, lvm.lvremove, "test-vg", "wrong-lv-name")
-        self.assertRaises(lvm.LVMError, lvm.lvremove, "wrong-vg-name", "test-lv")
-        self.assertRaises(lvm.LVMError, lvm.lvremove, "wrong-vg-name", "wrong-lv-name")
-        # lv already removed
-        self.assertRaises(lvm.LVMError, lvm.lvremove, "test-vg", "test-lv")
-
-        ##
-        ## vgremove
-        ##
-        # pass
-        self.assertEqual(lvm.vgremove("test-vg"), None)
-
-        # fail
-        self.assertRaises(lvm.LVMError, lvm.vgremove, "wrong-vg-name")
-        # vg already removed
-        self.assertRaises(lvm.LVMError, lvm.vgremove, "test-vg")
-
-        ##
-        ## pvremove
-        ##
-        # pass
-        for dev, file in self._LOOP_DEVICES:
-            self.assertEqual(lvm.pvremove(dev), None)
-
-        # fail
-        self.assertRaises(lvm.LVMError, lvm.pvremove, "/not/existing/device")
-        # pv already removed
-        self.assertRaises(lvm.LVMError, lvm.pvremove, self._LOOP_DEV0)
-
-    #def testGetPossiblePhysicalExtents(self):
-        # pass
-        self.assertEqual(lvm.getPossiblePhysicalExtents(4),
-                         filter(lambda pe: pe > 4, map(lambda power: 2**power, xrange(3, 25))))
-        self.assertEqual(lvm.getPossiblePhysicalExtents(100000),
-                         filter(lambda pe: pe > 100000, map(lambda power: 2**power, xrange(3, 25))))
-
-    #def testGetMaxLVSize(self):
-        # pass
-        self.assertEqual(lvm.getMaxLVSize(), 16*1024**2)
-
-    #def testSafeLVMName(self):
-        # pass
-        self.assertEqual(lvm.safeLvmName("/strange/lv*name5"), "strange_lvname5")
-
-    #def testClampSize(self):
-        # pass
-        self.assertEqual(lvm.clampSize(10, 4), 8L)
-        self.assertEqual(lvm.clampSize(10, 4, True), 12L)
-
-    #def testVGUsedSpace(self):
-        # TODO
-        pass
-
-    #def testVGFreeSpace(self):
-        # TODO
-        pass
-
-
-def suite():
-    return unittest.TestLoader().loadTestsFromTestCase(LVMTestCase)
-
-
-if __name__ == "__main__":
-    unittest.main()
diff --git a/tests/storage/devicelibs/mdraid.py b/tests/storage/devicelibs/mdraid.py
deleted file mode 100755
index 9dde22d..0000000
--- a/tests/storage/devicelibs/mdraid.py
+++ /dev/null
@@ -1,110 +0,0 @@
-#!/usr/bin/python
-import baseclass
-import unittest
-import time
-
-class MDRaidTestCase(baseclass.DevicelibsTestCase):
-
-    def setUp(self):
-        baseclass.DevicelibsTestCase.setUp(self)
-        import storage.devicelibs.mdraid as mdraid
-
-    def testMDRaid(self):
-        ##
-        ## getRaidLevels
-        ##
-        # pass
-        self.assertEqual(mdraid.getRaidLevels(), mdraid.getRaidLevels())
-
-        ##
-        ## get_raid_min_members
-        ##
-        # pass
-        self.assertEqual(mdraid.get_raid_min_members(mdraid.RAID0), 2)
-        self.assertEqual(mdraid.get_raid_min_members(mdraid.RAID1), 2)
-        self.assertEqual(mdraid.get_raid_min_members(mdraid.RAID5), 3)
-        self.assertEqual(mdraid.get_raid_min_members(mdraid.RAID6), 4)
-        self.assertEqual(mdraid.get_raid_min_members(mdraid.RAID10), 2)
-
-        # fail
-        # unsupported raid
-        self.assertRaises(ValueError, mdraid.get_raid_min_members, 4)
-
-        ##
-        ## get_raid_max_spares
-        ##
-        # pass
-        self.assertEqual(mdraid.get_raid_max_spares(mdraid.RAID0, 5), 0)
-        self.assertEqual(mdraid.get_raid_max_spares(mdraid.RAID1, 5), 3)
-        self.assertEqual(mdraid.get_raid_max_spares(mdraid.RAID5, 5), 2)
-        self.assertEqual(mdraid.get_raid_max_spares(mdraid.RAID6, 5), 1)
-        self.assertEqual(mdraid.get_raid_max_spares(mdraid.RAID10, 5), 3)
-
-        # fail
-        # unsupported raid
-        self.assertRaises(ValueError, mdraid.get_raid_max_spares, 4, 5)
-
-        ##
-        ## mdcreate
-        ##
-        # pass
-        self.assertEqual(mdraid.mdcreate("/dev/md0", 1, [self._LOOP_DEV0, self._LOOP_DEV1]), None)
-        # wait for raid to settle
-        time.sleep(2)
-
-        # fail
-        self.assertRaises(mdraid.MDRaidError, mdraid.mdcreate, "/dev/md1", 1, ["/not/existing/dev0", "/not/existing/dev1"])
-
-        ##
-        ## mddeactivate
-        ##
-        # pass
-        self.assertEqual(mdraid.mddeactivate("/dev/md0"), None)
-
-        # fail
-        self.assertRaises(mdraid.MDRaidError, mdraid.mddeactivate, "/not/existing/md")
-
-        ##
-        ## mdadd
-        ##
-        # pass
-        # TODO
-
-        # fail
-        self.assertRaises(mdraid.MDRaidError, mdraid.mdadd, "/not/existing/device")
-
-        ##
-        ## mdactivate
-        ##
-        # pass
-        self.assertEqual(mdraid.mdactivate("/dev/md0", [self._LOOP_DEV0, self._LOOP_DEV1], super_minor=0), None)
-        # wait for raid to settle
-        time.sleep(2)
-
-        # fail
-        self.assertRaises(mdraid.MDRaidError, mdraid.mdactivate, "/not/existing/md", super_minor=1)
-        # requires super_minor or uuid
-        self.assertRaises(ValueError, mdraid.mdactivate, "/dev/md1")
-
-        ##
-        ## mddestroy
-        ##
-        # pass
-        # deactivate first
-        self.assertEqual(mdraid.mddeactivate("/dev/md0"), None)
-
-        self.assertEqual(mdraid.mddestroy(self._LOOP_DEV0), None)
-        self.assertEqual(mdraid.mddestroy(self._LOOP_DEV1), None)
-
-        # fail
-        # not a component
-        self.assertRaises(mdraid.MDRaidError, mdraid.mddestroy, "/dev/md0")
-        self.assertRaises(mdraid.MDRaidError, mdraid.mddestroy, "/not/existing/device")
-
-
-def suite():
-    return unittest.TestLoader().loadTestsFromTestCase(MDRaidTestCase)
-
-
-if __name__ == "__main__":
-    unittest.main()
diff --git a/tests/storage/devicelibs/mpath.py b/tests/storage/devicelibs/mpath.py
deleted file mode 100755
index 813a516..0000000
--- a/tests/storage/devicelibs/mpath.py
+++ /dev/null
@@ -1,33 +0,0 @@
-#!/usr/bin/python
-import baseclass
-import unittest
-
-class MPathTestCase(baseclass.DevicelibsTestCase):
-    def setUp(self):
-        baseclass.DevicelibsTestCase.setUp(self)
-        import storage.devicelibs.mpath as mpath
-
-    def testMPath(self):
-        ##
-        ## parseMultipathOutput
-        ## 
-        output="""\
-create: mpathb (1ATA     ST3120026AS                                         5M) undef ATA,ST3120026AS
-size=112G features='0' hwhandler='0' wp=undef
-`-+- policy='round-robin 0' prio=1 status=undef
-  `- 2:0:0:0 sda 8:0  undef ready running
-create: mpatha (36006016092d21800703762872c60db11) undef DGC,RAID 5
-size=10G features='1 queue_if_no_path' hwhandler='1 emc' wp=undef
-`-+- policy='round-robin 0' prio=2 status=undef
-  |- 6:0:0:0 sdb 8:16 undef ready running
-  `- 7:0:0:0 sdc 8:32 undef ready running
-"""
-        topology = mpath.parseMultipathOutput(output)
-        expected = {'mpatha':['sdb','sdc'], 'mpathb':['sda']}
-        self.assertEqual(topology, expected)
-
-def suite():
-    return unittest.TestLoader().loadTestsFromTestCase(MPathTestCase)
-
-if __name__ == '__main__':
-    unittest.main()
diff --git a/tests/storage/devicelibs/swap.py b/tests/storage/devicelibs/swap.py
deleted file mode 100755
index ddf8d21..0000000
--- a/tests/storage/devicelibs/swap.py
+++ /dev/null
@@ -1,70 +0,0 @@
-#!/usr/bin/python
-import baseclass
-import unittest
-
-class SwapTestCase(baseclass.DevicelibsTestCase):
-
-    def setUp(self):
-        baseclass.DevicelibsTestCase.setUp(self)
-        import storage.devicelibs.swap as swap
-
-    def testSwap(self):
-        ##
-        ## mkswap
-        ##
-        # pass
-        self.assertEqual(swap.mkswap(self._LOOP_DEV0, "swap"), None)
-
-        # fail
-        self.assertRaises(swap.SwapError, swap.mkswap, "/not/existing/device")
-        
-        ##
-        ## swapon
-        ##
-        # pass
-        self.assertEqual(swap.swapon(self._LOOP_DEV0, 1), None)
-
-        # fail
-        self.assertRaises(swap.SwapError, swap.swapon, "/not/existing/device")
-        # not a swap partition
-        self.assertRaises(swap.SwapError, swap.swapon, self._LOOP_DEV1)
-        
-        # pass
-        # make another swap
-        self.assertEqual(swap.mkswap(self._LOOP_DEV1, "another-swap"), None)
-        self.assertEqual(swap.swapon(self._LOOP_DEV1), None)
-
-        ##
-        ## swapstatus
-        ##
-        # pass
-        self.assertEqual(swap.swapstatus(self._LOOP_DEV0), True)
-        self.assertEqual(swap.swapstatus(self._LOOP_DEV1), True)
-        
-        # does not fail
-        self.assertEqual(swap.swapstatus("/not/existing/device"), False)
-
-        ##
-        ## swapoff
-        ##
-        # pass
-        self.assertEqual(swap.swapoff(self._LOOP_DEV1), None)
-
-        # check status
-        self.assertEqual(swap.swapstatus(self._LOOP_DEV0), True)
-        self.assertEqual(swap.swapstatus(self._LOOP_DEV1), False)
-
-        self.assertEqual(swap.swapoff(self._LOOP_DEV0), None)
-
-        # fail
-        self.assertRaises(swap.SwapError, swap.swapoff, "/not/existing/device")
-        # already off
-        self.assertRaises(swap.SwapError, swap.swapoff, self._LOOP_DEV0)
-
-
-def suite():
-    return unittest.TestLoader().loadTestsFromTestCase(SwapTestCase)
-
-
-if __name__ == "__main__":
-    unittest.main()
diff --git a/tests/storage_test/Makefile.am b/tests/storage_test/Makefile.am
new file mode 100644
index 0000000..23565ab
--- /dev/null
+++ b/tests/storage_test/Makefile.am
@@ -0,0 +1,24 @@
+# tests/storage/Makefile.am for anaconda
+#
+# Copyright (C) 2009  Red Hat, Inc.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License as published
+# by the Free Software Foundation; either version 2.1 of the License, or
+# (at your option) any later version.
+#
+# 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 Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+#
+# Author: David Cantrell <dcantrell@xxxxxxxxxx>
+
+SUBDIRS = devicelibs_test
+
+EXTRA_DIST = *.py
+
+MAINTAINERCLEANFILES = Makefile.in
diff --git a/tests/storage_test/devicelibs_test/Makefile.am b/tests/storage_test/devicelibs_test/Makefile.am
new file mode 100644
index 0000000..fe45306
--- /dev/null
+++ b/tests/storage_test/devicelibs_test/Makefile.am
@@ -0,0 +1,30 @@
+# tests/storage/devicelibs/Makefile.am for anaconda
+#
+# Copyright (C) 2009  Red Hat, Inc.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License as published
+# by the Free Software Foundation; either version 2.1 of the License, or
+# (at your option) any later version.
+#
+# 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 Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+#
+# Author: David Cantrell <dcantrell@xxxxxxxxxx>
+
+EXTRA_DIST = *.py
+
+MAINTAINERCLEANFILES = Makefile.in
+
+TESTS_ENVIRONMENT = PYTHONPATH=$(top_builddir)/isys/.libs:$(top_builddir)/isys:$(top_builddir)
+
+TESTS = crypto.py \
+	lvm.py \
+	mdraid.py \
+	mpath.py \
+	swap.py
diff --git a/tests/storage_test/devicelibs_test/baseclass.py b/tests/storage_test/devicelibs_test/baseclass.py
new file mode 100644
index 0000000..c19bfc3
--- /dev/null
+++ b/tests/storage_test/devicelibs_test/baseclass.py
@@ -0,0 +1,55 @@
+import unittest
+import os
+import subprocess
+
+
+def makeLoopDev(device_name, file_name):
+    proc = subprocess.Popen(["dd", "if=/dev/zero", "of=%s" % file_name,
+                             "bs=1024", "count=102400"],
+                            stdout=subprocess.PIPE, stderr=subprocess.PIPE)
+    while True:
+        proc.communicate()
+        if proc.returncode is not None:
+            rc = proc.returncode
+            break
+    if rc:
+        raise OSError, "dd failed creating the file %s" % file_name
+
+    proc = subprocess.Popen(["losetup", device_name, file_name],
+                            stdout=subprocess.PIPE, stderr=subprocess.PIPE)
+    while True:
+        proc.communicate()
+        if proc.returncode is not None:
+            rc = proc.returncode
+            break
+    if rc:
+        raise OSError, "losetup failed setting up the loop device %s" % device_name
+
+def removeLoopDev(device_name, file_name):
+    proc = subprocess.Popen(["losetup", "-d", device_name],
+                            stdout=subprocess.PIPE, stderr=subprocess.PIPE)
+    while True:
+        proc.communicate()
+        if proc.returncode is not None:
+            rc = proc.returncode
+            break
+    if rc:
+        raise OSError, "losetup failed removing the loop device %s" % device_name
+
+    os.unlink(file_name)
+
+
+class DevicelibsTestCase(unittest.TestCase):
+
+    _LOOP_DEVICES = (("/dev/loop0", "/tmp/test-virtdev0"),
+                     ("/dev/loop1", "/tmp/test-virtdev1"))
+
+    ((_LOOP_DEV0, _LOOP_FILE0), (_LOOP_DEV1, _LOOP_FILE1)) = _LOOP_DEVICES
+
+    def setUp(self):
+        for dev, file in self._LOOP_DEVICES:
+            makeLoopDev(dev, file)
+
+    def tearDown(self):
+        for dev, file in self._LOOP_DEVICES:
+            removeLoopDev(dev, file)
diff --git a/tests/storage_test/devicelibs_test/crypto_test.py b/tests/storage_test/devicelibs_test/crypto_test.py
new file mode 100644
index 0000000..434fdcb
--- /dev/null
+++ b/tests/storage_test/devicelibs_test/crypto_test.py
@@ -0,0 +1,131 @@
+#!/usr/bin/python
+import baseclass
+import unittest
+
+import tempfile
+import os
+
+class CryptoTestCase(baseclass.DevicelibsTestCase):
+
+    def setUp(self):
+        baseclass.DevicelibsTestCase.setUp(self)
+        import storage.devicelibs.crypto as crypto
+
+
+    def testCrypto(self):
+        ##
+        ## is_luks
+        ##
+        # pass
+        self.assertEqual(crypto.is_luks(self._LOOP_DEV0), -22)
+        self.assertEqual(crypto.is_luks("/not/existing/device"), -22)
+
+        ##
+        ## luks_format
+        ##
+        # pass
+        self.assertEqual(crypto.luks_format(self._LOOP_DEV0, passphrase="secret", cipher="aes-cbc-essiv:sha256", key_size=256), None)
+
+        # make a key file
+        handle, keyfile = tempfile.mkstemp(prefix="key", text=False)
+        os.write(handle, "nobodyknows")
+        os.close(handle)
+
+        # format with key file
+        self.assertEqual(crypto.luks_format(self._LOOP_DEV1, key_file=keyfile), None)
+
+        # fail
+        self.assertRaises(crypto.CryptoError, crypto.luks_format, "/not/existing/device", passphrase="secret", cipher="aes-cbc-essiv:sha256", key_size=256)
+        # no passhprase or key file
+        self.assertRaises(ValueError, crypto.luks_format, self._LOOP_DEV1, cipher="aes-cbc-essiv:sha256", key_size=256)
+
+        ##
+        ## is_luks
+        ##
+        # pass
+        self.assertEqual(crypto.is_luks(self._LOOP_DEV0), 0)    # 0 = is luks
+        self.assertEqual(crypto.is_luks(self._LOOP_DEV1), 0)
+
+        ##
+        ## luks_add_key
+        ##
+        # pass
+        self.assertEqual(crypto.luks_add_key(self._LOOP_DEV0, new_passphrase="another-secret", passphrase="secret"), None)
+
+        # make another key file
+        handle, new_keyfile = tempfile.mkstemp(prefix="key", text=False)
+        os.write(handle, "area51")
+        os.close(handle)
+
+        # add new key file
+        self.assertEqual(crypto.luks_add_key(self._LOOP_DEV1, new_key_file=new_keyfile, key_file=keyfile), None)
+
+        # fail
+        self.assertRaises(RuntimeError, crypto.luks_add_key, self._LOOP_DEV0, new_passphrase="another-secret", passphrase="wrong-passphrase")
+
+        ##
+        ## luks_remove_key
+        ##
+        # fail
+        self.assertRaises(RuntimeError, crypto.luks_remove_key, self._LOOP_DEV0, del_passphrase="another-secret", passphrase="wrong-pasphrase")
+
+        # pass
+        self.assertEqual(crypto.luks_remove_key(self._LOOP_DEV0, del_passphrase="another-secret", passphrase="secret"), None)
+
+        # remove key file
+        self.assertEqual(crypto.luks_remove_key(self._LOOP_DEV1, del_key_file=new_keyfile, key_file=keyfile), None)
+
+        ##
+        ## luks_open
+        ##
+        # pass
+        self.assertEqual(crypto.luks_open(self._LOOP_DEV0, "crypted", passphrase="secret"), None)
+        self.assertEqual(crypto.luks_open(self._LOOP_DEV1, "encrypted", key_file=keyfile), None)
+
+        # fail
+        self.assertRaises(crypto.CryptoError, crypto.luks_open, "/not/existing/device", "another-crypted", passphrase="secret")
+        self.assertRaises(crypto.CryptoError, crypto.luks_open, "/not/existing/device", "another-crypted", key_file=keyfile)
+        # no passhprase or key file
+        self.assertRaises(ValueError, crypto.luks_open, self._LOOP_DEV1, "another-crypted")
+
+        ##
+        ## luks_status
+        ##
+        # pass
+        self.assertEqual(crypto.luks_status("crypted"), True)
+        self.assertEqual(crypto.luks_status("encrypted"), True)
+        self.assertEqual(crypto.luks_status("another-crypted"), False)
+
+        ##
+        ## luks_uuid
+        ##
+        # pass
+        uuid = crypto.luks_uuid(self._LOOP_DEV0)
+        self.assertEqual(crypto.luks_uuid(self._LOOP_DEV0), uuid)
+        uuid = crypto.luks_uuid(self._LOOP_DEV1)
+        self.assertEqual(crypto.luks_uuid(self._LOOP_DEV1), uuid)
+
+        ##
+        ## luks_close
+        ##
+        # pass
+        self.assertEqual(crypto.luks_close("crypted"), None)
+        self.assertEqual(crypto.luks_close("encrypted"), None)
+
+        # fail
+        self.assertRaises(crypto.CryptoError, crypto.luks_close, "wrong-name")
+        # already closed
+        self.assertRaises(crypto.CryptoError, crypto.luks_close, "crypted")
+        self.assertRaises(crypto.CryptoError, crypto.luks_close, "encrypted")
+
+        # cleanup
+        os.unlink(keyfile)
+        os.unlink(new_keyfile)
+
+
+def suite():
+    return unittest.TestLoader().loadTestsFromTestCase(CryptoTestCase)
+
+
+if __name__ == "__main__":
+    unittest.main()
diff --git a/tests/storage_test/devicelibs_test/lvm_test.py b/tests/storage_test/devicelibs_test/lvm_test.py
new file mode 100644
index 0000000..734644d
--- /dev/null
+++ b/tests/storage_test/devicelibs_test/lvm_test.py
@@ -0,0 +1,234 @@
+#!/usr/bin/python
+import baseclass
+import unittest
+
+class LVMTestCase(baseclass.DevicelibsTestCase):
+
+    def setUp(self):
+        baseclass.DevicelibsTestCase.setUp(self)
+        import storage.devicelibs.lvm as lvm
+
+    def testLVM(self):
+        ##
+        ## pvcreate
+        ##
+        # pass
+        for dev, file in self._LOOP_DEVICES:
+            self.assertEqual(lvm.pvcreate(dev), None)
+
+        # fail
+        self.assertRaises(lvm.LVMError, lvm.pvcreate, "/not/existing/device")
+
+        ##
+        ## pvresize
+        ##
+        # pass
+        for dev, file in self._LOOP_DEVICES:
+            self.assertEqual(lvm.pvresize(dev, 50), None)
+            self.assertEqual(lvm.pvresize(dev, 100), None)
+
+        # fail
+        self.assertRaises(lvm.LVMError, lvm.pvresize, "/not/existing/device", 50)
+
+        ##
+        ## vgcreate
+        ##
+        # pass
+        self.assertEqual(lvm.vgcreate("test-vg", [self._LOOP_DEV0, self._LOOP_DEV1], 4), None)
+
+        # fail
+        self.assertRaises(lvm.LVMError, lvm.vgcreate, "another-vg", ["/not/existing/device"], 4)
+        # vg already exists
+        self.assertRaises(lvm.LVMError, lvm.vgcreate, "test-vg", [self._LOOP_DEV0], 4)
+        # pe size must be power of 2
+        self.assertRaises(lvm.LVMError, lvm.vgcreate, "another-vg", [self._LOOP_DEV0], 5)
+
+        ##
+        ## pvremove
+        ##
+        # fail
+        # cannot remove pv now with vg created
+        self.assertRaises(lvm.LVMError, lvm.pvremove, self._LOOP_DEV0)
+
+        ##
+        ## vgdeactivate
+        ##
+        # pass
+        self.assertEqual(lvm.vgdeactivate("test-vg"), None)
+        
+        # fail
+        self.assertRaises(lvm.LVMError, lvm.vgdeactivate, "wrong-vg-name")
+        
+        ##
+        ## vgreduce
+        ##
+        # pass
+        self.assertEqual(lvm.vgreduce("test-vg", [self._LOOP_DEV1]), None)
+
+        # fail
+        self.assertRaises(lvm.LVMError, lvm.vgreduce, "wrong-vg-name", [self._LOOP_DEV1])
+        self.assertRaises(lvm.LVMError, lvm.vgreduce, "test-vg", ["/not/existing/device"])
+
+        ##
+        ## vgactivate
+        ##
+        # pass
+        self.assertEqual(lvm.vgactivate("test-vg"), None)
+
+        # fail
+        self.assertRaises(lvm.LVMError, lvm.vgactivate, "wrong-vg-name")
+        
+        ##
+        ## pvinfo
+        ##
+        # pass
+        self.assertEqual(lvm.pvinfo(self._LOOP_DEV0)["pv_name"], self._LOOP_DEV0)
+        # no vg
+        self.assertEqual(lvm.pvinfo(self._LOOP_DEV1)["pv_name"], self._LOOP_DEV1)
+
+        # fail
+        self.assertRaises(lvm.LVMError, lvm.pvinfo, "/not/existing/device")
+
+        ##
+        ## vginfo
+        ##
+        # pass
+        self.assertEqual(lvm.vginfo("test-vg")["pe_size"], "4.00")
+
+        # fail
+        self.assertRaises(lvm.LVMError, lvm.vginfo, "wrong-vg-name")
+
+        ##
+        ## lvcreate
+        ##
+        # pass
+        self.assertEqual(lvm.lvcreate("test-vg", "test-lv", 10), None)
+
+        # fail
+        self.assertRaises(lvm.LVMError, lvm.lvcreate, "wrong-vg-name", "another-lv", 10)
+
+        ##
+        ## lvdeactivate
+        ##
+        # pass
+        self.assertEqual(lvm.lvdeactivate("test-vg", "test-lv"), None)
+
+        # fail
+        self.assertRaises(lvm.LVMError, lvm.lvdeactivate, "test-vg", "wrong-lv-name")
+        self.assertRaises(lvm.LVMError, lvm.lvdeactivate, "wrong-vg-name", "test-lv")
+        self.assertRaises(lvm.LVMError, lvm.lvdeactivate, "wrong-vg-name", "wrong-lv-name")
+
+        ##
+        ## lvresize
+        ##
+        # pass
+        self.assertEqual(lvm.lvresize("test-vg", "test-lv", 60), None)
+
+        # fail
+        self.assertRaises(lvm.LVMError, lvm.lvresize, "test-vg", "wrong-lv-name", 80)
+        self.assertRaises(lvm.LVMError, lvm.lvresize, "wrong-vg-name", "test-lv", 80)
+        self.assertRaises(lvm.LVMError, lvm.lvresize, "wrong-vg-name", "wrong-lv-name", 80)
+        # changing to same size
+        self.assertRaises(lvm.LVMError, lvm.lvresize, "test-vg", "test-lv", 60)
+
+        ##
+        ## lvactivate
+        ##
+        # pass
+        self.assertEqual(lvm.lvactivate("test-vg", "test-lv"), None)
+
+        # fail
+        self.assertRaises(lvm.LVMError, lvm.lvactivate, "test-vg", "wrong-lv-name")
+        self.assertRaises(lvm.LVMError, lvm.lvactivate, "wrong-vg-name", "test-lv")
+        self.assertRaises(lvm.LVMError, lvm.lvactivate, "wrong-vg-name", "wrong-lv-name")
+
+        ##
+        ## lvs
+        ##
+        # pass
+        self.assertEqual(lvm.lvs("test-vg")["test-lv"]["size"], "60.00")
+
+        # fail
+        self.assertRaises(lvm.LVMError, lvm.lvs, "wrong-vg-name")
+
+        ##
+        ## has_lvm
+        ##
+        # pass
+        self.assertEqual(lvm.has_lvm(), True)
+
+        # fail
+        # TODO
+
+        ##
+        ## lvremove
+        ##
+        # pass
+        self.assertEqual(lvm.lvdeactivate("test-vg", "test-lv"), None)      # is deactivation needed?
+        self.assertEqual(lvm.lvremove("test-vg", "test-lv"), None)
+
+        # fail
+        self.assertRaises(lvm.LVMError, lvm.lvremove, "test-vg", "wrong-lv-name")
+        self.assertRaises(lvm.LVMError, lvm.lvremove, "wrong-vg-name", "test-lv")
+        self.assertRaises(lvm.LVMError, lvm.lvremove, "wrong-vg-name", "wrong-lv-name")
+        # lv already removed
+        self.assertRaises(lvm.LVMError, lvm.lvremove, "test-vg", "test-lv")
+
+        ##
+        ## vgremove
+        ##
+        # pass
+        self.assertEqual(lvm.vgremove("test-vg"), None)
+
+        # fail
+        self.assertRaises(lvm.LVMError, lvm.vgremove, "wrong-vg-name")
+        # vg already removed
+        self.assertRaises(lvm.LVMError, lvm.vgremove, "test-vg")
+
+        ##
+        ## pvremove
+        ##
+        # pass
+        for dev, file in self._LOOP_DEVICES:
+            self.assertEqual(lvm.pvremove(dev), None)
+
+        # fail
+        self.assertRaises(lvm.LVMError, lvm.pvremove, "/not/existing/device")
+        # pv already removed
+        self.assertRaises(lvm.LVMError, lvm.pvremove, self._LOOP_DEV0)
+
+    #def testGetPossiblePhysicalExtents(self):
+        # pass
+        self.assertEqual(lvm.getPossiblePhysicalExtents(4),
+                         filter(lambda pe: pe > 4, map(lambda power: 2**power, xrange(3, 25))))
+        self.assertEqual(lvm.getPossiblePhysicalExtents(100000),
+                         filter(lambda pe: pe > 100000, map(lambda power: 2**power, xrange(3, 25))))
+
+    #def testGetMaxLVSize(self):
+        # pass
+        self.assertEqual(lvm.getMaxLVSize(), 16*1024**2)
+
+    #def testSafeLVMName(self):
+        # pass
+        self.assertEqual(lvm.safeLvmName("/strange/lv*name5"), "strange_lvname5")
+
+    #def testClampSize(self):
+        # pass
+        self.assertEqual(lvm.clampSize(10, 4), 8L)
+        self.assertEqual(lvm.clampSize(10, 4, True), 12L)
+
+    #def testVGUsedSpace(self):
+        # TODO
+        pass
+
+    #def testVGFreeSpace(self):
+        # TODO
+        pass
+
+
+def suite():
+    return unittest.TestLoader().loadTestsFromTestCase(LVMTestCase)
+
+
+if __name__ == "__main__":
+    unittest.main()
diff --git a/tests/storage_test/devicelibs_test/mdraid_test.py b/tests/storage_test/devicelibs_test/mdraid_test.py
new file mode 100644
index 0000000..9dde22d
--- /dev/null
+++ b/tests/storage_test/devicelibs_test/mdraid_test.py
@@ -0,0 +1,110 @@
+#!/usr/bin/python
+import baseclass
+import unittest
+import time
+
+class MDRaidTestCase(baseclass.DevicelibsTestCase):
+
+    def setUp(self):
+        baseclass.DevicelibsTestCase.setUp(self)
+        import storage.devicelibs.mdraid as mdraid
+
+    def testMDRaid(self):
+        ##
+        ## getRaidLevels
+        ##
+        # pass
+        self.assertEqual(mdraid.getRaidLevels(), mdraid.getRaidLevels())
+
+        ##
+        ## get_raid_min_members
+        ##
+        # pass
+        self.assertEqual(mdraid.get_raid_min_members(mdraid.RAID0), 2)
+        self.assertEqual(mdraid.get_raid_min_members(mdraid.RAID1), 2)
+        self.assertEqual(mdraid.get_raid_min_members(mdraid.RAID5), 3)
+        self.assertEqual(mdraid.get_raid_min_members(mdraid.RAID6), 4)
+        self.assertEqual(mdraid.get_raid_min_members(mdraid.RAID10), 2)
+
+        # fail
+        # unsupported raid
+        self.assertRaises(ValueError, mdraid.get_raid_min_members, 4)
+
+        ##
+        ## get_raid_max_spares
+        ##
+        # pass
+        self.assertEqual(mdraid.get_raid_max_spares(mdraid.RAID0, 5), 0)
+        self.assertEqual(mdraid.get_raid_max_spares(mdraid.RAID1, 5), 3)
+        self.assertEqual(mdraid.get_raid_max_spares(mdraid.RAID5, 5), 2)
+        self.assertEqual(mdraid.get_raid_max_spares(mdraid.RAID6, 5), 1)
+        self.assertEqual(mdraid.get_raid_max_spares(mdraid.RAID10, 5), 3)
+
+        # fail
+        # unsupported raid
+        self.assertRaises(ValueError, mdraid.get_raid_max_spares, 4, 5)
+
+        ##
+        ## mdcreate
+        ##
+        # pass
+        self.assertEqual(mdraid.mdcreate("/dev/md0", 1, [self._LOOP_DEV0, self._LOOP_DEV1]), None)
+        # wait for raid to settle
+        time.sleep(2)
+
+        # fail
+        self.assertRaises(mdraid.MDRaidError, mdraid.mdcreate, "/dev/md1", 1, ["/not/existing/dev0", "/not/existing/dev1"])
+
+        ##
+        ## mddeactivate
+        ##
+        # pass
+        self.assertEqual(mdraid.mddeactivate("/dev/md0"), None)
+
+        # fail
+        self.assertRaises(mdraid.MDRaidError, mdraid.mddeactivate, "/not/existing/md")
+
+        ##
+        ## mdadd
+        ##
+        # pass
+        # TODO
+
+        # fail
+        self.assertRaises(mdraid.MDRaidError, mdraid.mdadd, "/not/existing/device")
+
+        ##
+        ## mdactivate
+        ##
+        # pass
+        self.assertEqual(mdraid.mdactivate("/dev/md0", [self._LOOP_DEV0, self._LOOP_DEV1], super_minor=0), None)
+        # wait for raid to settle
+        time.sleep(2)
+
+        # fail
+        self.assertRaises(mdraid.MDRaidError, mdraid.mdactivate, "/not/existing/md", super_minor=1)
+        # requires super_minor or uuid
+        self.assertRaises(ValueError, mdraid.mdactivate, "/dev/md1")
+
+        ##
+        ## mddestroy
+        ##
+        # pass
+        # deactivate first
+        self.assertEqual(mdraid.mddeactivate("/dev/md0"), None)
+
+        self.assertEqual(mdraid.mddestroy(self._LOOP_DEV0), None)
+        self.assertEqual(mdraid.mddestroy(self._LOOP_DEV1), None)
+
+        # fail
+        # not a component
+        self.assertRaises(mdraid.MDRaidError, mdraid.mddestroy, "/dev/md0")
+        self.assertRaises(mdraid.MDRaidError, mdraid.mddestroy, "/not/existing/device")
+
+
+def suite():
+    return unittest.TestLoader().loadTestsFromTestCase(MDRaidTestCase)
+
+
+if __name__ == "__main__":
+    unittest.main()
diff --git a/tests/storage_test/devicelibs_test/mpath_test.py b/tests/storage_test/devicelibs_test/mpath_test.py
new file mode 100644
index 0000000..813a516
--- /dev/null
+++ b/tests/storage_test/devicelibs_test/mpath_test.py
@@ -0,0 +1,33 @@
+#!/usr/bin/python
+import baseclass
+import unittest
+
+class MPathTestCase(baseclass.DevicelibsTestCase):
+    def setUp(self):
+        baseclass.DevicelibsTestCase.setUp(self)
+        import storage.devicelibs.mpath as mpath
+
+    def testMPath(self):
+        ##
+        ## parseMultipathOutput
+        ## 
+        output="""\
+create: mpathb (1ATA     ST3120026AS                                         5M) undef ATA,ST3120026AS
+size=112G features='0' hwhandler='0' wp=undef
+`-+- policy='round-robin 0' prio=1 status=undef
+  `- 2:0:0:0 sda 8:0  undef ready running
+create: mpatha (36006016092d21800703762872c60db11) undef DGC,RAID 5
+size=10G features='1 queue_if_no_path' hwhandler='1 emc' wp=undef
+`-+- policy='round-robin 0' prio=2 status=undef
+  |- 6:0:0:0 sdb 8:16 undef ready running
+  `- 7:0:0:0 sdc 8:32 undef ready running
+"""
+        topology = mpath.parseMultipathOutput(output)
+        expected = {'mpatha':['sdb','sdc'], 'mpathb':['sda']}
+        self.assertEqual(topology, expected)
+
+def suite():
+    return unittest.TestLoader().loadTestsFromTestCase(MPathTestCase)
+
+if __name__ == '__main__':
+    unittest.main()
diff --git a/tests/storage_test/devicelibs_test/swap_test.py b/tests/storage_test/devicelibs_test/swap_test.py
new file mode 100644
index 0000000..ddf8d21
--- /dev/null
+++ b/tests/storage_test/devicelibs_test/swap_test.py
@@ -0,0 +1,70 @@
+#!/usr/bin/python
+import baseclass
+import unittest
+
+class SwapTestCase(baseclass.DevicelibsTestCase):
+
+    def setUp(self):
+        baseclass.DevicelibsTestCase.setUp(self)
+        import storage.devicelibs.swap as swap
+
+    def testSwap(self):
+        ##
+        ## mkswap
+        ##
+        # pass
+        self.assertEqual(swap.mkswap(self._LOOP_DEV0, "swap"), None)
+
+        # fail
+        self.assertRaises(swap.SwapError, swap.mkswap, "/not/existing/device")
+        
+        ##
+        ## swapon
+        ##
+        # pass
+        self.assertEqual(swap.swapon(self._LOOP_DEV0, 1), None)
+
+        # fail
+        self.assertRaises(swap.SwapError, swap.swapon, "/not/existing/device")
+        # not a swap partition
+        self.assertRaises(swap.SwapError, swap.swapon, self._LOOP_DEV1)
+        
+        # pass
+        # make another swap
+        self.assertEqual(swap.mkswap(self._LOOP_DEV1, "another-swap"), None)
+        self.assertEqual(swap.swapon(self._LOOP_DEV1), None)
+
+        ##
+        ## swapstatus
+        ##
+        # pass
+        self.assertEqual(swap.swapstatus(self._LOOP_DEV0), True)
+        self.assertEqual(swap.swapstatus(self._LOOP_DEV1), True)
+        
+        # does not fail
+        self.assertEqual(swap.swapstatus("/not/existing/device"), False)
+
+        ##
+        ## swapoff
+        ##
+        # pass
+        self.assertEqual(swap.swapoff(self._LOOP_DEV1), None)
+
+        # check status
+        self.assertEqual(swap.swapstatus(self._LOOP_DEV0), True)
+        self.assertEqual(swap.swapstatus(self._LOOP_DEV1), False)
+
+        self.assertEqual(swap.swapoff(self._LOOP_DEV0), None)
+
+        # fail
+        self.assertRaises(swap.SwapError, swap.swapoff, "/not/existing/device")
+        # already off
+        self.assertRaises(swap.SwapError, swap.swapoff, self._LOOP_DEV0)
+
+
+def suite():
+    return unittest.TestLoader().loadTestsFromTestCase(SwapTestCase)
+
+
+if __name__ == "__main__":
+    unittest.main()
diff --git a/text.py b/text.py
deleted file mode 100644
index cb37467..0000000
--- a/text.py
+++ /dev/null
@@ -1,692 +0,0 @@
-#
-# text.py - text mode frontend to anaconda
-#
-# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006  Red Hat, Inc.
-# 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 as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# 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, see <http://www.gnu.org/licenses/>.
-#
-# Author(s): Erik Troan <ewt@xxxxxxxxxx>
-#            Matt Wilson <msw@xxxxxxxxxx>
-#
-
-from snack import *
-import sys
-import os
-import isys
-import iutil
-import time
-import signal
-import parted
-import product
-import string
-from language import expandLangs
-from flags import flags
-from constants_text import *
-from constants import *
-from network import hasActiveNetDev
-from installinterfacebase import InstallInterfaceBase
-import imputil
-
-import gettext
-_ = lambda x: gettext.ldgettext("anaconda", x)
-P_ = lambda x, y, z: gettext.ldngettext("anaconda", x, y, z)
-
-import logging
-log = logging.getLogger("anaconda")
-
-stepToClasses = {
-    "language" : ("language_text", "LanguageWindow"),
-    "keyboard" : ("keyboard_text", "KeyboardWindow"),
-    "welcome" : ("welcome_text", "WelcomeWindow"),
-    "parttype" : ("partition_text", "PartitionTypeWindow"),
-    "addswap" : ("upgrade_text", "UpgradeSwapWindow"),
-    "upgrademigratefs" : ("upgrade_text", "UpgradeMigrateFSWindow"),
-    "zfcpconfig": ("zfcp_text", ("ZFCPWindow")),
-    "findinstall" : ("upgrade_text", ("UpgradeExamineWindow")),
-    "upgbootloader": ("upgrade_bootloader_text", "UpgradeBootloaderWindow"),
-    "network" : ("network_text", ("HostnameWindow")),
-    "timezone" : ("timezone_text", "TimezoneWindow"),
-    "accounts" : ("userauth_text", "RootPasswordWindow"),
-    "tasksel": ("task_text", "TaskWindow"),
-    "install" : ("progress_text", "setupForInstall"),
-    "complete" : ("complete_text", "FinishedWindow"),
-}
-
-if iutil.isS390():
-    stepToClasses["bootloader"] = ("zipl_text", ( "ZiplWindow"))
-
-class InstallWindow:
-    def __call__ (self, screen):
-        raise RuntimeError, "Unimplemented screen"
-
-class WaitWindow:
-    def pop(self):
-	self.screen.popWindow()
-	self.screen.refresh()
-
-    def refresh(self):
-        pass
-
-    def __init__(self, screen, title, text):
-	self.screen = screen
-	width = 40
-	if (len(text) < width): width = len(text)
-
-	t = TextboxReflowed(width, text)
-
-	g = GridForm(self.screen, title, 1, 1)
-	g.add(t, 0, 0)
-	g.draw()
-	self.screen.refresh()
-
-class OkCancelWindow:
-    def getrc(self):
-	return self.rc
-
-    def __init__(self, screen, title, text):
-	rc = ButtonChoiceWindow(screen, title, text,
-			        buttons=[TEXT_OK_BUTTON, _("Cancel")])
-	if rc == string.lower(_("Cancel")):
-	    self.rc = 1
-	else:
-	    self.rc = 0
-
-class ProgressWindow:
-    def pop(self):
-	self.screen.popWindow()
-	self.screen.refresh()
-        del self.scale
-        self.scale = None
-
-    def pulse(self):
-        pass
-
-    def set(self, amount):
-        self.scale.set(int(float(amount) * self.multiplier))
-        self.screen.refresh()
-
-    def refresh(self):
-        pass
-
-    def __init__(self, screen, title, text, total, updpct = 0.05, pulse = False):
-        self.multiplier = 1
-        if total == 1.0:
-            self.multiplier = 100
-	self.screen = screen
-	width = 55
-	if (len(text) > width): width = len(text)
-
-	t = TextboxReflowed(width, text)
-
-	g = GridForm(self.screen, title, 1, 2)
-	g.add(t, 0, 0, (0, 0, 0, 1), anchorLeft=1)
-
-        self.scale = Scale(int(width), int(float(total) * self.multiplier))
-        if not pulse:
-            g.add(self.scale, 0, 1)
-                
-	g.draw()
-	self.screen.refresh()
-
-class LuksPassphraseWindow:
-    def __init__(self, screen, passphrase = "", preexist = False):
-        self.screen = screen
-        self.passphrase = passphrase
-        self.minLength = 8
-        self.preexist = preexist
-        self.txt = _("Choose a passphrase for the encrypted devices. You "
-                     "will be prompted for this passphrase during system boot.")
-        self.rc = None
-
-    def run(self):
-        toplevel = GridForm(self.screen, _("Passphrase for encrypted device"),
-                            1, 5)
-
-        txt = TextboxReflowed(65, self.txt)
-        toplevel.add(txt, 0, 0)
-
-        passphraseentry = Entry(60, password = 1)
-        toplevel.add(passphraseentry, 0, 1, (0,0,0,1))
-
-        confirmentry = Entry(60, password = 1)
-        toplevel.add(confirmentry, 0, 2, (0,0,0,1))
-
-        if self.preexist:
-            globalcheckbox = Checkbox(_("Also add this passphrase to all existing encrypted devices"), isOn = True)
-            toplevel.add(globalcheckbox, 0, 3)
-
-        buttons = ButtonBar(self.screen, [TEXT_OK_BUTTON, TEXT_CANCEL_BUTTON])
-        toplevel.add(buttons, 0, 4, growx=1)
-
-        passphraseentry.set(self.passphrase)
-        confirmentry.set(self.passphrase)
-
-        while True:
-            rc = toplevel.run()
-            res = buttons.buttonPressed(rc)
-
-            passphrase = None
-            if res == TEXT_OK_CHECK or rc == "F12":
-                passphrase = passphraseentry.value()
-                confirm = confirmentry.value()
-
-                if passphrase != confirm:
-                    ButtonChoiceWindow(self.screen,
-                                       _("Error with passphrase"),
-                                       _("The passphrases you entered were "
-                                         "different.  Please try again."),
-                                       buttons=[TEXT_OK_BUTTON])
-                    passphraseentry.set("")
-                    confirmentry.set("")
-                    continue
-
-                if len(passphrase) < self.minLength:
-                    ButtonChoiceWindow(self.screen,
-                                       _("Error with passphrase"),
-                                       P_("The passphrase must be at least "
-                                          "%d character long.",
-                                          "The passphrase must be at least "
-                                          "%d characters long.",
-                                          self.minLength)
-                                         % (self.minLength,),
-                                       buttons=[TEXT_OK_BUTTON])
-                    passphraseentry.set("")
-                    confirmentry.set("")
-                    continue
-            else:
-                passphrase = self.passphrase
-                passphraseentry.set(self.passphrase)
-                confirmentry.set(self.passphrase)
-
-            retrofit = False
-            if self.preexist:
-                retrofit = globalcheckbox.selected()
-            self.rc = passphrase
-            return (self.rc, retrofit)
-
-    def pop(self):
-        self.screen.popWindow()
-
-class PassphraseEntryWindow:
-    def __init__(self, screen, device):
-        self.screen = screen
-        self.txt = _("Device %s is encrypted. In order to "
-                     "access the device's contents during "
-                     "installation you must enter the device's "
-                     "passphrase below.") % (device,)
-        self.rc = None
-
-    def run(self):
-        toplevel = GridForm(self.screen, _("Passphrase"), 1, 4)
-
-        txt = TextboxReflowed(65, self.txt)
-        toplevel.add(txt, 0, 0)
-
-        passphraseentry = Entry(60, password = 1)
-        toplevel.add(passphraseentry, 0, 1, (0,0,0,1))
-
-        globalcheckbox = Checkbox(_("This is a global passphrase"))
-        toplevel.add(globalcheckbox, 0, 2)
-
-        buttons = ButtonBar(self.screen, [TEXT_OK_BUTTON, TEXT_CANCEL_BUTTON])
-        toplevel.add(buttons, 0, 3, growx=1)
-
-        rc = toplevel.run()
-        res = buttons.buttonPressed(rc)
-
-        passphrase = None
-        isglobal = False
-        if res == TEXT_OK_CHECK:
-            passphrase = passphraseentry.value().strip()
-            isglobal = globalcheckbox.selected()
-
-        self.rc = (passphrase, isglobal)
-        return self.rc
-
-    def pop(self):
-        self.screen.popWindow()
-
-class InstallInterface(InstallInterfaceBase):
-    def progressWindow(self, title, text, total, updpct = 0.05, pulse = False):
-        return ProgressWindow(self.screen, title, text, total, updpct, pulse)
-
-    def setInstallProgressClass(self, c):
-        self.instProgress = c
-
-    def exitWindow(self, title, text):
-        return self.messageWindow(title, text, type="custom",
-                                  custom_buttons=[_("Exit installer")])
-
-    def messageWindow(self, title, text, type="ok", default = None,
-		      custom_icon=None, custom_buttons=[]):
-	if type == "ok":
-	    ButtonChoiceWindow(self.screen, title, text,
-			       buttons=[TEXT_OK_BUTTON])
-        elif type == "yesno":
-            if default and default == "no":
-                btnlist = [TEXT_NO_BUTTON, TEXT_YES_BUTTON]
-            else:
-                btnlist = [TEXT_YES_BUTTON, TEXT_NO_BUTTON]
-	    rc = ButtonChoiceWindow(self.screen, title, text,
-			       buttons=btnlist)
-            if rc == "yes":
-                return 1
-            else:
-                return 0
-	elif type == "custom":
-	    tmpbut = []
-	    for but in custom_buttons:
-		tmpbut.append(string.replace(but,"_",""))
-
-	    rc = ButtonChoiceWindow(self.screen, title, text, width=60,
-				    buttons=tmpbut)
-
-	    idx = 0
-	    for b in tmpbut:
-		if string.lower(b) == rc:
-		    return idx
-		idx = idx + 1
-	    return 0
-	else:
-	    return OkCancelWindow(self.screen, title, text)
-
-    def detailedMessageWindow(self, title, text, longText=None, type="ok",
-                              default=None, custom_icon=None,
-                              custom_buttons=[], expanded=False):
-        t = TextboxReflowed(60, text, maxHeight=8)
-        lt = Textbox(60, 6, longText, scroll=1, wrap=1)
-        g = GridFormHelp(self.screen, title, help, 1, 3)
-        g.add(t, 0, 0)
-        g.add(lt, 0, 1, padding = (0, 1, 0, 1))
-
-        if type == "ok":
-            bb = ButtonBar(self.screen, [TEXT_OK_BUTTON])
-            g.add(bb, 0, 2, growx = 1)
-            return bb.buttonPressed(g.runOnce(None, None))
-        elif type == "yesno":
-            if default and default == "no":
-                buttons = [TEXT_NO_BUTTON, TEXT_YES_BUTTON]
-            else:
-                buttons = [TEXT_YES_BUTTON, TEXT_NO_BUTTON]
-
-            bb = ButtonBar(self.screen, buttons)
-            g.add(bb, 0, 2, growx = 1)
-            rc = bb.buttonPressed(g.runOnce(None, None))
-
-            if rc == "yes":
-                return 1
-            else:
-                return 0
-        elif type == "custom":
-            buttons = []
-            idx = 0
-
-            for button in custom_buttons:
-                buttons.append(string.replace(button, "_", ""))
-
-            bb = ButtonBar(self.screen, buttons)
-            g.add(bb, 0, 2, growx = 1)
-            rc = bb.buttonPressed(g.runOnce(None, None))
-
-            for b in buttons:
-                if string.lower(b) == rc:
-                    return idx
-                idx += 1
-
-            return 0
-        else:
-            return self.messageWindow(title, text, type, default, custom_icon,
-                                      custom_buttons)
-
-    def createRepoWindow(self):
-        self.messageWindow(_("Error"),
-                           _("Repository editing is not available in text mode."))
-
-    def editRepoWindow(self, repoObj):
-        self.messageWindow(_("Error"),
-                           _("Repository editing is not available in text mode."))
-
-    def entryWindow(self, title, text, prompt, entrylength = None):
-        (res, value) = EntryWindow(self.screen, title, text, [prompt])
-        if res == "cancel":
-            return None
-        r = value[0]
-        r.strip()
-        return r
-
-    def getLuksPassphrase(self, passphrase = "", preexist = False):
-        w = LuksPassphraseWindow(self.screen, passphrase = passphrase,
-                                 preexist = preexist)
-        rc = w.run()
-        w.pop()
-        return rc
-
-    def passphraseEntryWindow(self, device):
-        w = PassphraseEntryWindow(self.screen, device)
-        (passphrase, isglobal) = w.run()
-        w.pop()
-        return (passphrase, isglobal)
-
-    def enableNetwork(self):
-        if len(self.anaconda.network.netdevices) == 0:
-            return False
-        from netconfig_text import NetworkConfiguratorText
-        w = NetworkConfiguratorText(self.screen, self.anaconda)
-        ret = w.run()
-        return ret != INSTALL_BACK
-
-    def kickstartErrorWindow(self, text):
-        s = _("The following error was found while parsing the "
-              "kickstart configuration file:\n\n%s") %(text,)
-        self.messageWindow(_("Error Parsing Kickstart Config"),
-                           s,
-                           type = "custom",
-                           custom_buttons = [("_Reboot")],
-                           custom_icon="error")
-                           
-    def mainExceptionWindow(self, shortText, longTextFile):
-        from meh.ui.text import MainExceptionWindow
-        log.critical(shortText)
-        exnWin = MainExceptionWindow(shortText, longTextFile, screen=self.screen)
-        return exnWin
-
-    def saveExceptionWindow(self, accountManager, signature, *args, **kwargs):
-        from meh.ui.text import SaveExceptionWindow
-        win = SaveExceptionWindow (accountManager, signature, screen=self.screen,
-                                   *args, **kwargs)
-        win.run()
-
-    def waitWindow(self, title, text):
-	return WaitWindow(self.screen, title, text)
-
-    def beep(self):
-        # no-op.  could call newtBell() if it was bound
-        pass
-
-    def drawFrame(self):
-        self.screen.drawRootText (0, 0, self.screen.width * " ")
-        if productArch:
-          self.screen.drawRootText (0, 0, _("Welcome to %(productName)s for %(productArch)s") % {'productName': productName, 'productArch': productArch})
-        else:
-          self.screen.drawRootText (0, 0, _("Welcome to %s") % productName)
-
-        self.screen.pushHelpLine(_("  <Tab>/<Alt-Tab> between elements   |  <Space> selects   |  <F12> next screen"))
-
-    def setScreen(self, screen):
-        self.screen = screen
-
-    def shutdown(self):
-	self.screen.finish()
-	self.screen = None
-
-    def suspend(self):
-        self.screen.suspend()
-
-    def resume(self):
-        self.screen.resume()
-
-    def __init__(self):
-	InstallInterfaceBase.__init__(self)
-	signal.signal(signal.SIGINT, signal.SIG_IGN)
-	signal.signal(signal.SIGTSTP, signal.SIG_IGN)
-	self.screen = SnackScreen()
-        self.instProgress = None
-        self._initLabelAnswers = {}
-        self._inconsistentLVMAnswers = {}
-
-    def __del__(self):
-	if self.screen:
-	    self.screen.finish()
-
-    def isRealConsole(self):
-        """Returns True if this is a _real_ console that can do things, False
-        for non-real consoles such as serial, i/p virtual consoles or xen."""
-        if flags.serial or flags.virtpconsole:
-            return False
-        if isys.isPseudoTTY(0):
-            return False
-        if isys.isVioConsole():
-            return False
-        return True
-
-    def resetInitializeDiskQuestion(self):
-        self._initLabelAnswers = {}
-
-    def questionInitializeDisk(self, path, description, size, details=""):
-
-        retVal = False # The less destructive default
-
-        if not path:
-            return retVal
-
-        # we are caching answers so that we don't
-        # ask in each storage.reset() again
-        if path in self._initLabelAnswers:
-            log.info("UI not asking about disk initialization, "
-                     "using cached answer: %s" % self._initLabelAnswers[path])
-            return self._initLabelAnswers[path]
-        elif "all" in self._initLabelAnswers:
-            log.info("UI not asking about disk initialization, "
-                     "using cached answer: %s" % self._initLabelAnswers["all"])
-            return self._initLabelAnswers["all"]
-
-        rc = self.messageWindow(_("Warning"),
-                _("Error processing drive:\n\n"
-                  "%(path)s\n%(size)-0.fMB\n%(description)s\n\n"
-                  "This device may need to be reinitialized.\n\n"
-                  "REINITIALIZING WILL CAUSE ALL DATA TO BE LOST!\n\n"
-                  "This action may also be applied to all other disks "
-                  "needing reinitialization.%(details)s")
-                % {'path': path, 'size': size,
-                   'description': description, 'details': details},
-                type="custom",
-                custom_buttons = [ _("_Ignore"),
-                                   _("Ignore _all"),
-                                   _("_Re-initialize"),
-                                   _("Re-ini_tialize all") ],
-                custom_icon="question")
-        if rc == 0:
-            retVal = False
-        elif rc == 1:
-            path = "all"
-            retVal = False
-        elif rc == 2:
-            retVal = True
-        elif rc == 3:
-            path = "all"
-            retVal = True
-
-        self._initLabelAnswers[path] = retVal
-        return retVal
-
-    def resetReinitInconsistentLVMQuestion(self):
-        self._inconsistentLVMAnswers = {}
-
-    def questionReinitInconsistentLVM(self, pv_names=None, lv_name=None, vg_name=None):
-
-        retVal = False # The less destructive default
-        allSet = frozenset(["all"])
-
-        if not pv_names or (lv_name is None and vg_name is None):
-            return retVal
-
-        # We are caching answers so that we don't ask for ignoring
-        # in each storage.reset() again (note that reinitialization is
-        # done right after confirmation in dialog, not as a planned
-        # action).
-        key = frozenset(pv_names)
-        if key in self._inconsistentLVMAnswers:
-            log.info("UI not asking about disk initialization, "
-                     "using cached answer: %s" % self._inconsistentLVMAnswers[key])
-            return self._inconsistentLVMAnswers[key]
-        elif allSet in self._inconsistentLVMAnswers:
-            log.info("UI not asking about disk initialization, "
-                     "using cached answer: %s" % self._inconsistentLVMAnswers[allSet])
-            return self._inconsistentLVMAnswers[allSet]
-
-        if vg_name is not None:
-            message = "Volume Group %s" % vg_name
-        elif lv_name is not None:
-            message = "Logical Volume %s" % lv_name
-
-        na = {'msg': message, 'pvs': ", ".join(pv_names)}
-        rc = self.messageWindow(_("Warning"),
-                  _("Error processing LVM.\n"
-                    "There is inconsistent LVM data on %(msg)s.  You can "
-                    "reinitialize all related PVs (%(pvs)s) which will erase "
-                    "the LVM metadata, or ignore which will preserve the "
-                    "contents.  This action may also be applied to all other "
-                    "PVs with inconsistent metadata.") % na,
-                type="custom",
-                custom_buttons = [ _("_Ignore"),
-                                   _("Ignore _all"),
-                                   _("_Re-initialize"),
-                                   _("Re-ini_tialize all") ],
-                custom_icon="question")
-        if rc == 0:
-            retVal = False
-        elif rc == 1:
-            key = allSet
-            retVal = False
-        elif rc == 2:
-            retVal = True
-        elif rc == 3:
-            key = allSet
-            retval = True
-
-        self._inconsistentLVMAnswers[key] = retVal
-        return retVal
-
-    def run(self, anaconda):
-        self.anaconda = anaconda
-        instLang = anaconda.instLanguage
-
-        if instLang.getFontFile(instLang.instLang) == "none":
-            if not anaconda.ksdata:
-                ButtonChoiceWindow(self.screen, "Language Unavailable",
-                                   "%s display is unavailable in text mode.  "
-                                   "The installation will continue in "
-                                   "English." % (instLang.instLang,),
-                                   buttons=[TEXT_OK_BUTTON])
-
-	if not self.isRealConsole():
-	    self.screen.suspendCallback(spawnShell, self.screen)
-
-        # drop into the python debugger on ctrl-z if we're running in test mode
-        if flags.debug:
-            self.screen.suspendCallback(debugSelf, self.screen)
-
-        # draw the frame after setting up the fallback
-        self.drawFrame()
-
-	lastrc = INSTALL_OK
-	(step, instance) = anaconda.dispatch.currentStep()
-	while step:
-	    (file, classNames) = stepToClasses[step]
-
-	    if type(classNames) != type(()):
-		classNames = (classNames,)
-
-	    if lastrc == INSTALL_OK:
-		step = 0
-	    else:
-		step = len(classNames) - 1
-
-	    while step >= 0 and step < len(classNames):
-                # reget the args.  they could change (especially direction)
-                (foo, args) = anaconda.dispatch.currentStep()
-                nextWindow = None
-
-                while 1:
-                    try:
-                        found = imputil.imp.find_module(file)
-                        loaded = imputil.imp.load_module(classNames[step],
-                                                         found[0], found[1],
-                                                         found[2])
-                        nextWindow = loaded.__dict__[classNames[step]]
-                        break
-                    except ImportError, e:
-                        rc = ButtonChoiceWindow(self.screen, _("Error!"),
-                                          _("An error occurred when attempting "
-                                            "to load an installer interface "
-                                            "component.\n\nclassName = %s")
-                                          % (classNames[step],),
-                                          buttons=[_("Exit"), _("Retry")])
-
-                        if rc == string.lower(_("Exit")):
-                            sys.exit(0)
-
-		win = nextWindow()
-
-		#log.info("TUI running step %s (class %s, file %s)" % 
-			 #(step, file, classNames))
-
-                rc = win(self.screen, instance)
-
-		if rc == INSTALL_NOOP:
-		    rc = lastrc
-
-		if rc == INSTALL_BACK:
-		    step = step - 1
-                    anaconda.dispatch.dir = DISPATCH_BACK
-		elif rc == INSTALL_OK:
-		    step = step + 1
-                    anaconda.dispatch.dir = DISPATCH_FORWARD
-
-		lastrc = rc
-
-	    if step == -1:
-                if not anaconda.dispatch.canGoBack():
-                    ButtonChoiceWindow(self.screen, _("Cancelled"),
-                                       _("I can't go to the previous step "
-                                         "from here. You will have to try "
-                                         "again."),
-                                       buttons=[_("OK")])
-		anaconda.dispatch.gotoPrev()
-	    else:
-		anaconda.dispatch.gotoNext()
-
-	    (step, args) = anaconda.dispatch.currentStep()
-
-        self.screen.finish()
-
-    def setSteps(self, anaconda):
-        anaconda.dispatch.skipStep("filtertype", permanent=1)
-        anaconda.dispatch.skipStep("filter", permanent=1)
-        anaconda.dispatch.skipStep("cleardiskssel", permanent=1)
-        anaconda.dispatch.skipStep("group-selection", permanent=1)
-
-def killSelf(screen):
-    screen.finish()
-    os._exit(0)
-
-def debugSelf(screen):
-    screen.suspend()
-    import pdb
-    try:
-        pdb.set_trace()
-    except:
-        sys.exit(-1)
-    screen.resume()
-
-def spawnShell(screen):
-    screen.suspend()
-    print("\n\nType <exit> to return to the install program.\n")
-    if os.path.exists("/bin/sh"):
-        iutil.execConsole()
-    else:
-        print("Unable to find /bin/sh to execute!  Not starting shell")
-    time.sleep(5)
-    screen.resume()
diff --git a/textw/Makefile.am b/textw/Makefile.am
deleted file mode 100644
index 2624967..0000000
--- a/textw/Makefile.am
+++ /dev/null
@@ -1,24 +0,0 @@
-# textw/Makefile.am for anaconda
-#
-# Copyright (C) 2009  Red Hat, Inc.
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU Lesser General Public License as published
-# by the Free Software Foundation; either version 2.1 of the License, or
-# (at your option) any later version.
-#
-# 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 Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public License
-# along with this program.  If not, see <http://www.gnu.org/licenses/>.
-#
-# Author: David Cantrell <dcantrell@xxxxxxxxxx>
-
-pkgpyexecdir = $(pyexecdir)/py$(PACKAGE_NAME)
-textwdir = $(pkgpyexecdir)/textw
-textw_PYTHON = *.py
-
-MAINTAINERCLEANFILES = Makefile.in
diff --git a/textw/add_drive_text.py b/textw/add_drive_text.py
deleted file mode 100644
index 0fbd86c..0000000
--- a/textw/add_drive_text.py
+++ /dev/null
@@ -1,180 +0,0 @@
-import iutil
-import network
-import storage.iscsi
-import storage.fcoe
-import storage.zfcp
-from snack import *
-from constants_text import *
-from constants import *
-
-import gettext
-_ = lambda x: gettext.ldgettext("anaconda", x)
-
-import logging
-log = logging.getLogger("anaconda")
-
-class addDriveDialog(object):
-    def __init__(self, anaconda):
-        self.anaconda = anaconda
-
-    def addDriveDialog(self, screen):
-        newdrv = []
-        if storage.iscsi.has_iscsi():
-            newdrv.append("Add iSCSI target")
-        if iutil.isS390():
-            newdrv.append( "Add zFCP LUN" )
-        if storage.fcoe.has_fcoe():
-            newdrv.append("Add FCoE SAN")
-
-        if len(newdrv) == 0:
-            return INSTALL_BACK
-
-        (button, choice) = ListboxChoiceWindow(screen,
-                                   _("Advanced Storage Options"),
-                                   _("How would you like to modify "
-                                     "your drive configuration?"),
-                                   newdrv,
-                                   [ TEXT_OK_BUTTON, TEXT_BACK_BUTTON],
-                                               width=55, height=3)
-        
-        if button == TEXT_BACK_CHECK:
-            return INSTALL_BACK
-        if newdrv[choice] == "Add zFCP LUN":
-            try:
-                return self.addZFCPDriveDialog(screen)
-            except ValueError, e:
-                ButtonChoiceWindow(screen, _("Error"), str(e))
-                return INSTALL_BACK
-        elif newdrv[choice] == "Add FCoE SAN":
-            try:
-                return self.addFcoeDriveDialog(screen)
-            except ValueError, e:
-                ButtonChoiceWindow(screen, _("Error"), str(e))
-                return INSTALL_BACK
-        else:
-            try:
-                return self.addIscsiDriveDialog(screen)
-            except (ValueError, IOError), e:
-                ButtonChoiceWindow(screen, _("Error"), str(e))
-                return INSTALL_BACK
-
-    def addZFCPDriveDialog(self, screen):
-        (button, entries) = EntryWindow(screen,
-                                        _("Add FCP Device"),
-                                        _("zSeries machines can access industry-standard SCSI devices via Fibre Channel (FCP). You need to provide a 16 bit device number, a 64 bit World Wide Port Name (WWPN), and a 64 bit FCP LUN for each device."),
-                                        prompts = [ "Device number",
-                                                    "WWPN",
-                                                    "FCP LUN" ] )
-        if button == TEXT_CANCEL_CHECK:
-            return INSTALL_BACK
-
-        devnum = entries[0].strip()
-        wwpn = entries[1].strip()
-        fcplun = entries[2].strip()
-
-        # This may throw a value error, which gets handled by addDriveDialog()
-        storage.zfcp.ZFCP().addFCP(devnum, wwpn, fcplun)
-
-        return INSTALL_OK
-
-    def addFcoeDriveDialog(self, screen):
-        netdevs = self.anaconda.network.available()
-        devs = netdevs.keys()
-        devs.sort()
-
-        if not devs:
-            ButtonChoiceWindow(screen, _("Error"),
-                               _("No network cards present."))
-            return INSTALL_BACK
-
-        grid = GridFormHelp(screen, _("Add FCoE SAN"), "fcoeconfig",
-                            1, 4)
-
-        tb = TextboxReflowed(60,
-                        _("Select which NIC is connected to the FCoE SAN."))
-        grid.add(tb, 0, 0, anchorLeft = 1, padding = (0, 0, 0, 1))
-
-        interfaceList = Listbox(height=len(devs), scroll=1)
-        for dev in devs:
-            hwaddr = netdevs[dev].get("HWADDR")
-            if hwaddr:
-                desc = "%s - %.50s" % (dev, hwaddr)
-            else:
-                desc = dev
-
-            interfaceList.append(desc, dev)
-
-        interfaceList.setCurrent(devs[0])
-        grid.add(interfaceList, 0, 1, padding = (0, 1, 0, 0))
-
-        dcbCheckbox = Checkbox(_("Use DCB"), 1)
-        grid.add(dcbCheckbox, 0, 2, anchorLeft = 1)
-
-        buttons = ButtonBar(screen, [TEXT_OK_BUTTON, TEXT_BACK_BUTTON] )
-        grid.add(buttons, 0, 3, anchorLeft = 1, growx = 1)
-
-        result = grid.run()
-        if buttons.buttonPressed(result) == TEXT_BACK_CHECK:
-            screen.popWindow()
-            return INSTALL_BACK
-
-        nic = interfaceList.current()
-        dcb = dcbCheckbox.selected()
-
-        storage.fcoe.fcoe().addSan(nic=nic, dcb=dcb,
-                                   intf=self.anaconda.intf)
-
-        screen.popWindow()
-        return INSTALL_OK
-
-    def addIscsiDriveDialog(self, screen):
-        if not network.hasActiveNetDev():
-            ButtonChoiceWindow(screen, _("Error"),
-                               "Must have a network configuration set up "
-                               "for iSCSI config.  Please boot with "
-                               "'linux asknetwork'")
-            return INSTALL_BACK
-        
-        (button, entries) = EntryWindow(screen,
-                                        _("Configure iSCSI Parameters"),
-                                        _("To use iSCSI disks, you must provide the address of your iSCSI target and the iSCSI initiator name you've configured for your host."),
-                                        prompts = [ _("Target IP Address"),
-                                                    _("iSCSI Initiator Name"),
-                                                    _("CHAP username"),
-                                                    _("CHAP password"),
-                                                    _("Reverse CHAP username"),
-                                                    _("Reverse CHAP password") ])
-        if button == TEXT_CANCEL_CHECK:
-            return INSTALL_BACK
-
-        (user, pw, user_in, pw_in) = entries[2:]
-
-        target = entries[0].strip()
-        try:
-            count = len(target.split(":"))
-            idx = target.rfind("]:")
-            # Check for IPV6 [IPV6-ip]:port
-            if idx != -1:
-                ip = target[1:idx]
-                port = target[idx+2:]
-            # Check for IPV4 aaa.bbb.ccc.ddd:port
-            elif count == 2:
-                idx = target.rfind(":")
-                ip = target[:idx]
-                port = target[idx+1:]
-            else:
-                ip = target
-                port = "3260"
-            network.sanityCheckIPString(ip)
-        except network.IPMissing, msg:
-            raise ValueError, msg
-        except network.IPError, msg:
-            raise ValueError, msg
-
-        iname = entries[1].strip()
-        if not storage.iscsi.iscsi().initiatorSet:
-            storage.iscsi.iscsi().initiator = iname
-        storage.iscsi.iscsi().addTarget(ip, port, user, pw, user_in, pw_in,
-                                        intf=self.anaconda.intf)
-
-        return INSTALL_OK
diff --git a/textw/complete_text.py b/textw/complete_text.py
deleted file mode 100644
index fc4e5c1..0000000
--- a/textw/complete_text.py
+++ /dev/null
@@ -1,65 +0,0 @@
-#
-# complete_text.py: text mode congratulations windows
-#
-# Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006  Red Hat, Inc.
-# 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 as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# 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, see <http://www.gnu.org/licenses/>.
-#
-
-from snack import *
-from constants_text import *
-from constants import *
-import gettext
-import platform
-_ = lambda x: gettext.ldgettext("anaconda", x)
-
-class FinishedWindow:
-  
-  def __call__ (self, screen, anaconda):
-        bootstr = ""
-        buttonstr = _("Reboot")
-
-        bottomstr = _("<Enter> to exit")
-
-        screen.pushHelpLine (string.center(bottomstr, screen.width))
-
-        if isinstance(anaconda.platform, platform.S390):
-            txt = _("Congratulations, your %s installation is complete.\n\n") % (productName,)
-
-            if not anaconda.canReIPL:
-                buttonstr = _("Shutdown")
-
-                txt = txt + _("Please shutdown to use the installed system.\n")
-            else:
-                txt = txt + _("Please reboot to use the installed system.\n")
-
-            if not anaconda.reIPLMessage is None:
-                txt = txt + "\n" + anaconda.reIPLMessage + "\n\n"
-
-            txt = txt + _("Note that updates may be available to ensure the proper "
-                          "functioning of your system and installation of these "
-                          "updates is recommended after the reboot.")
-        else:
-            txt = _("Congratulations, your %s installation is complete.\n\n"
-                    "Please reboot to use the installed system.  "
-                    "Note that updates may be available to ensure the proper "
-                    "functioning of your system and installation of these "
-                    "updates is recommended after the reboot.") %(productName,)
-
-
-        rc = ButtonChoiceWindow (screen, _("Complete"), txt,
-                                 [ buttonstr ], help = "finished", width=60)
-
-        return INSTALL_OK
diff --git a/textw/constants_text.py b/textw/constants_text.py
deleted file mode 100644
index 1561d5a..0000000
--- a/textw/constants_text.py
+++ /dev/null
@@ -1,68 +0,0 @@
-#
-# constants_text.py: text mode constants
-#
-# Copyright (C) 2000, 2001, 2002  Red Hat, Inc.  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 as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# 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, see <http://www.gnu.org/licenses/>.
-#
-
-from constants import *
-import gettext
-_ = lambda x: gettext.ldgettext("anaconda", x)
-
-INSTALL_OK = 0
-INSTALL_BACK = -1
-INSTALL_NOOP = -2
-
-class Translator:
-    """A simple class to facilitate on-the-fly translation for newt buttons"""
-    def __init__(self, button, check):
-        self.button = button
-        self.check = check
-
-    def __getitem__(self, which):
-        if which == 0:
-            return _(self.button)
-        elif which == 1:
-            return self.check
-        raise IndexError
-
-    def __len__(self):
-        return 2
-
-TEXT_OK_STR = N_("OK")
-TEXT_OK_CHECK  = "ok"
-TEXT_OK_BUTTON = Translator(TEXT_OK_STR, TEXT_OK_CHECK)
-
-TEXT_CANCEL_STR = N_("Cancel")
-TEXT_CANCEL_CHECK  = "cancel"
-TEXT_CANCEL_BUTTON = Translator(TEXT_CANCEL_STR, TEXT_CANCEL_CHECK)
-
-TEXT_BACK_STR = N_("Back")
-TEXT_BACK_CHECK = "back"
-TEXT_BACK_BUTTON = Translator(TEXT_BACK_STR, TEXT_BACK_CHECK)
-
-TEXT_YES_STR = N_("Yes")
-TEXT_YES_CHECK = "yes"
-TEXT_YES_BUTTON = Translator(TEXT_YES_STR, TEXT_YES_CHECK)
-
-TEXT_NO_STR = N_("No")
-TEXT_NO_CHECK = "no"
-TEXT_NO_BUTTON = Translator(TEXT_NO_STR, TEXT_NO_CHECK)
-
-TEXT_EDIT_STR = N_("Edit")
-TEXT_EDIT_CHECK = "edit"
-TEXT_EDIT_BUTTON = Translator(TEXT_EDIT_STR, TEXT_EDIT_CHECK)
-
-TEXT_F12_CHECK = "F12"
diff --git a/textw/keyboard_text.py b/textw/keyboard_text.py
deleted file mode 100644
index aa0201a..0000000
--- a/textw/keyboard_text.py
+++ /dev/null
@@ -1,67 +0,0 @@
-#
-# keyboard_text: text mode keyboard setup dialogs
-#
-# Copyright (C) 2001, 2002  Red Hat, Inc.  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 as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# 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, see <http://www.gnu.org/licenses/>.
-#
-
-import isys
-from snack import *
-from constants_text import *
-from flags import flags
-
-from constants import *
-import gettext
-_ = lambda x: gettext.ldgettext("anaconda", x)
-
-import logging
-log = logging.getLogger("anaconda")
-
-class KeyboardWindow:
-    def __call__(self, screen, anaconda):
-        if flags.serial or flags.virtpconsole:
-	    return INSTALL_NOOP
-        keyboards = anaconda.keyboard.modelDict.keys()
-        keyboards.sort ()
-
-	if anaconda.keyboard.beenset:
-	    default = anaconda.keyboard.get ()
-	else:
-	    default = anaconda.instLanguage.getDefaultKeyboard(anaconda.rootPath)
-
-        if default not in keyboards:
-            default = 'us'
-
-        (button, choice) = \
-            ListboxChoiceWindow(screen, _("Keyboard Selection"),
-                                _("Which model keyboard is attached to this computer?"), keyboards, 
-                                buttons = [TEXT_OK_BUTTON, TEXT_BACK_BUTTON], width = 30, scroll = 1, height = 8,
-                                default = default, help = "kybd")
-        
-        if button == TEXT_BACK_CHECK:
-            return INSTALL_BACK
-
-        anaconda.keyboard.set (keyboards[choice])
-        anaconda.keyboard.beenset = 1
-
-        anaconda.keyboard.activate()
-
-        # FIXME: eventually, kbd.activate will do this
-	try:
-	    isys.loadKeymap(keyboards[choice])
-	except SystemError, (errno, msg):
-	    log.error("Could not install keymap %s: %s" % (keyboards[choice], msg))
-        return INSTALL_OK
-
diff --git a/textw/language_text.py b/textw/language_text.py
deleted file mode 100644
index 14c8503..0000000
--- a/textw/language_text.py
+++ /dev/null
@@ -1,70 +0,0 @@
-#
-# language_text.py: text mode language selection dialog
-#
-# Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007  Red Hat, Inc.
-# 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 as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# 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, see <http://www.gnu.org/licenses/>.
-#
-
-from snack import *
-from constants_text import *
-
-from constants import *
-import gettext
-_ = lambda x: gettext.ldgettext("anaconda", x)
-
-import logging
-log = logging.getLogger("anaconda")
-
-class LanguageWindow:
-    def __call__(self, screen, anaconda):
-        languages = anaconda.instLanguage.available ()
-        languages.sort()
-
-        current = anaconda.instLanguage.instLang
-
-        height = min((8, len(languages)))
-	buttons = [TEXT_OK_BUTTON, TEXT_BACK_BUTTON]
-
-        translated = []
-        for lang in languages:
-            translated.append ((_(lang), anaconda.instLanguage.getLangByName(lang)))
-        (button, choice) = \
-            ListboxChoiceWindow(screen, _("Language Selection"),
-			_("What language would you like to use during the "
-			  "installation process?"), translated, 
-			buttons, width = 30, default = _(current), scroll = 1,
-                                height = height, help = "lang")
-
-        if button == TEXT_BACK_CHECK:
-            return INSTALL_BACK
-
-        if anaconda.instLanguage.getFontFile(choice) == "none":
-            ButtonChoiceWindow(screen, "Language Unavailable",
-                               "%s display is unavailable in text mode.  The "
-                               "installation will continue in English." % (choice,),
-                               buttons=[TEXT_OK_BUTTON])
-            anaconda.instLanguage.instLang = choice
-            anaconda.instLanguage.systemLang = choice
-            anaconda.timezone.setTimezoneInfo(anaconda.instLanguage.getDefaultTimeZone(anaconda.rootPath))
-            return INSTALL_OK
-
-        anaconda.instLanguage.instLang = choice
-        anaconda.instLanguage.systemLang = choice
-        anaconda.timezone.setTimezoneInfo(anaconda.instLanguage.getDefaultTimeZone(anaconda.rootPath))
-
-	anaconda.intf.drawFrame()
-
-        return INSTALL_OK
diff --git a/textw/netconfig_text.py b/textw/netconfig_text.py
deleted file mode 100644
index 4cea192..0000000
--- a/textw/netconfig_text.py
+++ /dev/null
@@ -1,285 +0,0 @@
-#
-# netconfig_text.py: Configure a network interface now.
-#
-# Copyright (C) 2008  Red Hat, Inc.
-# 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 as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# 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, see <http://www.gnu.org/licenses/>.
-#
-# Author(s): Chris Lumens <clumens@xxxxxxxxxx>
-#            David Cantrell <dcantrell@xxxxxxxxxx>
-#
-
-
-import isys
-import network
-from snack import *
-from constants_text import *
-
-import gettext
-_ = lambda x: gettext.ldgettext("anaconda", x)
-
-class NetworkConfiguratorText:
-    def _handleIPError(self, field, errmsg):
-        self.anaconda.intf.messageWindow(_("Error With Data"),
-                                         _("An error occurred converting the "
-                                           "value entered for "
-                                           "\"%(field)s\":\n%(errmsg)s") \
-                                         % {'field': field, 'errmsg': errmsg})
-
-    def _handleIPMissing(self, field):
-        self.anaconda.intf.messageWindow(_("Error With Data"),
-                                         _("A value is required for the field %s") % field)
-
-    def _dhcpToggled(self, *args):
-        if self.dhcpCheckbox.selected():
-            self.ipv4Address.setFlags(FLAG_DISABLED, FLAGS_SET)
-            self.ipv4Netmask.setFlags(FLAG_DISABLED, FLAGS_SET)
-            #self.ipv6Address.setFlags(FLAG_DISABLED, FLAGS_SET)
-            #self.ipv6Netmask.setFlags(FLAG_DISABLED, FLAGS_SET)
-            self.gatewayEntry.setFlags(FLAG_DISABLED, FLAGS_SET)
-            self.nameserverEntry.setFlags(FLAG_DISABLED, FLAGS_SET)
-        else:
-            self.ipv4Address.setFlags(FLAG_DISABLED, int(self.ipv4Checkbox.selected()))
-            self.ipv4Netmask.setFlags(FLAG_DISABLED, int(self.ipv4Checkbox.selected()))
-            #self.ipv6Address.setFlags(FLAG_DISABLED, int(self.ipv6Checkbox.selected()))
-            #self.ipv6Netmask.setFlags(FLAG_DISABLED, int(self.ipv6Checkbox.selected()))
-            self.gatewayEntry.setFlags(FLAG_DISABLED, FLAGS_RESET)
-            self.nameserverEntry.setFlags(FLAG_DISABLED, FLAGS_RESET)
-
-    def _ipv4Toggled(self, *args):
-        if self.dhcpCheckbox.selected():
-            return
-
-        flag = FLAGS_RESET
-        if not self.ipv4Checkbox.selected():
-            flag = FLAGS_SET
-
-        self.ipv4Address.setFlags(FLAG_DISABLED, flag)
-        self.ipv4Netmask.setFlags(FLAG_DISABLED, flag)
-
-    #def _ipv6Toggled(self, *args):
-    #    if self.dhcpCheckbox.selected():
-    #        return
-    #
-    #    flag = FLAGS_RESET
-    #    if not self.ipv6Checkbox.selected():
-    #        flag = FLAGS_SET
-    #
-    #    self.ipv6Address.setFlags(FLAG_DISABLED, flag)
-    #    self.ipv6Netmask.setFlags(FLAG_DISABLED, flag)
-
-    def __init__(self, screen, anaconda):
-        self.screen = screen
-        self.anaconda = anaconda
-
-    def run(self):
-        grid = GridFormHelp(self.screen, _("Enable network interface"), "netconfig",
-                            1, 9)
-
-        tb = TextboxReflowed(60, _("This requires that you have an active "
-                                   "network connection during the installation "
-                                   "process.  Please configure a network "
-                                   "interface."))
-        grid.add(tb, 0, 0, anchorLeft = 1, padding = (0, 0, 0, 1))
-
-        self.interfaceList = CheckboxTree(height=3, scroll=1)
-
-        netdevs = self.anaconda.network.available()
-        devs = netdevs.keys()
-        devs.sort()
-        ksdevice = self.anaconda.network.getKSDevice()
-        if ksdevice:
-            ksdevice = ksdevice.get('DEVICE')
-        selected_interface = None
-
-        for dev in devs:
-            hwaddr = netdevs[dev].get("HWADDR")
-
-            if hwaddr:
-                desc = "%s - %.50s" % (dev, hwaddr)
-            else:
-                desc = dev
-
-            if selected_interface is None:
-                selected_interface = desc
-
-            if ksdevice and ksdevice == dev:
-                selected_interface = desc
-
-            self.interfaceList.append(desc)
-
-        if selected_interface:
-            self.interfaceList.setCurrent(selected_interface)
-        else:
-            self.interfaceList.setCurrent(0)
-
-        grid.add(self.interfaceList, 0, 1, padding = (0, 0, 0, 1))
-
-        self.dhcpCheckbox = Checkbox(_("Use dynamic IP configuration (DHCP)"), 1)
-        grid.add(self.dhcpCheckbox, 0, 2, anchorLeft = 1)
-
-        self.ipv4Checkbox = Checkbox(_("Enable IPv4 support"), 1)
-        grid.add(self.ipv4Checkbox, 0, 3, anchorLeft = 1)
-
-        #self.ipv6Checkbox = Checkbox(_("Enable IPv6 support"), 0)
-        #grid.add(self.ipv6Checkbox, 0, 4, anchorLeft = 1, padding = (0, 0, 0, 1))
-
-        ipv4Grid = Grid(4, 1)
-        ipv4Grid.setField(Label(_("IPv4 Address:")), 0, 0, padding = (0, 0, 1, 0))
-        self.ipv4Address = Entry(20, scroll=1)
-        ipv4Grid.setField(self.ipv4Address, 1, 0)
-        ipv4Grid.setField(Label("/"), 2, 0)
-        self.ipv4Netmask = Entry(20, scroll=0)
-        ipv4Grid.setField(self.ipv4Netmask, 3, 0)
-
-        grid.add(ipv4Grid, 0, 5, anchorLeft = 1)
-
-        #ipv6Grid = Grid(4, 1)
-        #ipv6Grid.setField(Label(_("IPv6 Address:")), 0, 0, padding = (0, 0, 1, 0))
-        #self.ipv6Address = Entry(20, scroll=1)
-        #ipv6Grid.setField(self.ipv6Address, 1, 0)
-        #ipv6Grid.setField(Label("/"), 2, 0)
-        #self.ipv6Netmask = Entry(20, scroll=0)
-        #ipv6Grid.setField(self.ipv6Netmask, 3, 0)
-
-        #grid.add(ipv6Grid, 0, 6, anchorLeft = 1)
-
-        extraGrid = Grid(4, 1)
-        extraGrid.setField(Label(_("Gateway:")), 0, 0, padding = (0, 0, 1, 0))
-        self.gatewayEntry = Entry(20, scroll=1)
-        extraGrid.setField(self.gatewayEntry, 1, 0, padding = (0, 0, 2, 0))
-        extraGrid.setField(Label(_("Nameserver:")), 2, 0, padding = (0, 0, 1, 0))
-        self.nameserverEntry = Entry(20, scroll=1)
-        extraGrid.setField(self.nameserverEntry, 3, 0)
-
-        grid.add(extraGrid, 0, 7, anchorLeft = 1)
-
-        buttons = ButtonBar(self.screen, [TEXT_OK_BUTTON, TEXT_BACK_BUTTON] )
-        grid.add(buttons, 0, 8, anchorLeft = 1, growx = 1)
-
-        self.dhcpCheckbox.setCallback(self._dhcpToggled)
-        self.ipv4Checkbox.setCallback(self._ipv4Toggled)
-        #self.ipv6Checkbox.setCallback(self._ipv6Toggled)
-
-        # Call these functions to set initial UI state.
-        self._ipv4Toggled()
-        #self._ipv6Toggled()
-        self._dhcpToggled()
-
-        netdevs = self.anaconda.network.available()
-
-        while True:
-            result = grid.run()
-            button = buttons.buttonPressed(result)
-
-            if button == TEXT_BACK_CHECK:
-                self.screen.popWindow()
-                return INSTALL_BACK
-
-            selected = map(lambda x: x.split()[0], self.interfaceList.getSelection())
-            if selected is None or selected == []:
-                self.anaconda.intf.messageWindow(_("Missing Device"),
-                                                 _("You must select a network device"))
-                continue
-
-            for name, dev in netdevs.items():
-                if name in selected:
-                    dev.set(('ONBOOT', 'yes'))
-                else:
-                    dev.set(('ONBOOT', 'no'))
-
-            selected_netdevs = []
-            for devname in selected:
-                if not netdevs.has_key(devname):
-                    continue
-
-                netdev = netdevs[devname]
-                selected_netdevs.append(netdev)
-                netdev.set(("ONBOOT", "yes"))
-
-                if self.dhcpCheckbox.selected():
-                    netdev.set(("BOOTPROTO", "dhcp"))
-                else:
-                    netdev.set(("BOOTPROTO", "static"))
-                    ipv4addr = self.ipv4Address.value()
-                    ipv4nm = self.ipv4Netmask.value()
-                    gateway = self.gatewayEntry.value()
-                    ns = self.nameserverEntry.value()
-
-                    try:
-                        network.sanityCheckIPString(ipv4addr)
-                        netdev.set(("IPADDR", ipv4addr))
-                    except network.IPMissing, msg:
-                        self._handleIPMissing(_("IP Address"))
-                        continue
-                    except network.IPError, msg:
-                        self._handleIPError(_("IP Address"), msg)
-                        continue
-
-                    if ipv4nm.find('.') == -1:
-                        # user provided a CIDR prefix
-                        try:
-                            if int(ipv4nm) > 32 or int(ipv4nm) < 0:
-                                msg = _("IPv4 CIDR prefix must be between 0 and 32.")
-                                self._handleIPError(_("IPv4 Network Mask"), msg)
-                                continue
-                            else:
-                                ipv4nm = isys.prefix2netmask(int(ipv4nm))
-                                netdev.set(("NETMASK", ipv4nm))
-                        except:
-                            self._handleIPMissing(_("IPv4 Network Mask"))
-                            continue
-                    else:
-                        # user provided a dotted-quad netmask
-                        try:
-                            network.sanityCheckIPString(ipv4nm)
-                            netdev.set(("NETMASK", ipv4nm))
-                        except network.IPMissing, msg:
-                            self._handleIPMissing(_("IPv4 Network Mask"))
-                            continue
-                        except network.IPError, msg:
-                            self._handleIPError(_("IPv4 Network Mask "), msg)
-                            continue
-
-                    try:
-                        if gateway:
-                            network.sanityCheckIPString(gateway)
-                            netdev.set(("GATEWAY", gateway))
-                    except network.IPMissing, msg:
-                        pass
-                    except network.IPError, msg:
-                        self._handleIPError(_("Gateway"), msg)
-                        continue
-
-                    try:
-                        if ns:
-                            network.sanityCheckIPString(ns)
-                            netdev.set(("DNS1", ns))
-                    except network.IPMissing, msg:
-                        pass
-                    except network.IPError, msg:
-                        self._handleIPError(_("Nameserver"), msg)
-                        continue
-
-            w = self.anaconda.intf.waitWindow(_("Configuring Network Interfaces"), _("Waiting for NetworkManager"))
-            result = self.anaconda.network.bringUp(devices=selected_netdevs)
-            w.pop()
-            if result:
-                break
-            else:
-                 self.anaconda.intf.messageWindow(_("Error"), _("Error configuring network device"), _("Error configuring network device %s") % netdev.get('DEVICE'))
-
-        self.screen.popWindow()
-        return INSTALL_OK
diff --git a/textw/network_text.py b/textw/network_text.py
deleted file mode 100644
index 26499b8..0000000
--- a/textw/network_text.py
+++ /dev/null
@@ -1,33 +0,0 @@
-#
-# network_text.py: text mode network configuration dialogs
-#
-# Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006  Red Hat, Inc.
-# 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 as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# 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, see <http://www.gnu.org/licenses/>.
-#
-# Author(s): Jeremy Katz <katzj@xxxxxxxxxx>
-#            Michael Fulbright <msf@xxxxxxxxxx>
-#            David Cantrell <dcantrell@xxxxxxxxxx>
-#
-from constants_text import *
-import network
-
-class HostnameWindow:
-    def __call__(self, screen, anaconda):
-        hname = network.getDefaultHostname(anaconda)
-        anaconda.network.hostname = hname
-        return INSTALL_OK
-
-# vim:tw=78:ts=4:et:sw=4
diff --git a/textw/partition_text.py b/textw/partition_text.py
deleted file mode 100644
index 193ff21..0000000
--- a/textw/partition_text.py
+++ /dev/null
@@ -1,162 +0,0 @@
-#
-# partition_text.py: allows the user to choose how to partition their disks
-# in text mode
-#
-# Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007  Red Hat, Inc.
-# 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 as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# 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, see <http://www.gnu.org/licenses/>.
-#
-# Author(s): Jeremy Katz <katzj@xxxxxxxxxx>
-#
-
-import os, sys
-import isys
-import string
-import copy
-import network
-import parted
-import storage.iscsi
-import storage.fcoe
-import storage.zfcp
-from partIntfHelpers import *
-from snack import *
-from constants_text import *
-from constants import *
-from add_drive_text import addDriveDialog
-
-import gettext
-_ = lambda x: gettext.ldgettext("anaconda", x)
-
-import logging
-log = logging.getLogger("anaconda")
-
-class PartitionTypeWindow:
-    def typeboxChange(self, (typebox, drivelist)):
-        flag = FLAGS_RESET
-        if typebox.current() == CLEARPART_TYPE_NONE:
-            flag = FLAGS_SET
-        # XXX need a way to disable the checkbox tree
-
-    def clearDrivelist(self):
-        # XXX remove parted object refs
-        #     need to put in clear() method for checkboxtree in snack
-        self.drivelist.key2item = {}
-        self.drivelist.item2key = {}
-
-    def __call__(self, screen, anaconda):
-        self.anaconda = anaconda
-
-        while 1:
-            g = GridFormHelp(screen, _("Partitioning Type"), "autopart", 1, 6)
-
-            txt = TextboxReflowed(65, _("Installation requires partitioning of your hard drive.  The default layout is suitable for most users.  Select what space to use and which drives to use as the install target."))
-            g.add(txt, 0, 0, (0, 0, 0, 0))
-
-            opts = ((_("Use entire drive"), CLEARPART_TYPE_ALL),
-                    (_("Replace existing Linux system"), CLEARPART_TYPE_LINUX),
-                    (_("Use free space"), CLEARPART_TYPE_NONE))
-            typebox = Listbox(height = len(opts), scroll = 0)
-            for (txt, val) in opts:
-                typebox.append(txt, val)
-
-            if anaconda.storage.clearPartType is None:
-                preselection = CLEARPART_TYPE_LINUX
-            else:
-                preselection = anaconda.storage.clearPartType
-            typebox.setCurrent(preselection)
-
-            g.add(typebox, 0, 1, (0, 1, 0, 0))
-
-            # list of drives to select which to clear
-            subgrid = Grid(1, 2)
-            subgrid.setField(TextboxReflowed(55, _("Which drive(s) do you want to "
-                                                   "use for this installation?")),
-                             0, 0)
-            drivelist = CheckboxTree(height=2, scroll=1)
-            subgrid.setField(drivelist, 0, 1)
-            g.add(subgrid, 0, 2, (0, 1, 0, 0))
-
-            bb = ButtonBar(screen, [ TEXT_OK_BUTTON, TEXT_BACK_BUTTON ])
-            g.add(bb, 0, 5, (0,1,0,0))
-
-
-            typebox.setCallback(self.typeboxChange, (typebox, drivelist))
-            self.drivelist = drivelist
-
-            g.addHotKey("F2")
-            screen.pushHelpLine (_("<Space>,<+>,<-> selection   |   <F2> Add drive   |   <F12> next screen"))
-
-            # restore the drive list each time
-            disks = anaconda.storage.partitioned
-            cleardrives = anaconda.storage.clearPartDisks
-
-            for disk in disks:
-                model = disk.model
-
-                if not cleardrives or len(cleardrives) < 1:
-                    selected = 1
-                else:
-                    if disk in cleardrives:
-                        selected = 1
-                    else:
-                        selected = 0
-
-                sizestr = "%8.0f MB" % (disk.size,)
-                diskdesc = "%6s %s (%s)" % (disk.name, sizestr, model[:23],)
-
-                drivelist.append(diskdesc, selected = selected)
-
-            rc = g.run()
-
-            if len(self.drivelist.getSelection()) > 0:
-                sel = map(lambda s: s.split()[0], self.drivelist.getSelection())
-            else:
-                sel = []
-            partmethod_ans = typebox.current()
-            res = bb.buttonPressed(rc)
-
-            self.clearDrivelist()
-            screen.popHelpLine()
-            screen.popWindow()
-
-            if rc == "F2":
-                addDialog = addDriveDialog(anaconda)
-                if addDialog.addDriveDialog(screen) != INSTALL_BACK:
-                    anaconda.storage.reset()
-                    anaconda.bootloader.updateDriveList()
-                continue
-
-            if res == TEXT_BACK_CHECK:
-                return INSTALL_BACK
-
-            if anaconda.storage.checkNoDisks():
-                continue
-
-            if len(sel) < 1:
-                mustHaveSelectedDrive(anaconda.intf)
-                continue
-
-            anaconda.dispatch.skipStep("autopartitionexecute", skip = 0)
-            anaconda.storage.doAutoPart = True
-            anaconda.storage.clearPartType = partmethod_ans
-            anaconda.storage.clearPartDisks = sel
-            break
-
-        # ask to review autopartition layout - but only if it's not custom partitioning
-        anaconda.dispatch.skipStep("partition", skip = 1)
-        anaconda.dispatch.skipStep("bootloader", skip = 1)
-
-        return INSTALL_OK
-
diff --git a/textw/progress_text.py b/textw/progress_text.py
deleted file mode 100644
index 579408a..0000000
--- a/textw/progress_text.py
+++ /dev/null
@@ -1,131 +0,0 @@
-#
-# progress_text.py: text mode install/upgrade progress dialog
-#
-# Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007  Red Hat, Inc.
-# 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 as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# 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, see <http://www.gnu.org/licenses/>.
-#
-
-from constants import *
-from snack import *
-from constants_text import *
-from iutil import strip_markup
-
-import gettext
-_ = lambda x: gettext.ldgettext("anaconda", x)
-
-import logging
-log = logging.getLogger("anaconda")
-
-class InstallProgressWindow:
-    def __init__(self, screen):
-	self.screen = screen
-	self.drawn = False
-
-        self.pct = 0
-
-    def __del__ (self):
-	if self.drawn:
-            self.screen.popWindow ()
-
-    def _setupScreen(self):
-        screen = self.screen
-
-        self.grid = GridForm(self.screen, _("Package Installation"), 1, 6)
-
-        self.width = 65
-        self.progress = Scale(self.width, 100)
-        self.grid.add (self.progress, 0, 1, (0, 1, 0, 0))
-
-        self.label = Label("")
-        self.grid.add(self.label, 0, 2, (0, 1, 0, 0), anchorLeft = 1)
-
-        self.info = Textbox(self.width, 4, "", wrap = 1)
-        self.grid.add(self.info, 0, 3, (0, 1, 0, 0))
-
-        self.grid.draw()
-        screen.refresh()
-        self.drawn = True
-
-    def processEvents(self):
-        if not self.drawn:
-            return
-        self.grid.draw()
-        self.screen.refresh()
-
-    def setShowPercentage(self, val):
-        pass
-
-    def get_fraction(self):
-        return self.pct
-
-    def set_fraction(self, pct):
-        if not self.drawn:
-            self._setupScreen()
-
-        if pct > 1.0:
-            pct = 1.0
-
-        self.progress.set(int(pct * 100))
-        self.pct = pct
-        self.processEvents()
-
-    def set_label(self, txt):
-        if not self.drawn:
-            self._setupScreen()
-        
-        self.info.setText(strip_markup(txt))
-        self.processEvents()
-
-    def set_text(self, txt):
-        if not self.drawn:
-            self._setupScreen()
-        
-        if len(txt) > self.width:
-            txt = txt[:self.width]
-        else:
-            spaces = (self.width - len(txt)) / 2
-            txt = (" " * spaces) + txt
-        
-        self.label.setText(strip_markup(txt))
-        self.processEvents()
-
-class setupForInstall:
-
-    def __call__(self, screen, anaconda):
-	if anaconda.dir == DISPATCH_BACK:
-	    anaconda.intf.setInstallProgressClass(None)
-	    return INSTALL_BACK
-
-        anaconda.intf.setInstallProgressClass(InstallProgressWindow(screen))
-	return INSTALL_OK
-
-if __name__ == "__main__":
-    screen = SnackScreen()
-    ipw = InstallProgressWindow(screen)
-
-    import time
-    ipw._setupScreen()
-    time.sleep(2)
-
-    ipw.set_label("testing blah\n<b>blahblahb</b>lahbl ahalsdfkj")
-    ipw.set_text("blah blah blah")
-    ipw.set_fraction(0.25)
-    time.sleep(2)
-
-    p = ipw.get_fraction()
-
-    screen.finish()
-    print(p)
diff --git a/textw/statusline_text.py b/textw/statusline_text.py
deleted file mode 100644
index 4a4a3db..0000000
--- a/textw/statusline_text.py
+++ /dev/null
@@ -1,78 +0,0 @@
-#
-# statusline_text.py: text mode status line management functions
-#
-# Copyright (C) 2000, 2001  Red Hat, Inc.  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 as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# 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, see <http://www.gnu.org/licenses/>.
-#
-
-# XXX this file appears to be unused.
-
-import string
-import copy
-
-class CleanStatusLine:
-
-    def centerLabel(self, str, space):
-        return string.center(str, space)
-
-    def formatStatusLine(self, args):
-        if len(args) == 1:
-            return self.centerLabel(args[0], self.width)
-
-        nonspaces = 0
-        for i in args:
-            nonspaces = nonspaces + len(i)
-
-        spaceEach = (self.width-nonspaces)/len(args)
-        outstr = ""
-
-        j = 0
-        for i in args:
-            str = self.centerLabel(i, len(i) + spaceEach)
-            outstr = outstr + str
-            j = j + 1
-            if j != len(args):
-                outstr = outstr + "|"
-
-        return outstr
-
-    def setdefaultStatusLine(self, rargs, largs):
-        self.rargs = rargs
-        self.largs = largs
-        
-
-#    def defaultStatusLine(self):
-#    def __str__(self):
-#        args = copy.deepcopy(self.largs)
-#        args.extend(self.rargs)
-#        return self.formatStatusLine(args)
-        
-#    def customStatusLine(self, optargs):
-    def __str__(self):
-        args = copy.deepcopy(self.largs)
-        if self.optargs != None:
-            args.extend(self.optargs)
-        args.extend(self.rargs)
-        return self.formatStatusLine(args)
-
-
-    def __init__(self, args, optargs=None):
-#        self.largs = ["<Tab>/<Alt-Tab> between elements"]
-#        self.rargs = ["<F12> next screen"]
-        (self.largs, self.rargs) = args
-        self.optargs = optargs
-            
-        self.width = 80
-        
diff --git a/textw/task_text.py b/textw/task_text.py
deleted file mode 100644
index 17d312b..0000000
--- a/textw/task_text.py
+++ /dev/null
@@ -1,28 +0,0 @@
-#
-# task_gui.py: Choose tasks for installation
-#
-# Copyright (C) 2006  Red Hat, Inc.  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 as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# 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, see <http://www.gnu.org/licenses/>.
-#
-
-from constants_text import *
-from constants import *
-
-class TaskWindow:
-    def __call__(self, screen, anaconda):
-        anaconda.backend.resetPackageSelections()
-        anaconda.backend.selectGroup("Core")
-
-        return INSTALL_OK
diff --git a/textw/timezone_text.py b/textw/timezone_text.py
deleted file mode 100644
index c78442a..0000000
--- a/textw/timezone_text.py
+++ /dev/null
@@ -1,131 +0,0 @@
-#
-# timezone_text.py: text mode timezone selection dialog
-#
-# Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006  Red Hat, Inc.
-# 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 as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# 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, see <http://www.gnu.org/licenses/>.
-#
-
-import sys
-import string
-import iutil
-from time import *
-from snack import *
-from constants_text import *
-from bootloader import hasWindows
-from scdate.core import zonetab
-
-from constants import *
-import gettext
-_ = lambda x: gettext.ldgettext("anaconda", x)
-
-sys.path.append("/usr/share/system-config-date")
-
-class TimezoneWindow:
-
-    def getTimezoneList(self):
-        zt = zonetab.ZoneTab()
-        zoneList = [ x.tz for x in zt.getEntries() ]
-        zoneList.sort()
-        return zoneList
-
-    def updateSysClock(self):
-	args = ["--hctosys"]
-	if self.c.selected():
-	    args.append("--utc")
-
-	iutil.execWithRedirect("hwclock", args)
-	self.g.setTimer(500)
-	self.updateClock()
-
-    def updateClock(self):
-        # disable for now
-        return
-        
-#	if os.access("/usr/share/zoneinfo/" + self.l.current(), os.R_OK):
-#	    os.environ['TZ'] = self.l.current()
-#	    self.label.setText(self.currentTime())
-#	else:
-#	    self.label.setText("")
-
-    def currentTime(self):
-	return "Current time: " + strftime("%X %Z", localtime(time()))
-
-    def __call__(self, screen, anaconda):
-	timezones = self.getTimezoneList()
-	(default, asUtc) = anaconda.timezone.getTimezoneInfo()
-        if not default:
-	    default = anaconda.instLanguage.getDefaultTimeZone(anaconda.rootPath)
-
-	bb = ButtonBar(screen, [TEXT_OK_BUTTON, TEXT_BACK_BUTTON])
-	t = TextboxReflowed(30, 
-			_("In which time zone are you located?"))
-
-        if not anaconda.ksdata and not hasWindows(anaconda.bootloader):
-            asUtc = True
-
-#
-# disabling this for now
-# 
-#	self.label = Label(self.currentTime())
-		
-	self.l = Listbox(5, scroll = 1, returnExit = 0)
-
-        for tz in timezones:
-	    self.l.append(gettext.ldgettext("system-config-date", tz), tz)
-
-	self.l.setCurrent(default.replace("_", " "))
-#	self.l.setCallback(self.updateClock)
-        
-	self.c = Checkbox(_("System clock uses UTC"), isOn = asUtc)
-#	self.c.setCallback(self.updateSysClock)
-
-	self.g = GridFormHelp(screen, _("Time Zone Selection"), "timezone",
-			      1, 5)
-	self.g.add(t, 0, 0)
-#	self.g.add(self.label, 0, 1, padding = (0, 1, 0, 0), anchorLeft = 1)
-	self.g.add(self.c, 0, 2, padding = (0, 1, 0, 1), anchorLeft = 1)
-	self.g.add(self.l, 0, 3, padding = (0, 0, 0, 1))
-	self.g.add(bb, 0, 4, growx = 1)
-
-# disabling for now
-#	self.updateClock()
-#	self.updateSysClock()
-#
-#	self.g.setTimer(500)
-#
-#	result = "TIMER"
-#	while result == "TIMER":
-#	    result = self.g.run()
-#	    if result == "TIMER":
-#		self.updateClock()
-
-        result = ""
-        while 1:
-            result = self.g.run()
-            rc = bb.buttonPressed (result)
-            
-            if rc == TEXT_BACK_CHECK:
-                screen.popWindow()
-                return INSTALL_BACK
-            else:
-                break
-
-        screen.popWindow()
-	anaconda.timezone.setTimezoneInfo(self.l.current().replace(" ", "_"), asUtc = self.c.selected())
-
-	return INSTALL_OK
-
-
diff --git a/textw/upgrade_bootloader_text.py b/textw/upgrade_bootloader_text.py
deleted file mode 100644
index db736f3..0000000
--- a/textw/upgrade_bootloader_text.py
+++ /dev/null
@@ -1,183 +0,0 @@
-#
-# upgrade_bootloader_text.py: text bootloader dialog for upgrades
-#
-# Copyright (C) 2002  Red Hat, Inc.  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 as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# 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, see <http://www.gnu.org/licenses/>.
-#
-# Author(s): Jeremy Katz <katzj@xxxxxxxxxx>
-#
-
-from snack import *
-from constants_text import *
-from flags import flags
-import string
-from booty import checkbootloader
-from storage.devices import devicePathToName
-
-from constants import *
-import gettext
-_ = lambda x: gettext.ldgettext("anaconda", x)
-
-import logging
-log = logging.getLogger("anaconda")
-
-class UpgradeBootloaderWindow:
-    def _ideToLibata(self, rootPath):
-        try:
-            f = open("/proc/modules", "r")
-            buf = f.read()
-            if buf.find("libata") == -1:
-                return False
-        except:
-            log.debug("error reading /proc/modules")
-            pass
-
-        try:
-            f = open(rootPath + "/etc/modprobe.conf")
-        except:
-            log.debug("error reading /etc/modprobe.conf")
-            return False
-
-        modlines = f.readlines()
-        f.close()
-
-        try:
-            f = open("/tmp/scsidisks")
-        except:
-            log.debug("error reading /tmp/scsidisks")
-            return False
-        mods = []
-        for l in f.readlines():
-            (disk, mod) = l.split()
-            if mod.strip() not in mods:
-                mods.append(mod.strip())
-        f.close()
-
-        for l in modlines:
-            stripped = l.strip()
-
-            if stripped == "" or stripped[0] == "#":
-                continue
-
-            if stripped.find("scsi_hostadapter") != -1:
-                mod = stripped.split()[-1]
-                if mod in mods:
-                    mods.remove(mod)
-
-        if len(mods) > 0:
-            return True
-        return False
-
-    def __call__(self, screen, anaconda):
-        self.screen = screen
-        self.dispatch = anaconda.dispatch
-        self.bl = anaconda.bootloader
-
-        newToLibata = self._ideToLibata(anaconda.rootPath)
-        (self.type, self.bootDev) = \
-                    checkbootloader.getBootloaderTypeAndBoot(anaconda.rootPath, storage=anaconda.storage)
-
-        blradio = RadioGroup()
-
-        (update, newbl, nobl) = (0, 0, 0)
-        if not self.dispatch.stepInSkipList("bootloader"):
-            newbl = 1
-        elif self.dispatch.stepInSkipList("instbootloader"):
-            nobl = 1
-        else:
-            if newToLibata or self.type is None or self.bootDev is None:
-                newbl = 1
-            else:
-                update = 1
-
-        if newToLibata or self.type is None or self.bootDev is None:
-            if newToLibata:
-                t = TextboxReflowed(53,
-                    _("Due to system changes, your boot loader "
-                      "configuration can not be automatically updated."))
-            else:
-                t = TextboxReflowed(53,
-                  _("The installer is unable to detect the boot loader "
-                    "currently in use on your system."))
-            
-
-            self.update_radio = blradio.add(_("Update boot loader configuration"),
-                                            "update", update)
-            self.update_radio.w.checkboxSetFlags(FLAG_DISABLED, FLAGS_SET)
-        else:
-            t = TextboxReflowed(53,
-                                _("The installer has detected the %(type)s "
-                                  "boot loader currently installed on "
-                                  "%(bootDev)s.")
-                                % {'type': self.type, 'bootDev': self.bootDev})
-
-            self.update_radio = blradio.add(_("Update boot loader configuration"),
-                                            "update", update)
-
-        self.nobl_radio = blradio.add(_("Skip boot loader updating"),
-                                      "nobl", nobl)
-        self.newbl_radio = blradio.add(_("Create new boot loader "
-                                         "configuration"),
-                                       "newbl", newbl)
-
-        buttons = ButtonBar(screen, [TEXT_OK_BUTTON, TEXT_BACK_BUTTON])
-
-        grid = GridFormHelp(screen, _("Upgrade Boot Loader Configuration"),
-                            "bl-upgrade", 1, 5)
-
-        grid.add(t, 0, 0, (0,0,0,1))
-        grid.add(self.update_radio, 0, 1, (0,0,0,0))
-        grid.add(self.nobl_radio, 0, 2, (0,0,0,0))
-        grid.add(self.newbl_radio, 0, 3, (0,0,0,1))
-        grid.add(buttons, 0, 4, growx = 1)
-
-
-        while 1:
-            result = grid.run()
-
-            button = buttons.buttonPressed(result)
-
-            if button == TEXT_BACK_CHECK:
-                screen.popWindow()
-                return INSTALL_BACK        
-
-            if blradio.getSelection() == "nobl":                           
-                self.dispatch.skipStep("bootloadersetup", skip = 1)
-                self.dispatch.skipStep("bootloader", skip = 1)
-                self.dispatch.skipStep("bootloaderadvanced", skip = 1)
-                self.dispatch.skipStep("instbootloader", skip = 1)
-            elif blradio.getSelection() == "newbl":
-                self.dispatch.skipStep("bootloadersetup", skip = 0)
-                self.dispatch.skipStep("bootloader", skip = 0)
-                self.dispatch.skipStep("bootloaderadvanced", skip = 0)
-                self.dispatch.skipStep("instbootloader", skip = 0)
-                self.bl.doUpgradeOnly = 0
-            else:
-                self.dispatch.skipStep("bootloadersetup", skip = 0)
-                self.dispatch.skipStep("bootloader", skip = 1)
-                self.dispatch.skipStep("bootloaderadvanced", skip = 1)
-                self.dispatch.skipStep("instbootloader", skip = 0)
-                self.bl.doUpgradeOnly = 1
-
-                if self.type == "GRUB":
-                    self.bl.useGrubVal = 1
-                else:
-                    self.bl.useGrubVal = 0
-                self.bl.setDevice(devicePathToName(self.bootDev))
-
-
-
-            screen.popWindow()
-            return INSTALL_OK
diff --git a/textw/upgrade_text.py b/textw/upgrade_text.py
deleted file mode 100644
index 7fd7ebe..0000000
--- a/textw/upgrade_text.py
+++ /dev/null
@@ -1,258 +0,0 @@
-#
-# upgrade_text.py: text mode upgrade dialogs
-#
-# Copyright (C) 2001  Red Hat, Inc.  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 as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# 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, see <http://www.gnu.org/licenses/>.
-#
-
-import isys
-import iutil
-import upgrade
-from constants_text import *
-from snack import *
-from flags import flags
-from constants import *
-from storage.formats import getFormat
-
-import gettext
-_ = lambda x: gettext.ldgettext("anaconda", x)
-
-import logging
-log = logging.getLogger("anaconda")
-
-seenExamineScreen = False
-
-class UpgradeMigrateFSWindow:
-    def __call__ (self, screen, anaconda):
-      
-        migent = anaconda.storage.migratableDevices
-
-	g = GridFormHelp(screen, _("Migrate File Systems"), "upmigfs", 1, 4)
-
-	text = (_("This release of %(productName)s supports "
-                 "an updated file system, which has several "
-                 "benefits over the file system traditionally shipped "
-                 "in %(productName)s.  This installation program can migrate "
-                 "formatted partitions without data loss.\n\n"
-                 "Which of these partitions would you like to migrate?") %
-                  {'productName': productName})
-
-	tb = TextboxReflowed(60, text)
-	g.add(tb, 0, 0, anchorLeft = 1, padding = (0, 0, 0, 1))
-
-        partlist = CheckboxTree(height=4, scroll=1)
-        for device in migent:
-            if not device.format.exists:
-                migrating = True
-            else:
-                migrating = False
-
-            # FIXME: the fstype at least will be wrong here
-            partlist.append("%s - %s - %s" % (device.path,
-                                              device.format.type,
-                                              device.format.mountpoint),
-                                              device, migrating)
-            
-	g.add(partlist, 0, 1, padding = (0, 0, 0, 1))
-        
-	buttons = ButtonBar(screen, [TEXT_OK_BUTTON, TEXT_BACK_BUTTON] )
-	g.add(buttons, 0, 3, anchorLeft = 1, growx = 1)
-
-	while 1:
-	    result = g.run()
-        
-	    if (buttons.buttonPressed(result)):
-		result = buttons.buttonPressed(result)
-
-	    if result == TEXT_BACK_CHECK:
-		screen.popWindow()
-		return INSTALL_BACK
-
-            # reset
-            # XXX the way to do this is by scheduling and cancelling actions
-            #for entry in migent:
-            #    entry.setFormat(0)
-            #    entry.setMigrate(0)
-            #    entry.fsystem = entry.origfsystem
-
-            for entry in partlist.getSelection():
-                try:
-                    newfs = getFormat(entry.format.migratetofs[0])
-                except Exception, e:
-                    log.info("failed to get new filesystem type, defaulting to ext3: %s" %(e,))
-                    newfs = getFormat("ext3")
-                    anaconda.storage.migrateFormat(entry, newfs)
-
-            screen.popWindow()
-            return INSTALL_OK
-
-class UpgradeSwapWindow:
-    def __call__ (self, screen, anaconda):
-	(fsList, suggSize, suggDev) = anaconda.upgradeSwapInfo
-
-        ramDetected = iutil.memInstalled()/1024
-
-	text = _("Recent kernels (2.4 or newer) need significantly more swap than older "
-		 "kernels, up to twice the amount of RAM on the "
-		 "system.  You currently have %dMB of swap configured, but "
-		 "you may create additional swap space on one of your "
-		 "file systems now.") % (iutil.swapAmount() / 1024)
-
-	tb = TextboxReflowed(60, text)
-	amount = Entry(10, scroll = 0)
-	amount.set(str(suggSize))
-
-	l = len(fsList)
-	scroll = 0
-	if l > 4:
-	    l = 4
-	    scroll = 1
-	listbox = Listbox(l, scroll = scroll)
-
-	liLabel = Label("%-25s %-15s %8s" % (_("Mount Point"), 
-			_("Partition"), _("Free Space")))
-
-	count = 0
-	for (device, size) in fsList:
-	    listbox.append("%-25s %-15s %6dMB" % (device.format.mountpoint,
-                                                  device.path,
-                                                  size),
-                                                  count)
-
-	    if (device == suggDev):
-		listbox.setCurrent(count)
-
-	    count = count + 1
-
-	buttons = ButtonBar(screen, [TEXT_OK_BUTTON, (_("Skip"), "skip"),  
-			    TEXT_BACK_BUTTON] )
-
-	amGrid = Grid(2, 3)
-	amGrid.setField(Label(_("RAM detected (MB):")), 0, 0, anchorLeft = 1,
-			padding = (0, 0, 1, 0))
-	amGrid.setField(Label(str(ramDetected)), 1, 0, anchorLeft = 1)
-	amGrid.setField(Label(_("Suggested size (MB):")), 0, 1, anchorLeft = 1,
-			padding = (0, 0, 1, 0))
-	amGrid.setField(Label(str(suggSize)), 1, 1, anchorLeft = 1)
-	amGrid.setField(Label(_("Swap file size (MB):")), 0, 2, anchorLeft = 1,
-			padding = (0, 0, 1, 0))
-	amGrid.setField(amount, 1, 2)
-	
-	liGrid = Grid(1, 2)
-	liGrid.setField(liLabel, 0, 0)
-	liGrid.setField(listbox, 0, 1)
-
-	g = GridFormHelp(screen, _("Add Swap"), "upgradeswap", 1, 4)
-	g.add(tb, 0, 0, anchorLeft = 1, padding = (0, 0, 0, 1))
-	g.add(amGrid, 0, 1, padding = (0, 0, 0, 1))
-	g.add(liGrid, 0, 2, padding = (0, 0, 0, 1))
-	g.add(buttons, 0, 3, anchorLeft = 1, growx = 1)
-
-	while 1:
-	    result = g.run()
-
-	    if (buttons.buttonPressed(result)):
-		result = buttons.buttonPressed(result)
-
-	    if result == TEXT_BACK_CHECK:
-		screen.popWindow()
-		return INSTALL_BACK
-	    elif result == "skip":
-		screen.popWindow()
-		return INSTALL_OK
-
-	    val = amount.value()
-            
-	    try:
-		val = int(val)
-	    except ValueError:
-		anaconda.intf.messageWindow(_("Error"),
-                                   _("The value you entered is not a "
-                                     "valid number."))
-
-	    if type(val) == type(1):
-		(dev, size) = fsList[listbox.current()]
-		if size < (val + 16):
-		    anaconda.intf.messageWindow(_("Error"),
-                                       _("There is not enough space on the "
-                                         "device you selected for the swap "
-                                         "partition."))
-                elif val > 2000 or val < 1:
-                    anaconda.intf.messageWindow(_("Warning"), 
-                                       _("The swap file must be between 1 "
-                                         "and 2000 MB in size."))
-		else:
-		    screen.popWindow()
-                    anaconda.storage.createSwapFile(dev, val)
-                    anaconda.dispatch.skipStep("addswap", 1)
-		    return INSTALL_OK
-
-	raise ValueError
-	
-class UpgradeExamineWindow:
-    def __call__ (self, screen, anaconda):
-        parts = anaconda.rootParts
-
-        height = min(len(parts), 11) + 1
-        if height == 12:
-            scroll = 1
-        else:
-            scroll = 0
-        partList = []
-        partList.append(_("Reinstall System"))
-
-        global seenExamineScreen
-
-	if (not seenExamineScreen and anaconda.dispatch.stepInSkipList("installtype")) or anaconda.upgrade:
-            default = 1
-        else:
-            default = 0
-
-        for (device, desc) in parts:
-            partList.append("%s (%s)" %(desc, device.path))
-
-        (button, choice) =  ListboxChoiceWindow(screen, _("System to Upgrade"),
-                            _("There seem to be one or more existing Linux installations "
-                              "on your system.\n\nPlease choose one to upgrade, "
-			      "or select 'Reinstall System' to freshly install "
-			      "your system."), partList,
-                                                [ TEXT_OK_BUTTON,
-                                                  TEXT_BACK_BUTTON ],
-                                                width = 55, scroll = scroll,
-                                                height = height,
-                                                default = default,
-                                                help = "upgraderoot")
-
-        if button == TEXT_BACK_CHECK:
-            return INSTALL_BACK
-        else:
-            if choice == 0:
-                root = None
-            else:
-                root = parts[choice - 1]
-
-        if root is not None:
-            upgrade.setSteps(anaconda)
-            anaconda.upgrade = True
-
-            anaconda.upgradeRoot = [(root[0], root[1])]
-            anaconda.rootParts = parts
-            anaconda.dispatch.skipStep("installtype", skip = 1)
-        else:
-            anaconda.dispatch.skipStep("installtype", skip = 0)
-            anaconda.upgradeRoot = None
-
-        seenExamineScreen = True
-        return INSTALL_OK
diff --git a/textw/userauth_text.py b/textw/userauth_text.py
deleted file mode 100644
index 111858c..0000000
--- a/textw/userauth_text.py
+++ /dev/null
@@ -1,107 +0,0 @@
-#
-# userauth_text.py: text mode authentication setup dialogs
-#
-# Copyright (C) 2000, 2001, 2002, 2008  Red Hat, Inc.  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 as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# 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, see <http://www.gnu.org/licenses/>.
-#
-
-from snack import *
-from constants_text import *
-import cracklib
-
-from constants import *
-import gettext
-_ = lambda x: gettext.ldgettext("anaconda", x)
-
-class RootPasswordWindow:
-    def __call__ (self, screen, anaconda):
-        toplevel = GridFormHelp(screen, _("Root Password"), "rootpw", 1, 3)
-
-        toplevel.add(TextboxReflowed(37,
-                                     _("Pick a root password. You must "
-                                       "type it twice to ensure you know "
-                                       "it and do not make a typing "
-                                       "mistake. ")),
-                     0, 0, (0, 0, 0, 1))
-
-        if anaconda.users.rootPassword["isCrypted"]:
-            anaconda.users.rootPassword["password"] = ""
-
-        entry1 = Entry(24, password=1,
-                       text=anaconda.users.rootPassword["password"])
-        entry2 = Entry(24, password=1,
-                       text=anaconda.users.rootPassword["password"])
-        passgrid = Grid(2, 2)
-        passgrid.setField(Label(_("Password:")), 0, 0, (0, 0, 1, 0),
-                          anchorLeft=1)
-        passgrid.setField(Label(_("Password (confirm):")), 0, 1, (0, 0, 1, 0),
-                          anchorLeft=1)
-        passgrid.setField(entry1, 1, 0)
-        passgrid.setField(entry2, 1, 1)
-        toplevel.add(passgrid, 0, 1, (0, 0, 0, 1))
-
-        bb = ButtonBar(screen, (TEXT_OK_BUTTON, TEXT_BACK_BUTTON))
-        toplevel.add(bb, 0, 2, growx = 1)
-
-        while 1:
-            toplevel.setCurrent(entry1)
-            result = toplevel.run()
-            rc = bb.buttonPressed(result)
-            if rc == TEXT_BACK_CHECK:
-                screen.popWindow()
-                return INSTALL_BACK
-            if len(entry1.value()) < 6:
-                ButtonChoiceWindow(screen, _("Password Length"),
-                    _("The root password must be at least 6 characters long."),
-                    buttons = [ TEXT_OK_BUTTON ], width = 50)
-            elif entry1.value() != entry2.value():
-                ButtonChoiceWindow(screen, _("Password Mismatch"),
-                    _("The passwords you entered were different. Please "
-                      "try again."), buttons = [ TEXT_OK_BUTTON ], width = 50)
-            elif self.hasBadChars(entry1.value()):
-                ButtonChoiceWindow(screen, _("Error with Password"),
-                    _("Requested password contains non-ASCII characters, "
-                      "which are not allowed."),
-                    buttons = [ TEXT_OK_BUTTON ], width = 50)
-            else:
-                try:
-                    cracklib.FascistCheck(entry1.value())
-                except ValueError, e:
-                    msg = gettext.ldgettext("cracklib", e)
-                    ret = anaconda.intf.messageWindow(_("Weak Password"),
-                             _("You have provided a weak password: %s\n\n"
-                               "Would you like to continue with this password?"
-                               % (msg, )),
-                             type = "yesno", default="no")
-                    if ret == 1:
-                        break
-                else:
-                    break
-
-            entry1.set("")
-            entry2.set("")
-
-        screen.popWindow()
-        anaconda.users.rootPassword["password"] = entry1.value()
-        anaconda.users.rootPassword["isCrypted"] = False
-        return INSTALL_OK
-
-    def hasBadChars(self, pw):
-        allowed = string.digits + string.ascii_letters + \
-                  string.punctuation + " "
-        for letter in pw:
-            if letter not in allowed:
-                return True
-        return False
diff --git a/textw/welcome_text.py b/textw/welcome_text.py
deleted file mode 100644
index bf58b58..0000000
--- a/textw/welcome_text.py
+++ /dev/null
@@ -1,47 +0,0 @@
-#
-# welcome_text.py: text mode welcome window
-#
-# Copyright (C) 2001, 2002  Red Hat, Inc.  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 as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# 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, see <http://www.gnu.org/licenses/>.
-#
-
-from snack import *
-from constants_text import *
-from constants import *
-import sys
-import gettext
-_ = lambda x: gettext.ldgettext("anaconda", x)
-
-class WelcomeWindow:
-    def __call__(self, screen, anaconda):
-        rc = ButtonChoiceWindow(screen, _("%s") % (productName,),
-                                _("Welcome to %s!\n\n")
-                                % (productName, ),
-                                buttons = [TEXT_OK_BUTTON], width = 50,
-                                help = "welcome")
-
-        if anaconda.requiresNetworkInstall():
-            anaconda.intf.messageWindow(_("Network Install Required"),
-                                        _("Your installation source is set to "
-                                          "a network location, but no netork "
-                                          "devices were found on your "
-                                          "system.  To avoid a network "
-                                          "installation, boot with the full "
-                                          "DVD, full CD set, or do not pass "
-                                          "a repo= parameter that specifies "
-                                          "a network source."))
-            sys.exit(0)
-
-        return INSTALL_OK
diff --git a/textw/zipl_text.py b/textw/zipl_text.py
deleted file mode 100644
index 9a1b202..0000000
--- a/textw/zipl_text.py
+++ /dev/null
@@ -1,102 +0,0 @@
-#
-# zipl_text.py: text mode z/IPL setup dialog
-#
-# Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006  Red Hat, Inc.
-# 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 as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# 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, see <http://www.gnu.org/licenses/>.
-#
-
-import string
-from snack import *
-from constants_text import *
-
-from constants import *
-from storage.dasd import getDasdPorts
-
-import gettext
-_ = lambda x: gettext.ldgettext("anaconda", x)
-
-class ZiplWindow:
-    def __call__(self, screen, anaconda):
-        self.bl = anaconda.bootloader
-
-        t = TextboxReflowed(53,
-                         _("The z/IPL Boot Loader will be installed "
-                           "on your system after installation is complete. "
-                           "You can now enter any additional kernel and "
-                           "chandev parameters which your machine or your "
-                           "setup require."))
-
-        kernelparms = ""
-        kernelentry = Entry(48, scroll = 1, returnExit = 1)
-        chandeventry1 = Entry(48, scroll = 1, returnExit = 1)
-        chandeventry2 = Entry(48, scroll = 1, returnExit = 1)
-
-        if self.bl.args and self.bl.args.get():
-            kernelparms = self.bl.args.get()
-        if getDasdPorts() and (kernelparms.find("dasd=") == -1):
-            if len(kernelparms) > 0:
-                kernelparms = "%s dasd=%s" %(kernelparms, getDasdPorts())
-            else:
-                kernelparms = "dasd=%s" %(getDasdPorts(),)
-        kernelentry.set(kernelparms)
-
-        if self.bl.args and self.bl.args.chandevget():
-            cdevs = self.bl.args.chandevget()
-            chandeventry1.set('')
-            chandeventry2.set('')
-            if len(cdevs) > 0:
-                chandeventry1.set(cdevs[0])
-            if len(cdevs) > 1:
-                chandeventry2.set(string.join(cdevs[1:],';'))
-
-        buttons = ButtonBar(screen, [TEXT_OK_BUTTON,
-                            TEXT_BACK_BUTTON ] )
-
-        grid = GridFormHelp(screen, _("z/IPL Configuration"), 
-                            "zipl-s390", 1, 5)
-        grid.add(t, 0, 0)
-        sg = Grid(2, 1)
-        sg.setField(Label(_("Kernel Parameters") + ": "), 0, 0, anchorLeft=1)
-        sg.setField(kernelentry, 1, 0, anchorLeft=1)
-        grid.add(sg, 0, 1, padding = (0, 1, 0, 1))
-        sg = Grid(2, 1)
-        sg.setField(Label(_("Chandev line ") + "1: "), 0, 0, anchorLeft=1)
-        sg.setField(chandeventry1, 1, 0, anchorLeft=1)
-        grid.add(sg, 0, 2, padding = (0, 1, 0, 1))
-        sg = Grid(2, 1)
-        sg.setField(Label(_("Chandev line ") + "2: "), 0, 0, anchorLeft=1)
-        sg.setField(chandeventry2, 1, 0, anchorLeft=1)
-        grid.add(sg, 0, 3, padding = (0, 1, 0, 1))
-        grid.add(buttons, 0, 4, growx = 1)
-
-        result = grid.runOnce ()
-        button = buttons.buttonPressed(result)
-        
-        if button == TEXT_BACK_CHECK:
-            return INSTALL_BACK
-
-        if kernelentry.value():
-            self.bl.args.set(string.strip(kernelentry.value()))
-        else:
-            self.bl.args.set("")
-
-        cdevs = []
-        if chandeventry1.value():
-            cdevs.append(string.strip(chandeventry1.value()))
-        if chandeventry2.value():
-            cdevs.append(string.strip(chandeventry2.value()))
-        self.bl.args.chandevset(cdevs)
-        return INSTALL_OK
diff --git a/timezone.py b/timezone.py
deleted file mode 100644
index 74d66db..0000000
--- a/timezone.py
+++ /dev/null
@@ -1,76 +0,0 @@
-#
-# timezone.py - timezone install data
-#
-# Copyright (C) 2001  Red Hat, Inc.  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 as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# 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, see <http://www.gnu.org/licenses/>.
-#
-
-import shutil
-import iutil
-import os
-from flags import flags
-
-import logging
-log = logging.getLogger("anaconda")
-
-class Timezone:
-    def writeKS(self, f):
-        f.write("timezone")
-        if self.utc:
-            f.write(" --utc")
-        f.write(" %s\n" % self.tz)
-
-    def write(self, instPath):
-        fromFile = instPath + "/usr/share/zoneinfo/" + self.tz
-
-        if not os.access(fromFile, os.R_OK):
-            log.error("Timezone to be copied (%s) doesn't exist" % fromFile)
-        else:
-            try:
-                shutil.copyfile(fromFile, instPath + "/etc/localtime")
-            except OSError as e:
-                log.error("Error copying timezone (from %s): %s" % (fromFile, e.strerror))
-
-        f = open(instPath + "/etc/sysconfig/clock", "w")
-
-        f.write('ZONE="%s"\n' % self.tz)
-        f.close()
-
-        try:
-            f = open(instPath + "/etc/adjtime", "r")
-            lines = f.readlines()
-            f.close()
-        except:
-            lines = [ "0.0 0 0.0\n", "0\n" ]
-
-        f = open(instPath + "/etc/adjtime", "w")
-        f.write(lines[0])
-        f.write(lines[1])
-        if self.utc:
-            f.write("UTC\n")
-        else:
-            f.write("LOCAL\n")
-        f.close()
-
-    def getTimezoneInfo(self):
-        return (self.tz, self.utc)
-
-    def setTimezoneInfo(self, timezone, asUtc = 0):
-        self.tz = timezone
-        self.utc = asUtc
-
-    def __init__(self):
-        self.tz = "America/New_York"
-        self.utc = 0
diff --git a/ui/GroupSelector.glade b/ui/GroupSelector.glade
deleted file mode 100644
index 956b020..0000000
--- a/ui/GroupSelector.glade
+++ /dev/null
@@ -1,394 +0,0 @@
-<?xml version="1.0" standalone="no"?> <!--*- mode: xml -*-->
-<!DOCTYPE glade-interface SYSTEM "http://glade.gnome.org/glade-2.0.dtd";>
-
-<glade-interface>
-
-<widget class="GtkWindow" id="groupSelectionWindow">
-  <property name="visible">True</property>
-  <property name="title" translatable="yes">window1</property>
-  <property name="type">GTK_WINDOW_TOPLEVEL</property>
-  <property name="window_position">GTK_WIN_POS_NONE</property>
-  <property name="modal">False</property>
-  <property name="resizable">True</property>
-  <property name="destroy_with_parent">False</property>
-  <property name="decorated">True</property>
-  <property name="skip_taskbar_hint">False</property>
-  <property name="skip_pager_hint">False</property>
-  <property name="type_hint">GDK_WINDOW_TYPE_HINT_NORMAL</property>
-  <property name="gravity">GDK_GRAVITY_NORTH_WEST</property>
-  <property name="focus_on_map">True</property>
-  <property name="urgency_hint">False</property>
-  <signal name="destroy_event" handler="on_groupSelectionWindow_destroy_event" last_modification_time="Fri, 02 Dec 2005 21:41:59 GMT"/>
-  <signal name="delete_event" handler="on_groupSelectionWindow_delete_event" last_modification_time="Fri, 02 Dec 2005 21:42:23 GMT"/>
-
-  <child>
-    <widget class="GtkVBox" id="groupSelectionBox">
-      <property name="border_width">12</property>
-      <property name="width_request">700</property>
-      <property name="visible">True</property>
-      <property name="homogeneous">False</property>
-      <property name="spacing">6</property>
-
-      <child>
-	<widget class="GtkHBox" id="hbox1">
-	  <property name="border_width">12</property>
-	  <property name="visible">True</property>
-	  <property name="homogeneous">False</property>
-	  <property name="spacing">12</property>
-
-	  <child>
-	    <widget class="GtkScrolledWindow" id="categorySW">
-	      <property name="visible">True</property>
-	      <property name="can_focus">True</property>
-	      <property name="hscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
-	      <property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
-	      <property name="shadow_type">GTK_SHADOW_IN</property>
-	      <property name="window_placement">GTK_CORNER_TOP_LEFT</property>
-
-	      <child>
-		<widget class="GtkTreeView" id="categoryList">
-		  <property name="width_request">275</property>
-		  <property name="visible">True</property>
-		  <property name="can_focus">True</property>
-		  <property name="headers_visible">False</property>
-		  <property name="rules_hint">False</property>
-		  <property name="reorderable">False</property>
-		  <property name="enable_search">True</property>
-		  <property name="fixed_height_mode">False</property>
-		  <property name="hover_selection">False</property>
-		  <property name="hover_expand">False</property>
-		</widget>
-	      </child>
-	    </widget>
-	    <packing>
-	      <property name="padding">0</property>
-	      <property name="expand">True</property>
-	      <property name="fill">True</property>
-	    </packing>
-	  </child>
-
-	  <child>
-	    <widget class="GtkScrolledWindow" id="groupSW">
-	      <property name="visible">True</property>
-	      <property name="can_focus">True</property>
-	      <property name="hscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
-	      <property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
-	      <property name="shadow_type">GTK_SHADOW_IN</property>
-	      <property name="window_placement">GTK_CORNER_TOP_LEFT</property>
-
-	      <child>
-		<widget class="GtkTreeView" id="groupList">
-		  <property name="width_request">325</property>
-		  <property name="visible">True</property>
-		  <property name="can_focus">True</property>
-		  <property name="headers_visible">False</property>
-		  <property name="rules_hint">False</property>
-		  <property name="reorderable">False</property>
-		  <property name="enable_search">True</property>
-		  <property name="fixed_height_mode">False</property>
-		  <property name="hover_selection">False</property>
-		  <property name="hover_expand">False</property>
-		  <signal name="button_press_event" handler="on_groupList_button_press" last_modification_time="Sat, 04 Feb 2006 01:22:04 GMT"/>
-		  <signal name="popup_menu" handler="on_groupList_popup_menu" last_modification_time="Sat, 04 Feb 2006 01:22:13 GMT"/>
-		</widget>
-	      </child>
-	    </widget>
-	    <packing>
-	      <property name="padding">0</property>
-	      <property name="expand">True</property>
-	      <property name="fill">True</property>
-	    </packing>
-	  </child>
-	</widget>
-	<packing>
-	  <property name="padding">0</property>
-	  <property name="expand">True</property>
-	  <property name="fill">True</property>
-	</packing>
-      </child>
-
-      <child>
-	<widget class="GtkAlignment" id="alignment1">
-	  <property name="visible">True</property>
-	  <property name="xalign">0.5</property>
-	  <property name="yalign">0.5</property>
-	  <property name="xscale">0.75</property>
-	  <property name="yscale">1</property>
-	  <property name="top_padding">0</property>
-	  <property name="bottom_padding">0</property>
-	  <property name="left_padding">0</property>
-	  <property name="right_padding">0</property>
-
-	  <child>
-	    <widget class="GtkVBox" id="vbox2">
-	      <property name="border_width">12</property>
-	      <property name="visible">True</property>
-	      <property name="homogeneous">False</property>
-	      <property name="spacing">6</property>
-
-	      <child>
-		<widget class="GtkScrolledWindow" id="scrolledwindow3">
-		  <property name="height_request">82</property>
-		  <property name="visible">True</property>
-		  <property name="can_focus">True</property>
-		  <property name="hscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
-		  <property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
-		  <property name="shadow_type">GTK_SHADOW_IN</property>
-		  <property name="window_placement">GTK_CORNER_TOP_LEFT</property>
-
-		  <child>
-		    <widget class="GtkTextView" id="groupDescriptionTextView">
-		      <property name="visible">True</property>
-		      <property name="can_focus">True</property>
-		      <property name="editable">False</property>
-		      <property name="overwrite">False</property>
-		      <property name="accepts_tab">True</property>
-		      <property name="justification">GTK_JUSTIFY_LEFT</property>
-		      <property name="wrap_mode">GTK_WRAP_WORD</property>
-		      <property name="cursor_visible">False</property>
-		      <property name="pixels_above_lines">0</property>
-		      <property name="pixels_below_lines">0</property>
-		      <property name="pixels_inside_wrap">0</property>
-		      <property name="left_margin">0</property>
-		      <property name="right_margin">0</property>
-		      <property name="indent">0</property>
-		      <property name="text" translatable="yes"></property>
-		    </widget>
-		  </child>
-		</widget>
-		<packing>
-		  <property name="padding">0</property>
-		  <property name="expand">False</property>
-		  <property name="fill">False</property>
-		</packing>
-	      </child>
-
-	      <child>
-		<widget class="GtkLabel" id="optionalLabel">
-		  <property name="visible">True</property>
-		  <property name="label" translatable="yes"></property>
-		  <property name="use_underline">False</property>
-		  <property name="use_markup">False</property>
-		  <property name="justify">GTK_JUSTIFY_RIGHT</property>
-		  <property name="wrap">False</property>
-		  <property name="selectable">False</property>
-		  <property name="xalign">0.949999988079</property>
-		  <property name="yalign">1</property>
-		  <property name="xpad">0</property>
-		  <property name="ypad">0</property>
-		  <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
-		  <property name="width_chars">-1</property>
-		  <property name="single_line_mode">False</property>
-		  <property name="angle">0</property>
-		</widget>
-		<packing>
-		  <property name="padding">0</property>
-		  <property name="expand">False</property>
-		  <property name="fill">False</property>
-		</packing>
-	      </child>
-
-	      <child>
-		<widget class="GtkHButtonBox" id="hbuttonbox2">
-		  <property name="border_width">6</property>
-		  <property name="visible">True</property>
-		  <property name="layout_style">GTK_BUTTONBOX_END</property>
-		  <property name="spacing">0</property>
-
-		  <child>
-		    <widget class="GtkButton" id="detailsButton">
-		      <property name="visible">True</property>
-		      <property name="can_default">True</property>
-		      <property name="can_focus">True</property>
-		      <property name="label" translatable="yes">_Optional packages</property>
-		      <property name="use_underline">True</property>
-		      <property name="relief">GTK_RELIEF_NORMAL</property>
-		      <property name="focus_on_click">True</property>
-		      <signal name="clicked" handler="on_detailsButton_clicked" last_modification_time="Fri, 02 Dec 2005 21:39:06 GMT"/>
-		    </widget>
-		  </child>
-		</widget>
-		<packing>
-		  <property name="padding">0</property>
-		  <property name="expand">True</property>
-		  <property name="fill">True</property>
-		</packing>
-	      </child>
-	    </widget>
-	  </child>
-	</widget>
-	<packing>
-	  <property name="padding">0</property>
-	  <property name="expand">False</property>
-	  <property name="fill">False</property>
-	</packing>
-      </child>
-    </widget>
-  </child>
-</widget>
-
-<widget class="GtkDialog" id="groupDetailsDialog">
-  <property name="width_request">550</property>
-  <property name="height_request">300</property>
-  <property name="title" translatable="yes">dialog1</property>
-  <property name="type">GTK_WINDOW_TOPLEVEL</property>
-  <property name="window_position">GTK_WIN_POS_CENTER_ON_PARENT</property>
-  <property name="modal">True</property>
-  <property name="resizable">True</property>
-  <property name="destroy_with_parent">False</property>
-  <property name="decorated">True</property>
-  <property name="skip_taskbar_hint">False</property>
-  <property name="skip_pager_hint">False</property>
-  <property name="type_hint">GDK_WINDOW_TYPE_HINT_DIALOG</property>
-  <property name="gravity">GDK_GRAVITY_NORTH_WEST</property>
-  <property name="focus_on_map">True</property>
-  <property name="urgency_hint">False</property>
-  <property name="has_separator">True</property>
-  <signal name="destroy" handler="on_groupDetailsDialog_destroy" last_modification_time="Tue, 06 Dec 2005 21:31:56 GMT"/>
-  <signal name="delete_event" handler="on_groupDetailsDialog_delete_event" last_modification_time="Tue, 06 Dec 2005 21:32:34 GMT"/>
-
-  <child internal-child="vbox">
-    <widget class="GtkVBox" id="dialog-vbox1">
-      <property name="visible">True</property>
-      <property name="homogeneous">False</property>
-      <property name="spacing">0</property>
-
-      <child internal-child="action_area">
-	<widget class="GtkHButtonBox" id="dialog-action_area1">
-	  <property name="visible">True</property>
-	  <property name="layout_style">GTK_BUTTONBOX_END</property>
-
-	  <child>
-	    <widget class="GtkButton" id="groupDetailsCloseButton">
-	      <property name="visible">True</property>
-	      <property name="can_default">True</property>
-	      <property name="can_focus">True</property>
-	      <property name="label">gtk-close</property>
-	      <property name="use_stock">True</property>
-	      <property name="relief">GTK_RELIEF_NORMAL</property>
-	      <property name="focus_on_click">True</property>
-	      <property name="response_id">-7</property>
-	      <signal name="clicked" handler="on_groupDetailsCloseButton_clicked" last_modification_time="Tue, 06 Dec 2005 21:31:46 GMT"/>
-	    </widget>
-	  </child>
-	</widget>
-	<packing>
-	  <property name="padding">0</property>
-	  <property name="expand">False</property>
-	  <property name="fill">True</property>
-	  <property name="pack_type">GTK_PACK_END</property>
-	</packing>
-      </child>
-
-      <child>
-	<widget class="GtkVBox" id="vbox4">
-	  <property name="border_width">12</property>
-	  <property name="visible">True</property>
-	  <property name="homogeneous">False</property>
-	  <property name="spacing">6</property>
-
-	  <child>
-	    <widget class="GtkLabel" id="label1">
-	      <property name="visible">True</property>
-	      <property name="label" translatable="yes">Some packages associated with this group are not required to be installed but may provide additional functionality.  Please choose the packages which you would like to have installed.</property>
-	      <property name="use_underline">False</property>
-	      <property name="use_markup">False</property>
-	      <property name="justify">GTK_JUSTIFY_LEFT</property>
-	      <property name="wrap">True</property>
-	      <property name="selectable">False</property>
-	      <property name="xalign">0</property>
-	      <property name="yalign">0.5</property>
-	      <property name="xpad">0</property>
-	      <property name="ypad">0</property>
-	      <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
-	      <property name="width_chars">-1</property>
-	      <property name="single_line_mode">False</property>
-	      <property name="angle">0</property>
-	    </widget>
-	    <packing>
-	      <property name="padding">0</property>
-	      <property name="expand">False</property>
-	      <property name="fill">False</property>
-	    </packing>
-	  </child>
-
-	  <child>
-	    <widget class="GtkScrolledWindow" id="packageSW">
-	      <property name="visible">True</property>
-	      <property name="can_focus">True</property>
-	      <property name="hscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
-	      <property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
-	      <property name="shadow_type">GTK_SHADOW_IN</property>
-	      <property name="window_placement">GTK_CORNER_TOP_LEFT</property>
-
-	      <child>
-		<widget class="GtkTreeView" id="packageList">
-		  <property name="visible">True</property>
-		  <property name="can_focus">True</property>
-		  <property name="headers_visible">False</property>
-		  <property name="rules_hint">False</property>
-		  <property name="reorderable">False</property>
-		  <property name="enable_search">True</property>
-		  <property name="fixed_height_mode">False</property>
-		  <property name="hover_selection">False</property>
-		  <property name="hover_expand">False</property>
-		</widget>
-	      </child>
-	    </widget>
-	    <packing>
-	      <property name="padding">0</property>
-	      <property name="expand">True</property>
-	      <property name="fill">True</property>
-	    </packing>
-	  </child>
-	</widget>
-	<packing>
-	  <property name="padding">0</property>
-	  <property name="expand">True</property>
-	  <property name="fill">True</property>
-	</packing>
-      </child>
-    </widget>
-  </child>
-</widget>
-
-<widget class="GtkMenu" id="groupPopupMenu">
-
-  <child>
-    <widget class="GtkMenuItem" id="selectgrp">
-      <property name="visible">True</property>
-      <property name="label" translatable="yes">_Select</property>
-      <property name="use_underline">True</property>
-      <signal name="activate" handler="on_selectgrp_activate" last_modification_time="Wed, 13 Sep 2006 16:57:47 GMT"/>
-    </widget>
-  </child>
-
-  <child>
-    <widget class="GtkMenuItem" id="select">
-      <property name="visible">True</property>
-      <property name="label" translatable="yes">_Select all optional packages</property>
-      <property name="use_underline">True</property>
-      <signal name="activate" handler="on_select_activate" last_modification_time="Sat, 04 Feb 2006 00:26:28 GMT"/>
-    </widget>
-  </child>
-
-  <child>
-    <widget class="GtkMenuItem" id="deselectgrp">
-      <property name="visible">True</property>
-      <property name="label" translatable="yes">_Deselect</property>
-      <property name="use_underline">True</property>
-      <signal name="activate" handler="on_deselectgrp_activate" last_modification_time="Wed, 13 Sep 2006 16:57:47 GMT"/>
-    </widget>
-  </child>
-
-  <child>
-    <widget class="GtkMenuItem" id="deselect">
-      <property name="visible">True</property>
-      <property name="label" translatable="yes">_Deselect all optional packages</property>
-      <property name="use_underline">True</property>
-      <signal name="activate" handler="on_deselect_activate" last_modification_time="Sat, 04 Feb 2006 00:26:28 GMT"/>
-    </widget>
-  </child>
-</widget>
-
-</glade-interface>
diff --git a/ui/Makefile.am b/ui/Makefile.am
deleted file mode 100644
index 39e1c56..0000000
--- a/ui/Makefile.am
+++ /dev/null
@@ -1,25 +0,0 @@
-# ui/Makefile.am for anaconda
-#
-# Copyright (C) 2009  Red Hat, Inc.
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU Lesser General Public License as published
-# by the Free Software Foundation; either version 2.1 of the License, or
-# (at your option) any later version.
-#
-# 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 Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public License
-# along with this program.  If not, see <http://www.gnu.org/licenses/>.
-#
-# Author: David Cantrell <dcantrell@xxxxxxxxxx>
-
-uidir = $(datadir)/$(PACKAGE_NAME)/ui
-dist_ui_DATA = *.glade
-
-MAINTAINERCLEANFILES = Makefile.in
-
-CLEANFILES = *.h
diff --git a/ui/account.glade b/ui/account.glade
deleted file mode 100644
index ca7c6be..0000000
--- a/ui/account.glade
+++ /dev/null
@@ -1,278 +0,0 @@
-<?xml version="1.0" standalone="no"?> <!--*- mode: xml -*-->
-<!DOCTYPE glade-interface SYSTEM "http://glade.gnome.org/glade-2.0.dtd";>
-
-<glade-interface>
-
-<widget class="GtkWindow" id="account_window">
-  <property name="border_width">18</property>
-  <property name="title" translatable="yes" context="yes"></property>
-  <property name="type">GTK_WINDOW_TOPLEVEL</property>
-  <property name="window_position">GTK_WIN_POS_NONE</property>
-  <property name="modal">False</property>
-  <property name="resizable">True</property>
-  <property name="destroy_with_parent">False</property>
-  <property name="decorated">True</property>
-  <property name="skip_taskbar_hint">False</property>
-  <property name="skip_pager_hint">False</property>
-  <property name="type_hint">GDK_WINDOW_TYPE_HINT_NORMAL</property>
-  <property name="gravity">GDK_GRAVITY_NORTH_WEST</property>
-  <property name="focus_on_map">True</property>
-  <property name="urgency_hint">False</property>
-
-  <child>
-    <widget class="GtkAlignment" id="account_align">
-      <property name="width_request">400</property>
-      <property name="visible">True</property>
-      <property name="xalign">0</property>
-      <property name="yalign">0</property>
-      <property name="xscale">1</property>
-      <property name="yscale">1</property>
-      <property name="top_padding">0</property>
-      <property name="bottom_padding">0</property>
-      <property name="left_padding">0</property>
-      <property name="right_padding">0</property>
-
-      <child>
-	<widget class="GtkVBox" id="account_box">
-	  <property name="border_width">5</property>
-	  <property name="visible">True</property>
-	  <property name="homogeneous">False</property>
-	  <property name="spacing">10</property>
-
-	  <child>
-	    <widget class="GtkAlignment" id="alignment2">
-	      <property name="visible">True</property>
-	      <property name="xalign">0</property>
-	      <property name="yalign">0</property>
-	      <property name="xscale">1</property>
-	      <property name="yscale">1</property>
-	      <property name="top_padding">0</property>
-	      <property name="bottom_padding">0</property>
-	      <property name="left_padding">0</property>
-	      <property name="right_padding">0</property>
-
-	      <child>
-		<widget class="GtkHBox" id="desc_box">
-		  <property name="visible">True</property>
-		  <property name="homogeneous">False</property>
-		  <property name="spacing">0</property>
-
-		  <child>
-		    <widget class="GtkImage" id="icon">
-		      <property name="visible">True</property>
-		      <property name="xalign">0.5</property>
-		      <property name="yalign">0.5</property>
-		      <property name="xpad">0</property>
-		      <property name="ypad">0</property>
-		    </widget>
-		    <packing>
-		      <property name="padding">0</property>
-		      <property name="expand">False</property>
-		      <property name="fill">False</property>
-		    </packing>
-		  </child>
-
-		  <child>
-		    <widget class="GtkLabel" id="desc">
-		      <property name="visible">True</property>
-		      <property name="label" translatable="yes">The root account is used for administering the system.  Enter a password for the root user.</property>
-		      <property name="use_underline">False</property>
-		      <property name="use_markup">False</property>
-		      <property name="justify">GTK_JUSTIFY_LEFT</property>
-		      <property name="wrap">True</property>
-		      <property name="selectable">False</property>
-		      <property name="xalign">0</property>
-		      <property name="yalign">0.5</property>
-		      <property name="xpad">0</property>
-		      <property name="ypad">0</property>
-		      <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
-		      <property name="width_chars">-1</property>
-		      <property name="single_line_mode">False</property>
-		      <property name="angle">0</property>
-		    </widget>
-		    <packing>
-		      <property name="padding">0</property>
-		      <property name="expand">False</property>
-		      <property name="fill">False</property>
-		    </packing>
-		  </child>
-		</widget>
-	      </child>
-	    </widget>
-	    <packing>
-	      <property name="padding">0</property>
-	      <property name="expand">False</property>
-	      <property name="fill">False</property>
-	    </packing>
-	  </child>
-
-	  <child>
-	    <widget class="GtkAlignment" id="alignment4">
-	      <property name="visible">True</property>
-	      <property name="xalign">0.5</property>
-	      <property name="yalign">0.5</property>
-	      <property name="xscale">1</property>
-	      <property name="yscale">1</property>
-	      <property name="top_padding">0</property>
-	      <property name="bottom_padding">0</property>
-	      <property name="left_padding">0</property>
-	      <property name="right_padding">0</property>
-
-	      <child>
-		<widget class="GtkTable" id="table1">
-		  <property name="width_request">365</property>
-		  <property name="visible">True</property>
-		  <property name="n_rows">3</property>
-		  <property name="n_columns">2</property>
-		  <property name="homogeneous">False</property>
-		  <property name="row_spacing">5</property>
-		  <property name="column_spacing">5</property>
-
-		  <child>
-		    <widget class="GtkLabel" id="pwlabel">
-		      <property name="visible">True</property>
-		      <property name="label" translatable="yes">Root Password:</property>
-		      <property name="use_underline">False</property>
-		      <property name="use_markup">True</property>
-		      <property name="justify">GTK_JUSTIFY_LEFT</property>
-		      <property name="wrap">False</property>
-		      <property name="selectable">False</property>
-		      <property name="xalign">0</property>
-		      <property name="yalign">0.5</property>
-		      <property name="xpad">0</property>
-		      <property name="ypad">0</property>
-		      <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
-		      <property name="width_chars">-1</property>
-		      <property name="single_line_mode">False</property>
-		      <property name="angle">0</property>
-		    </widget>
-		    <packing>
-		      <property name="left_attach">0</property>
-		      <property name="right_attach">1</property>
-		      <property name="top_attach">0</property>
-		      <property name="bottom_attach">1</property>
-		      <property name="x_options">fill</property>
-		      <property name="y_options"></property>
-		    </packing>
-		  </child>
-
-		  <child>
-		    <widget class="GtkLabel" id="confirmlabel">
-		      <property name="visible">True</property>
-		      <property name="label" translatable="yes">Confirm:</property>
-		      <property name="use_underline">False</property>
-		      <property name="use_markup">True</property>
-		      <property name="justify">GTK_JUSTIFY_LEFT</property>
-		      <property name="wrap">False</property>
-		      <property name="selectable">False</property>
-		      <property name="xalign">0</property>
-		      <property name="yalign">0.5</property>
-		      <property name="xpad">0</property>
-		      <property name="ypad">0</property>
-		      <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
-		      <property name="width_chars">-1</property>
-		      <property name="single_line_mode">False</property>
-		      <property name="angle">0</property>
-		    </widget>
-		    <packing>
-		      <property name="left_attach">0</property>
-		      <property name="right_attach">1</property>
-		      <property name="top_attach">1</property>
-		      <property name="bottom_attach">2</property>
-		      <property name="x_options">fill</property>
-		      <property name="y_options"></property>
-		    </packing>
-		  </child>
-
-		  <child>
-		    <widget class="GtkLabel" id="capslock">
-		      <property name="visible">True</property>
-		      <property name="label" translatable="yes"></property>
-		      <property name="use_underline">False</property>
-		      <property name="use_markup">True</property>
-		      <property name="justify">GTK_JUSTIFY_LEFT</property>
-		      <property name="wrap">False</property>
-		      <property name="selectable">False</property>
-		      <property name="xalign">0</property>
-		      <property name="yalign">0.5</property>
-		      <property name="xpad">0</property>
-		      <property name="ypad">0</property>
-		      <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
-		      <property name="width_chars">-1</property>
-		      <property name="single_line_mode">False</property>
-		      <property name="angle">0</property>
-		    </widget>
-		    <packing>
-		      <property name="left_attach">1</property>
-		      <property name="right_attach">2</property>
-		      <property name="top_attach">2</property>
-		      <property name="bottom_attach">3</property>
-		      <property name="x_options">fill</property>
-		      <property name="y_options"></property>
-		    </packing>
-		  </child>
-
-		  <child>
-		    <widget class="GtkEntry" id="pw">
-		      <property name="width_request">256</property>
-		      <property name="visible">True</property>
-		      <property name="can_focus">True</property>
-		      <property name="has_focus">True</property>
-		      <property name="editable">True</property>
-		      <property name="visibility">False</property>
-		      <property name="max_length">0</property>
-		      <property name="text" translatable="yes"></property>
-		      <property name="has_frame">True</property>
-		      <property name="invisible_char">â?¢</property>
-		      <property name="activates_default">False</property>
-		    </widget>
-		    <packing>
-		      <property name="left_attach">1</property>
-		      <property name="right_attach">2</property>
-		      <property name="top_attach">0</property>
-		      <property name="bottom_attach">1</property>
-		      <property name="x_options">fill</property>
-		      <property name="y_options"></property>
-		    </packing>
-		  </child>
-
-		  <child>
-		    <widget class="GtkEntry" id="confirm">
-		      <property name="width_request">256</property>
-		      <property name="visible">True</property>
-		      <property name="can_default">True</property>
-		      <property name="has_default">True</property>
-		      <property name="can_focus">True</property>
-		      <property name="editable">True</property>
-		      <property name="visibility">False</property>
-		      <property name="max_length">0</property>
-		      <property name="text" translatable="yes"></property>
-		      <property name="has_frame">True</property>
-		      <property name="invisible_char">â?¢</property>
-		      <property name="activates_default">True</property>
-		    </widget>
-		    <packing>
-		      <property name="left_attach">1</property>
-		      <property name="right_attach">2</property>
-		      <property name="top_attach">1</property>
-		      <property name="bottom_attach">2</property>
-		      <property name="x_options">fill</property>
-		      <property name="y_options"></property>
-		    </packing>
-		  </child>
-		</widget>
-	      </child>
-	    </widget>
-	    <packing>
-	      <property name="padding">0</property>
-	      <property name="expand">False</property>
-	      <property name="fill">False</property>
-	    </packing>
-	  </child>
-	</widget>
-      </child>
-    </widget>
-  </child>
-</widget>
-
-</glade-interface>
diff --git a/ui/adddrive.glade b/ui/adddrive.glade
deleted file mode 100644
index 289c71b..0000000
--- a/ui/adddrive.glade
+++ /dev/null
@@ -1,196 +0,0 @@
-<?xml version="1.0" standalone="no"?> <!--*- mode: xml -*-->
-<!DOCTYPE glade-interface SYSTEM "http://glade.gnome.org/glade-2.0.dtd";>
-
-<glade-interface>
-
-<widget class="GtkDialog" id="addDriveDialog">
-  <property name="visible">True</property>
-  <property name="title" translatable="yes" context="yes">Advanced Storage Options</property>
-  <property name="type">GTK_WINDOW_TOPLEVEL</property>
-  <property name="window_position">GTK_WIN_POS_CENTER</property>
-  <property name="modal">False</property>
-  <property name="resizable">True</property>
-  <property name="destroy_with_parent">False</property>
-  <property name="decorated">True</property>
-  <property name="skip_taskbar_hint">False</property>
-  <property name="skip_pager_hint">False</property>
-  <property name="type_hint">GDK_WINDOW_TYPE_HINT_DIALOG</property>
-  <property name="gravity">GDK_GRAVITY_NORTH_WEST</property>
-  <property name="focus_on_map">True</property>
-  <property name="urgency_hint">False</property>
-  <property name="has_separator">True</property>
-
-  <child internal-child="vbox">
-    <widget class="GtkVBox" id="dialog1-vbox">
-      <property name="visible">True</property>
-      <property name="homogeneous">False</property>
-      <property name="spacing">0</property>
-
-      <child internal-child="action_area">
-	<widget class="GtkHButtonBox" id="dialog1-action_area">
-	  <property name="visible">True</property>
-	  <property name="layout_style">GTK_BUTTONBOX_END</property>
-
-	  <child>
-	    <widget class="GtkButton" id="cancelButton">
-	      <property name="visible">True</property>
-	      <property name="label">gtk-cancel</property>
-	      <property name="use_stock">True</property>
-	      <property name="relief">GTK_RELIEF_NORMAL</property>
-	      <property name="focus_on_click">True</property>
-	      <property name="response_id">-6</property>
-	      <signal name="clicked" handler="on_cancelButton_clicked"/>
-	    </widget>
-	  </child>
-
-	  <child>
-	    <widget class="GtkButton" id="okButton">
-	      <property name="visible">True</property>
-	      <property name="relief">GTK_RELIEF_NORMAL</property>
-	      <property name="focus_on_click">True</property>
-	      <property name="response_id">-5</property>
-	      <signal name="clicked" handler="on_okButton_clicked"/>
-
-	      <child>
-		<widget class="GtkLabel" id="label2">
-		  <property name="visible">True</property>
-		  <property name="label" translatable="yes">_Add drive</property>
-		  <property name="use_underline">True</property>
-		  <property name="use_markup">False</property>
-		  <property name="justify">GTK_JUSTIFY_LEFT</property>
-		  <property name="wrap">False</property>
-		  <property name="selectable">False</property>
-		  <property name="xalign">0.5</property>
-		  <property name="yalign">0.5</property>
-		  <property name="xpad">0</property>
-		  <property name="ypad">0</property>
-		  <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
-		  <property name="width_chars">-1</property>
-		  <property name="single_line_mode">False</property>
-		  <property name="angle">0</property>
-		</widget>
-	      </child>
-	    </widget>
-	  </child>
-	</widget>
-	<packing>
-	  <property name="padding">0</property>
-	  <property name="expand">False</property>
-	  <property name="fill">True</property>
-	  <property name="pack_type">GTK_PACK_END</property>
-	</packing>
-      </child>
-
-      <child>
-	<widget class="GtkVBox" id="vbox1">
-	  <property name="border_width">18</property>
-	  <property name="visible">True</property>
-	  <property name="homogeneous">False</property>
-	  <property name="spacing">12</property>
-
-	  <child>
-	    <widget class="GtkLabel" id="label1">
-	      <property name="visible">True</property>
-	      <property name="label" translatable="yes" context="yes">How would you like to modify your drive configuration?</property>
-	      <property name="use_underline">False</property>
-	      <property name="use_markup">False</property>
-	      <property name="justify">GTK_JUSTIFY_LEFT</property>
-	      <property name="wrap">True</property>
-	      <property name="selectable">False</property>
-	      <property name="xalign">0.5</property>
-	      <property name="yalign">0.5</property>
-	      <property name="xpad">0</property>
-	      <property name="ypad">0</property>
-	      <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
-	      <property name="width_chars">-1</property>
-	      <property name="single_line_mode">False</property>
-	      <property name="angle">0</property>
-	    </widget>
-	    <packing>
-	      <property name="padding">0</property>
-	      <property name="expand">False</property>
-	      <property name="fill">False</property>
-	    </packing>
-	  </child>
-
-	  <child>
-	    <widget class="GtkVBox" id="vbox2">
-	      <property name="visible">True</property>
-	      <property name="homogeneous">False</property>
-	      <property name="spacing">6</property>
-
-	      <child>
-		<widget class="GtkRadioButton" id="iscsiRadio">
-		  <property name="visible">True</property>
-		  <property name="label" translatable="yes" context="yes">Add _iSCSI target</property>
-		  <property name="use_underline">True</property>
-		  <property name="relief">GTK_RELIEF_NORMAL</property>
-		  <property name="focus_on_click">True</property>
-		  <property name="active">False</property>
-		  <property name="inconsistent">False</property>
-		  <property name="draw_indicator">True</property>
-		  <signal name="group-changed" handler="on_radio_changed"/>
-		</widget>
-		<packing>
-		  <property name="padding">0</property>
-		  <property name="expand">True</property>
-		  <property name="fill">True</property>
-		</packing>
-	      </child>
-
-	      <child>
-		<widget class="GtkRadioButton" id="zfcpRadio">
-		  <property name="visible">True</property>
-		  <property name="label" translatable="yes" context="yes">Add _ZFCP LUN</property>
-		  <property name="use_underline">True</property>
-		  <property name="relief">GTK_RELIEF_NORMAL</property>
-		  <property name="focus_on_click">True</property>
-		  <property name="active">False</property>
-		  <property name="inconsistent">False</property>
-		  <property name="draw_indicator">True</property>
-		  <property name="group">iscsiRadio</property>
-		</widget>
-		<packing>
-		  <property name="padding">0</property>
-		  <property name="expand">True</property>
-		  <property name="fill">True</property>
-		</packing>
-	      </child>
-
-	      <child>
-		<widget class="GtkRadioButton" id="fcoeRadio">
-		  <property name="visible">True</property>
-		  <property name="label" translatable="yes" context="yes">Add _FCoE SAN</property>
-		  <property name="use_underline">True</property>
-		  <property name="relief">GTK_RELIEF_NORMAL</property>
-		  <property name="focus_on_click">True</property>
-		  <property name="active">False</property>
-		  <property name="inconsistent">False</property>
-		  <property name="draw_indicator">True</property>
-		  <property name="group">iscsiRadio</property>
-		</widget>
-		<packing>
-		  <property name="padding">0</property>
-		  <property name="expand">True</property>
-		  <property name="fill">True</property>
-		</packing>
-	      </child>
-	    </widget>
-	    <packing>
-	      <property name="padding">0</property>
-	      <property name="expand">True</property>
-	      <property name="fill">True</property>
-	    </packing>
-	  </child>
-	</widget>
-	<packing>
-	  <property name="padding">0</property>
-	  <property name="expand">True</property>
-	  <property name="fill">False</property>
-	</packing>
-      </child>
-    </widget>
-  </child>
-</widget>
-
-</glade-interface>
diff --git a/ui/addrepo.glade b/ui/addrepo.glade
deleted file mode 100644
index 7a6637e..0000000
--- a/ui/addrepo.glade
+++ /dev/null
@@ -1,1016 +0,0 @@
-<?xml version="1.0" standalone="no"?> <!--*- mode: xml -*-->
-<!DOCTYPE glade-interface SYSTEM "http://glade.gnome.org/glade-2.0.dtd";>
-
-<glade-interface>
-
-<widget class="GtkDialog" id="addRepoDialog">
-  <property name="width_request">440</property>
-  <property name="height_request">400</property>
-  <property name="visible">True</property>
-  <property name="title" translatable="yes">Add Repository</property>
-  <property name="type">GTK_WINDOW_TOPLEVEL</property>
-  <property name="window_position">GTK_WIN_POS_CENTER</property>
-  <property name="modal">False</property>
-  <property name="resizable">True</property>
-  <property name="destroy_with_parent">False</property>
-  <property name="decorated">True</property>
-  <property name="skip_taskbar_hint">False</property>
-  <property name="skip_pager_hint">False</property>
-  <property name="type_hint">GDK_WINDOW_TYPE_HINT_DIALOG</property>
-  <property name="gravity">GDK_GRAVITY_NORTH_WEST</property>
-  <property name="focus_on_map">True</property>
-  <property name="urgency_hint">False</property>
-  <property name="has_separator">True</property>
-  <signal name="destroy" handler="on_addRepoDialog_destroy" last_modification_time="Thu, 24 Apr 2008 14:22:26 GMT"/>
-
-  <child internal-child="vbox">
-    <widget class="GtkVBox" id="dialog-vbox1">
-      <property name="visible">True</property>
-      <property name="homogeneous">False</property>
-      <property name="spacing">0</property>
-
-      <child internal-child="action_area">
-	<widget class="GtkHButtonBox" id="dialog-action_area1">
-	  <property name="visible">True</property>
-	  <property name="layout_style">GTK_BUTTONBOX_END</property>
-
-	  <child>
-	    <widget class="GtkButton" id="cancelButton">
-	      <property name="visible">True</property>
-	      <property name="can_default">True</property>
-	      <property name="can_focus">True</property>
-	      <property name="label">gtk-cancel</property>
-	      <property name="use_stock">True</property>
-	      <property name="relief">GTK_RELIEF_NORMAL</property>
-	      <property name="focus_on_click">True</property>
-	      <property name="response_id">-6</property>
-	      <signal name="clicked" handler="on_cancelButton_clicked" last_modification_time="Thu, 24 Apr 2008 14:25:58 GMT"/>
-	    </widget>
-	  </child>
-
-	  <child>
-	    <widget class="GtkButton" id="okButton">
-	      <property name="visible">True</property>
-	      <property name="can_default">True</property>
-	      <property name="can_focus">True</property>
-	      <property name="label">gtk-ok</property>
-	      <property name="use_stock">True</property>
-	      <property name="relief">GTK_RELIEF_NORMAL</property>
-	      <property name="focus_on_click">True</property>
-	      <property name="response_id">-5</property>
-	      <signal name="clicked" handler="on_okButton_clicked" last_modification_time="Thu, 24 Apr 2008 14:25:51 GMT"/>
-	    </widget>
-	  </child>
-	</widget>
-	<packing>
-	  <property name="padding">0</property>
-	  <property name="expand">False</property>
-	  <property name="fill">True</property>
-	  <property name="pack_type">GTK_PACK_END</property>
-	</packing>
-      </child>
-
-      <child>
-	<widget class="GtkVBox" id="vbox1">
-	  <property name="visible">True</property>
-	  <property name="homogeneous">False</property>
-	  <property name="spacing">5</property>
-
-	  <child>
-	    <widget class="GtkLabel" id="descLabel">
-	      <property name="visible">True</property>
-	      <property name="label" translatable="yes">Please provide the configuration information for this software repository.</property>
-	      <property name="use_underline">False</property>
-	      <property name="use_markup">False</property>
-	      <property name="justify">GTK_JUSTIFY_LEFT</property>
-	      <property name="wrap">True</property>
-	      <property name="selectable">False</property>
-	      <property name="xalign">0.5</property>
-	      <property name="yalign">0.5</property>
-	      <property name="xpad">0</property>
-	      <property name="ypad">5</property>
-	      <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
-	      <property name="width_chars">-1</property>
-	      <property name="single_line_mode">False</property>
-	      <property name="angle">0</property>
-	    </widget>
-	    <packing>
-	      <property name="padding">0</property>
-	      <property name="expand">False</property>
-	      <property name="fill">False</property>
-	    </packing>
-	  </child>
-
-	  <child>
-	    <widget class="GtkTable" id="table5">
-	      <property name="visible">True</property>
-	      <property name="n_rows">2</property>
-	      <property name="n_columns">2</property>
-	      <property name="homogeneous">False</property>
-	      <property name="row_spacing">5</property>
-	      <property name="column_spacing">5</property>
-
-	      <child>
-		<widget class="GtkLabel" id="nameLabel">
-		  <property name="visible">True</property>
-		  <property name="label" translatable="yes">&lt;b&gt;Repository _name:&lt;/b&gt;</property>
-		  <property name="use_underline">True</property>
-		  <property name="use_markup">True</property>
-		  <property name="justify">GTK_JUSTIFY_LEFT</property>
-		  <property name="wrap">False</property>
-		  <property name="selectable">False</property>
-		  <property name="xalign">0.5</property>
-		  <property name="yalign">0.5</property>
-		  <property name="xpad">0</property>
-		  <property name="ypad">0</property>
-		  <property name="mnemonic_widget">nameEntry</property>
-		  <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
-		  <property name="width_chars">-1</property>
-		  <property name="single_line_mode">False</property>
-		  <property name="angle">0</property>
-		</widget>
-		<packing>
-		  <property name="left_attach">0</property>
-		  <property name="right_attach">1</property>
-		  <property name="top_attach">0</property>
-		  <property name="bottom_attach">1</property>
-		  <property name="x_options">fill</property>
-		  <property name="y_options"></property>
-		</packing>
-	      </child>
-
-	      <child>
-		<widget class="GtkEntry" id="nameEntry">
-		  <property name="visible">True</property>
-		  <property name="can_focus">True</property>
-		  <property name="editable">True</property>
-		  <property name="visibility">True</property>
-		  <property name="max_length">0</property>
-		  <property name="text" translatable="yes"></property>
-		  <property name="has_frame">True</property>
-		  <property name="invisible_char">â?¢</property>
-		  <property name="activates_default">False</property>
-		</widget>
-		<packing>
-		  <property name="left_attach">1</property>
-		  <property name="right_attach">2</property>
-		  <property name="top_attach">0</property>
-		  <property name="bottom_attach">1</property>
-		  <property name="y_options"></property>
-		</packing>
-	      </child>
-
-	      <child>
-		<widget class="GtkLabel" id="typeLabel">
-		  <property name="visible">True</property>
-		  <property name="label" translatable="yes">&lt;b&gt;Repository _type:&lt;/b&gt;</property>
-		  <property name="use_underline">True</property>
-		  <property name="use_markup">True</property>
-		  <property name="justify">GTK_JUSTIFY_LEFT</property>
-		  <property name="wrap">False</property>
-		  <property name="selectable">False</property>
-		  <property name="xalign">0.5</property>
-		  <property name="yalign">0.5</property>
-		  <property name="xpad">0</property>
-		  <property name="ypad">0</property>
-		  <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
-		  <property name="width_chars">-1</property>
-		  <property name="single_line_mode">False</property>
-		  <property name="angle">0</property>
-		</widget>
-		<packing>
-		  <property name="left_attach">0</property>
-		  <property name="right_attach">1</property>
-		  <property name="top_attach">1</property>
-		  <property name="bottom_attach">2</property>
-		  <property name="x_options">fill</property>
-		  <property name="y_options"></property>
-		</packing>
-	      </child>
-
-	      <child>
-		<widget class="GtkComboBox" id="typeComboBox">
-		  <property name="visible">True</property>
-		  <property name="items" translatable="yes">HTTP/FTP
-CD/DVD
-NFS
-Hard Drive</property>
-		  <property name="add_tearoffs">False</property>
-		  <property name="focus_on_click">True</property>
-		  <signal name="changed" handler="on_typeComboBox_changed" last_modification_time="Thu, 24 Apr 2008 13:48:24 GMT"/>
-		</widget>
-		<packing>
-		  <property name="left_attach">1</property>
-		  <property name="right_attach">2</property>
-		  <property name="top_attach">1</property>
-		  <property name="bottom_attach">2</property>
-		  <property name="x_options">fill</property>
-		  <property name="y_options">fill</property>
-		</packing>
-	      </child>
-	    </widget>
-	    <packing>
-	      <property name="padding">0</property>
-	      <property name="expand">False</property>
-	      <property name="fill">True</property>
-	    </packing>
-	  </child>
-
-	  <child>
-	    <widget class="GtkNotebook" id="typeNotebook">
-	      <property name="visible">True</property>
-	      <property name="show_tabs">False</property>
-	      <property name="show_border">False</property>
-	      <property name="tab_pos">GTK_POS_TOP</property>
-	      <property name="scrollable">False</property>
-	      <property name="enable_popup">False</property>
-
-	      <child>
-		<widget class="GtkVBox" id="urlVBox">
-		  <property name="visible">True</property>
-		  <property name="homogeneous">False</property>
-		  <property name="spacing">5</property>
-
-		  <child>
-		    <widget class="GtkHBox" id="hbox3">
-		      <property name="visible">True</property>
-		      <property name="homogeneous">False</property>
-		      <property name="spacing">5</property>
-
-		      <child>
-			<widget class="GtkLabel" id="label20">
-			  <property name="visible">True</property>
-			  <property name="label" translatable="yes">Repository _URL</property>
-			  <property name="use_underline">True</property>
-			  <property name="use_markup">False</property>
-			  <property name="justify">GTK_JUSTIFY_LEFT</property>
-			  <property name="wrap">False</property>
-			  <property name="selectable">False</property>
-			  <property name="xalign">0.5</property>
-			  <property name="yalign">0.5</property>
-			  <property name="xpad">0</property>
-			  <property name="ypad">0</property>
-			  <property name="mnemonic_widget">baseurlEntry</property>
-			  <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
-			  <property name="width_chars">-1</property>
-			  <property name="single_line_mode">False</property>
-			  <property name="angle">0</property>
-			</widget>
-			<packing>
-			  <property name="padding">0</property>
-			  <property name="expand">False</property>
-			  <property name="fill">False</property>
-			</packing>
-		      </child>
-
-		      <child>
-			<widget class="GtkEntry" id="baseurlEntry">
-			  <property name="visible">True</property>
-			  <property name="can_focus">True</property>
-			  <property name="editable">True</property>
-			  <property name="visibility">True</property>
-			  <property name="max_length">0</property>
-			  <property name="text" translatable="yes"></property>
-			  <property name="has_frame">True</property>
-			  <property name="invisible_char">â?¢</property>
-			  <property name="activates_default">False</property>
-			</widget>
-			<packing>
-			  <property name="padding">0</property>
-			  <property name="expand">True</property>
-			  <property name="fill">True</property>
-			</packing>
-		      </child>
-		    </widget>
-		    <packing>
-		      <property name="padding">0</property>
-		      <property name="expand">True</property>
-		      <property name="fill">True</property>
-		    </packing>
-		  </child>
-
-		  <child>
-		    <widget class="GtkCheckButton" id="mirrorlistCheckbox">
-		      <property name="visible">True</property>
-		      <property name="can_focus">True</property>
-		      <property name="label" translatable="yes">URL is a _mirror list</property>
-		      <property name="use_underline">True</property>
-		      <property name="relief">GTK_RELIEF_NORMAL</property>
-		      <property name="focus_on_click">True</property>
-		      <property name="active">False</property>
-		      <property name="inconsistent">False</property>
-		      <property name="draw_indicator">True</property>
-		      <signal name="toggled" handler="on_mirrorlistCheckbox_toggled" last_modification_time="Thu, 24 Apr 2008 15:23:14 GMT"/>
-		    </widget>
-		    <packing>
-		      <property name="padding">0</property>
-		      <property name="expand">False</property>
-		      <property name="fill">False</property>
-		    </packing>
-		  </child>
-
-		  <child>
-		    <widget class="GtkCheckButton" id="proxyCheckbox">
-		      <property name="visible">True</property>
-		      <property name="can_focus">True</property>
-		      <property name="label" translatable="yes">Configure _proxy</property>
-		      <property name="use_underline">True</property>
-		      <property name="relief">GTK_RELIEF_NORMAL</property>
-		      <property name="focus_on_click">True</property>
-		      <property name="active">False</property>
-		      <property name="inconsistent">False</property>
-		      <property name="draw_indicator">True</property>
-		      <signal name="toggled" handler="on_proxyCheckbox_toggled" last_modification_time="Thu, 24 Apr 2008 13:49:32 GMT"/>
-		    </widget>
-		    <packing>
-		      <property name="padding">0</property>
-		      <property name="expand">False</property>
-		      <property name="fill">False</property>
-		    </packing>
-		  </child>
-
-		  <child>
-		    <widget class="GtkTable" id="proxyTable">
-		      <property name="visible">True</property>
-		      <property name="n_rows">3</property>
-		      <property name="n_columns">2</property>
-		      <property name="homogeneous">False</property>
-		      <property name="row_spacing">10</property>
-		      <property name="column_spacing">5</property>
-
-		      <child>
-			<widget class="GtkLabel" id="label11">
-			  <property name="visible">True</property>
-			  <property name="label" translatable="yes">Proxy U_RL (host:port)</property>
-			  <property name="use_underline">True</property>
-			  <property name="use_markup">False</property>
-			  <property name="justify">GTK_JUSTIFY_LEFT</property>
-			  <property name="wrap">False</property>
-			  <property name="selectable">False</property>
-			  <property name="xalign">0</property>
-			  <property name="yalign">0.5</property>
-			  <property name="xpad">10</property>
-			  <property name="ypad">0</property>
-			  <property name="mnemonic_widget">proxyEntry</property>
-			  <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
-			  <property name="width_chars">-1</property>
-			  <property name="single_line_mode">False</property>
-			  <property name="angle">0</property>
-			</widget>
-			<packing>
-			  <property name="left_attach">0</property>
-			  <property name="right_attach">1</property>
-			  <property name="top_attach">0</property>
-			  <property name="bottom_attach">1</property>
-			  <property name="x_options">fill</property>
-			  <property name="y_options"></property>
-			</packing>
-		      </child>
-
-		      <child>
-			<widget class="GtkLabel" id="label12">
-			  <property name="visible">True</property>
-			  <property name="label" translatable="yes">Proxy u_sername</property>
-			  <property name="use_underline">True</property>
-			  <property name="use_markup">False</property>
-			  <property name="justify">GTK_JUSTIFY_LEFT</property>
-			  <property name="wrap">False</property>
-			  <property name="selectable">False</property>
-			  <property name="xalign">0</property>
-			  <property name="yalign">0.5</property>
-			  <property name="xpad">10</property>
-			  <property name="ypad">0</property>
-			  <property name="mnemonic_widget">usernameEntry</property>
-			  <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
-			  <property name="width_chars">-1</property>
-			  <property name="single_line_mode">False</property>
-			  <property name="angle">0</property>
-			</widget>
-			<packing>
-			  <property name="left_attach">0</property>
-			  <property name="right_attach">1</property>
-			  <property name="top_attach">1</property>
-			  <property name="bottom_attach">2</property>
-			  <property name="x_options">fill</property>
-			  <property name="y_options"></property>
-			</packing>
-		      </child>
-
-		      <child>
-			<widget class="GtkLabel" id="label13">
-			  <property name="visible">True</property>
-			  <property name="label" translatable="yes">Proxy pass_word</property>
-			  <property name="use_underline">True</property>
-			  <property name="use_markup">False</property>
-			  <property name="justify">GTK_JUSTIFY_LEFT</property>
-			  <property name="wrap">False</property>
-			  <property name="selectable">False</property>
-			  <property name="xalign">0</property>
-			  <property name="yalign">0.5</property>
-			  <property name="xpad">10</property>
-			  <property name="ypad">0</property>
-			  <property name="mnemonic_widget">passwordEntry</property>
-			  <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
-			  <property name="width_chars">-1</property>
-			  <property name="single_line_mode">False</property>
-			  <property name="angle">0</property>
-			</widget>
-			<packing>
-			  <property name="left_attach">0</property>
-			  <property name="right_attach">1</property>
-			  <property name="top_attach">2</property>
-			  <property name="bottom_attach">3</property>
-			  <property name="x_options">fill</property>
-			  <property name="y_options"></property>
-			</packing>
-		      </child>
-
-		      <child>
-			<widget class="GtkEntry" id="proxyEntry">
-			  <property name="visible">True</property>
-			  <property name="can_focus">True</property>
-			  <property name="editable">True</property>
-			  <property name="visibility">True</property>
-			  <property name="max_length">0</property>
-			  <property name="text" translatable="yes"></property>
-			  <property name="has_frame">True</property>
-			  <property name="invisible_char">â?¢</property>
-			  <property name="activates_default">False</property>
-			</widget>
-			<packing>
-			  <property name="left_attach">1</property>
-			  <property name="right_attach">2</property>
-			  <property name="top_attach">0</property>
-			  <property name="bottom_attach">1</property>
-			  <property name="y_options"></property>
-			</packing>
-		      </child>
-
-		      <child>
-			<widget class="GtkEntry" id="usernameEntry">
-			  <property name="visible">True</property>
-			  <property name="can_focus">True</property>
-			  <property name="editable">True</property>
-			  <property name="visibility">True</property>
-			  <property name="max_length">0</property>
-			  <property name="text" translatable="yes"></property>
-			  <property name="has_frame">True</property>
-			  <property name="invisible_char">â?¢</property>
-			  <property name="activates_default">False</property>
-			</widget>
-			<packing>
-			  <property name="left_attach">1</property>
-			  <property name="right_attach">2</property>
-			  <property name="top_attach">1</property>
-			  <property name="bottom_attach">2</property>
-			  <property name="y_options"></property>
-			</packing>
-		      </child>
-
-		      <child>
-			<widget class="GtkEntry" id="passwordEntry">
-			  <property name="visible">True</property>
-			  <property name="can_focus">True</property>
-			  <property name="editable">True</property>
-			  <property name="visibility">True</property>
-			  <property name="max_length">0</property>
-			  <property name="text" translatable="yes"></property>
-			  <property name="has_frame">True</property>
-			  <property name="invisible_char">â?¢</property>
-			  <property name="activates_default">False</property>
-			</widget>
-			<packing>
-			  <property name="left_attach">1</property>
-			  <property name="right_attach">2</property>
-			  <property name="top_attach">2</property>
-			  <property name="bottom_attach">3</property>
-			  <property name="y_options"></property>
-			</packing>
-		      </child>
-		    </widget>
-		    <packing>
-		      <property name="padding">0</property>
-		      <property name="expand">True</property>
-		      <property name="fill">True</property>
-		    </packing>
-		  </child>
-		</widget>
-		<packing>
-		  <property name="tab_expand">False</property>
-		  <property name="tab_fill">True</property>
-		</packing>
-	      </child>
-
-	      <child>
-		<widget class="GtkLabel" id="label21">
-		  <property name="visible">True</property>
-		  <property name="label" translatable="yes"></property>
-		  <property name="use_underline">False</property>
-		  <property name="use_markup">False</property>
-		  <property name="justify">GTK_JUSTIFY_LEFT</property>
-		  <property name="wrap">False</property>
-		  <property name="selectable">False</property>
-		  <property name="xalign">0.5</property>
-		  <property name="yalign">0.5</property>
-		  <property name="xpad">0</property>
-		  <property name="ypad">0</property>
-		  <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
-		  <property name="width_chars">-1</property>
-		  <property name="single_line_mode">False</property>
-		  <property name="angle">0</property>
-		</widget>
-		<packing>
-		  <property name="type">tab</property>
-		</packing>
-	      </child>
-
-	      <child>
-		<placeholder/>
-	      </child>
-
-	      <child>
-		<widget class="GtkLabel" id="label22">
-		  <property name="visible">True</property>
-		  <property name="label" translatable="yes"></property>
-		  <property name="use_underline">False</property>
-		  <property name="use_markup">False</property>
-		  <property name="justify">GTK_JUSTIFY_LEFT</property>
-		  <property name="wrap">False</property>
-		  <property name="selectable">False</property>
-		  <property name="xalign">0.5</property>
-		  <property name="yalign">0.5</property>
-		  <property name="xpad">0</property>
-		  <property name="ypad">0</property>
-		  <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
-		  <property name="width_chars">-1</property>
-		  <property name="single_line_mode">False</property>
-		  <property name="angle">0</property>
-		</widget>
-		<packing>
-		  <property name="type">tab</property>
-		</packing>
-	      </child>
-
-	      <child>
-		<widget class="GtkLabel" id="label19">
-		  <property name="visible">True</property>
-		  <property name="label" translatable="yes"></property>
-		  <property name="use_underline">False</property>
-		  <property name="use_markup">False</property>
-		  <property name="justify">GTK_JUSTIFY_LEFT</property>
-		  <property name="wrap">False</property>
-		  <property name="selectable">False</property>
-		  <property name="xalign">0.5</property>
-		  <property name="yalign">0.5</property>
-		  <property name="xpad">0</property>
-		  <property name="ypad">0</property>
-		  <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
-		  <property name="width_chars">-1</property>
-		  <property name="single_line_mode">False</property>
-		  <property name="angle">0</property>
-		</widget>
-		<packing>
-		  <property name="tab_expand">False</property>
-		  <property name="tab_fill">True</property>
-		</packing>
-	      </child>
-
-	      <child>
-		<widget class="GtkLabel" id="label23">
-		  <property name="visible">True</property>
-		  <property name="label" translatable="yes"></property>
-		  <property name="use_underline">False</property>
-		  <property name="use_markup">False</property>
-		  <property name="justify">GTK_JUSTIFY_LEFT</property>
-		  <property name="wrap">False</property>
-		  <property name="selectable">False</property>
-		  <property name="xalign">0.5</property>
-		  <property name="yalign">0.5</property>
-		  <property name="xpad">0</property>
-		  <property name="ypad">0</property>
-		  <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
-		  <property name="width_chars">-1</property>
-		  <property name="single_line_mode">False</property>
-		  <property name="angle">0</property>
-		</widget>
-		<packing>
-		  <property name="type">tab</property>
-		</packing>
-	      </child>
-
-	      <child>
-		<placeholder/>
-	      </child>
-
-	      <child>
-		<widget class="GtkLabel" id="label24">
-		  <property name="visible">True</property>
-		  <property name="label" translatable="yes"></property>
-		  <property name="use_underline">False</property>
-		  <property name="use_markup">False</property>
-		  <property name="justify">GTK_JUSTIFY_LEFT</property>
-		  <property name="wrap">False</property>
-		  <property name="selectable">False</property>
-		  <property name="xalign">0.5</property>
-		  <property name="yalign">0.5</property>
-		  <property name="xpad">0</property>
-		  <property name="ypad">0</property>
-		  <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
-		  <property name="width_chars">-1</property>
-		  <property name="single_line_mode">False</property>
-		  <property name="angle">0</property>
-		</widget>
-		<packing>
-		  <property name="type">tab</property>
-		</packing>
-	      </child>
-
-	      <child>
-		<widget class="GtkTable" id="table3">
-		  <property name="visible">True</property>
-		  <property name="n_rows">3</property>
-		  <property name="n_columns">2</property>
-		  <property name="homogeneous">False</property>
-		  <property name="row_spacing">10</property>
-		  <property name="column_spacing">5</property>
-
-		  <child>
-		    <widget class="GtkLabel" id="label14">
-		      <property name="visible">True</property>
-		      <property name="label" translatable="yes">_Server</property>
-		      <property name="use_underline">True</property>
-		      <property name="use_markup">False</property>
-		      <property name="justify">GTK_JUSTIFY_LEFT</property>
-		      <property name="wrap">False</property>
-		      <property name="selectable">False</property>
-		      <property name="xalign">0</property>
-		      <property name="yalign">0.5</property>
-		      <property name="xpad">0</property>
-		      <property name="ypad">0</property>
-		      <property name="mnemonic_widget">nfsServerEntry</property>
-		      <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
-		      <property name="width_chars">-1</property>
-		      <property name="single_line_mode">False</property>
-		      <property name="angle">0</property>
-		    </widget>
-		    <packing>
-		      <property name="left_attach">0</property>
-		      <property name="right_attach">1</property>
-		      <property name="top_attach">0</property>
-		      <property name="bottom_attach">1</property>
-		      <property name="x_options">fill</property>
-		      <property name="y_options"></property>
-		    </packing>
-		  </child>
-
-		  <child>
-		    <widget class="GtkLabel" id="label15">
-		      <property name="visible">True</property>
-		      <property name="label" translatable="yes">_Path</property>
-		      <property name="use_underline">True</property>
-		      <property name="use_markup">False</property>
-		      <property name="justify">GTK_JUSTIFY_LEFT</property>
-		      <property name="wrap">False</property>
-		      <property name="selectable">False</property>
-		      <property name="xalign">0</property>
-		      <property name="yalign">0.5</property>
-		      <property name="xpad">0</property>
-		      <property name="ypad">0</property>
-		      <property name="mnemonic_widget">nfsPathEntry</property>
-		      <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
-		      <property name="width_chars">-1</property>
-		      <property name="single_line_mode">False</property>
-		      <property name="angle">0</property>
-		    </widget>
-		    <packing>
-		      <property name="left_attach">0</property>
-		      <property name="right_attach">1</property>
-		      <property name="top_attach">1</property>
-		      <property name="bottom_attach">2</property>
-		      <property name="x_options">fill</property>
-		      <property name="y_options"></property>
-		    </packing>
-		  </child>
-
-		  <child>
-		    <widget class="GtkLabel" id="label16">
-		      <property name="visible">True</property>
-		      <property name="label" translatable="yes">_Options</property>
-		      <property name="use_underline">True</property>
-		      <property name="use_markup">False</property>
-		      <property name="justify">GTK_JUSTIFY_LEFT</property>
-		      <property name="wrap">False</property>
-		      <property name="selectable">False</property>
-		      <property name="xalign">0</property>
-		      <property name="yalign">0.5</property>
-		      <property name="xpad">0</property>
-		      <property name="ypad">0</property>
-		      <property name="mnemonic_widget">nfsOptionsEntry</property>
-		      <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
-		      <property name="width_chars">-1</property>
-		      <property name="single_line_mode">False</property>
-		      <property name="angle">0</property>
-		    </widget>
-		    <packing>
-		      <property name="left_attach">0</property>
-		      <property name="right_attach">1</property>
-		      <property name="top_attach">2</property>
-		      <property name="bottom_attach">3</property>
-		      <property name="x_options">fill</property>
-		      <property name="y_options"></property>
-		    </packing>
-		  </child>
-
-		  <child>
-		    <widget class="GtkEntry" id="nfsServerEntry">
-		      <property name="visible">True</property>
-		      <property name="can_focus">True</property>
-		      <property name="editable">True</property>
-		      <property name="visibility">True</property>
-		      <property name="max_length">0</property>
-		      <property name="text" translatable="yes"></property>
-		      <property name="has_frame">True</property>
-		      <property name="invisible_char">â?¢</property>
-		      <property name="activates_default">False</property>
-		    </widget>
-		    <packing>
-		      <property name="left_attach">1</property>
-		      <property name="right_attach">2</property>
-		      <property name="top_attach">0</property>
-		      <property name="bottom_attach">1</property>
-		      <property name="y_options"></property>
-		    </packing>
-		  </child>
-
-		  <child>
-		    <widget class="GtkEntry" id="nfsPathEntry">
-		      <property name="visible">True</property>
-		      <property name="can_focus">True</property>
-		      <property name="editable">True</property>
-		      <property name="visibility">True</property>
-		      <property name="max_length">0</property>
-		      <property name="text" translatable="yes"></property>
-		      <property name="has_frame">True</property>
-		      <property name="invisible_char">â?¢</property>
-		      <property name="activates_default">False</property>
-		    </widget>
-		    <packing>
-		      <property name="left_attach">1</property>
-		      <property name="right_attach">2</property>
-		      <property name="top_attach">1</property>
-		      <property name="bottom_attach">2</property>
-		      <property name="y_options"></property>
-		    </packing>
-		  </child>
-
-		  <child>
-		    <widget class="GtkEntry" id="nfsOptionsEntry">
-		      <property name="visible">True</property>
-		      <property name="can_focus">True</property>
-		      <property name="editable">True</property>
-		      <property name="visibility">True</property>
-		      <property name="max_length">0</property>
-		      <property name="text" translatable="yes"></property>
-		      <property name="has_frame">True</property>
-		      <property name="invisible_char">â?¢</property>
-		      <property name="activates_default">False</property>
-		    </widget>
-		    <packing>
-		      <property name="left_attach">1</property>
-		      <property name="right_attach">2</property>
-		      <property name="top_attach">2</property>
-		      <property name="bottom_attach">3</property>
-		      <property name="y_options"></property>
-		    </packing>
-		  </child>
-		</widget>
-		<packing>
-		  <property name="tab_expand">False</property>
-		  <property name="tab_fill">True</property>
-		</packing>
-	      </child>
-
-	      <child>
-		<widget class="GtkLabel" id="label25">
-		  <property name="visible">True</property>
-		  <property name="label" translatable="yes"></property>
-		  <property name="use_underline">False</property>
-		  <property name="use_markup">False</property>
-		  <property name="justify">GTK_JUSTIFY_LEFT</property>
-		  <property name="wrap">False</property>
-		  <property name="selectable">False</property>
-		  <property name="xalign">0.5</property>
-		  <property name="yalign">0.5</property>
-		  <property name="xpad">0</property>
-		  <property name="ypad">0</property>
-		  <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
-		  <property name="width_chars">-1</property>
-		  <property name="single_line_mode">False</property>
-		  <property name="angle">0</property>
-		</widget>
-		<packing>
-		  <property name="type">tab</property>
-		</packing>
-	      </child>
-
-	      <child>
-		<placeholder/>
-	      </child>
-
-	      <child>
-		<widget class="GtkLabel" id="label26">
-		  <property name="visible">True</property>
-		  <property name="label" translatable="yes"></property>
-		  <property name="use_underline">False</property>
-		  <property name="use_markup">False</property>
-		  <property name="justify">GTK_JUSTIFY_LEFT</property>
-		  <property name="wrap">False</property>
-		  <property name="selectable">False</property>
-		  <property name="xalign">0.5</property>
-		  <property name="yalign">0.5</property>
-		  <property name="xpad">0</property>
-		  <property name="ypad">0</property>
-		  <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
-		  <property name="width_chars">-1</property>
-		  <property name="single_line_mode">False</property>
-		  <property name="angle">0</property>
-		</widget>
-		<packing>
-		  <property name="type">tab</property>
-		</packing>
-	      </child>
-
-	      <child>
-		<widget class="GtkTable" id="table4">
-		  <property name="visible">True</property>
-		  <property name="n_rows">2</property>
-		  <property name="n_columns">2</property>
-		  <property name="homogeneous">False</property>
-		  <property name="row_spacing">10</property>
-		  <property name="column_spacing">5</property>
-
-		  <child>
-		    <widget class="GtkLabel" id="label17">
-		      <property name="visible">True</property>
-		      <property name="label" translatable="yes">_Partition</property>
-		      <property name="use_underline">True</property>
-		      <property name="use_markup">False</property>
-		      <property name="justify">GTK_JUSTIFY_LEFT</property>
-		      <property name="wrap">False</property>
-		      <property name="selectable">False</property>
-		      <property name="xalign">0</property>
-		      <property name="yalign">0.5</property>
-		      <property name="xpad">0</property>
-		      <property name="ypad">0</property>
-		      <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
-		      <property name="width_chars">-1</property>
-		      <property name="single_line_mode">False</property>
-		      <property name="angle">0</property>
-		    </widget>
-		    <packing>
-		      <property name="left_attach">0</property>
-		      <property name="right_attach">1</property>
-		      <property name="top_attach">0</property>
-		      <property name="bottom_attach">1</property>
-		      <property name="x_options">fill</property>
-		      <property name="y_options"></property>
-		    </packing>
-		  </child>
-
-		  <child>
-		    <widget class="GtkLabel" id="label18">
-		      <property name="visible">True</property>
-		      <property name="label" translatable="yes">_Directory</property>
-		      <property name="use_underline">True</property>
-		      <property name="use_markup">False</property>
-		      <property name="justify">GTK_JUSTIFY_LEFT</property>
-		      <property name="wrap">False</property>
-		      <property name="selectable">False</property>
-		      <property name="xalign">0</property>
-		      <property name="yalign">0.5</property>
-		      <property name="xpad">0</property>
-		      <property name="ypad">0</property>
-		      <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
-		      <property name="width_chars">-1</property>
-		      <property name="single_line_mode">False</property>
-		      <property name="angle">0</property>
-		    </widget>
-		    <packing>
-		      <property name="left_attach">0</property>
-		      <property name="right_attach">1</property>
-		      <property name="top_attach">1</property>
-		      <property name="bottom_attach">2</property>
-		      <property name="x_options">fill</property>
-		      <property name="y_options"></property>
-		    </packing>
-		  </child>
-
-		  <child>
-		    <widget class="GtkComboBox" id="partitionComboBox">
-		      <property name="visible">True</property>
-		      <property name="add_tearoffs">False</property>
-		      <property name="focus_on_click">True</property>
-		    </widget>
-		    <packing>
-		      <property name="left_attach">1</property>
-		      <property name="right_attach">2</property>
-		      <property name="top_attach">0</property>
-		      <property name="bottom_attach">1</property>
-		      <property name="y_options">fill</property>
-		    </packing>
-		  </child>
-
-		  <child>
-		    <widget class="GtkFileChooserButton" id="directoryChooserButton">
-		      <property name="visible">True</property>
-		      <property name="title" translatable="yes">Select A Directory</property>
-		      <property name="action">GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER</property>
-		      <property name="local_only">True</property>
-		      <property name="show_hidden">False</property>
-		      <property name="do_overwrite_confirmation">False</property>
-		      <property name="width_chars">-1</property>
-		    </widget>
-		    <packing>
-		      <property name="left_attach">1</property>
-		      <property name="right_attach">2</property>
-		      <property name="top_attach">1</property>
-		      <property name="bottom_attach">2</property>
-		      <property name="x_options">fill</property>
-		      <property name="y_options">fill</property>
-		    </packing>
-		  </child>
-		</widget>
-		<packing>
-		  <property name="tab_expand">False</property>
-		  <property name="tab_fill">True</property>
-		</packing>
-	      </child>
-
-	      <child>
-		<widget class="GtkLabel" id="label27">
-		  <property name="visible">True</property>
-		  <property name="label" translatable="yes"></property>
-		  <property name="use_underline">False</property>
-		  <property name="use_markup">False</property>
-		  <property name="justify">GTK_JUSTIFY_LEFT</property>
-		  <property name="wrap">False</property>
-		  <property name="selectable">False</property>
-		  <property name="xalign">0.5</property>
-		  <property name="yalign">0.5</property>
-		  <property name="xpad">0</property>
-		  <property name="ypad">0</property>
-		  <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
-		  <property name="width_chars">-1</property>
-		  <property name="single_line_mode">False</property>
-		  <property name="angle">0</property>
-		</widget>
-		<packing>
-		  <property name="type">tab</property>
-		</packing>
-	      </child>
-
-	      <child>
-		<placeholder/>
-	      </child>
-
-	      <child>
-		<widget class="GtkLabel" id="label28">
-		  <property name="visible">True</property>
-		  <property name="label" translatable="yes"></property>
-		  <property name="use_underline">False</property>
-		  <property name="use_markup">False</property>
-		  <property name="justify">GTK_JUSTIFY_LEFT</property>
-		  <property name="wrap">False</property>
-		  <property name="selectable">False</property>
-		  <property name="xalign">0.5</property>
-		  <property name="yalign">0.5</property>
-		  <property name="xpad">0</property>
-		  <property name="ypad">0</property>
-		  <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
-		  <property name="width_chars">-1</property>
-		  <property name="single_line_mode">False</property>
-		  <property name="angle">0</property>
-		</widget>
-		<packing>
-		  <property name="type">tab</property>
-		</packing>
-	      </child>
-	    </widget>
-	    <packing>
-	      <property name="padding">0</property>
-	      <property name="expand">True</property>
-	      <property name="fill">False</property>
-	    </packing>
-	  </child>
-	</widget>
-	<packing>
-	  <property name="padding">0</property>
-	  <property name="expand">True</property>
-	  <property name="fill">True</property>
-	</packing>
-      </child>
-    </widget>
-  </child>
-</widget>
-
-</glade-interface>
diff --git a/ui/anaconda.glade b/ui/anaconda.glade
deleted file mode 100644
index 08e9e64..0000000
--- a/ui/anaconda.glade
+++ /dev/null
@@ -1,270 +0,0 @@
-<?xml version="1.0" standalone="no"?> <!--*- mode: xml -*-->
-<!DOCTYPE glade-interface SYSTEM "http://glade.gnome.org/glade-2.0.dtd";>
-
-<glade-interface>
-
-<widget class="GtkWindow" id="mainWindow">
-  <property name="width_request">610</property>
-  <property name="height_request">450</property>
-  <property name="title" translatable="yes"></property>
-  <property name="type">GTK_WINDOW_TOPLEVEL</property>
-  <property name="window_position">GTK_WIN_POS_CENTER</property>
-  <property name="modal">False</property>
-  <property name="default_width">800</property>
-  <property name="default_height">600</property>
-  <property name="resizable">False</property>
-  <property name="destroy_with_parent">False</property>
-  <property name="decorated">True</property>
-  <property name="skip_taskbar_hint">False</property>
-  <property name="skip_pager_hint">False</property>
-  <property name="type_hint">GDK_WINDOW_TYPE_HINT_NORMAL</property>
-  <property name="gravity">GDK_GRAVITY_CENTER</property>
-  <property name="focus_on_map">True</property>
-  <property name="urgency_hint">False</property>
-  <signal name="key_release_event" handler="on_mainWindow_key_release_event" last_modification_time="Wed, 12 Jan 2005 20:53:20 GMT"/>
-  <signal name="delete_event" handler="on_mainWindow_delete_event" last_modification_time="Wed, 12 Jan 2005 21:03:14 GMT"/>
-
-  <child>
-    <widget class="GtkVBox" id="mainBox">
-      <property name="visible">True</property>
-      <property name="homogeneous">False</property>
-      <property name="spacing">12</property>
-
-      <child>
-	<widget class="GtkImage" id="headerImage">
-	  <property name="visible">True</property>
-	  <property name="xalign">0.5</property>
-	  <property name="yalign">0.5</property>
-	  <property name="xpad">0</property>
-	  <property name="ypad">0</property>
-	</widget>
-	<packing>
-	  <property name="padding">0</property>
-	  <property name="expand">False</property>
-	  <property name="fill">True</property>
-	</packing>
-      </child>
-
-      <child>
-	<widget class="GtkTable" id="mainTable">
-	  <property name="border_width">12</property>
-	  <property name="visible">True</property>
-	  <property name="n_rows">1</property>
-	  <property name="n_columns">2</property>
-	  <property name="homogeneous">False</property>
-	  <property name="row_spacing">0</property>
-	  <property name="column_spacing">0</property>
-
-	  <child>
-	    <widget class="GtkFrame" id="installFrame">
-	      <property name="visible">True</property>
-	      <property name="label_xalign">0</property>
-	      <property name="label_yalign">0.5</property>
-	      <property name="shadow_type">GTK_SHADOW_NONE</property>
-
-	      <child>
-		<widget class="GtkAlignment" id="alignment5">
-		  <property name="visible">True</property>
-		  <property name="xalign">0.5</property>
-		  <property name="yalign">0.5</property>
-		  <property name="xscale">1</property>
-		  <property name="yscale">1</property>
-		  <property name="top_padding">0</property>
-		  <property name="bottom_padding">0</property>
-		  <property name="left_padding">12</property>
-		  <property name="right_padding">0</property>
-
-		  <child>
-		    <placeholder/>
-		  </child>
-		</widget>
-	      </child>
-	    </widget>
-	    <packing>
-	      <property name="left_attach">1</property>
-	      <property name="right_attach">2</property>
-	      <property name="top_attach">0</property>
-	      <property name="bottom_attach">1</property>
-	    </packing>
-	  </child>
-	</widget>
-	<packing>
-	  <property name="padding">0</property>
-	  <property name="expand">True</property>
-	  <property name="fill">True</property>
-	</packing>
-      </child>
-
-      <child>
-	<widget class="GtkHBox" id="buttonBar">
-	  <property name="border_width">12</property>
-	  <property name="visible">True</property>
-	  <property name="homogeneous">False</property>
-	  <property name="spacing">6</property>
-
-	  <child>
-	    <placeholder/>
-	  </child>
-
-	  <child>
-	    <widget class="GtkButton" id="debugButton">
-	      <property name="can_focus">True</property>
-	      <property name="relief">GTK_RELIEF_NORMAL</property>
-	      <property name="focus_on_click">True</property>
-	      <signal name="clicked" handler="on_debugButton_clicked" last_modification_time="Wed, 12 Jan 2005 20:02:25 GMT"/>
-
-	      <child>
-		<widget class="GtkLabel" id="label4">
-		  <property name="visible">True</property>
-		  <property name="label" translatable="yes">_Debug</property>
-		  <property name="use_underline">True</property>
-		  <property name="use_markup">False</property>
-		  <property name="justify">GTK_JUSTIFY_LEFT</property>
-		  <property name="wrap">False</property>
-		  <property name="selectable">False</property>
-		  <property name="xalign">0.5</property>
-		  <property name="yalign">0.5</property>
-		  <property name="xpad">0</property>
-		  <property name="ypad">0</property>
-		  <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
-		  <property name="width_chars">-1</property>
-		  <property name="single_line_mode">False</property>
-		  <property name="angle">0</property>
-		</widget>
-	      </child>
-	    </widget>
-	    <packing>
-	      <property name="padding">0</property>
-	      <property name="expand">False</property>
-	      <property name="fill">False</property>
-	    </packing>
-	  </child>
-
-	  <child>
-	    <widget class="GtkHButtonBox" id="hbuttonbox2">
-	      <property name="visible">True</property>
-	      <property name="layout_style">GTK_BUTTONBOX_END</property>
-	      <property name="spacing">18</property>
-
-	      <child>
-		<widget class="GtkButton" id="backButton">
-		  <property name="visible">True</property>
-		  <property name="can_default">True</property>
-		  <property name="can_focus">True</property>
-		  <property name="relief">GTK_RELIEF_NORMAL</property>
-		  <property name="focus_on_click">True</property>
-		  <signal name="clicked" handler="on_backButton_clicked" last_modification_time="Wed, 12 Jan 2005 20:02:34 GMT"/>
-
-		  <child>
-		    <widget class="GtkLabel" id="label8">
-		      <property name="visible">True</property>
-		      <property name="label" translatable="yes">_Back</property>
-		      <property name="use_underline">True</property>
-		      <property name="use_markup">False</property>
-		      <property name="justify">GTK_JUSTIFY_LEFT</property>
-		      <property name="wrap">False</property>
-		      <property name="selectable">False</property>
-		      <property name="xalign">0.5</property>
-		      <property name="yalign">0.5</property>
-		      <property name="xpad">0</property>
-		      <property name="ypad">0</property>
-		      <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
-		      <property name="width_chars">-1</property>
-		      <property name="single_line_mode">False</property>
-		      <property name="angle">0</property>
-		    </widget>
-		  </child>
-		</widget>
-	      </child>
-
-	      <child>
-		<widget class="GtkButton" id="nextButton">
-		  <property name="visible">True</property>
-		  <property name="can_default">True</property>
-		  <property name="can_focus">True</property>
-		  <property name="relief">GTK_RELIEF_NORMAL</property>
-		  <property name="focus_on_click">True</property>
-		  <signal name="clicked" handler="on_nextButton_clicked" last_modification_time="Wed, 12 Jan 2005 20:01:46 GMT"/>
-
-		  <child>
-		    <widget class="GtkLabel" id="label6">
-		      <property name="visible">True</property>
-		      <property name="label" translatable="yes">_Next</property>
-		      <property name="use_underline">True</property>
-		      <property name="use_markup">False</property>
-		      <property name="justify">GTK_JUSTIFY_LEFT</property>
-		      <property name="wrap">False</property>
-		      <property name="selectable">False</property>
-		      <property name="xalign">0.5</property>
-		      <property name="yalign">0.5</property>
-		      <property name="xpad">0</property>
-		      <property name="ypad">0</property>
-		      <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
-		      <property name="width_chars">-1</property>
-		      <property name="single_line_mode">False</property>
-		      <property name="angle">0</property>
-		    </widget>
-		  </child>
-		</widget>
-	      </child>
-
-	      <child>
-		<widget class="GtkButton" id="rebootButton">
-		  <property name="can_default">True</property>
-		  <property name="can_focus">True</property>
-		  <property name="relief">GTK_RELIEF_NORMAL</property>
-		  <property name="focus_on_click">True</property>
-		  <signal name="clicked" handler="on_rebootButton_clicked" last_modification_time="Wed, 12 Jan 2005 21:46:55 GMT"/>
-
-		  <child>
-		    <widget class="GtkLabel" id="label7">
-		      <property name="visible">True</property>
-		      <property name="label" translatable="yes">Reboo_t</property>
-		      <property name="use_underline">True</property>
-		      <property name="use_markup">False</property>
-		      <property name="justify">GTK_JUSTIFY_LEFT</property>
-		      <property name="wrap">False</property>
-		      <property name="selectable">False</property>
-		      <property name="xalign">0.5</property>
-		      <property name="yalign">0.5</property>
-		      <property name="xpad">0</property>
-		      <property name="ypad">0</property>
-		      <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
-		      <property name="width_chars">-1</property>
-		      <property name="single_line_mode">False</property>
-		      <property name="angle">0</property>
-		    </widget>
-		  </child>
-		</widget>
-	      </child>
-
-	      <child>
-		<widget class="GtkButton" id="closeButton">
-		  <property name="can_default">True</property>
-		  <property name="can_focus">True</property>
-		  <property name="label">gtk-close</property>
-		  <property name="use_stock">True</property>
-		  <property name="relief">GTK_RELIEF_NORMAL</property>
-		  <property name="focus_on_click">True</property>
-		  <signal name="clicked" handler="on_closeButton_clicked" last_modification_time="Wed, 04 Apr 2007 20:23:13 GMT"/>
-		</widget>
-	      </child>
-	    </widget>
-	    <packing>
-	      <property name="padding">0</property>
-	      <property name="expand">True</property>
-	      <property name="fill">True</property>
-	    </packing>
-	  </child>
-	</widget>
-	<packing>
-	  <property name="padding">0</property>
-	  <property name="expand">False</property>
-	  <property name="fill">True</property>
-	</packing>
-      </child>
-    </widget>
-  </child>
-</widget>
-
-</glade-interface>
diff --git a/ui/autopart.glade b/ui/autopart.glade
deleted file mode 100644
index f58ebd1..0000000
--- a/ui/autopart.glade
+++ /dev/null
@@ -1,300 +0,0 @@
-<?xml version="1.0" standalone="no"?> <!--*- mode: xml -*-->
-<!DOCTYPE glade-interface SYSTEM "http://glade.gnome.org/glade-2.0.dtd";>
-
-<glade-interface>
-
-<widget class="GtkWindow" id="unused1">
-  <property name="border_width">18</property>
-  <property name="title" translatable="yes" context="yes"></property>
-  <property name="type">GTK_WINDOW_TOPLEVEL</property>
-  <property name="window_position">GTK_WIN_POS_NONE</property>
-  <property name="modal">False</property>
-  <property name="default_width">440</property>
-  <property name="default_height">250</property>
-  <property name="resizable">True</property>
-  <property name="destroy_with_parent">False</property>
-  <property name="decorated">True</property>
-  <property name="skip_taskbar_hint">False</property>
-  <property name="skip_pager_hint">False</property>
-  <property name="type_hint">GDK_WINDOW_TYPE_HINT_NORMAL</property>
-  <property name="gravity">GDK_GRAVITY_NORTH_WEST</property>
-  <property name="focus_on_map">True</property>
-  <property name="urgency_hint">False</property>
-
-  <child>
-    <widget class="GtkTable" id="parttypeTable">
-      <property name="visible">True</property>
-      <property name="n_rows">4</property>
-      <property name="n_columns">1</property>
-      <property name="homogeneous">False</property>
-      <property name="row_spacing">0</property>
-      <property name="column_spacing">0</property>
-
-      <child>
-	<widget class="GtkLabel" id="mainlabel">
-	  <property name="visible">True</property>
-	  <property name="label" translatable="yes">Which type of installation would you like?</property>
-	  <property name="use_underline">False</property>
-	  <property name="use_markup">False</property>
-	  <property name="justify">GTK_JUSTIFY_LEFT</property>
-	  <property name="wrap">True</property>
-	  <property name="selectable">False</property>
-	  <property name="xalign">0</property>
-	  <property name="yalign">0</property>
-	  <property name="xpad">0</property>
-	  <property name="ypad">0</property>
-	  <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
-	  <property name="width_chars">-1</property>
-	  <property name="single_line_mode">False</property>
-	  <property name="angle">0</property>
-	</widget>
-	<packing>
-	  <property name="left_attach">0</property>
-	  <property name="right_attach">1</property>
-	  <property name="top_attach">0</property>
-	  <property name="bottom_attach">1</property>
-	  <property name="x_options">fill</property>
-	  <property name="y_options"></property>
-	</packing>
-      </child>
-
-      <child>
-	<widget class="GtkCheckButton" id="encryptButton">
-	  <property name="visible">True</property>
-	  <property name="can_focus">True</property>
-	  <property name="label" translatable="yes">_Encrypt system</property>
-	  <property name="use_underline">True</property>
-	  <property name="relief">GTK_RELIEF_NORMAL</property>
-	  <property name="focus_on_click">True</property>
-	  <property name="active">False</property>
-	  <property name="inconsistent">False</property>
-	  <property name="draw_indicator">True</property>
-	</widget>
-	<packing>
-	  <property name="left_attach">0</property>
-	  <property name="right_attach">1</property>
-	  <property name="top_attach">2</property>
-	  <property name="bottom_attach">3</property>
-	  <property name="x_options">fill</property>
-	  <property name="y_options"></property>
-	</packing>
-      </child>
-
-      <child>
-	<widget class="GtkCheckButton" id="reviewButton">
-	  <property name="label" translatable="yes" context="yes">Re_view and modify partitioning layout</property>
-	  <property name="use_underline">True</property>
-	  <property name="relief">GTK_RELIEF_NORMAL</property>
-	  <property name="focus_on_click">True</property>
-	  <property name="active">False</property>
-	  <property name="inconsistent">False</property>
-	  <property name="draw_indicator">True</property>
-	</widget>
-	<packing>
-	  <property name="left_attach">0</property>
-	  <property name="right_attach">1</property>
-	  <property name="top_attach">3</property>
-	  <property name="bottom_attach">4</property>
-	  <property name="x_options">fill</property>
-	  <property name="y_options"></property>
-	</packing>
-      </child>
-    </widget>
-  </child>
-</widget>
-
-<widget class="GtkDialog" id="shrinkDialog">
-  <property name="border_width">12</property>
-  <property name="visible">True</property>
-  <property name="title" translatable="yes">Volume to Shrink</property>
-  <property name="type">GTK_WINDOW_TOPLEVEL</property>
-  <property name="window_position">GTK_WIN_POS_CENTER</property>
-  <property name="modal">False</property>
-  <property name="resizable">True</property>
-  <property name="destroy_with_parent">False</property>
-  <property name="decorated">True</property>
-  <property name="skip_taskbar_hint">False</property>
-  <property name="skip_pager_hint">False</property>
-  <property name="type_hint">GDK_WINDOW_TYPE_HINT_DIALOG</property>
-  <property name="gravity">GDK_GRAVITY_NORTH_WEST</property>
-  <property name="focus_on_map">True</property>
-  <property name="urgency_hint">False</property>
-  <property name="has_separator">True</property>
-
-  <child internal-child="vbox">
-    <widget class="GtkVBox" id="dialog-vbox1">
-      <property name="visible">True</property>
-      <property name="homogeneous">False</property>
-      <property name="spacing">0</property>
-
-      <child internal-child="action_area">
-	<widget class="GtkHButtonBox" id="dialog-action_area1">
-	  <property name="visible">True</property>
-	  <property name="layout_style">GTK_BUTTONBOX_END</property>
-
-	  <child>
-	    <widget class="GtkButton" id="button4">
-	      <property name="visible">True</property>
-	      <property name="can_default">True</property>
-	      <property name="can_focus">True</property>
-	      <property name="label">gtk-cancel</property>
-	      <property name="use_stock">True</property>
-	      <property name="relief">GTK_RELIEF_NORMAL</property>
-	      <property name="focus_on_click">True</property>
-	      <property name="response_id">-6</property>
-	    </widget>
-	  </child>
-
-	  <child>
-	    <widget class="GtkButton" id="button5">
-	      <property name="visible">True</property>
-	      <property name="can_default">True</property>
-	      <property name="can_focus">True</property>
-	      <property name="relief">GTK_RELIEF_NORMAL</property>
-	      <property name="focus_on_click">True</property>
-	      <property name="response_id">-5</property>
-
-	      <child>
-		<widget class="GtkLabel" id="label7">
-		  <property name="visible">True</property>
-		  <property name="label" translatable="yes">_Shrink</property>
-		  <property name="use_underline">True</property>
-		  <property name="use_markup">False</property>
-		  <property name="justify">GTK_JUSTIFY_LEFT</property>
-		  <property name="wrap">False</property>
-		  <property name="selectable">False</property>
-		  <property name="xalign">0.5</property>
-		  <property name="yalign">0.5</property>
-		  <property name="xpad">0</property>
-		  <property name="ypad">0</property>
-		  <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
-		  <property name="width_chars">-1</property>
-		  <property name="single_line_mode">False</property>
-		  <property name="angle">0</property>
-		</widget>
-	      </child>
-	    </widget>
-	  </child>
-	</widget>
-	<packing>
-	  <property name="padding">0</property>
-	  <property name="expand">False</property>
-	  <property name="fill">True</property>
-	  <property name="pack_type">GTK_PACK_END</property>
-	</packing>
-      </child>
-
-      <child>
-	<widget class="GtkVBox" id="vbox2">
-	  <property name="visible">True</property>
-	  <property name="homogeneous">False</property>
-	  <property name="spacing">6</property>
-
-	  <child>
-	    <widget class="GtkLabel" id="label5">
-	      <property name="visible">True</property>
-	      <property name="label" translatable="yes">Which partition would you like to shrink to make room for your installation?</property>
-	      <property name="use_underline">False</property>
-	      <property name="use_markup">False</property>
-	      <property name="justify">GTK_JUSTIFY_LEFT</property>
-	      <property name="wrap">True</property>
-	      <property name="selectable">False</property>
-	      <property name="xalign">0.5</property>
-	      <property name="yalign">0.5</property>
-	      <property name="xpad">0</property>
-	      <property name="ypad">0</property>
-	      <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
-	      <property name="width_chars">-1</property>
-	      <property name="single_line_mode">False</property>
-	      <property name="angle">0</property>
-	    </widget>
-	    <packing>
-	      <property name="padding">0</property>
-	      <property name="expand">False</property>
-	      <property name="fill">False</property>
-	    </packing>
-	  </child>
-
-	  <child>
-	    <widget class="GtkComboBox" id="shrinkPartCombo">
-	      <property name="visible">True</property>
-	      <property name="add_tearoffs">False</property>
-	      <property name="focus_on_click">True</property>
-	      <signal name="changed" handler="on_resizePartCombo_changed" last_modification_time="Tue, 05 Feb 2008 18:27:52 GMT"/>
-	    </widget>
-	    <packing>
-	      <property name="padding">0</property>
-	      <property name="expand">False</property>
-	      <property name="fill">True</property>
-	    </packing>
-	  </child>
-
-	  <child>
-	    <widget class="GtkHBox" id="hbox4">
-	      <property name="visible">True</property>
-	      <property name="homogeneous">False</property>
-	      <property name="spacing">6</property>
-
-	      <child>
-		<widget class="GtkLabel" id="label6">
-		  <property name="visible">True</property>
-		  <property name="label" translatable="yes">&lt;b&gt;Shrink partition _to size (in MB):&lt;/b&gt;</property>
-		  <property name="use_underline">True</property>
-		  <property name="use_markup">True</property>
-		  <property name="justify">GTK_JUSTIFY_LEFT</property>
-		  <property name="wrap">False</property>
-		  <property name="selectable">False</property>
-		  <property name="xalign">0.5</property>
-		  <property name="yalign">0.5</property>
-		  <property name="xpad">0</property>
-		  <property name="ypad">0</property>
-		  <property name="mnemonic_widget">shrinkSB</property>
-		  <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
-		  <property name="width_chars">-1</property>
-		  <property name="single_line_mode">False</property>
-		  <property name="angle">0</property>
-		</widget>
-		<packing>
-		  <property name="padding">0</property>
-		  <property name="expand">False</property>
-		  <property name="fill">False</property>
-		</packing>
-	      </child>
-
-	      <child>
-		<widget class="GtkSpinButton" id="shrinkSB">
-		  <property name="visible">True</property>
-		  <property name="can_focus">True</property>
-		  <property name="climb_rate">1</property>
-		  <property name="digits">0</property>
-		  <property name="numeric">True</property>
-		  <property name="update_policy">GTK_UPDATE_IF_VALID</property>
-		  <property name="snap_to_ticks">False</property>
-		  <property name="wrap">False</property>
-		  <property name="adjustment">1 0 100 1 1 0</property>
-		</widget>
-		<packing>
-		  <property name="padding">0</property>
-		  <property name="expand">True</property>
-		  <property name="fill">True</property>
-		</packing>
-	      </child>
-	    </widget>
-	    <packing>
-	      <property name="padding">0</property>
-	      <property name="expand">False</property>
-	      <property name="fill">False</property>
-	    </packing>
-	  </child>
-	</widget>
-	<packing>
-	  <property name="padding">0</property>
-	  <property name="expand">True</property>
-	  <property name="fill">True</property>
-	</packing>
-      </child>
-    </widget>
-  </child>
-</widget>
-
-</glade-interface>
diff --git a/ui/blwhere.glade b/ui/blwhere.glade
deleted file mode 100644
index b043413..0000000
--- a/ui/blwhere.glade
+++ /dev/null
@@ -1,378 +0,0 @@
-<?xml version="1.0" standalone="no"?> <!--*- mode: xml -*-->
-<!DOCTYPE glade-interface SYSTEM "http://glade.gnome.org/glade-2.0.dtd";>
-
-<glade-interface>
-
-<widget class="GtkDialog" id="blwhereDialog">
-  <property name="visible">True</property>
-  <property name="title" translatable="yes">Boot loader device</property>
-  <property name="type">GTK_WINDOW_TOPLEVEL</property>
-  <property name="window_position">GTK_WIN_POS_CENTER_ALWAYS</property>
-  <property name="modal">False</property>
-  <property name="resizable">True</property>
-  <property name="destroy_with_parent">False</property>
-  <property name="decorated">True</property>
-  <property name="skip_taskbar_hint">False</property>
-  <property name="skip_pager_hint">False</property>
-  <property name="type_hint">GDK_WINDOW_TYPE_HINT_DIALOG</property>
-  <property name="gravity">GDK_GRAVITY_NORTH_WEST</property>
-  <property name="focus_on_map">True</property>
-  <property name="urgency_hint">False</property>
-  <property name="has_separator">True</property>
-
-  <child internal-child="vbox">
-    <widget class="GtkVBox" id="dialog-vbox1">
-      <property name="visible">True</property>
-      <property name="homogeneous">False</property>
-      <property name="spacing">6</property>
-
-      <child internal-child="action_area">
-	<widget class="GtkHButtonBox" id="dialog-action_area1">
-	  <property name="visible">True</property>
-	  <property name="layout_style">GTK_BUTTONBOX_END</property>
-
-	  <child>
-	    <widget class="GtkButton" id="cancelbutton1">
-	      <property name="visible">True</property>
-	      <property name="can_default">True</property>
-	      <property name="can_focus">True</property>
-	      <property name="label">gtk-cancel</property>
-	      <property name="use_stock">True</property>
-	      <property name="relief">GTK_RELIEF_NORMAL</property>
-	      <property name="focus_on_click">True</property>
-	      <property name="response_id">-6</property>
-	    </widget>
-	  </child>
-
-	  <child>
-	    <widget class="GtkButton" id="okbutton1">
-	      <property name="visible">True</property>
-	      <property name="can_default">True</property>
-	      <property name="can_focus">True</property>
-	      <property name="label">gtk-ok</property>
-	      <property name="use_stock">True</property>
-	      <property name="relief">GTK_RELIEF_NORMAL</property>
-	      <property name="focus_on_click">True</property>
-	      <property name="response_id">-5</property>
-	    </widget>
-	  </child>
-	</widget>
-	<packing>
-	  <property name="padding">0</property>
-	  <property name="expand">False</property>
-	  <property name="fill">True</property>
-	  <property name="pack_type">GTK_PACK_END</property>
-	</packing>
-      </child>
-
-      <child>
-	<widget class="GtkVBox" id="vbox1">
-	  <property name="visible">True</property>
-	  <property name="homogeneous">False</property>
-	  <property name="spacing">6</property>
-
-	  <child>
-	    <widget class="GtkLabel" id="label1">
-	      <property name="visible">True</property>
-	      <property name="label" translatable="yes">Where would you like to install the boot loader for your system?</property>
-	      <property name="use_underline">False</property>
-	      <property name="use_markup">False</property>
-	      <property name="justify">GTK_JUSTIFY_LEFT</property>
-	      <property name="wrap">True</property>
-	      <property name="selectable">False</property>
-	      <property name="xalign">0.5</property>
-	      <property name="yalign">0.5</property>
-	      <property name="xpad">0</property>
-	      <property name="ypad">0</property>
-	      <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
-	      <property name="width_chars">-1</property>
-	      <property name="single_line_mode">False</property>
-	      <property name="angle">0</property>
-	    </widget>
-	    <packing>
-	      <property name="padding">0</property>
-	      <property name="expand">False</property>
-	      <property name="fill">False</property>
-	    </packing>
-	  </child>
-
-	  <child>
-	    <widget class="GtkRadioButton" id="mbrRadio">
-	      <property name="can_focus">True</property>
-	      <property name="label" translatable="yes">MBR</property>
-	      <property name="use_underline">True</property>
-	      <property name="relief">GTK_RELIEF_NORMAL</property>
-	      <property name="focus_on_click">True</property>
-	      <property name="active">False</property>
-	      <property name="inconsistent">False</property>
-	      <property name="draw_indicator">True</property>
-	    </widget>
-	    <packing>
-	      <property name="padding">0</property>
-	      <property name="expand">False</property>
-	      <property name="fill">False</property>
-	    </packing>
-	  </child>
-
-	  <child>
-	    <widget class="GtkRadioButton" id="bootRadio">
-	      <property name="can_focus">True</property>
-	      <property name="label" translatable="yes">/boot</property>
-	      <property name="use_underline">True</property>
-	      <property name="relief">GTK_RELIEF_NORMAL</property>
-	      <property name="focus_on_click">True</property>
-	      <property name="active">False</property>
-	      <property name="inconsistent">False</property>
-	      <property name="draw_indicator">True</property>
-	      <property name="group">mbrRadio</property>
-	    </widget>
-	    <packing>
-	      <property name="padding">0</property>
-	      <property name="expand">False</property>
-	      <property name="fill">False</property>
-	    </packing>
-	  </child>
-
-	  <child>
-	    <widget class="GtkExpander" id="expander1">
-	      <property name="visible">True</property>
-	      <property name="can_focus">True</property>
-	      <property name="expanded">False</property>
-	      <property name="spacing">0</property>
-
-	      <child>
-		<widget class="GtkAlignment" id="alignment1">
-		  <property name="visible">True</property>
-		  <property name="xalign">0.5</property>
-		  <property name="yalign">0.5</property>
-		  <property name="xscale">0.75</property>
-		  <property name="yscale">1</property>
-		  <property name="top_padding">0</property>
-		  <property name="bottom_padding">0</property>
-		  <property name="left_padding">0</property>
-		  <property name="right_padding">0</property>
-
-		  <child>
-		    <widget class="GtkTable" id="table1">
-		      <property name="visible">True</property>
-		      <property name="n_rows">4</property>
-		      <property name="n_columns">2</property>
-		      <property name="homogeneous">False</property>
-		      <property name="row_spacing">6</property>
-		      <property name="column_spacing">18</property>
-
-		      <child>
-			<widget class="GtkLabel" id="bd1Label">
-			  <property name="visible">True</property>
-			  <property name="label" translatable="yes">First BIOS drive:</property>
-			  <property name="use_underline">False</property>
-			  <property name="use_markup">False</property>
-			  <property name="justify">GTK_JUSTIFY_LEFT</property>
-			  <property name="wrap">False</property>
-			  <property name="selectable">False</property>
-			  <property name="xalign">0</property>
-			  <property name="yalign">0.5</property>
-			  <property name="xpad">0</property>
-			  <property name="ypad">0</property>
-			  <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
-			  <property name="width_chars">-1</property>
-			  <property name="single_line_mode">False</property>
-			  <property name="angle">0</property>
-			</widget>
-			<packing>
-			  <property name="left_attach">0</property>
-			  <property name="right_attach">1</property>
-			  <property name="top_attach">0</property>
-			  <property name="bottom_attach">1</property>
-			  <property name="x_options">fill</property>
-			  <property name="y_options"></property>
-			</packing>
-		      </child>
-
-		      <child>
-			<widget class="GtkLabel" id="bd2Label">
-			  <property name="label" translatable="yes">Second BIOS drive:</property>
-			  <property name="use_underline">False</property>
-			  <property name="use_markup">False</property>
-			  <property name="justify">GTK_JUSTIFY_LEFT</property>
-			  <property name="wrap">False</property>
-			  <property name="selectable">False</property>
-			  <property name="xalign">0</property>
-			  <property name="yalign">0.5</property>
-			  <property name="xpad">0</property>
-			  <property name="ypad">0</property>
-			  <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
-			  <property name="width_chars">-1</property>
-			  <property name="single_line_mode">False</property>
-			  <property name="angle">0</property>
-			</widget>
-			<packing>
-			  <property name="left_attach">0</property>
-			  <property name="right_attach">1</property>
-			  <property name="top_attach">1</property>
-			  <property name="bottom_attach">2</property>
-			  <property name="x_options">fill</property>
-			  <property name="y_options"></property>
-			</packing>
-		      </child>
-
-		      <child>
-			<widget class="GtkLabel" id="bd3Label">
-			  <property name="label" translatable="yes">Third BIOS drive:</property>
-			  <property name="use_underline">False</property>
-			  <property name="use_markup">False</property>
-			  <property name="justify">GTK_JUSTIFY_LEFT</property>
-			  <property name="wrap">False</property>
-			  <property name="selectable">False</property>
-			  <property name="xalign">0</property>
-			  <property name="yalign">0.5</property>
-			  <property name="xpad">0</property>
-			  <property name="ypad">0</property>
-			  <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
-			  <property name="width_chars">-1</property>
-			  <property name="single_line_mode">False</property>
-			  <property name="angle">0</property>
-			</widget>
-			<packing>
-			  <property name="left_attach">0</property>
-			  <property name="right_attach">1</property>
-			  <property name="top_attach">2</property>
-			  <property name="bottom_attach">3</property>
-			  <property name="x_options">fill</property>
-			  <property name="y_options"></property>
-			</packing>
-		      </child>
-
-		      <child>
-			<widget class="GtkLabel" id="bd4Label">
-			  <property name="label" translatable="yes">Fourth BIOS drive:</property>
-			  <property name="use_underline">False</property>
-			  <property name="use_markup">False</property>
-			  <property name="justify">GTK_JUSTIFY_LEFT</property>
-			  <property name="wrap">False</property>
-			  <property name="selectable">False</property>
-			  <property name="xalign">0</property>
-			  <property name="yalign">0.5</property>
-			  <property name="xpad">0</property>
-			  <property name="ypad">0</property>
-			  <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
-			  <property name="width_chars">-1</property>
-			  <property name="single_line_mode">False</property>
-			  <property name="angle">0</property>
-			</widget>
-			<packing>
-			  <property name="left_attach">0</property>
-			  <property name="right_attach">1</property>
-			  <property name="top_attach">3</property>
-			  <property name="bottom_attach">4</property>
-			  <property name="x_options">fill</property>
-			  <property name="y_options"></property>
-			</packing>
-		      </child>
-
-		      <child>
-			<widget class="GtkComboBox" id="bd2Combo">
-			  <property name="add_tearoffs">False</property>
-			  <property name="focus_on_click">True</property>
-			</widget>
-			<packing>
-			  <property name="left_attach">1</property>
-			  <property name="right_attach">2</property>
-			  <property name="top_attach">1</property>
-			  <property name="bottom_attach">2</property>
-			  <property name="x_options">fill</property>
-			  <property name="y_options">fill</property>
-			</packing>
-		      </child>
-
-		      <child>
-			<widget class="GtkComboBox" id="bd4Combo">
-			  <property name="add_tearoffs">False</property>
-			  <property name="focus_on_click">True</property>
-			</widget>
-			<packing>
-			  <property name="left_attach">1</property>
-			  <property name="right_attach">2</property>
-			  <property name="top_attach">3</property>
-			  <property name="bottom_attach">4</property>
-			  <property name="x_options">fill</property>
-			  <property name="y_options">fill</property>
-			</packing>
-		      </child>
-
-		      <child>
-			<widget class="GtkComboBox" id="bd3Combo">
-			  <property name="add_tearoffs">False</property>
-			  <property name="focus_on_click">True</property>
-			</widget>
-			<packing>
-			  <property name="left_attach">1</property>
-			  <property name="right_attach">2</property>
-			  <property name="top_attach">2</property>
-			  <property name="bottom_attach">3</property>
-			  <property name="x_options">fill</property>
-			  <property name="y_options">fill</property>
-			</packing>
-		      </child>
-
-		      <child>
-			<widget class="GtkComboBox" id="bd1Combo">
-			  <property name="visible">True</property>
-			  <property name="add_tearoffs">False</property>
-			  <property name="focus_on_click">True</property>
-			</widget>
-			<packing>
-			  <property name="left_attach">1</property>
-			  <property name="right_attach">2</property>
-			  <property name="top_attach">0</property>
-			  <property name="bottom_attach">1</property>
-			  <property name="x_options">fill</property>
-			  <property name="y_options">fill</property>
-			</packing>
-		      </child>
-		    </widget>
-		  </child>
-		</widget>
-	      </child>
-
-	      <child>
-		<widget class="GtkLabel" id="label2">
-		  <property name="visible">True</property>
-		  <property name="label" translatable="yes">BIOS Drive Order</property>
-		  <property name="use_underline">False</property>
-		  <property name="use_markup">False</property>
-		  <property name="justify">GTK_JUSTIFY_LEFT</property>
-		  <property name="wrap">False</property>
-		  <property name="selectable">False</property>
-		  <property name="xalign">0.5</property>
-		  <property name="yalign">0.5</property>
-		  <property name="xpad">0</property>
-		  <property name="ypad">0</property>
-		  <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
-		  <property name="width_chars">-1</property>
-		  <property name="single_line_mode">False</property>
-		  <property name="angle">0</property>
-		</widget>
-		<packing>
-		  <property name="type">label_item</property>
-		</packing>
-	      </child>
-	    </widget>
-	    <packing>
-	      <property name="padding">0</property>
-	      <property name="expand">True</property>
-	      <property name="fill">True</property>
-	    </packing>
-	  </child>
-	</widget>
-	<packing>
-	  <property name="padding">0</property>
-	  <property name="expand">True</property>
-	  <property name="fill">True</property>
-	</packing>
-      </child>
-    </widget>
-  </child>
-</widget>
-
-</glade-interface>
diff --git a/ui/cleardisks.glade b/ui/cleardisks.glade
deleted file mode 100644
index f8c9b15..0000000
--- a/ui/cleardisks.glade
+++ /dev/null
@@ -1,300 +0,0 @@
-<?xml version="1.0" standalone="no"?> <!--*- mode: xml -*-->
-<!DOCTYPE glade-interface SYSTEM "http://glade.gnome.org/glade-2.0.dtd";>
-
-<glade-interface>
-
-<widget class="GtkWindow" id="cleardisksWindow">
-  <property name="border_width">6</property>
-  <property name="width_request">600</property>
-  <property name="title" translatable="yes" context="yes"></property>
-  <property name="type">GTK_WINDOW_TOPLEVEL</property>
-  <property name="window_position">GTK_WIN_POS_NONE</property>
-  <property name="modal">False</property>
-  <property name="resizable">True</property>
-  <property name="destroy_with_parent">False</property>
-  <property name="decorated">True</property>
-  <property name="skip_taskbar_hint">False</property>
-  <property name="skip_pager_hint">False</property>
-  <property name="type_hint">GDK_WINDOW_TYPE_HINT_NORMAL</property>
-  <property name="gravity">GDK_GRAVITY_NORTH_WEST</property>
-  <property name="focus_on_map">True</property>
-  <property name="urgency_hint">False</property>
-
-  <child>
-    <widget class="GtkVBox" id="vbox">
-      <property name="visible">True</property>
-      <property name="homogeneous">False</property>
-      <property name="spacing">12</property>
-
-      <child>
-	<widget class="GtkLabel" id="label1">
-	  <property name="width_request">600</property>
-	  <property name="visible">True</property>
-	  <property name="label" translatable="yes">Below are the storage devices you've selected to be a part of this installation.  Please indicate using the arrows below which devices you'd like to use as data devices (these will not be formatted, only mounted) and which devices you'd like to use as installation target devices (these may be formatted).  Please also indicate which system drive will have the bootloader installed.</property>
-	  <property name="use_underline">False</property>
-	  <property name="use_markup">False</property>
-	  <property name="justify">GTK_JUSTIFY_LEFT</property>
-	  <property name="wrap">True</property>
-	  <property name="selectable">False</property>
-	  <property name="xalign">0</property>
-	  <property name="yalign">0</property>
-	  <property name="xpad">0</property>
-	  <property name="ypad">0</property>
-	  <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
-	  <property name="width_chars">-1</property>
-	  <property name="single_line_mode">False</property>
-	  <property name="angle">0</property>
-	</widget>
-	<packing>
-	  <property name="padding">0</property>
-	  <property name="expand">False</property>
-	  <property name="fill">False</property>
-	</packing>
-      </child>
-
-      <child>
-	<widget class="GtkHBox" id="hbox2">
-	  <property name="visible">True</property>
-	  <property name="homogeneous">False</property>
-	  <property name="spacing">6</property>
-
-	  <child>
-	    <widget class="GtkVBox" id="vbox1">
-	      <property name="visible">True</property>
-	      <property name="homogeneous">False</property>
-	      <property name="spacing">0</property>
-
-	      <child>
-		<widget class="GtkLabel" id="label4">
-		  <property name="visible">True</property>
-		  <property name="label" translatable="yes">&lt;b&gt;Data Storage Devices&lt;/b&gt; (to be mounted only)</property>
-		  <property name="use_underline">False</property>
-		  <property name="use_markup">True</property>
-		  <property name="justify">GTK_JUSTIFY_LEFT</property>
-		  <property name="wrap">False</property>
-		  <property name="selectable">False</property>
-		  <property name="xalign">0</property>
-		  <property name="yalign">0.5</property>
-		  <property name="xpad">0</property>
-		  <property name="ypad">0</property>
-		  <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
-		  <property name="width_chars">-1</property>
-		  <property name="single_line_mode">False</property>
-		  <property name="angle">0</property>
-		</widget>
-		<packing>
-		  <property name="padding">0</property>
-		  <property name="expand">False</property>
-		  <property name="fill">False</property>
-		</packing>
-	      </child>
-
-	      <child>
-		<widget class="GtkScrolledWindow" id="leftScroll">
-		  <property name="visible">True</property>
-		  <property name="can_focus">True</property>
-		  <property name="hscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
-		  <property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
-		  <property name="shadow_type">GTK_SHADOW_ETCHED_IN</property>
-		  <property name="window_placement">GTK_CORNER_TOP_LEFT</property>
-
-		  <child>
-		    <placeholder/>
-		  </child>
-		</widget>
-		<packing>
-		  <property name="padding">0</property>
-		  <property name="expand">True</property>
-		  <property name="fill">True</property>
-		</packing>
-	      </child>
-	    </widget>
-	    <packing>
-	      <property name="padding">0</property>
-	      <property name="expand">True</property>
-	      <property name="fill">True</property>
-	    </packing>
-	  </child>
-
-	  <child>
-	    <widget class="GtkVButtonBox" id="vbuttonbox1">
-	      <property name="visible">True</property>
-	      <property name="layout_style">GTK_BUTTONBOX_SPREAD</property>
-	      <property name="spacing">0</property>
-
-	      <child>
-		<widget class="GtkButton" id="addButton">
-		  <property name="visible">True</property>
-		  <property name="can_default">True</property>
-		  <property name="can_focus">True</property>
-		  <property name="relief">GTK_RELIEF_NORMAL</property>
-		  <property name="focus_on_click">True</property>
-
-		  <child>
-		    <widget class="GtkImage" id="image3">
-		      <property name="visible">True</property>
-		      <property name="stock">gtk-go-forward</property>
-		      <property name="icon_size">4</property>
-		      <property name="xalign">0.5</property>
-		      <property name="yalign">0.5</property>
-		      <property name="xpad">0</property>
-		      <property name="ypad">0</property>
-		    </widget>
-		  </child>
-		</widget>
-	      </child>
-
-	      <child>
-		<widget class="GtkButton" id="removeButton">
-		  <property name="visible">True</property>
-		  <property name="can_default">True</property>
-		  <property name="can_focus">True</property>
-		  <property name="relief">GTK_RELIEF_NORMAL</property>
-		  <property name="focus_on_click">True</property>
-
-		  <child>
-		    <widget class="GtkImage" id="image2">
-		      <property name="visible">True</property>
-		      <property name="stock">gtk-go-back</property>
-		      <property name="icon_size">4</property>
-		      <property name="xalign">0.5</property>
-		      <property name="yalign">0.5</property>
-		      <property name="xpad">0</property>
-		      <property name="ypad">0</property>
-		    </widget>
-		  </child>
-		</widget>
-	      </child>
-	    </widget>
-	    <packing>
-	      <property name="padding">0</property>
-	      <property name="expand">False</property>
-	      <property name="fill">False</property>
-	    </packing>
-	  </child>
-
-	  <child>
-	    <widget class="GtkVBox" id="vbox2">
-	      <property name="visible">True</property>
-	      <property name="homogeneous">False</property>
-	      <property name="spacing">0</property>
-
-	      <child>
-		<widget class="GtkLabel" id="label5">
-		  <property name="visible">True</property>
-		  <property name="label" translatable="yes">&lt;b&gt;Install Target Devices&lt;/b&gt;</property>
-		  <property name="use_underline">False</property>
-		  <property name="use_markup">True</property>
-		  <property name="justify">GTK_JUSTIFY_LEFT</property>
-		  <property name="wrap">False</property>
-		  <property name="selectable">False</property>
-		  <property name="xalign">0</property>
-		  <property name="yalign">0.5</property>
-		  <property name="xpad">0</property>
-		  <property name="ypad">0</property>
-		  <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
-		  <property name="width_chars">-1</property>
-		  <property name="single_line_mode">False</property>
-		  <property name="angle">0</property>
-		</widget>
-		<packing>
-		  <property name="padding">0</property>
-		  <property name="expand">False</property>
-		  <property name="fill">False</property>
-		</packing>
-	      </child>
-
-	      <child>
-		<widget class="GtkScrolledWindow" id="rightScroll">
-		  <property name="visible">True</property>
-		  <property name="can_focus">True</property>
-		  <property name="hscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
-		  <property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
-		  <property name="shadow_type">GTK_SHADOW_ETCHED_IN</property>
-		  <property name="window_placement">GTK_CORNER_TOP_LEFT</property>
-
-		  <child>
-		    <placeholder/>
-		  </child>
-		</widget>
-		<packing>
-		  <property name="padding">0</property>
-		  <property name="expand">True</property>
-		  <property name="fill">True</property>
-		</packing>
-	      </child>
-	    </widget>
-	    <packing>
-	      <property name="padding">0</property>
-	      <property name="expand">True</property>
-	      <property name="fill">True</property>
-	    </packing>
-	  </child>
-	</widget>
-	<packing>
-	  <property name="padding">0</property>
-	  <property name="expand">True</property>
-	  <property name="fill">True</property>
-	</packing>
-      </child>
-
-      <child>
-	<widget class="GtkHBox" id="installTargetHBox">
-	  <property name="visible">True</property>
-	  <property name="homogeneous">False</property>
-	  <property name="spacing">0</property>
-
-	  <child>
-	    <widget class="GtkImage" id="installTargetImage">
-	      <property name="visible">True</property>
-	      <property name="stock">gtk-dialog-info</property>
-	      <property name="icon_size">4</property>
-	      <property name="xalign">0.5</property>
-	      <property name="yalign">0</property>
-	      <property name="xpad">0</property>
-	      <property name="ypad">0</property>
-	    </widget>
-	    <packing>
-	      <property name="padding">0</property>
-	      <property name="expand">False</property>
-	      <property name="fill">False</property>
-	    </packing>
-	  </child>
-
-	  <child>
-	    <widget class="GtkLabel" id="installTargetTip">
-	      <property name="width_request">600</property>
-	      <property name="visible">True</property>
-	      <property name="label" translatable="yes">&lt;b&gt;Tip:&lt;/b&gt; Install target devices will be reformatted and wiped of any data.  Make sure you have backups.</property>
-	      <property name="use_underline">False</property>
-	      <property name="use_markup">True</property>
-	      <property name="justify">GTK_JUSTIFY_LEFT</property>
-	      <property name="wrap">True</property>
-	      <property name="selectable">False</property>
-	      <property name="xalign">0</property>
-	      <property name="yalign">0</property>
-	      <property name="xpad">0</property>
-	      <property name="ypad">0</property>
-	      <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
-	      <property name="width_chars">-1</property>
-	      <property name="single_line_mode">False</property>
-	      <property name="angle">0</property>
-	    </widget>
-	    <packing>
-	      <property name="padding">0</property>
-	      <property name="expand">False</property>
-	      <property name="fill">False</property>
-	    </packing>
-	  </child>
-	</widget>
-	<packing>
-	  <property name="padding">0</property>
-	  <property name="expand">False</property>
-	  <property name="fill">False</property>
-	</packing>
-      </child>
-    </widget>
-  </child>
-</widget>
-
-</glade-interface>
diff --git a/ui/create-storage.glade b/ui/create-storage.glade
deleted file mode 100644
index 98db7d7..0000000
--- a/ui/create-storage.glade
+++ /dev/null
@@ -1,379 +0,0 @@
-<?xml version="1.0"?>
-<glade-interface>
-  <!-- interface-requires gtk+ 2.10 -->
-  <!-- interface-naming-policy toplevel-contextual -->
-  <widget class="GtkDialog" id="create_storage_dialog">
-    <property name="visible">True</property>
-    <property name="title" translatable="yes">Create Storage</property>
-    <property name="modal">True</property>
-    <property name="window_position">center-always</property>
-    <property name="type_hint">dialog</property>
-    <child internal-child="vbox">
-      <widget class="GtkVBox" id="dialog-vbox1">
-        <property name="visible">True</property>
-        <property name="orientation">vertical</property>
-        <property name="spacing">2</property>
-        <child>
-          <widget class="GtkVBox" id="vbox1">
-            <property name="visible">True</property>
-            <property name="orientation">vertical</property>
-            <child>
-              <widget class="GtkHBox" id="hbox1">
-                <property name="visible">True</property>
-                <child>
-                  <widget class="GtkLabel" id="label1">
-                    <property name="visible">True</property>
-                    <property name="xalign">0</property>
-                    <property name="xpad">2</property>
-                    <property name="label" translatable="yes">Create Partition</property>
-                  </widget>
-                  <packing>
-                    <property name="position">0</property>
-                  </packing>
-                </child>
-                <child>
-                  <placeholder/>
-                </child>
-              </widget>
-              <packing>
-                <property name="position">0</property>
-              </packing>
-            </child>
-            <child>
-              <widget class="GtkVBox" id="vbox2">
-                <property name="visible">True</property>
-                <property name="orientation">vertical</property>
-                <child>
-                  <widget class="GtkRadioButton" id="create_storage_rb_standard_part">
-                    <property name="label" translatable="yes">Standard Partition</property>
-                    <property name="visible">True</property>
-                    <property name="sensitive">False</property>
-                    <property name="can_focus">True</property>
-                    <property name="receives_default">False</property>
-                    <property name="draw_indicator">True</property>
-                  </widget>
-                  <packing>
-                    <property name="position">0</property>
-                  </packing>
-                </child>
-                <child>
-                  <widget class="GtkLabel" id="label4">
-                    <property name="visible">True</property>
-                    <property name="xalign">0</property>
-                    <property name="xpad">20</property>
-                    <property name="label" translatable="yes">&lt;span size="small" color="gray"&gt;General purpose partition creation&lt;/span&gt;</property>
-                    <property name="use_markup">True</property>
-                  </widget>
-                  <packing>
-                    <property name="position">1</property>
-                  </packing>
-                </child>
-              </widget>
-              <packing>
-                <property name="position">1</property>
-              </packing>
-            </child>
-            <child>
-              <widget class="GtkHBox" id="hbox2">
-                <property name="visible">True</property>
-                <child>
-                  <widget class="GtkLabel" id="label2">
-                    <property name="visible">True</property>
-                    <property name="xalign">0</property>
-                    <property name="xpad">2</property>
-                    <property name="label" translatable="yes">Create Software RAID</property>
-                  </widget>
-                  <packing>
-                    <property name="position">0</property>
-                  </packing>
-                </child>
-                <child>
-                  <widget class="GtkLinkButton" id="create_storage_info_raid">
-                    <property name="label">gtk-info</property>
-                    <property name="visible">True</property>
-                    <property name="can_focus">True</property>
-                    <property name="receives_default">True</property>
-                    <property name="has_tooltip">True</property>
-                    <property name="relief">none</property>
-                    <property name="use_stock">True</property>
-                    <property name="xalign">1</property>
-                  </widget>
-                  <packing>
-                    <property name="expand">False</property>
-                    <property name="position">1</property>
-                  </packing>
-                </child>
-              </widget>
-              <packing>
-                <property name="position">2</property>
-              </packing>
-            </child>
-            <child>
-              <widget class="GtkVBox" id="vbox3">
-                <property name="visible">True</property>
-                <property name="orientation">vertical</property>
-                <child>
-                  <widget class="GtkRadioButton" id="create_storage_rb_raid_part">
-                    <property name="label" translatable="yes">RAID Partition</property>
-                    <property name="visible">True</property>
-                    <property name="sensitive">False</property>
-                    <property name="can_focus">True</property>
-                    <property name="receives_default">False</property>
-                    <property name="draw_indicator">True</property>
-                    <property name="group">create_storage_rb_standard_part</property>
-                  </widget>
-                  <packing>
-                    <property name="position">0</property>
-                  </packing>
-                </child>
-                <child>
-                  <widget class="GtkLabel" id="label5">
-                    <property name="visible">True</property>
-                    <property name="xalign">0</property>
-                    <property name="xpad">20</property>
-                    <property name="label" translatable="yes">&lt;span size="small" color="gray"&gt;Create a RAID formatted partition&lt;/span&gt;</property>
-                    <property name="use_markup">True</property>
-                  </widget>
-                  <packing>
-                    <property name="position">1</property>
-                  </packing>
-                </child>
-              </widget>
-              <packing>
-                <property name="position">3</property>
-              </packing>
-            </child>
-            <child>
-              <widget class="GtkVBox" id="vbox4">
-                <property name="visible">True</property>
-                <property name="orientation">vertical</property>
-                <child>
-                  <widget class="GtkRadioButton" id="create_storage_rb_raid_dev">
-                    <property name="label" translatable="yes">RAID Device</property>
-                    <property name="visible">True</property>
-                    <property name="sensitive">False</property>
-                    <property name="can_focus">True</property>
-                    <property name="receives_default">False</property>
-                    <property name="draw_indicator">True</property>
-                    <property name="group">create_storage_rb_standard_part</property>
-                  </widget>
-                  <packing>
-                    <property name="position">0</property>
-                  </packing>
-                </child>
-                <child>
-                  <widget class="GtkLabel" id="label6">
-                    <property name="visible">True</property>
-                    <property name="xalign">0</property>
-                    <property name="xpad">20</property>
-                    <property name="label" translatable="yes">&lt;span size="small" color="gray"&gt;Requires at least 2 free RAID formatted partitions&lt;/span&gt;</property>
-                    <property name="use_markup">True</property>
-                  </widget>
-                  <packing>
-                    <property name="position">1</property>
-                  </packing>
-                </child>
-              </widget>
-              <packing>
-                <property name="position">4</property>
-              </packing>
-            </child>
-            <child>
-              <widget class="GtkHBox" id="hbox3">
-                <property name="visible">True</property>
-                <child>
-                  <widget class="GtkLabel" id="label3">
-                    <property name="visible">True</property>
-                    <property name="xalign">0</property>
-                    <property name="xpad">2</property>
-                    <property name="label" translatable="yes">Create LVM</property>
-                  </widget>
-                  <packing>
-                    <property name="position">0</property>
-                  </packing>
-                </child>
-                <child>
-                  <widget class="GtkLinkButton" id="create_storage_info_lvm">
-                    <property name="label">gtk-info</property>
-                    <property name="visible">True</property>
-                    <property name="can_focus">True</property>
-                    <property name="receives_default">True</property>
-                    <property name="has_tooltip">True</property>
-                    <property name="relief">none</property>
-                    <property name="use_stock">True</property>
-                    <property name="xalign">1</property>
-                  </widget>
-                  <packing>
-                    <property name="expand">False</property>
-                    <property name="position">1</property>
-                  </packing>
-                </child>
-              </widget>
-              <packing>
-                <property name="position">5</property>
-              </packing>
-            </child>
-            <child>
-              <widget class="GtkVBox" id="vbox6">
-                <property name="visible">True</property>
-                <property name="orientation">vertical</property>
-                <child>
-                  <widget class="GtkRadioButton" id="create_storage_rb_lvm_vg">
-                    <property name="label" translatable="yes">LVM Volume Group</property>
-                    <property name="visible">True</property>
-                    <property name="sensitive">False</property>
-                    <property name="can_focus">True</property>
-                    <property name="receives_default">False</property>
-                    <property name="draw_indicator">True</property>
-                    <property name="group">create_storage_rb_standard_part</property>
-                  </widget>
-                  <packing>
-                    <property name="position">0</property>
-                  </packing>
-                </child>
-                <child>
-                  <widget class="GtkLabel" id="label8">
-                    <property name="visible">True</property>
-                    <property name="xalign">0</property>
-                    <property name="xpad">20</property>
-                    <property name="label" translatable="yes">&lt;span size="small" color="gray"&gt;Requires at least 1 free LVM formatted partition&lt;/span&gt;</property>
-                    <property name="use_markup">True</property>
-                  </widget>
-                  <packing>
-                    <property name="position">1</property>
-                  </packing>
-                </child>
-              </widget>
-              <packing>
-                <property name="position">6</property>
-              </packing>
-            </child>
-            <child>
-              <widget class="GtkVBox" id="vbox7">
-                <property name="visible">True</property>
-                <property name="orientation">vertical</property>
-                <child>
-                  <widget class="GtkHBox" id="create_storage_hb_lvm_lv">
-                    <property name="visible">True</property>
-                    <child>
-                      <widget class="GtkRadioButton" id="create_storage_rb_lvm_lv">
-                        <property name="label" translatable="yes">LVM Logical Volume</property>
-                        <property name="visible">True</property>
-                        <property name="sensitive">False</property>
-                        <property name="can_focus">True</property>
-                        <property name="receives_default">False</property>
-                        <property name="draw_indicator">True</property>
-                        <property name="group">create_storage_rb_standard_part</property>
-                      </widget>
-                      <packing>
-                        <property name="position">0</property>
-                      </packing>
-                    </child>
-                    <child>
-                      <placeholder/>
-                    </child>
-                  </widget>
-                  <packing>
-                    <property name="position">0</property>
-                  </packing>
-                </child>
-                <child>
-                  <widget class="GtkLabel" id="label9">
-                    <property name="visible">True</property>
-                    <property name="xalign">0</property>
-                    <property name="xpad">20</property>
-                    <property name="label" translatable="yes">&lt;span size="small" color="gray"&gt;Create a logical volume on selected volume group&lt;/span&gt;</property>
-                    <property name="use_markup">True</property>
-                  </widget>
-                  <packing>
-                    <property name="position">1</property>
-                  </packing>
-                </child>
-              </widget>
-              <packing>
-                <property name="position">7</property>
-              </packing>
-            </child>
-            <child>
-              <widget class="GtkVBox" id="vbox8">
-                <property name="visible">True</property>
-                <property name="orientation">vertical</property>
-                <child>
-                  <widget class="GtkRadioButton" id="create_storage_rb_lvm_part">
-                    <property name="label" translatable="yes">LVM Physical Volume</property>
-                    <property name="visible">True</property>
-                    <property name="sensitive">False</property>
-                    <property name="can_focus">True</property>
-                    <property name="receives_default">False</property>
-                    <property name="draw_indicator">True</property>
-                    <property name="group">create_storage_rb_standard_part</property>
-                  </widget>
-                  <packing>
-                    <property name="position">0</property>
-                  </packing>
-                </child>
-                <child>
-                  <widget class="GtkLabel" id="label10">
-                    <property name="visible">True</property>
-                    <property name="xalign">0</property>
-                    <property name="xpad">20</property>
-                    <property name="label" translatable="yes">&lt;span size="small" color="gray"&gt;Create an LVM formatted partition&lt;/span&gt;</property>
-                    <property name="use_markup">True</property>
-                  </widget>
-                  <packing>
-                    <property name="position">1</property>
-                  </packing>
-                </child>
-              </widget>
-              <packing>
-                <property name="position">8</property>
-              </packing>
-            </child>
-          </widget>
-          <packing>
-            <property name="position">1</property>
-          </packing>
-        </child>
-        <child internal-child="action_area">
-          <widget class="GtkHButtonBox" id="dialog-action_area1">
-            <property name="visible">True</property>
-            <property name="layout_style">end</property>
-            <child>
-              <widget class="GtkButton" id="storage_create_button_cancel">
-                <property name="label">gtk-cancel</property>
-                <property name="visible">True</property>
-                <property name="can_focus">True</property>
-                <property name="receives_default">True</property>
-                <property name="use_stock">True</property>
-              </widget>
-              <packing>
-                <property name="expand">False</property>
-                <property name="fill">False</property>
-                <property name="position">0</property>
-              </packing>
-            </child>
-            <child>
-              <widget class="GtkButton" id="storage_create_button_create">
-                <property name="label" translatable="yes">Create</property>
-                <property name="response_id">1</property>
-                <property name="visible">True</property>
-                <property name="can_focus">True</property>
-                <property name="receives_default">True</property>
-              </widget>
-              <packing>
-                <property name="expand">False</property>
-                <property name="fill">False</property>
-                <property name="position">1</property>
-              </packing>
-            </child>
-          </widget>
-          <packing>
-            <property name="expand">False</property>
-            <property name="pack_type">end</property>
-            <property name="position">0</property>
-          </packing>
-        </child>
-      </widget>
-    </child>
-  </widget>
-</glade-interface>
diff --git a/ui/detailed-dialog.glade b/ui/detailed-dialog.glade
deleted file mode 100644
index 7c69656..0000000
--- a/ui/detailed-dialog.glade
+++ /dev/null
@@ -1,171 +0,0 @@
-<?xml version="1.0" standalone="no"?> <!--*- mode: xml -*-->
-<!DOCTYPE glade-interface SYSTEM "http://glade.gnome.org/glade-2.0.dtd";>
-
-<glade-interface>
-
-<widget class="GtkDialog" id="detailedDialog">
-  <property name="visible">True</property>
-  <property name="title"></property>
-  <property name="type">GTK_WINDOW_TOPLEVEL</property>
-  <property name="window_position">GTK_WIN_POS_CENTER</property>
-  <property name="modal">True</property>
-  <property name="default_width">550</property>
-  <property name="default_height">400</property>
-  <property name="resizable">True</property>
-  <property name="destroy_with_parent">False</property>
-  <property name="decorated">True</property>
-  <property name="skip_taskbar_hint">False</property>
-  <property name="skip_pager_hint">False</property>
-  <property name="type_hint">GDK_WINDOW_TYPE_HINT_DIALOG</property>
-  <property name="gravity">GDK_GRAVITY_NORTH_WEST</property>
-  <property name="focus_on_map">True</property>
-  <property name="urgency_hint">False</property>
-  <property name="has_separator">True</property>
-
-  <child internal-child="vbox">
-    <widget class="GtkVBox" id="detailedDialog-vbox">
-      <property name="visible">True</property>
-      <property name="homogeneous">False</property>
-      <property name="spacing">12</property>
-
-      <child internal-child="action_area">
-	<widget class="GtkHButtonBox" id="buttonBox">
-	  <property name="visible">True</property>
-	  <property name="layout_style">GTK_BUTTONBOX_END</property>
-	</widget>
-	<packing>
-	  <property name="padding">0</property>
-	  <property name="expand">False</property>
-	  <property name="fill">True</property>
-	  <property name="pack_type">GTK_PACK_END</property>
-	</packing>
-      </child>
-
-      <child>
-	<widget class="GtkVBox" id="mainVBox">
-	  <property name="visible">True</property>
-	  <property name="homogeneous">False</property>
-	  <property name="spacing">12</property>
-
-	  <child>
-	    <widget class="GtkHBox" id="hbox1">
-	      <property name="visible">True</property>
-	      <property name="homogeneous">False</property>
-	      <property name="spacing">6</property>
-
-	      <child>
-		<placeholder/>
-	      </child>
-
-	      <child>
-		<widget class="GtkLabel" id="info">
-		  <property name="visible">True</property>
-		  <property name="label" translatable="yes">Info</property>
-		  <property name="use_underline">False</property>
-		  <property name="use_markup">False</property>
-		  <property name="justify">GTK_JUSTIFY_LEFT</property>
-		  <property name="wrap">True</property>
-		  <property name="selectable">False</property>
-		  <property name="xalign">0</property>
-		  <property name="yalign">0.5</property>
-		  <property name="xpad">0</property>
-		  <property name="ypad">0</property>
-		  <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
-		  <property name="width_chars">-1</property>
-		  <property name="single_line_mode">False</property>
-		  <property name="angle">0</property>
-		</widget>
-		<packing>
-		  <property name="padding">0</property>
-		  <property name="expand">True</property>
-		  <property name="fill">True</property>
-		</packing>
-	      </child>
-	    </widget>
-	    <packing>
-	      <property name="padding">0</property>
-	      <property name="expand">False</property>
-	      <property name="fill">False</property>
-	    </packing>
-	  </child>
-
-	  <child>
-	    <widget class="GtkExpander" id="detailedExpander">
-	      <property name="visible">True</property>
-	      <property name="can_focus">True</property>
-	      <property name="expanded">False</property>
-	      <property name="spacing">0</property>
-
-	      <child>
-		<widget class="GtkScrolledWindow" id="scrolledwindow2">
-		  <property name="visible">True</property>
-		  <property name="can_focus">True</property>
-		  <property name="hscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
-		  <property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
-		  <property name="shadow_type">GTK_SHADOW_IN</property>
-		  <property name="window_placement">GTK_CORNER_TOP_LEFT</property>
-
-		  <child>
-		    <widget class="GtkTextView" id="detailedView">
-		      <property name="visible">True</property>
-		      <property name="can_focus">True</property>
-		      <property name="editable">False</property>
-		      <property name="overwrite">False</property>
-		      <property name="accepts_tab">True</property>
-		      <property name="justification">GTK_JUSTIFY_LEFT</property>
-		      <property name="wrap_mode">GTK_WRAP_NONE</property>
-		      <property name="cursor_visible">False</property>
-		      <property name="pixels_above_lines">0</property>
-		      <property name="pixels_below_lines">0</property>
-		      <property name="pixels_inside_wrap">0</property>
-		      <property name="left_margin">0</property>
-		      <property name="right_margin">0</property>
-		      <property name="indent">0</property>
-		      <property name="text" translatable="yes"></property>
-		    </widget>
-		  </child>
-		</widget>
-	      </child>
-
-	      <child>
-		<widget class="GtkLabel" id="label1">
-		  <property name="visible">True</property>
-		  <property name="label" translatable="yes">_Details</property>
-		  <property name="use_underline">True</property>
-		  <property name="use_markup">False</property>
-		  <property name="justify">GTK_JUSTIFY_LEFT</property>
-		  <property name="wrap">False</property>
-		  <property name="selectable">False</property>
-		  <property name="xalign">0.5</property>
-		  <property name="yalign">0.5</property>
-		  <property name="xpad">0</property>
-		  <property name="ypad">0</property>
-		  <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
-		  <property name="width_chars">-1</property>
-		  <property name="single_line_mode">False</property>
-		  <property name="angle">0</property>
-		</widget>
-		<packing>
-		  <property name="type">label_item</property>
-		</packing>
-	      </child>
-	    </widget>
-	    <packing>
-	      <property name="padding">0</property>
-	      <property name="expand">True</property>
-	      <property name="fill">True</property>
-	      <property name="pack_type">GTK_PACK_END</property>
-	    </packing>
-	  </child>
-	</widget>
-	<packing>
-	  <property name="padding">0</property>
-	  <property name="expand">True</property>
-	  <property name="fill">True</property>
-	</packing>
-      </child>
-    </widget>
-  </child>
-</widget>
-
-</glade-interface>
diff --git a/ui/fcoe-config.glade b/ui/fcoe-config.glade
deleted file mode 100644
index 57c72ab..0000000
--- a/ui/fcoe-config.glade
+++ /dev/null
@@ -1,130 +0,0 @@
-<?xml version="1.0"?>
-<glade-interface>
-  <!-- interface-requires gtk+ 2.16 -->
-  <!-- interface-naming-policy toplevel-contextual -->
-  <widget class="GtkDialog" id="fcoeDialog">
-    <property name="title" translatable="yes">Configure FCoE Parameters</property>
-    <property name="window_position">center</property>
-    <property name="type_hint">dialog</property>
-    <child internal-child="vbox">
-      <widget class="GtkVBox" id="dialog-vbox1">
-        <property name="visible">True</property>
-        <property name="orientation">vertical</property>
-        <child>
-          <widget class="GtkVBox" id="vbox1">
-            <property name="visible">True</property>
-            <property name="border_width">12</property>
-            <property name="orientation">vertical</property>
-            <property name="spacing">12</property>
-            <child>
-              <widget class="GtkLabel" id="label3">
-                <property name="visible">True</property>
-                <property name="label" translatable="yes">Please select the network interface which is connected to
-your FCoE switch.</property>
-                <property name="wrap">True</property>
-              </widget>
-              <packing>
-                <property name="expand">False</property>
-                <property name="fill">False</property>
-                <property name="position">0</property>
-              </packing>
-            </child>
-            <child>
-              <widget class="GtkHBox" id="hbox2">
-                <property name="visible">True</property>
-                <child>
-                  <widget class="GtkLabel" id="label1">
-                    <property name="visible">True</property>
-                    <property name="label" translatable="yes">NIC:</property>
-                  </widget>
-                  <packing>
-                    <property name="expand">False</property>
-                    <property name="position">0</property>
-                  </packing>
-                </child>
-                <child>
-                  <widget class="GtkComboBox" id="fcoeNicCombo">
-                    <property name="visible">True</property>
-                  </widget>
-                  <packing>
-                    <property name="expand">False</property>
-                    <property name="position">1</property>
-                  </packing>
-                </child>
-              </widget>
-              <packing>
-                <property name="expand">False</property>
-                <property name="position">1</property>
-              </packing>
-            </child>
-            <child>
-              <widget class="GtkCheckButton" id="dcbCheckbutton">
-                <property name="label" translatable="yes">Use DCB</property>
-                <property name="visible">True</property>
-                <property name="can_focus">True</property>
-                <property name="receives_default">False</property>
-                <property name="active">True</property>
-                <property name="draw_indicator">True</property>
-              </widget>
-              <packing>
-                <property name="expand">False</property>
-                <property name="position">2</property>
-              </packing>
-            </child>
-          </widget>
-          <packing>
-            <property name="position">2</property>
-          </packing>
-        </child>
-        <child internal-child="action_area">
-          <widget class="GtkHButtonBox" id="dialog-action_area1">
-            <property name="visible">True</property>
-            <property name="layout_style">end</property>
-            <child>
-              <widget class="GtkButton" id="button1">
-                <property name="label">gtk-cancel</property>
-                <property name="response_id">-6</property>
-                <property name="visible">True</property>
-                <property name="can_focus">True</property>
-                <property name="can_default">True</property>
-                <property name="receives_default">False</property>
-                <property name="use_stock">True</property>
-              </widget>
-              <packing>
-                <property name="expand">False</property>
-                <property name="fill">False</property>
-                <property name="position">0</property>
-              </packing>
-            </child>
-            <child>
-              <widget class="GtkButton" id="button2">
-                <property name="response_id">-10</property>
-                <property name="visible">True</property>
-                <property name="can_focus">True</property>
-                <property name="can_default">True</property>
-                <property name="receives_default">False</property>
-                <child>
-                  <widget class="GtkLabel" id="label6">
-                    <property name="visible">True</property>
-                    <property name="label" translatable="yes">_Add FCoE Disk(s)</property>
-                    <property name="use_underline">True</property>
-                  </widget>
-                </child>
-              </widget>
-              <packing>
-                <property name="expand">False</property>
-                <property name="fill">False</property>
-                <property name="position">1</property>
-              </packing>
-            </child>
-          </widget>
-          <packing>
-            <property name="expand">False</property>
-            <property name="pack_type">end</property>
-            <property name="position">0</property>
-          </packing>
-        </child>
-      </widget>
-    </child>
-  </widget>
-</glade-interface>
diff --git a/ui/filter.glade b/ui/filter.glade
deleted file mode 100644
index c8c2ba8..0000000
--- a/ui/filter.glade
+++ /dev/null
@@ -1,1387 +0,0 @@
-<?xml version="1.0" standalone="no"?> <!--*- mode: xml -*-->
-<!DOCTYPE glade-interface SYSTEM "http://glade.gnome.org/glade-2.0.dtd";>
-
-<glade-interface>
-
-<widget class="GtkWindow" id="advancedFilterWindow">
-  <property name="border_width">6</property>
-  <property name="title" translatable="yes" context="yes"></property>
-  <property name="type">GTK_WINDOW_TOPLEVEL</property>
-  <property name="window_position">GTK_WIN_POS_NONE</property>
-  <property name="modal">False</property>
-  <property name="resizable">True</property>
-  <property name="destroy_with_parent">False</property>
-  <property name="decorated">True</property>
-  <property name="skip_taskbar_hint">False</property>
-  <property name="skip_pager_hint">False</property>
-  <property name="type_hint">GDK_WINDOW_TYPE_HINT_NORMAL</property>
-  <property name="gravity">GDK_GRAVITY_NORTH_WEST</property>
-  <property name="focus_on_map">True</property>
-  <property name="urgency_hint">False</property>
-
-  <child>
-    <widget class="GtkVBox" id="vbox">
-      <property name="visible">True</property>
-      <property name="homogeneous">False</property>
-      <property name="spacing">6</property>
-
-      <child>
-	<widget class="GtkLabel" id="label1">
-	  <property name="width_request">600</property>
-	  <property name="visible">True</property>
-	  <property name="label" translatable="yes">Please select the drives you'd like to install the operating system on, as well as any drives you'd like to automatically mount on your system:</property>
-	  <property name="use_underline">False</property>
-	  <property name="use_markup">False</property>
-	  <property name="justify">GTK_JUSTIFY_LEFT</property>
-	  <property name="wrap">True</property>
-	  <property name="selectable">False</property>
-	  <property name="xalign">0</property>
-	  <property name="yalign">0</property>
-	  <property name="xpad">0</property>
-	  <property name="ypad">0</property>
-	  <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
-	  <property name="width_chars">-1</property>
-	  <property name="single_line_mode">False</property>
-	  <property name="angle">0</property>
-	</widget>
-	<packing>
-	  <property name="padding">0</property>
-	  <property name="expand">False</property>
-	  <property name="fill">False</property>
-	</packing>
-      </child>
-
-      <child>
-	<widget class="GtkNotebook" id="notebook">
-	  <property name="visible">True</property>
-	  <property name="can_focus">True</property>
-	  <property name="show_tabs">True</property>
-	  <property name="show_border">True</property>
-	  <property name="tab_pos">GTK_POS_TOP</property>
-	  <property name="scrollable">False</property>
-	  <property name="enable_popup">False</property>
-
-	  <child>
-	    <widget class="GtkScrolledWindow" id="basicScroll">
-	      <property name="visible">True</property>
-	      <property name="can_focus">True</property>
-	      <property name="hscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
-	      <property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
-	      <property name="shadow_type">GTK_SHADOW_ETCHED_IN</property>
-	      <property name="window_placement">GTK_CORNER_TOP_LEFT</property>
-
-	      <child>
-		<placeholder/>
-	      </child>
-	    </widget>
-	    <packing>
-	      <property name="tab_expand">False</property>
-	      <property name="tab_fill">True</property>
-	    </packing>
-	  </child>
-
-	  <child>
-	    <widget class="GtkLabel" id="label4">
-	      <property name="visible">True</property>
-	      <property name="label" translatable="yes">Basic Devices</property>
-	      <property name="use_underline">False</property>
-	      <property name="use_markup">False</property>
-	      <property name="justify">GTK_JUSTIFY_LEFT</property>
-	      <property name="wrap">False</property>
-	      <property name="selectable">False</property>
-	      <property name="xalign">0.5</property>
-	      <property name="yalign">0.5</property>
-	      <property name="xpad">0</property>
-	      <property name="ypad">0</property>
-	      <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
-	      <property name="width_chars">-1</property>
-	      <property name="single_line_mode">False</property>
-	      <property name="angle">0</property>
-	    </widget>
-	    <packing>
-	      <property name="type">tab</property>
-	    </packing>
-	  </child>
-
-	  <child>
-	    <widget class="GtkScrolledWindow" id="raidScroll">
-	      <property name="visible">True</property>
-	      <property name="can_focus">True</property>
-	      <property name="hscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
-	      <property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
-	      <property name="shadow_type">GTK_SHADOW_ETCHED_IN</property>
-	      <property name="window_placement">GTK_CORNER_TOP_LEFT</property>
-
-	      <child>
-		<placeholder/>
-	      </child>
-	    </widget>
-	    <packing>
-	      <property name="tab_expand">False</property>
-	      <property name="tab_fill">True</property>
-	    </packing>
-	  </child>
-
-	  <child>
-	    <widget class="GtkLabel" id="label5">
-	      <property name="visible">True</property>
-	      <property name="label" translatable="yes">Firmware RAID</property>
-	      <property name="use_underline">False</property>
-	      <property name="use_markup">False</property>
-	      <property name="justify">GTK_JUSTIFY_LEFT</property>
-	      <property name="wrap">False</property>
-	      <property name="selectable">False</property>
-	      <property name="xalign">0.5</property>
-	      <property name="yalign">0.5</property>
-	      <property name="xpad">0</property>
-	      <property name="ypad">0</property>
-	      <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
-	      <property name="width_chars">-1</property>
-	      <property name="single_line_mode">False</property>
-	      <property name="angle">0</property>
-	    </widget>
-	    <packing>
-	      <property name="type">tab</property>
-	    </packing>
-	  </child>
-
-	  <child>
-	    <widget class="GtkVBox" id="mpathVBox">
-	      <property name="visible">True</property>
-	      <property name="homogeneous">False</property>
-	      <property name="spacing">6</property>
-
-	      <child>
-		<widget class="GtkHBox" id="mpathFilterHBox">
-		  <property name="visible">True</property>
-		  <property name="homogeneous">False</property>
-		  <property name="spacing">6</property>
-
-		  <child>
-		    <widget class="GtkLabel" id="label11">
-		      <property name="visible">True</property>
-		      <property name="label" translatable="yes">Filter By:</property>
-		      <property name="use_underline">False</property>
-		      <property name="use_markup">False</property>
-		      <property name="justify">GTK_JUSTIFY_LEFT</property>
-		      <property name="wrap">False</property>
-		      <property name="selectable">False</property>
-		      <property name="xalign">0.5</property>
-		      <property name="yalign">0.5</property>
-		      <property name="xpad">0</property>
-		      <property name="ypad">0</property>
-		      <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
-		      <property name="width_chars">-1</property>
-		      <property name="single_line_mode">False</property>
-		      <property name="angle">0</property>
-		    </widget>
-		    <packing>
-		      <property name="padding">0</property>
-		      <property name="expand">False</property>
-		      <property name="fill">False</property>
-		    </packing>
-		  </child>
-
-		  <child>
-		    <widget class="GtkComboBoxEntry" id="mpathFilterBy">
-		      <property name="visible">True</property>
-		      <property name="items" translatable="yes">Interconnect
-Vendor
-Identifier</property>
-		      <property name="add_tearoffs">False</property>
-		      <property name="has_frame">True</property>
-		      <property name="focus_on_click">True</property>
-		    </widget>
-		    <packing>
-		      <property name="padding">0</property>
-		      <property name="expand">False</property>
-		      <property name="fill">False</property>
-		    </packing>
-		  </child>
-
-		  <child>
-		    <widget class="GtkNotebook" id="mpathNotebook">
-		      <property name="visible">True</property>
-		      <property name="show_tabs">False</property>
-		      <property name="show_border">False</property>
-		      <property name="tab_pos">GTK_POS_TOP</property>
-		      <property name="scrollable">False</property>
-		      <property name="enable_popup">False</property>
-
-		      <child>
-			<widget class="GtkHBox" id="hbox11">
-			  <property name="visible">True</property>
-			  <property name="homogeneous">False</property>
-			  <property name="spacing">6</property>
-
-			  <child>
-			    <widget class="GtkLabel" id="label28">
-			      <property name="visible">True</property>
-			      <property name="label" translatable="yes">Show Only Devices Using:</property>
-			      <property name="use_underline">False</property>
-			      <property name="use_markup">False</property>
-			      <property name="justify">GTK_JUSTIFY_LEFT</property>
-			      <property name="wrap">False</property>
-			      <property name="selectable">False</property>
-			      <property name="xalign">0.5</property>
-			      <property name="yalign">0.5</property>
-			      <property name="xpad">0</property>
-			      <property name="ypad">0</property>
-			      <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
-			      <property name="width_chars">-1</property>
-			      <property name="single_line_mode">False</property>
-			      <property name="angle">0</property>
-			    </widget>
-			    <packing>
-			      <property name="padding">0</property>
-			      <property name="expand">False</property>
-			      <property name="fill">False</property>
-			    </packing>
-			  </child>
-
-			  <child>
-			    <widget class="GtkComboBoxEntry" id="mpathInterconnectEntry">
-			      <property name="visible">True</property>
-			      <property name="add_tearoffs">False</property>
-			      <property name="has_frame">True</property>
-			      <property name="focus_on_click">True</property>
-			    </widget>
-			    <packing>
-			      <property name="padding">0</property>
-			      <property name="expand">True</property>
-			      <property name="fill">True</property>
-			    </packing>
-			  </child>
-			</widget>
-			<packing>
-			  <property name="tab_expand">False</property>
-			  <property name="tab_fill">True</property>
-			</packing>
-		      </child>
-
-		      <child>
-			<widget class="GtkLabel" id="label29">
-			  <property name="visible">True</property>
-			  <property name="label" translatable="yes">label22</property>
-			  <property name="use_underline">False</property>
-			  <property name="use_markup">False</property>
-			  <property name="justify">GTK_JUSTIFY_LEFT</property>
-			  <property name="wrap">False</property>
-			  <property name="selectable">False</property>
-			  <property name="xalign">0.5</property>
-			  <property name="yalign">0.5</property>
-			  <property name="xpad">0</property>
-			  <property name="ypad">0</property>
-			  <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
-			  <property name="width_chars">-1</property>
-			  <property name="single_line_mode">False</property>
-			  <property name="angle">0</property>
-			</widget>
-			<packing>
-			  <property name="type">tab</property>
-			</packing>
-		      </child>
-
-		      <child>
-			<widget class="GtkHBox" id="hbox12">
-			  <property name="visible">True</property>
-			  <property name="homogeneous">False</property>
-			  <property name="spacing">6</property>
-
-			  <child>
-			    <widget class="GtkLabel" id="label30">
-			      <property name="visible">True</property>
-			      <property name="label" translatable="yes">Show Only Devices From:</property>
-			      <property name="use_underline">False</property>
-			      <property name="use_markup">False</property>
-			      <property name="justify">GTK_JUSTIFY_LEFT</property>
-			      <property name="wrap">False</property>
-			      <property name="selectable">False</property>
-			      <property name="xalign">0.5</property>
-			      <property name="yalign">0.5</property>
-			      <property name="xpad">0</property>
-			      <property name="ypad">0</property>
-			      <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
-			      <property name="width_chars">-1</property>
-			      <property name="single_line_mode">False</property>
-			      <property name="angle">0</property>
-			    </widget>
-			    <packing>
-			      <property name="padding">0</property>
-			      <property name="expand">False</property>
-			      <property name="fill">False</property>
-			    </packing>
-			  </child>
-
-			  <child>
-			    <widget class="GtkComboBoxEntry" id="mpathVendorEntry">
-			      <property name="visible">True</property>
-			      <property name="add_tearoffs">False</property>
-			      <property name="has_frame">True</property>
-			      <property name="focus_on_click">True</property>
-			    </widget>
-			    <packing>
-			      <property name="padding">0</property>
-			      <property name="expand">True</property>
-			      <property name="fill">True</property>
-			    </packing>
-			  </child>
-			</widget>
-			<packing>
-			  <property name="tab_expand">False</property>
-			  <property name="tab_fill">True</property>
-			</packing>
-		      </child>
-
-		      <child>
-			<widget class="GtkLabel" id="label31">
-			  <property name="visible">True</property>
-			  <property name="label" translatable="yes">label23</property>
-			  <property name="use_underline">False</property>
-			  <property name="use_markup">False</property>
-			  <property name="justify">GTK_JUSTIFY_LEFT</property>
-			  <property name="wrap">False</property>
-			  <property name="selectable">False</property>
-			  <property name="xalign">0.5</property>
-			  <property name="yalign">0.5</property>
-			  <property name="xpad">0</property>
-			  <property name="ypad">0</property>
-			  <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
-			  <property name="width_chars">-1</property>
-			  <property name="single_line_mode">False</property>
-			  <property name="angle">0</property>
-			</widget>
-			<packing>
-			  <property name="type">tab</property>
-			</packing>
-		      </child>
-
-		      <child>
-			<widget class="GtkHBox" id="hbox13">
-			  <property name="visible">True</property>
-			  <property name="homogeneous">False</property>
-			  <property name="spacing">6</property>
-
-			  <child>
-			    <widget class="GtkLabel" id="label32">
-			      <property name="visible">True</property>
-			      <property name="label" translatable="yes">Show Identifiers that Include:</property>
-			      <property name="use_underline">False</property>
-			      <property name="use_markup">False</property>
-			      <property name="justify">GTK_JUSTIFY_LEFT</property>
-			      <property name="wrap">False</property>
-			      <property name="selectable">False</property>
-			      <property name="xalign">0.5</property>
-			      <property name="yalign">0.5</property>
-			      <property name="xpad">0</property>
-			      <property name="ypad">0</property>
-			      <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
-			      <property name="width_chars">-1</property>
-			      <property name="single_line_mode">False</property>
-			      <property name="angle">0</property>
-			    </widget>
-			    <packing>
-			      <property name="padding">0</property>
-			      <property name="expand">False</property>
-			      <property name="fill">False</property>
-			    </packing>
-			  </child>
-
-			  <child>
-			    <widget class="GtkEntry" id="mpathIDEntry">
-			      <property name="visible">True</property>
-			      <property name="can_focus">True</property>
-			      <property name="editable">True</property>
-			      <property name="visibility">True</property>
-			      <property name="max_length">0</property>
-			      <property name="text" translatable="yes"></property>
-			      <property name="has_frame">True</property>
-			      <property name="invisible_char">â??</property>
-			      <property name="activates_default">False</property>
-			    </widget>
-			    <packing>
-			      <property name="padding">0</property>
-			      <property name="expand">True</property>
-			      <property name="fill">True</property>
-			    </packing>
-			  </child>
-			</widget>
-			<packing>
-			  <property name="tab_expand">False</property>
-			  <property name="tab_fill">True</property>
-			</packing>
-		      </child>
-
-		      <child>
-			<widget class="GtkLabel" id="label33">
-			  <property name="visible">True</property>
-			  <property name="label" translatable="yes">label24</property>
-			  <property name="use_underline">False</property>
-			  <property name="use_markup">False</property>
-			  <property name="justify">GTK_JUSTIFY_LEFT</property>
-			  <property name="wrap">False</property>
-			  <property name="selectable">False</property>
-			  <property name="xalign">0.5</property>
-			  <property name="yalign">0.5</property>
-			  <property name="xpad">0</property>
-			  <property name="ypad">0</property>
-			  <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
-			  <property name="width_chars">-1</property>
-			  <property name="single_line_mode">False</property>
-			  <property name="angle">0</property>
-			</widget>
-			<packing>
-			  <property name="type">tab</property>
-			</packing>
-		      </child>
-		    </widget>
-		    <packing>
-		      <property name="padding">0</property>
-		      <property name="expand">True</property>
-		      <property name="fill">True</property>
-		    </packing>
-		  </child>
-		</widget>
-		<packing>
-		  <property name="padding">0</property>
-		  <property name="expand">False</property>
-		  <property name="fill">True</property>
-		</packing>
-	      </child>
-
-	      <child>
-		<widget class="GtkScrolledWindow" id="mpathScroll">
-		  <property name="visible">True</property>
-		  <property name="can_focus">True</property>
-		  <property name="hscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
-		  <property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
-		  <property name="shadow_type">GTK_SHADOW_ETCHED_IN</property>
-		  <property name="window_placement">GTK_CORNER_TOP_LEFT</property>
-
-		  <child>
-		    <placeholder/>
-		  </child>
-		</widget>
-		<packing>
-		  <property name="padding">0</property>
-		  <property name="expand">True</property>
-		  <property name="fill">True</property>
-		</packing>
-	      </child>
-	    </widget>
-	    <packing>
-	      <property name="tab_expand">False</property>
-	      <property name="tab_fill">True</property>
-	    </packing>
-	  </child>
-
-	  <child>
-	    <widget class="GtkLabel" id="label6">
-	      <property name="visible">True</property>
-	      <property name="label" translatable="yes">Multipath Devices</property>
-	      <property name="use_underline">False</property>
-	      <property name="use_markup">False</property>
-	      <property name="justify">GTK_JUSTIFY_LEFT</property>
-	      <property name="wrap">False</property>
-	      <property name="selectable">False</property>
-	      <property name="xalign">0.5</property>
-	      <property name="yalign">0.5</property>
-	      <property name="xpad">0</property>
-	      <property name="ypad">0</property>
-	      <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
-	      <property name="width_chars">-1</property>
-	      <property name="single_line_mode">False</property>
-	      <property name="angle">0</property>
-	    </widget>
-	    <packing>
-	      <property name="type">tab</property>
-	    </packing>
-	  </child>
-
-	  <child>
-	    <widget class="GtkVBox" id="otherVBox">
-	      <property name="visible">True</property>
-	      <property name="homogeneous">False</property>
-	      <property name="spacing">6</property>
-
-	      <child>
-		<widget class="GtkHBox" id="otherFilterHBox">
-		  <property name="visible">True</property>
-		  <property name="homogeneous">False</property>
-		  <property name="spacing">6</property>
-
-		  <child>
-		    <widget class="GtkLabel" id="label35">
-		      <property name="visible">True</property>
-		      <property name="label" translatable="yes">Filter By:</property>
-		      <property name="use_underline">False</property>
-		      <property name="use_markup">False</property>
-		      <property name="justify">GTK_JUSTIFY_LEFT</property>
-		      <property name="wrap">False</property>
-		      <property name="selectable">False</property>
-		      <property name="xalign">0.5</property>
-		      <property name="yalign">0.5</property>
-		      <property name="xpad">0</property>
-		      <property name="ypad">0</property>
-		      <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
-		      <property name="width_chars">-1</property>
-		      <property name="single_line_mode">False</property>
-		      <property name="angle">0</property>
-		    </widget>
-		    <packing>
-		      <property name="padding">0</property>
-		      <property name="expand">False</property>
-		      <property name="fill">False</property>
-		    </packing>
-		  </child>
-
-		  <child>
-		    <widget class="GtkComboBoxEntry" id="otherFilterBy">
-		      <property name="visible">True</property>
-		      <property name="items" translatable="yes">Interconnect
-Vendor
-Identifier</property>
-		      <property name="add_tearoffs">False</property>
-		      <property name="has_frame">True</property>
-		      <property name="focus_on_click">True</property>
-		    </widget>
-		    <packing>
-		      <property name="padding">0</property>
-		      <property name="expand">False</property>
-		      <property name="fill">False</property>
-		    </packing>
-		  </child>
-
-		  <child>
-		    <widget class="GtkNotebook" id="otherNotebook">
-		      <property name="visible">True</property>
-		      <property name="show_tabs">False</property>
-		      <property name="show_border">False</property>
-		      <property name="tab_pos">GTK_POS_TOP</property>
-		      <property name="scrollable">False</property>
-		      <property name="enable_popup">False</property>
-
-		      <child>
-			<widget class="GtkHBox" id="hbox15">
-			  <property name="visible">True</property>
-			  <property name="homogeneous">False</property>
-			  <property name="spacing">6</property>
-
-			  <child>
-			    <widget class="GtkLabel" id="label36">
-			      <property name="visible">True</property>
-			      <property name="label" translatable="yes">Show Only Devices Using:</property>
-			      <property name="use_underline">False</property>
-			      <property name="use_markup">False</property>
-			      <property name="justify">GTK_JUSTIFY_LEFT</property>
-			      <property name="wrap">False</property>
-			      <property name="selectable">False</property>
-			      <property name="xalign">0.5</property>
-			      <property name="yalign">0.5</property>
-			      <property name="xpad">0</property>
-			      <property name="ypad">0</property>
-			      <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
-			      <property name="width_chars">-1</property>
-			      <property name="single_line_mode">False</property>
-			      <property name="angle">0</property>
-			    </widget>
-			    <packing>
-			      <property name="padding">0</property>
-			      <property name="expand">False</property>
-			      <property name="fill">False</property>
-			    </packing>
-			  </child>
-
-			  <child>
-			    <widget class="GtkComboBoxEntry" id="otherInterconnectEntry">
-			      <property name="visible">True</property>
-			      <property name="add_tearoffs">False</property>
-			      <property name="has_frame">True</property>
-			      <property name="focus_on_click">True</property>
-			    </widget>
-			    <packing>
-			      <property name="padding">0</property>
-			      <property name="expand">True</property>
-			      <property name="fill">True</property>
-			    </packing>
-			  </child>
-			</widget>
-			<packing>
-			  <property name="tab_expand">False</property>
-			  <property name="tab_fill">True</property>
-			</packing>
-		      </child>
-
-		      <child>
-			<widget class="GtkLabel" id="label37">
-			  <property name="visible">True</property>
-			  <property name="label" translatable="yes">label22</property>
-			  <property name="use_underline">False</property>
-			  <property name="use_markup">False</property>
-			  <property name="justify">GTK_JUSTIFY_LEFT</property>
-			  <property name="wrap">False</property>
-			  <property name="selectable">False</property>
-			  <property name="xalign">0.5</property>
-			  <property name="yalign">0.5</property>
-			  <property name="xpad">0</property>
-			  <property name="ypad">0</property>
-			  <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
-			  <property name="width_chars">-1</property>
-			  <property name="single_line_mode">False</property>
-			  <property name="angle">0</property>
-			</widget>
-			<packing>
-			  <property name="type">tab</property>
-			</packing>
-		      </child>
-
-		      <child>
-			<widget class="GtkHBox" id="hbox16">
-			  <property name="visible">True</property>
-			  <property name="homogeneous">False</property>
-			  <property name="spacing">6</property>
-
-			  <child>
-			    <widget class="GtkLabel" id="label38">
-			      <property name="visible">True</property>
-			      <property name="label" translatable="yes">Show Only Devices From:</property>
-			      <property name="use_underline">False</property>
-			      <property name="use_markup">False</property>
-			      <property name="justify">GTK_JUSTIFY_LEFT</property>
-			      <property name="wrap">False</property>
-			      <property name="selectable">False</property>
-			      <property name="xalign">0.5</property>
-			      <property name="yalign">0.5</property>
-			      <property name="xpad">0</property>
-			      <property name="ypad">0</property>
-			      <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
-			      <property name="width_chars">-1</property>
-			      <property name="single_line_mode">False</property>
-			      <property name="angle">0</property>
-			    </widget>
-			    <packing>
-			      <property name="padding">0</property>
-			      <property name="expand">False</property>
-			      <property name="fill">False</property>
-			    </packing>
-			  </child>
-
-			  <child>
-			    <widget class="GtkComboBoxEntry" id="otherVendorEntry">
-			      <property name="visible">True</property>
-			      <property name="add_tearoffs">False</property>
-			      <property name="has_frame">True</property>
-			      <property name="focus_on_click">True</property>
-			    </widget>
-			    <packing>
-			      <property name="padding">0</property>
-			      <property name="expand">True</property>
-			      <property name="fill">True</property>
-			    </packing>
-			  </child>
-			</widget>
-			<packing>
-			  <property name="tab_expand">False</property>
-			  <property name="tab_fill">True</property>
-			</packing>
-		      </child>
-
-		      <child>
-			<widget class="GtkLabel" id="label39">
-			  <property name="visible">True</property>
-			  <property name="label" translatable="yes">label23</property>
-			  <property name="use_underline">False</property>
-			  <property name="use_markup">False</property>
-			  <property name="justify">GTK_JUSTIFY_LEFT</property>
-			  <property name="wrap">False</property>
-			  <property name="selectable">False</property>
-			  <property name="xalign">0.5</property>
-			  <property name="yalign">0.5</property>
-			  <property name="xpad">0</property>
-			  <property name="ypad">0</property>
-			  <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
-			  <property name="width_chars">-1</property>
-			  <property name="single_line_mode">False</property>
-			  <property name="angle">0</property>
-			</widget>
-			<packing>
-			  <property name="type">tab</property>
-			</packing>
-		      </child>
-
-		      <child>
-			<widget class="GtkHBox" id="hbox17">
-			  <property name="visible">True</property>
-			  <property name="homogeneous">False</property>
-			  <property name="spacing">6</property>
-
-			  <child>
-			    <widget class="GtkLabel" id="label40">
-			      <property name="visible">True</property>
-			      <property name="label" translatable="yes">Show Identifiers that Include:</property>
-			      <property name="use_underline">False</property>
-			      <property name="use_markup">False</property>
-			      <property name="justify">GTK_JUSTIFY_LEFT</property>
-			      <property name="wrap">False</property>
-			      <property name="selectable">False</property>
-			      <property name="xalign">0.5</property>
-			      <property name="yalign">0.5</property>
-			      <property name="xpad">0</property>
-			      <property name="ypad">0</property>
-			      <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
-			      <property name="width_chars">-1</property>
-			      <property name="single_line_mode">False</property>
-			      <property name="angle">0</property>
-			    </widget>
-			    <packing>
-			      <property name="padding">0</property>
-			      <property name="expand">False</property>
-			      <property name="fill">False</property>
-			    </packing>
-			  </child>
-
-			  <child>
-			    <widget class="GtkEntry" id="otherIDEntry">
-			      <property name="visible">True</property>
-			      <property name="can_focus">True</property>
-			      <property name="editable">True</property>
-			      <property name="visibility">True</property>
-			      <property name="max_length">0</property>
-			      <property name="text" translatable="yes"></property>
-			      <property name="has_frame">True</property>
-			      <property name="invisible_char">â??</property>
-			      <property name="activates_default">False</property>
-			    </widget>
-			    <packing>
-			      <property name="padding">0</property>
-			      <property name="expand">True</property>
-			      <property name="fill">True</property>
-			    </packing>
-			  </child>
-			</widget>
-			<packing>
-			  <property name="tab_expand">False</property>
-			  <property name="tab_fill">True</property>
-			</packing>
-		      </child>
-
-		      <child>
-			<widget class="GtkLabel" id="label41">
-			  <property name="visible">True</property>
-			  <property name="label" translatable="yes">label24</property>
-			  <property name="use_underline">False</property>
-			  <property name="use_markup">False</property>
-			  <property name="justify">GTK_JUSTIFY_LEFT</property>
-			  <property name="wrap">False</property>
-			  <property name="selectable">False</property>
-			  <property name="xalign">0.5</property>
-			  <property name="yalign">0.5</property>
-			  <property name="xpad">0</property>
-			  <property name="ypad">0</property>
-			  <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
-			  <property name="width_chars">-1</property>
-			  <property name="single_line_mode">False</property>
-			  <property name="angle">0</property>
-			</widget>
-			<packing>
-			  <property name="type">tab</property>
-			</packing>
-		      </child>
-		    </widget>
-		    <packing>
-		      <property name="padding">0</property>
-		      <property name="expand">True</property>
-		      <property name="fill">True</property>
-		    </packing>
-		  </child>
-		</widget>
-		<packing>
-		  <property name="padding">0</property>
-		  <property name="expand">False</property>
-		  <property name="fill">True</property>
-		</packing>
-	      </child>
-
-	      <child>
-		<widget class="GtkScrolledWindow" id="otherScroll">
-		  <property name="visible">True</property>
-		  <property name="can_focus">True</property>
-		  <property name="hscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
-		  <property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
-		  <property name="shadow_type">GTK_SHADOW_ETCHED_IN</property>
-		  <property name="window_placement">GTK_CORNER_TOP_LEFT</property>
-
-		  <child>
-		    <placeholder/>
-		  </child>
-		</widget>
-		<packing>
-		  <property name="padding">0</property>
-		  <property name="expand">True</property>
-		  <property name="fill">True</property>
-		</packing>
-	      </child>
-	    </widget>
-	    <packing>
-	      <property name="tab_expand">False</property>
-	      <property name="tab_fill">True</property>
-	    </packing>
-	  </child>
-
-	  <child>
-	    <widget class="GtkLabel" id="label34">
-	      <property name="visible">True</property>
-	      <property name="label" translatable="yes">Other SAN Devices</property>
-	      <property name="use_underline">False</property>
-	      <property name="use_markup">False</property>
-	      <property name="justify">GTK_JUSTIFY_LEFT</property>
-	      <property name="wrap">False</property>
-	      <property name="selectable">False</property>
-	      <property name="xalign">0.5</property>
-	      <property name="yalign">0.5</property>
-	      <property name="xpad">0</property>
-	      <property name="ypad">0</property>
-	      <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
-	      <property name="width_chars">-1</property>
-	      <property name="single_line_mode">False</property>
-	      <property name="angle">0</property>
-	    </widget>
-	    <packing>
-	      <property name="type">tab</property>
-	    </packing>
-	  </child>
-
-	  <child>
-	    <widget class="GtkVBox" id="searchVBox">
-	      <property name="visible">True</property>
-	      <property name="homogeneous">False</property>
-	      <property name="spacing">0</property>
-
-	      <child>
-		<widget class="GtkHBox" id="searchFilterHBox">
-		  <property name="visible">True</property>
-		  <property name="homogeneous">False</property>
-		  <property name="spacing">6</property>
-
-		  <child>
-		    <widget class="GtkLabel" id="label15">
-		      <property name="visible">True</property>
-		      <property name="label" translatable="yes">Search By:</property>
-		      <property name="use_underline">False</property>
-		      <property name="use_markup">False</property>
-		      <property name="justify">GTK_JUSTIFY_LEFT</property>
-		      <property name="wrap">False</property>
-		      <property name="selectable">False</property>
-		      <property name="xalign">0.5</property>
-		      <property name="yalign">0.5</property>
-		      <property name="xpad">0</property>
-		      <property name="ypad">0</property>
-		      <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
-		      <property name="width_chars">-1</property>
-		      <property name="single_line_mode">False</property>
-		      <property name="angle">0</property>
-		    </widget>
-		    <packing>
-		      <property name="padding">0</property>
-		      <property name="expand">False</property>
-		      <property name="fill">False</property>
-		    </packing>
-		  </child>
-
-		  <child>
-		    <widget class="GtkComboBoxEntry" id="searchFilterBy">
-		      <property name="visible">True</property>
-		      <property name="items" translatable="yes">Port / Target / LUN
-Target Identifier</property>
-		      <property name="add_tearoffs">False</property>
-		      <property name="has_frame">True</property>
-		      <property name="focus_on_click">True</property>
-		    </widget>
-		    <packing>
-		      <property name="padding">0</property>
-		      <property name="expand">False</property>
-		      <property name="fill">False</property>
-		    </packing>
-		  </child>
-
-		  <child>
-		    <widget class="GtkNotebook" id="searchNotebook">
-		      <property name="visible">True</property>
-		      <property name="show_tabs">False</property>
-		      <property name="show_border">False</property>
-		      <property name="tab_pos">GTK_POS_TOP</property>
-		      <property name="scrollable">False</property>
-		      <property name="enable_popup">False</property>
-
-		      <child>
-			<widget class="GtkHBox" id="hbox6">
-			  <property name="visible">True</property>
-			  <property name="homogeneous">False</property>
-			  <property name="spacing">6</property>
-
-			  <child>
-			    <widget class="GtkLabel" id="label18">
-			      <property name="visible">True</property>
-			      <property name="label" translatable="yes">Port:</property>
-			      <property name="use_underline">False</property>
-			      <property name="use_markup">False</property>
-			      <property name="justify">GTK_JUSTIFY_LEFT</property>
-			      <property name="wrap">False</property>
-			      <property name="selectable">False</property>
-			      <property name="xalign">0.5</property>
-			      <property name="yalign">0.5</property>
-			      <property name="xpad">0</property>
-			      <property name="ypad">0</property>
-			      <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
-			      <property name="width_chars">-1</property>
-			      <property name="single_line_mode">False</property>
-			      <property name="angle">0</property>
-			    </widget>
-			    <packing>
-			      <property name="padding">0</property>
-			      <property name="expand">False</property>
-			      <property name="fill">False</property>
-			    </packing>
-			  </child>
-
-			  <child>
-			    <widget class="GtkEntry" id="searchPortEntry">
-			      <property name="width_request">50</property>
-			      <property name="visible">True</property>
-			      <property name="can_focus">True</property>
-			      <property name="editable">True</property>
-			      <property name="visibility">True</property>
-			      <property name="max_length">0</property>
-			      <property name="text" translatable="yes"></property>
-			      <property name="has_frame">True</property>
-			      <property name="invisible_char">â??</property>
-			      <property name="activates_default">False</property>
-			    </widget>
-			    <packing>
-			      <property name="padding">0</property>
-			      <property name="expand">False</property>
-			      <property name="fill">False</property>
-			    </packing>
-			  </child>
-
-			  <child>
-			    <widget class="GtkLabel" id="label19">
-			      <property name="visible">True</property>
-			      <property name="label" translatable="yes">Target:</property>
-			      <property name="use_underline">False</property>
-			      <property name="use_markup">False</property>
-			      <property name="justify">GTK_JUSTIFY_LEFT</property>
-			      <property name="wrap">False</property>
-			      <property name="selectable">False</property>
-			      <property name="xalign">0.5</property>
-			      <property name="yalign">0.5</property>
-			      <property name="xpad">0</property>
-			      <property name="ypad">0</property>
-			      <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
-			      <property name="width_chars">-1</property>
-			      <property name="single_line_mode">False</property>
-			      <property name="angle">0</property>
-			    </widget>
-			    <packing>
-			      <property name="padding">0</property>
-			      <property name="expand">False</property>
-			      <property name="fill">False</property>
-			    </packing>
-			  </child>
-
-			  <child>
-			    <widget class="GtkEntry" id="searchTargetEntry">
-			      <property name="width_request">50</property>
-			      <property name="visible">True</property>
-			      <property name="can_focus">True</property>
-			      <property name="editable">True</property>
-			      <property name="visibility">True</property>
-			      <property name="max_length">0</property>
-			      <property name="text" translatable="yes"></property>
-			      <property name="has_frame">True</property>
-			      <property name="invisible_char">â??</property>
-			      <property name="activates_default">False</property>
-			    </widget>
-			    <packing>
-			      <property name="padding">0</property>
-			      <property name="expand">False</property>
-			      <property name="fill">False</property>
-			    </packing>
-			  </child>
-
-			  <child>
-			    <widget class="GtkLabel" id="label20">
-			      <property name="visible">True</property>
-			      <property name="label" translatable="yes">LUN:</property>
-			      <property name="use_underline">False</property>
-			      <property name="use_markup">False</property>
-			      <property name="justify">GTK_JUSTIFY_LEFT</property>
-			      <property name="wrap">False</property>
-			      <property name="selectable">False</property>
-			      <property name="xalign">0.5</property>
-			      <property name="yalign">0.5</property>
-			      <property name="xpad">0</property>
-			      <property name="ypad">0</property>
-			      <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
-			      <property name="width_chars">-1</property>
-			      <property name="single_line_mode">False</property>
-			      <property name="angle">0</property>
-			    </widget>
-			    <packing>
-			      <property name="padding">0</property>
-			      <property name="expand">False</property>
-			      <property name="fill">False</property>
-			    </packing>
-			  </child>
-
-			  <child>
-			    <widget class="GtkEntry" id="searchLUNEntry">
-			      <property name="width_request">50</property>
-			      <property name="visible">True</property>
-			      <property name="can_focus">True</property>
-			      <property name="editable">True</property>
-			      <property name="visibility">True</property>
-			      <property name="max_length">0</property>
-			      <property name="text" translatable="yes"></property>
-			      <property name="has_frame">True</property>
-			      <property name="invisible_char">â??</property>
-			      <property name="activates_default">False</property>
-			    </widget>
-			    <packing>
-			      <property name="padding">0</property>
-			      <property name="expand">False</property>
-			      <property name="fill">False</property>
-			    </packing>
-			  </child>
-			</widget>
-			<packing>
-			  <property name="tab_expand">False</property>
-			  <property name="tab_fill">True</property>
-			</packing>
-		      </child>
-
-		      <child>
-			<widget class="GtkLabel" id="label16">
-			  <property name="visible">True</property>
-			  <property name="label" translatable="yes">label16</property>
-			  <property name="use_underline">False</property>
-			  <property name="use_markup">False</property>
-			  <property name="justify">GTK_JUSTIFY_LEFT</property>
-			  <property name="wrap">False</property>
-			  <property name="selectable">False</property>
-			  <property name="xalign">0.5</property>
-			  <property name="yalign">0.5</property>
-			  <property name="xpad">0</property>
-			  <property name="ypad">0</property>
-			  <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
-			  <property name="width_chars">-1</property>
-			  <property name="single_line_mode">False</property>
-			  <property name="angle">0</property>
-			</widget>
-			<packing>
-			  <property name="type">tab</property>
-			</packing>
-		      </child>
-
-		      <child>
-			<widget class="GtkHBox" id="hbox7">
-			  <property name="visible">True</property>
-			  <property name="homogeneous">False</property>
-			  <property name="spacing">6</property>
-
-			  <child>
-			    <widget class="GtkLabel" id="label21">
-			      <property name="visible">True</property>
-			      <property name="label" translatable="yes">Identifier:</property>
-			      <property name="use_underline">False</property>
-			      <property name="use_markup">False</property>
-			      <property name="justify">GTK_JUSTIFY_LEFT</property>
-			      <property name="wrap">False</property>
-			      <property name="selectable">False</property>
-			      <property name="xalign">0.5</property>
-			      <property name="yalign">0.5</property>
-			      <property name="xpad">0</property>
-			      <property name="ypad">0</property>
-			      <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
-			      <property name="width_chars">-1</property>
-			      <property name="single_line_mode">False</property>
-			      <property name="angle">0</property>
-			    </widget>
-			    <packing>
-			      <property name="padding">0</property>
-			      <property name="expand">False</property>
-			      <property name="fill">False</property>
-			    </packing>
-			  </child>
-
-			  <child>
-			    <widget class="GtkEntry" id="searchIDEntry">
-			      <property name="visible">True</property>
-			      <property name="can_focus">True</property>
-			      <property name="editable">True</property>
-			      <property name="visibility">True</property>
-			      <property name="max_length">0</property>
-			      <property name="text" translatable="yes"></property>
-			      <property name="has_frame">True</property>
-			      <property name="invisible_char">â??</property>
-			      <property name="activates_default">False</property>
-			    </widget>
-			    <packing>
-			      <property name="padding">0</property>
-			      <property name="expand">True</property>
-			      <property name="fill">True</property>
-			    </packing>
-			  </child>
-			</widget>
-			<packing>
-			  <property name="tab_expand">False</property>
-			  <property name="tab_fill">True</property>
-			</packing>
-		      </child>
-
-		      <child>
-			<widget class="GtkLabel" id="label17">
-			  <property name="visible">True</property>
-			  <property name="label" translatable="yes">label17</property>
-			  <property name="use_underline">False</property>
-			  <property name="use_markup">False</property>
-			  <property name="justify">GTK_JUSTIFY_LEFT</property>
-			  <property name="wrap">False</property>
-			  <property name="selectable">False</property>
-			  <property name="xalign">0.5</property>
-			  <property name="yalign">0.5</property>
-			  <property name="xpad">0</property>
-			  <property name="ypad">0</property>
-			  <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
-			  <property name="width_chars">-1</property>
-			  <property name="single_line_mode">False</property>
-			  <property name="angle">0</property>
-			</widget>
-			<packing>
-			  <property name="type">tab</property>
-			</packing>
-		      </child>
-		    </widget>
-		    <packing>
-		      <property name="padding">0</property>
-		      <property name="expand">True</property>
-		      <property name="fill">True</property>
-		    </packing>
-		  </child>
-		</widget>
-		<packing>
-		  <property name="padding">0</property>
-		  <property name="expand">False</property>
-		  <property name="fill">True</property>
-		</packing>
-	      </child>
-
-	      <child>
-		<widget class="GtkLabel" id="label10">
-		  <property name="visible">True</property>
-		  <property name="label" translatable="yes">Search Results:</property>
-		  <property name="use_underline">False</property>
-		  <property name="use_markup">False</property>
-		  <property name="justify">GTK_JUSTIFY_LEFT</property>
-		  <property name="wrap">False</property>
-		  <property name="selectable">False</property>
-		  <property name="xalign">0</property>
-		  <property name="yalign">0</property>
-		  <property name="xpad">0</property>
-		  <property name="ypad">0</property>
-		  <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
-		  <property name="width_chars">-1</property>
-		  <property name="single_line_mode">False</property>
-		  <property name="angle">0</property>
-		</widget>
-		<packing>
-		  <property name="padding">0</property>
-		  <property name="expand">False</property>
-		  <property name="fill">False</property>
-		</packing>
-	      </child>
-
-	      <child>
-		<widget class="GtkScrolledWindow" id="searchScroll">
-		  <property name="visible">True</property>
-		  <property name="can_focus">True</property>
-		  <property name="hscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
-		  <property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
-		  <property name="shadow_type">GTK_SHADOW_ETCHED_IN</property>
-		  <property name="window_placement">GTK_CORNER_TOP_LEFT</property>
-
-		  <child>
-		    <placeholder/>
-		  </child>
-		</widget>
-		<packing>
-		  <property name="padding">0</property>
-		  <property name="expand">True</property>
-		  <property name="fill">True</property>
-		</packing>
-	      </child>
-	    </widget>
-	    <packing>
-	      <property name="tab_expand">False</property>
-	      <property name="tab_fill">True</property>
-	    </packing>
-	  </child>
-
-	  <child>
-	    <widget class="GtkLabel" id="label8">
-	      <property name="visible">True</property>
-	      <property name="label" translatable="yes">Search</property>
-	      <property name="use_underline">False</property>
-	      <property name="use_markup">False</property>
-	      <property name="justify">GTK_JUSTIFY_LEFT</property>
-	      <property name="wrap">False</property>
-	      <property name="selectable">False</property>
-	      <property name="xalign">0.5</property>
-	      <property name="yalign">0.5</property>
-	      <property name="xpad">0</property>
-	      <property name="ypad">0</property>
-	      <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
-	      <property name="width_chars">-1</property>
-	      <property name="single_line_mode">False</property>
-	      <property name="angle">0</property>
-	    </widget>
-	    <packing>
-	      <property name="type">tab</property>
-	    </packing>
-	  </child>
-	</widget>
-	<packing>
-	  <property name="padding">0</property>
-	  <property name="expand">True</property>
-	  <property name="fill">True</property>
-	</packing>
-      </child>
-
-      <child>
-	<widget class="GtkHButtonBox" id="buttonBox">
-	  <property name="visible">True</property>
-	  <property name="layout_style">GTK_BUTTONBOX_END</property>
-	  <property name="spacing">0</property>
-
-	  <child>
-	    <widget class="GtkButton" id="addAdvancedButton">
-	      <property name="visible">True</property>
-	      <property name="can_default">True</property>
-	      <property name="can_focus">True</property>
-	      <property name="relief">GTK_RELIEF_NORMAL</property>
-	      <property name="focus_on_click">True</property>
-
-	      <child>
-		<widget class="GtkLabel" id="label9">
-		  <property name="visible">True</property>
-		  <property name="label" translatable="yes">Add Advanced Target</property>
-		  <property name="use_underline">True</property>
-		  <property name="use_markup">False</property>
-		  <property name="justify">GTK_JUSTIFY_LEFT</property>
-		  <property name="wrap">False</property>
-		  <property name="selectable">False</property>
-		  <property name="xalign">0.5</property>
-		  <property name="yalign">0.5</property>
-		  <property name="xpad">0</property>
-		  <property name="ypad">0</property>
-		  <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
-		  <property name="width_chars">-1</property>
-		  <property name="single_line_mode">False</property>
-		  <property name="angle">0</property>
-		</widget>
-	      </child>
-	    </widget>
-	  </child>
-	</widget>
-	<packing>
-	  <property name="padding">0</property>
-	  <property name="expand">False</property>
-	  <property name="fill">False</property>
-	</packing>
-      </child>
-
-      <child>
-	<widget class="GtkLabel" id="sizeLabel">
-	  <property name="visible">True</property>
-	  <property name="label" translatable="yes">Selected devices: %s (%s) out of %s (%s).</property>
-	  <property name="use_underline">False</property>
-	  <property name="use_markup">True</property>
-	  <property name="justify">GTK_JUSTIFY_LEFT</property>
-	  <property name="wrap">False</property>
-	  <property name="selectable">False</property>
-	  <property name="xalign">0</property>
-	  <property name="yalign">0</property>
-	  <property name="xpad">0</property>
-	  <property name="ypad">0</property>
-	  <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
-	  <property name="width_chars">-1</property>
-	  <property name="single_line_mode">False</property>
-	  <property name="angle">0</property>
-	</widget>
-	<packing>
-	  <property name="padding">0</property>
-	  <property name="expand">False</property>
-	  <property name="fill">False</property>
-	</packing>
-      </child>
-
-      <child>
-	<widget class="GtkHBox" id="hbox1">
-	  <property name="visible">True</property>
-	  <property name="homogeneous">False</property>
-	  <property name="spacing">0</property>
-
-	  <child>
-	    <widget class="GtkImage" id="image1">
-	      <property name="visible">True</property>
-	      <property name="stock">gtk-dialog-info</property>
-	      <property name="icon_size">4</property>
-	      <property name="xalign">0.5</property>
-	      <property name="yalign">0</property>
-	      <property name="xpad">0</property>
-	      <property name="ypad">0</property>
-	    </widget>
-	    <packing>
-	      <property name="padding">0</property>
-	      <property name="expand">False</property>
-	      <property name="fill">False</property>
-	    </packing>
-	  </child>
-
-	  <child>
-	    <widget class="GtkLabel" id="label3">
-	      <property name="width_request">600</property>
-	      <property name="visible">True</property>
-	      <property name="label" translatable="yes">&lt;b&gt;Tip:&lt;/b&gt; Selected drives will not be formatted unless you choose to do so later during installation.  Also, note that post-installation you may mount drives you did not select here by modifying your /etc/fstab file.</property>
-	      <property name="use_underline">False</property>
-	      <property name="use_markup">True</property>
-	      <property name="justify">GTK_JUSTIFY_LEFT</property>
-	      <property name="wrap">True</property>
-	      <property name="selectable">False</property>
-	      <property name="xalign">0</property>
-	      <property name="yalign">0</property>
-	      <property name="xpad">0</property>
-	      <property name="ypad">0</property>
-	      <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
-	      <property name="width_chars">-1</property>
-	      <property name="single_line_mode">False</property>
-	      <property name="angle">0</property>
-	    </widget>
-	    <packing>
-	      <property name="padding">0</property>
-	      <property name="expand">False</property>
-	      <property name="fill">False</property>
-	    </packing>
-	  </child>
-	</widget>
-	<packing>
-	  <property name="padding">0</property>
-	  <property name="expand">False</property>
-	  <property name="fill">False</property>
-	</packing>
-      </child>
-    </widget>
-  </child>
-</widget>
-
-</glade-interface>
diff --git a/ui/iscsi-config.glade b/ui/iscsi-config.glade
deleted file mode 100644
index 0757a2e..0000000
--- a/ui/iscsi-config.glade
+++ /dev/null
@@ -1,456 +0,0 @@
-<?xml version="1.0" standalone="no"?> <!--*- mode: xml -*-->
-<!DOCTYPE glade-interface SYSTEM "http://glade.gnome.org/glade-2.0.dtd";>
-
-<glade-interface>
-
-<widget class="GtkDialog" id="iscsiDialog">
-  <property name="title" translatable="yes">Configure iSCSI Parameters</property>
-  <property name="type">GTK_WINDOW_TOPLEVEL</property>
-  <property name="window_position">GTK_WIN_POS_CENTER</property>
-  <property name="modal">False</property>
-  <property name="resizable">True</property>
-  <property name="destroy_with_parent">False</property>
-  <property name="decorated">True</property>
-  <property name="skip_taskbar_hint">False</property>
-  <property name="skip_pager_hint">False</property>
-  <property name="type_hint">GDK_WINDOW_TYPE_HINT_DIALOG</property>
-  <property name="gravity">GDK_GRAVITY_NORTH_WEST</property>
-  <property name="focus_on_map">True</property>
-  <property name="urgency_hint">False</property>
-  <property name="has_separator">True</property>
-
-  <child internal-child="vbox">
-    <widget class="GtkVBox" id="dialog-vbox1">
-      <property name="visible">True</property>
-      <property name="homogeneous">False</property>
-      <property name="spacing">0</property>
-
-      <child internal-child="action_area">
-	<widget class="GtkHButtonBox" id="dialog-action_area1">
-	  <property name="visible">True</property>
-	  <property name="layout_style">GTK_BUTTONBOX_END</property>
-
-	  <child>
-	    <widget class="GtkButton" id="button1">
-	      <property name="visible">True</property>
-	      <property name="can_default">True</property>
-	      <property name="can_focus">True</property>
-	      <property name="label">gtk-cancel</property>
-	      <property name="use_stock">True</property>
-	      <property name="relief">GTK_RELIEF_NORMAL</property>
-	      <property name="focus_on_click">True</property>
-	      <property name="response_id">-6</property>
-	    </widget>
-	  </child>
-
-	  <child>
-	    <widget class="GtkButton" id="button2">
-	      <property name="visible">True</property>
-	      <property name="can_default">True</property>
-	      <property name="can_focus">True</property>
-	      <property name="relief">GTK_RELIEF_NORMAL</property>
-	      <property name="focus_on_click">True</property>
-	      <property name="response_id">-10</property>
-
-	      <child>
-		<widget class="GtkLabel" id="label6">
-		  <property name="visible">True</property>
-		  <property name="label" translatable="yes">_Add target</property>
-		  <property name="use_underline">True</property>
-		  <property name="use_markup">False</property>
-		  <property name="justify">GTK_JUSTIFY_LEFT</property>
-		  <property name="wrap">False</property>
-		  <property name="selectable">False</property>
-		  <property name="xalign">0.5</property>
-		  <property name="yalign">0.5</property>
-		  <property name="xpad">0</property>
-		  <property name="ypad">0</property>
-		  <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
-		  <property name="width_chars">-1</property>
-		  <property name="single_line_mode">False</property>
-		  <property name="angle">0</property>
-		</widget>
-	      </child>
-	    </widget>
-	  </child>
-	</widget>
-	<packing>
-	  <property name="padding">0</property>
-	  <property name="expand">False</property>
-	  <property name="fill">True</property>
-	  <property name="pack_type">GTK_PACK_END</property>
-	</packing>
-      </child>
-
-      <child>
-	<widget class="GtkVBox" id="vbox1">
-	  <property name="border_width">12</property>
-	  <property name="visible">True</property>
-	  <property name="homogeneous">False</property>
-	  <property name="spacing">12</property>
-
-	  <child>
-	    <widget class="GtkLabel" id="label3">
-	      <property name="visible">True</property>
-	      <property name="label" translatable="yes">To use iSCSI disks, you must provide the address of your iSCSI target and the iSCSI initiator name you've configured for your host.</property>
-	      <property name="use_underline">False</property>
-	      <property name="use_markup">False</property>
-	      <property name="justify">GTK_JUSTIFY_LEFT</property>
-	      <property name="wrap">True</property>
-	      <property name="selectable">False</property>
-	      <property name="xalign">0.5</property>
-	      <property name="yalign">0.5</property>
-	      <property name="xpad">0</property>
-	      <property name="ypad">0</property>
-	      <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
-	      <property name="width_chars">-1</property>
-	      <property name="single_line_mode">False</property>
-	      <property name="angle">0</property>
-	    </widget>
-	    <packing>
-	      <property name="padding">0</property>
-	      <property name="expand">False</property>
-	      <property name="fill">False</property>
-	    </packing>
-	  </child>
-
-	  <child>
-	    <widget class="GtkTable" id="iscsiTable">
-	      <property name="border_width">12</property>
-	      <property name="visible">True</property>
-	      <property name="n_rows">6</property>
-	      <property name="n_columns">2</property>
-	      <property name="homogeneous">False</property>
-	      <property name="row_spacing">6</property>
-	      <property name="column_spacing">6</property>
-
-	      <child>
-		<widget class="GtkLabel" id="labeliscsiAddr">
-		  <property name="visible">True</property>
-		  <property name="label" translatable="yes">&lt;b&gt;_Target IP Address:&lt;/b&gt;</property>
-		  <property name="use_underline">True</property>
-		  <property name="use_markup">True</property>
-		  <property name="justify">GTK_JUSTIFY_LEFT</property>
-		  <property name="wrap">False</property>
-		  <property name="selectable">False</property>
-		  <property name="xalign">0</property>
-		  <property name="yalign">0.5</property>
-		  <property name="xpad">0</property>
-		  <property name="ypad">0</property>
-		  <property name="mnemonic_widget">iscsiAddrEntry</property>
-		  <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
-		  <property name="width_chars">-1</property>
-		  <property name="single_line_mode">False</property>
-		  <property name="angle">0</property>
-		</widget>
-		<packing>
-		  <property name="left_attach">0</property>
-		  <property name="right_attach">1</property>
-		  <property name="top_attach">0</property>
-		  <property name="bottom_attach">1</property>
-		  <property name="x_options">fill</property>
-		  <property name="y_options"></property>
-		</packing>
-	      </child>
-
-	      <child>
-		<widget class="GtkEntry" id="iscsiAddrEntry">
-		  <property name="visible">True</property>
-		  <property name="can_focus">True</property>
-		  <property name="editable">True</property>
-		  <property name="visibility">True</property>
-		  <property name="max_length">0</property>
-		  <property name="text" translatable="yes"></property>
-		  <property name="has_frame">True</property>
-		  <property name="invisible_char">â?¢</property>
-		  <property name="activates_default">False</property>
-		  <property name="width_chars">45</property>
-		</widget>
-		<packing>
-		  <property name="left_attach">1</property>
-		  <property name="right_attach">2</property>
-		  <property name="top_attach">0</property>
-		  <property name="bottom_attach">1</property>
-		  <property name="x_options">fill</property>
-		  <property name="y_options"></property>
-		</packing>
-	      </child>
-
-	      <child>
-		<widget class="GtkLabel" id="labeliscsiInititiator">
-		  <property name="visible">True</property>
-		  <property name="label" translatable="yes">&lt;b&gt;iSCSI Initiator _Name:&lt;/b&gt;</property>
-		  <property name="use_underline">True</property>
-		  <property name="use_markup">True</property>
-		  <property name="justify">GTK_JUSTIFY_LEFT</property>
-		  <property name="wrap">False</property>
-		  <property name="selectable">False</property>
-		  <property name="xalign">0</property>
-		  <property name="yalign">0.5</property>
-		  <property name="xpad">0</property>
-		  <property name="ypad">0</property>
-		  <property name="mnemonic_widget">iscsiInitiatorEntry</property>
-		  <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
-		  <property name="width_chars">-1</property>
-		  <property name="single_line_mode">False</property>
-		  <property name="angle">0</property>
-		</widget>
-		<packing>
-		  <property name="left_attach">0</property>
-		  <property name="right_attach">1</property>
-		  <property name="top_attach">1</property>
-		  <property name="bottom_attach">2</property>
-		  <property name="x_options">fill</property>
-		  <property name="y_options"></property>
-		</packing>
-	      </child>
-
-	      <child>
-		<widget class="GtkEntry" id="iscsiInitiatorEntry">
-		  <property name="visible">True</property>
-		  <property name="can_focus">True</property>
-		  <property name="editable">True</property>
-		  <property name="visibility">True</property>
-		  <property name="max_length">0</property>
-		  <property name="text" translatable="yes"></property>
-		  <property name="has_frame">True</property>
-		  <property name="invisible_char">â?¢</property>
-		  <property name="activates_default">False</property>
-		  <property name="width_chars">45</property>
-		</widget>
-		<packing>
-		  <property name="left_attach">1</property>
-		  <property name="right_attach">2</property>
-		  <property name="top_attach">1</property>
-		  <property name="bottom_attach">2</property>
-		  <property name="x_options">fill</property>
-		  <property name="y_options"></property>
-		</packing>
-	      </child>
-
-	      <child>
-		<widget class="GtkLabel" id="userLabel">
-		  <property name="visible">True</property>
-		  <property name="label" translatable="yes">&lt;b&gt;CHAP _Username:&lt;/b&gt;</property>
-		  <property name="use_underline">True</property>
-		  <property name="use_markup">True</property>
-		  <property name="justify">GTK_JUSTIFY_LEFT</property>
-		  <property name="wrap">False</property>
-		  <property name="selectable">False</property>
-		  <property name="xalign">0</property>
-		  <property name="yalign">0.5</property>
-		  <property name="xpad">0</property>
-		  <property name="ypad">0</property>
-		  <property name="mnemonic_widget">userEntry</property>
-		  <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
-		  <property name="width_chars">-1</property>
-		  <property name="single_line_mode">False</property>
-		  <property name="angle">0</property>
-		</widget>
-		<packing>
-		  <property name="left_attach">0</property>
-		  <property name="right_attach">1</property>
-		  <property name="top_attach">2</property>
-		  <property name="bottom_attach">3</property>
-		  <property name="x_options">fill</property>
-		  <property name="y_options"></property>
-		</packing>
-	      </child>
-
-	      <child>
-		<widget class="GtkEntry" id="userEntry">
-		  <property name="visible">True</property>
-		  <property name="can_focus">True</property>
-		  <property name="editable">True</property>
-		  <property name="visibility">True</property>
-		  <property name="max_length">0</property>
-		  <property name="text" translatable="yes"></property>
-		  <property name="has_frame">True</property>
-		  <property name="invisible_char">â?¢</property>
-		  <property name="activates_default">False</property>
-		  <property name="width_chars">45</property>
-		</widget>
-		<packing>
-		  <property name="left_attach">1</property>
-		  <property name="right_attach">2</property>
-		  <property name="top_attach">2</property>
-		  <property name="bottom_attach">3</property>
-		  <property name="x_options">fill</property>
-		  <property name="y_options"></property>
-		</packing>
-	      </child>
-
-	      <child>
-		<widget class="GtkLabel" id="passLabel">
-		  <property name="visible">True</property>
-		  <property name="label" translatable="yes">&lt;b&gt;CHAP _Password:&lt;/b&gt;</property>
-		  <property name="use_underline">True</property>
-		  <property name="use_markup">True</property>
-		  <property name="justify">GTK_JUSTIFY_LEFT</property>
-		  <property name="wrap">False</property>
-		  <property name="selectable">False</property>
-		  <property name="xalign">0</property>
-		  <property name="yalign">0.5</property>
-		  <property name="xpad">0</property>
-		  <property name="ypad">0</property>
-		  <property name="mnemonic_widget">passEntry</property>
-		  <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
-		  <property name="width_chars">-1</property>
-		  <property name="single_line_mode">False</property>
-		  <property name="angle">0</property>
-		</widget>
-		<packing>
-		  <property name="left_attach">0</property>
-		  <property name="right_attach">1</property>
-		  <property name="top_attach">3</property>
-		  <property name="bottom_attach">4</property>
-		  <property name="x_options">fill</property>
-		  <property name="y_options"></property>
-		</packing>
-	      </child>
-
-	      <child>
-		<widget class="GtkEntry" id="passEntry">
-		  <property name="visible">True</property>
-		  <property name="can_focus">True</property>
-		  <property name="editable">True</property>
-		  <property name="visibility">False</property>
-		  <property name="max_length">0</property>
-		  <property name="text" translatable="yes"></property>
-		  <property name="has_frame">True</property>
-		  <property name="invisible_char">â?¢</property>
-		  <property name="activates_default">False</property>
-		  <property name="width_chars">45</property>
-		</widget>
-		<packing>
-		  <property name="left_attach">1</property>
-		  <property name="right_attach">2</property>
-		  <property name="top_attach">3</property>
-		  <property name="bottom_attach">4</property>
-		  <property name="x_options">fill</property>
-		  <property name="y_options"></property>
-		</packing>
-	      </child>
-
-	      <child>
-		<widget class="GtkLabel" id="userinLabel">
-		  <property name="visible">True</property>
-		  <property name="label" translatable="yes">&lt;b&gt;Reverse CHAP U_sername:&lt;/b&gt;</property>
-		  <property name="use_underline">True</property>
-		  <property name="use_markup">True</property>
-		  <property name="justify">GTK_JUSTIFY_LEFT</property>
-		  <property name="wrap">False</property>
-		  <property name="selectable">False</property>
-		  <property name="xalign">0</property>
-		  <property name="yalign">0.5</property>
-		  <property name="xpad">0</property>
-		  <property name="ypad">0</property>
-		  <property name="mnemonic_widget">userinEntry</property>
-		  <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
-		  <property name="width_chars">-1</property>
-		  <property name="single_line_mode">False</property>
-		  <property name="angle">0</property>
-		</widget>
-		<packing>
-		  <property name="left_attach">0</property>
-		  <property name="right_attach">1</property>
-		  <property name="top_attach">4</property>
-		  <property name="bottom_attach">5</property>
-		  <property name="x_options">fill</property>
-		  <property name="y_options"></property>
-		</packing>
-	      </child>
-
-	      <child>
-		<widget class="GtkEntry" id="userinEntry">
-		  <property name="visible">True</property>
-		  <property name="can_focus">True</property>
-		  <property name="editable">True</property>
-		  <property name="visibility">True</property>
-		  <property name="max_length">0</property>
-		  <property name="text" translatable="yes"></property>
-		  <property name="has_frame">True</property>
-		  <property name="invisible_char">â?¢</property>
-		  <property name="activates_default">False</property>
-		  <property name="width_chars">45</property>
-		</widget>
-		<packing>
-		  <property name="left_attach">1</property>
-		  <property name="right_attach">2</property>
-		  <property name="top_attach">4</property>
-		  <property name="bottom_attach">5</property>
-		  <property name="x_options">fill</property>
-		  <property name="y_options"></property>
-		</packing>
-	      </child>
-
-	      <child>
-		<widget class="GtkLabel" id="passinLabel">
-		  <property name="visible">True</property>
-		  <property name="label" translatable="yes">&lt;b&gt;Reverse CHAP P_assword:&lt;/b&gt;</property>
-		  <property name="use_underline">True</property>
-		  <property name="use_markup">True</property>
-		  <property name="justify">GTK_JUSTIFY_LEFT</property>
-		  <property name="wrap">False</property>
-		  <property name="selectable">False</property>
-		  <property name="xalign">0</property>
-		  <property name="yalign">0.5</property>
-		  <property name="xpad">0</property>
-		  <property name="ypad">0</property>
-		  <property name="mnemonic_widget">passinEntry</property>
-		  <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
-		  <property name="width_chars">-1</property>
-		  <property name="single_line_mode">False</property>
-		  <property name="angle">0</property>
-		</widget>
-		<packing>
-		  <property name="left_attach">0</property>
-		  <property name="right_attach">1</property>
-		  <property name="top_attach">5</property>
-		  <property name="bottom_attach">6</property>
-		  <property name="x_options">fill</property>
-		  <property name="y_options"></property>
-		</packing>
-	      </child>
-
-	      <child>
-		<widget class="GtkEntry" id="passinEntry">
-		  <property name="visible">True</property>
-		  <property name="can_focus">True</property>
-		  <property name="editable">True</property>
-		  <property name="visibility">False</property>
-		  <property name="max_length">0</property>
-		  <property name="text" translatable="yes"></property>
-		  <property name="has_frame">True</property>
-		  <property name="invisible_char">â?¢</property>
-		  <property name="activates_default">False</property>
-		  <property name="width_chars">45</property>
-		</widget>
-		<packing>
-		  <property name="left_attach">1</property>
-		  <property name="right_attach">2</property>
-		  <property name="top_attach">5</property>
-		  <property name="bottom_attach">6</property>
-		  <property name="x_options">fill</property>
-		  <property name="y_options"></property>
-		</packing>
-	      </child>
-	    </widget>
-	    <packing>
-	      <property name="padding">0</property>
-	      <property name="expand">True</property>
-	      <property name="fill">True</property>
-	    </packing>
-	  </child>
-	</widget>
-	<packing>
-	  <property name="padding">0</property>
-	  <property name="expand">True</property>
-	  <property name="fill">True</property>
-	</packing>
-      </child>
-    </widget>
-  </child>
-</widget>
-
-</glade-interface>
diff --git a/ui/lukspassphrase.glade b/ui/lukspassphrase.glade
deleted file mode 100644
index b688e8a..0000000
--- a/ui/lukspassphrase.glade
+++ /dev/null
@@ -1,446 +0,0 @@
-<?xml version="1.0" standalone="no"?> <!--*- mode: xml -*-->
-<!DOCTYPE glade-interface SYSTEM "http://glade.gnome.org/glade-2.0.dtd";>
-
-<glade-interface>
-
-<widget class="GtkDialog" id="luksPassphraseDialog">
-  <property name="visible">True</property>
-  <property name="title" translatable="yes">Enter passphrase for encrypted partition</property>
-  <property name="type">GTK_WINDOW_TOPLEVEL</property>
-  <property name="window_position">GTK_WIN_POS_CENTER</property>
-  <property name="modal">False</property>
-  <property name="resizable">True</property>
-  <property name="destroy_with_parent">False</property>
-  <property name="decorated">True</property>
-  <property name="skip_taskbar_hint">False</property>
-  <property name="skip_pager_hint">False</property>
-  <property name="type_hint">GDK_WINDOW_TYPE_HINT_DIALOG</property>
-  <property name="gravity">GDK_GRAVITY_NORTH_WEST</property>
-  <property name="focus_on_map">True</property>
-  <property name="urgency_hint">False</property>
-  <property name="has_separator">True</property>
-
-  <child internal-child="vbox">
-    <widget class="GtkVBox" id="dialog-vbox1">
-      <property name="visible">True</property>
-      <property name="homogeneous">False</property>
-      <property name="spacing">0</property>
-
-      <child internal-child="action_area">
-	<widget class="GtkHButtonBox" id="dialog-action_area1">
-	  <property name="visible">True</property>
-	  <property name="layout_style">GTK_BUTTONBOX_END</property>
-
-	  <child>
-	    <widget class="GtkButton" id="cancelbutton1">
-	      <property name="visible">True</property>
-	      <property name="can_default">True</property>
-	      <property name="can_focus">True</property>
-	      <property name="label">gtk-cancel</property>
-	      <property name="use_stock">True</property>
-	      <property name="relief">GTK_RELIEF_NORMAL</property>
-	      <property name="focus_on_click">True</property>
-	      <property name="response_id">-6</property>
-	    </widget>
-	  </child>
-
-	  <child>
-	    <widget class="GtkButton" id="okbutton1">
-	      <property name="visible">True</property>
-	      <property name="can_default">True</property>
-	      <property name="can_focus">True</property>
-	      <property name="label">gtk-ok</property>
-	      <property name="use_stock">True</property>
-	      <property name="relief">GTK_RELIEF_NORMAL</property>
-	      <property name="focus_on_click">True</property>
-	      <property name="response_id">-5</property>
-	    </widget>
-	  </child>
-	</widget>
-	<packing>
-	  <property name="padding">0</property>
-	  <property name="expand">False</property>
-	  <property name="fill">True</property>
-	  <property name="pack_type">GTK_PACK_END</property>
-	</packing>
-      </child>
-
-      <child>
-	<widget class="GtkVBox" id="vbox1">
-	  <property name="visible">True</property>
-	  <property name="homogeneous">False</property>
-	  <property name="spacing">0</property>
-
-	  <child>
-	    <widget class="GtkHBox" id="hbox2">
-	      <property name="visible">True</property>
-	      <property name="homogeneous">False</property>
-	      <property name="spacing">0</property>
-
-	      <child>
-		<widget class="GtkImage" id="image2">
-		  <property name="visible">True</property>
-		  <property name="icon_size">6</property>
-		  <property name="icon_name">gtk-dialog-authentication</property>
-		  <property name="xalign">0.5</property>
-		  <property name="yalign">0.5</property>
-		  <property name="xpad">0</property>
-		  <property name="ypad">0</property>
-		</widget>
-		<packing>
-		  <property name="padding">0</property>
-		  <property name="expand">True</property>
-		  <property name="fill">True</property>
-		</packing>
-	      </child>
-
-	      <child>
-		<widget class="GtkLabel" id="mainLabel">
-		  <property name="visible">True</property>
-		  <property name="label" translatable="yes">Choose a passphrase for this encrypted partition. You will be prompted for the passphrase during system boot.</property>
-		  <property name="use_underline">False</property>
-		  <property name="use_markup">False</property>
-		  <property name="justify">GTK_JUSTIFY_LEFT</property>
-		  <property name="wrap">True</property>
-		  <property name="selectable">False</property>
-		  <property name="xalign">0</property>
-		  <property name="yalign">0.5</property>
-		  <property name="xpad">5</property>
-		  <property name="ypad">15</property>
-		  <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
-		  <property name="width_chars">-1</property>
-		  <property name="single_line_mode">False</property>
-		  <property name="angle">0</property>
-		</widget>
-		<packing>
-		  <property name="padding">0</property>
-		  <property name="expand">True</property>
-		  <property name="fill">True</property>
-		</packing>
-	      </child>
-	    </widget>
-	    <packing>
-	      <property name="padding">0</property>
-	      <property name="expand">False</property>
-	      <property name="fill">False</property>
-	    </packing>
-	  </child>
-
-	  <child>
-	    <widget class="GtkTable" id="entryTable">
-	      <property name="visible">True</property>
-	      <property name="n_rows">2</property>
-	      <property name="n_columns">2</property>
-	      <property name="homogeneous">False</property>
-	      <property name="row_spacing">10</property>
-	      <property name="column_spacing">5</property>
-
-	      <child>
-		<widget class="GtkLabel" id="passphraseEntryLabel">
-		  <property name="visible">True</property>
-		  <property name="label" translatable="yes">Enter passphrase:</property>
-		  <property name="use_underline">False</property>
-		  <property name="use_markup">False</property>
-		  <property name="justify">GTK_JUSTIFY_RIGHT</property>
-		  <property name="wrap">False</property>
-		  <property name="selectable">False</property>
-		  <property name="xalign">0</property>
-		  <property name="yalign">0.5</property>
-		  <property name="xpad">5</property>
-		  <property name="ypad">0</property>
-		  <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
-		  <property name="width_chars">-1</property>
-		  <property name="single_line_mode">False</property>
-		  <property name="angle">0</property>
-		</widget>
-		<packing>
-		  <property name="left_attach">0</property>
-		  <property name="right_attach">1</property>
-		  <property name="top_attach">0</property>
-		  <property name="bottom_attach">1</property>
-		  <property name="x_options">fill</property>
-		  <property name="y_options"></property>
-		</packing>
-	      </child>
-
-	      <child>
-		<widget class="GtkLabel" id="confirmEntryLabel">
-		  <property name="visible">True</property>
-		  <property name="label" translatable="yes">Confirm passphrase:</property>
-		  <property name="use_underline">False</property>
-		  <property name="use_markup">False</property>
-		  <property name="justify">GTK_JUSTIFY_RIGHT</property>
-		  <property name="wrap">False</property>
-		  <property name="selectable">False</property>
-		  <property name="xalign">0</property>
-		  <property name="yalign">0.5</property>
-		  <property name="xpad">5</property>
-		  <property name="ypad">0</property>
-		  <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
-		  <property name="width_chars">-1</property>
-		  <property name="single_line_mode">False</property>
-		  <property name="angle">0</property>
-		</widget>
-		<packing>
-		  <property name="left_attach">0</property>
-		  <property name="right_attach">1</property>
-		  <property name="top_attach">1</property>
-		  <property name="bottom_attach">2</property>
-		  <property name="x_options">fill</property>
-		  <property name="y_options"></property>
-		</packing>
-	      </child>
-
-	      <child>
-		<widget class="GtkEntry" id="passphraseEntry">
-		  <property name="visible">True</property>
-		  <property name="can_focus">True</property>
-		  <property name="editable">True</property>
-		  <property name="visibility">False</property>
-		  <property name="max_length">500</property>
-		  <property name="text" translatable="yes"></property>
-		  <property name="has_frame">True</property>
-		  <property name="invisible_char">â?¢</property>
-		  <property name="activates_default">False</property>
-		</widget>
-		<packing>
-		  <property name="left_attach">1</property>
-		  <property name="right_attach">2</property>
-		  <property name="top_attach">0</property>
-		  <property name="bottom_attach">1</property>
-		  <property name="y_options"></property>
-		</packing>
-	      </child>
-
-	      <child>
-		<widget class="GtkEntry" id="confirmEntry">
-		  <property name="visible">True</property>
-		  <property name="can_focus">True</property>
-		  <property name="editable">True</property>
-		  <property name="visibility">False</property>
-		  <property name="max_length">500</property>
-		  <property name="text" translatable="yes"></property>
-		  <property name="has_frame">True</property>
-		  <property name="invisible_char">â?¢</property>
-		  <property name="activates_default">False</property>
-		</widget>
-		<packing>
-		  <property name="left_attach">1</property>
-		  <property name="right_attach">2</property>
-		  <property name="top_attach">1</property>
-		  <property name="bottom_attach">2</property>
-		  <property name="y_options"></property>
-		</packing>
-	      </child>
-	    </widget>
-	    <packing>
-	      <property name="padding">0</property>
-	      <property name="expand">True</property>
-	      <property name="fill">True</property>
-	    </packing>
-	  </child>
-
-	  <child>
-	    <widget class="GtkCheckButton" id="globalcheckbutton">
-	      <property name="border_width">5</property>
-	      <property name="visible">True</property>
-	      <property name="can_focus">True</property>
-	      <property name="label" translatable="yes">Also add this passphrase to all existing encrypted devices to streamline the boot process</property>
-	      <property name="use_underline">True</property>
-	      <property name="relief">GTK_RELIEF_NORMAL</property>
-	      <property name="focus_on_click">True</property>
-	      <property name="active">False</property>
-	      <property name="inconsistent">False</property>
-	      <property name="draw_indicator">True</property>
-	    </widget>
-	    <packing>
-	      <property name="padding">0</property>
-	      <property name="expand">False</property>
-	      <property name="fill">False</property>
-	    </packing>
-	  </child>
-	</widget>
-	<packing>
-	  <property name="padding">0</property>
-	  <property name="expand">True</property>
-	  <property name="fill">True</property>
-	</packing>
-      </child>
-    </widget>
-  </child>
-</widget>
-
-<widget class="GtkDialog" id="passphraseEntryDialog">
-  <property name="visible">True</property>
-  <property name="title" translatable="yes">Passphrase</property>
-  <property name="type">GTK_WINDOW_TOPLEVEL</property>
-  <property name="window_position">GTK_WIN_POS_CENTER_ALWAYS</property>
-  <property name="modal">True</property>
-  <property name="resizable">True</property>
-  <property name="destroy_with_parent">False</property>
-  <property name="icon_name">gtk-dialog-authentication</property>
-  <property name="decorated">True</property>
-  <property name="skip_taskbar_hint">False</property>
-  <property name="skip_pager_hint">False</property>
-  <property name="type_hint">GDK_WINDOW_TYPE_HINT_DIALOG</property>
-  <property name="gravity">GDK_GRAVITY_NORTH_WEST</property>
-  <property name="focus_on_map">True</property>
-  <property name="urgency_hint">False</property>
-  <property name="has_separator">True</property>
-
-  <child internal-child="vbox">
-    <widget class="GtkVBox" id="dialog2-vbox1">
-      <property name="visible">True</property>
-      <property name="homogeneous">False</property>
-      <property name="spacing">0</property>
-
-      <child internal-child="action_area">
-	<widget class="GtkHButtonBox" id="dialog2-action_area1">
-	  <property name="visible">True</property>
-	  <property name="layout_style">GTK_BUTTONBOX_END</property>
-
-	  <child>
-	    <widget class="GtkButton" id="cancelbutton2">
-	      <property name="visible">True</property>
-	      <property name="can_default">True</property>
-	      <property name="can_focus">True</property>
-	      <property name="label">gtk-cancel</property>
-	      <property name="use_stock">True</property>
-	      <property name="relief">GTK_RELIEF_NORMAL</property>
-	      <property name="focus_on_click">True</property>
-	      <property name="response_id">-6</property>
-	    </widget>
-	  </child>
-
-	  <child>
-	    <widget class="GtkButton" id="okbutton2">
-	      <property name="visible">True</property>
-	      <property name="can_default">True</property>
-	      <property name="can_focus">True</property>
-	      <property name="label">gtk-ok</property>
-	      <property name="use_stock">True</property>
-	      <property name="relief">GTK_RELIEF_NORMAL</property>
-	      <property name="focus_on_click">True</property>
-	      <property name="response_id">-5</property>
-	    </widget>
-	  </child>
-	</widget>
-	<packing>
-	  <property name="padding">0</property>
-	  <property name="expand">False</property>
-	  <property name="fill">True</property>
-	  <property name="pack_type">GTK_PACK_END</property>
-	</packing>
-      </child>
-
-      <child>
-	<widget class="GtkVBox" id="vbox2">
-	  <property name="visible">True</property>
-	  <property name="homogeneous">False</property>
-	  <property name="spacing">0</property>
-
-	  <child>
-	    <widget class="GtkHBox" id="hbox1">
-	      <property name="visible">True</property>
-	      <property name="homogeneous">False</property>
-	      <property name="spacing">12</property>
-
-	      <child>
-		<widget class="GtkImage" id="image1">
-		  <property name="visible">True</property>
-		  <property name="icon_size">6</property>
-		  <property name="icon_name">gtk-dialog-authentication</property>
-		  <property name="xalign">0.5</property>
-		  <property name="yalign">0.5</property>
-		  <property name="xpad">0</property>
-		  <property name="ypad">0</property>
-		</widget>
-		<packing>
-		  <property name="padding">0</property>
-		  <property name="expand">False</property>
-		  <property name="fill">True</property>
-		</packing>
-	      </child>
-
-	      <child>
-		<widget class="GtkLabel" id="passphraseLabel">
-		  <property name="visible">True</property>
-		  <property name="label" translatable="yes">label1</property>
-		  <property name="use_underline">False</property>
-		  <property name="use_markup">False</property>
-		  <property name="justify">GTK_JUSTIFY_LEFT</property>
-		  <property name="wrap">True</property>
-		  <property name="selectable">False</property>
-		  <property name="xalign">0.5</property>
-		  <property name="yalign">0.5</property>
-		  <property name="xpad">0</property>
-		  <property name="ypad">0</property>
-		  <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
-		  <property name="width_chars">-1</property>
-		  <property name="single_line_mode">False</property>
-		  <property name="angle">0</property>
-		</widget>
-		<packing>
-		  <property name="padding">0</property>
-		  <property name="expand">True</property>
-		  <property name="fill">True</property>
-		</packing>
-	      </child>
-	    </widget>
-	    <packing>
-	      <property name="padding">0</property>
-	      <property name="expand">False</property>
-	      <property name="fill">False</property>
-	    </packing>
-	  </child>
-
-	  <child>
-	    <widget class="GtkEntry" id="passphraseEntry2">
-	      <property name="visible">True</property>
-	      <property name="can_focus">True</property>
-	      <property name="has_focus">True</property>
-	      <property name="editable">True</property>
-	      <property name="visibility">False</property>
-	      <property name="max_length">500</property>
-	      <property name="text" translatable="yes"></property>
-	      <property name="has_frame">True</property>
-	      <property name="invisible_char">â?¢</property>
-	      <property name="activates_default">False</property>
-	    </widget>
-	    <packing>
-	      <property name="padding">0</property>
-	      <property name="expand">False</property>
-	      <property name="fill">False</property>
-	    </packing>
-	  </child>
-
-	  <child>
-	    <widget class="GtkCheckButton" id="globalcheckbutton">
-	      <property name="visible">True</property>
-	      <property name="can_focus">True</property>
-	      <property name="label" translatable="yes">This is a global passphrase</property>
-	      <property name="use_underline">True</property>
-	      <property name="relief">GTK_RELIEF_NORMAL</property>
-	      <property name="focus_on_click">True</property>
-	      <property name="active">False</property>
-	      <property name="inconsistent">False</property>
-	      <property name="draw_indicator">True</property>
-	    </widget>
-	    <packing>
-	      <property name="padding">0</property>
-	      <property name="expand">False</property>
-	      <property name="fill">False</property>
-	    </packing>
-	  </child>
-	</widget>
-	<packing>
-	  <property name="padding">0</property>
-	  <property name="expand">True</property>
-	  <property name="fill">True</property>
-	</packing>
-      </child>
-    </widget>
-  </child>
-</widget>
-
-</glade-interface>
diff --git a/ui/netconfig.glade b/ui/netconfig.glade
deleted file mode 100644
index cb8991f..0000000
--- a/ui/netconfig.glade
+++ /dev/null
@@ -1,538 +0,0 @@
-<?xml version="1.0" standalone="no"?> <!--*- mode: xml -*-->
-<!DOCTYPE glade-interface SYSTEM "http://glade.gnome.org/glade-2.0.dtd";>
-
-<glade-interface>
-
-<widget class="GtkDialog" id="NetworkConfigWindow">
-  <property name="visible">True</property>
-  <property name="title" translatable="yes">Enable network interface</property>
-  <property name="type">GTK_WINDOW_TOPLEVEL</property>
-  <property name="window_position">GTK_WIN_POS_CENTER_ALWAYS</property>
-  <property name="modal">False</property>
-  <property name="resizable">True</property>
-  <property name="destroy_with_parent">False</property>
-  <property name="decorated">True</property>
-  <property name="skip_taskbar_hint">False</property>
-  <property name="skip_pager_hint">False</property>
-  <property name="type_hint">GDK_WINDOW_TYPE_HINT_DIALOG</property>
-  <property name="gravity">GDK_GRAVITY_NORTH_WEST</property>
-  <property name="focus_on_map">True</property>
-  <property name="urgency_hint">False</property>
-  <property name="has_separator">True</property>
-
-  <child internal-child="vbox">
-    <widget class="GtkVBox" id="dialog-vbox1">
-      <property name="visible">True</property>
-      <property name="homogeneous">False</property>
-      <property name="spacing">0</property>
-
-      <child internal-child="action_area">
-	<widget class="GtkHButtonBox" id="dialog-action_area1">
-	  <property name="visible">True</property>
-	  <property name="layout_style">GTK_BUTTONBOX_END</property>
-
-	  <child>
-	    <widget class="GtkButton" id="cancelButton">
-	      <property name="visible">True</property>
-	      <property name="can_default">True</property>
-	      <property name="can_focus">True</property>
-	      <property name="label">gtk-cancel</property>
-	      <property name="use_stock">True</property>
-	      <property name="relief">GTK_RELIEF_NORMAL</property>
-	      <property name="focus_on_click">True</property>
-	      <property name="response_id">-6</property>
-	    </widget>
-	  </child>
-
-	  <child>
-	    <widget class="GtkButton" id="okButton">
-	      <property name="visible">True</property>
-	      <property name="can_default">True</property>
-	      <property name="can_focus">True</property>
-	      <property name="label">gtk-ok</property>
-	      <property name="use_stock">True</property>
-	      <property name="relief">GTK_RELIEF_NORMAL</property>
-	      <property name="focus_on_click">True</property>
-	      <property name="response_id">-5</property>
-	    </widget>
-	  </child>
-	</widget>
-	<packing>
-	  <property name="padding">0</property>
-	  <property name="expand">False</property>
-	  <property name="fill">True</property>
-	  <property name="pack_type">GTK_PACK_END</property>
-	</packing>
-      </child>
-
-      <child>
-	<widget class="GtkVBox" id="vbox1">
-	  <property name="border_width">18</property>
-	  <property name="visible">True</property>
-	  <property name="homogeneous">False</property>
-	  <property name="spacing">12</property>
-
-	  <child>
-	    <widget class="GtkLabel" id="label1">
-	      <property name="visible">True</property>
-	      <property name="label" translatable="yes" context="yes">This requires that you have an active network connection during the installation process.  Please configure a network interface.</property>
-	      <property name="use_underline">False</property>
-	      <property name="use_markup">False</property>
-	      <property name="justify">GTK_JUSTIFY_LEFT</property>
-	      <property name="wrap">True</property>
-	      <property name="selectable">False</property>
-	      <property name="xalign">0</property>
-	      <property name="yalign">0</property>
-	      <property name="xpad">0</property>
-	      <property name="ypad">0</property>
-	      <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
-	      <property name="width_chars">-1</property>
-	      <property name="single_line_mode">False</property>
-	      <property name="angle">0</property>
-	    </widget>
-	    <packing>
-	      <property name="padding">0</property>
-	      <property name="expand">False</property>
-	      <property name="fill">False</property>
-	    </packing>
-	  </child>
-
-	  <child>
-	    <widget class="GtkHBox" id="interfaceBox">
-	      <property name="visible">True</property>
-	      <property name="homogeneous">False</property>
-	      <property name="spacing">6</property>
-
-	      <child>
-		<widget class="GtkLabel" id="interfaceLabel">
-		  <property name="visible">True</property>
-		  <property name="label" translatable="yes" context="yes">&lt;b&gt;_Interface:&lt;/b&gt;</property>
-		  <property name="use_underline">True</property>
-		  <property name="use_markup">True</property>
-		  <property name="justify">GTK_JUSTIFY_LEFT</property>
-		  <property name="wrap">False</property>
-		  <property name="selectable">False</property>
-		  <property name="xalign">0</property>
-		  <property name="yalign">0.5</property>
-		  <property name="xpad">0</property>
-		  <property name="ypad">0</property>
-		  <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
-		  <property name="width_chars">-1</property>
-		  <property name="single_line_mode">False</property>
-		  <property name="angle">0</property>
-		</widget>
-		<packing>
-		  <property name="padding">0</property>
-		  <property name="expand">False</property>
-		  <property name="fill">False</property>
-		</packing>
-	      </child>
-
-	      <child>
-		<widget class="GtkComboBox" id="interfaceCombo">
-		  <property name="visible">True</property>
-		  <property name="add_tearoffs">False</property>
-		  <property name="focus_on_click">True</property>
-		  <signal name="changed" handler="on_interfaceCombo_changed"/>
-		</widget>
-		<packing>
-		  <property name="padding">0</property>
-		  <property name="expand">True</property>
-		  <property name="fill">True</property>
-		</packing>
-	      </child>
-	    </widget>
-	    <packing>
-	      <property name="padding">0</property>
-	      <property name="expand">True</property>
-	      <property name="fill">True</property>
-	    </packing>
-	  </child>
-
-	  <child>
-	    <widget class="GtkCheckButton" id="dhcpCheckbutton">
-	      <property name="visible">True</property>
-	      <property name="label" translatable="yes" context="yes">Use _dynamic IP configuration (DHCP)</property>
-	      <property name="use_underline">True</property>
-	      <property name="relief">GTK_RELIEF_NORMAL</property>
-	      <property name="focus_on_click">True</property>
-	      <property name="active">False</property>
-	      <property name="inconsistent">False</property>
-	      <property name="draw_indicator">True</property>
-	      <signal name="toggled" handler="on_dhcpCheckbutton_toggled"/>
-	    </widget>
-	    <packing>
-	      <property name="padding">0</property>
-	      <property name="expand">True</property>
-	      <property name="fill">True</property>
-	    </packing>
-	  </child>
-
-	  <child>
-	    <widget class="GtkCheckButton" id="ipv4Checkbutton">
-	      <property name="visible">True</property>
-	      <property name="label" translatable="yes" context="yes">Enable IPv_4 support</property>
-	      <property name="use_underline">True</property>
-	      <property name="relief">GTK_RELIEF_NORMAL</property>
-	      <property name="focus_on_click">True</property>
-	      <property name="active">False</property>
-	      <property name="inconsistent">False</property>
-	      <property name="draw_indicator">True</property>
-	      <signal name="toggled" handler="on_ipv4Checkbutton_toggled"/>
-	    </widget>
-	    <packing>
-	      <property name="padding">0</property>
-	      <property name="expand">True</property>
-	      <property name="fill">True</property>
-	    </packing>
-	  </child>
-
-	  <child>
-	    <widget class="GtkCheckButton" id="ipv6Checkbutton">
-	      <property name="label" translatable="yes" context="yes">Enable IPv_6 support</property>
-	      <property name="use_underline">True</property>
-	      <property name="relief">GTK_RELIEF_NORMAL</property>
-	      <property name="focus_on_click">True</property>
-	      <property name="active">False</property>
-	      <property name="inconsistent">False</property>
-	      <property name="draw_indicator">True</property>
-	      <signal name="toggled" handler="on_ipv6Checkbutton_toggled"/>
-	    </widget>
-	    <packing>
-	      <property name="padding">0</property>
-	      <property name="expand">True</property>
-	      <property name="fill">True</property>
-	    </packing>
-	  </child>
-
-	  <child>
-	    <widget class="GtkHBox" id="ipv4Box">
-	      <property name="visible">True</property>
-	      <property name="homogeneous">False</property>
-	      <property name="spacing">6</property>
-
-	      <child>
-		<widget class="GtkLabel" id="ipv4Label">
-		  <property name="visible">True</property>
-		  <property name="label" translatable="yes" context="yes">&lt;b&gt;IPv4 Address:&lt;/b&gt;</property>
-		  <property name="use_underline">False</property>
-		  <property name="use_markup">True</property>
-		  <property name="justify">GTK_JUSTIFY_LEFT</property>
-		  <property name="wrap">False</property>
-		  <property name="selectable">False</property>
-		  <property name="xalign">0</property>
-		  <property name="yalign">0.5</property>
-		  <property name="xpad">0</property>
-		  <property name="ypad">0</property>
-		  <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
-		  <property name="width_chars">-1</property>
-		  <property name="single_line_mode">False</property>
-		  <property name="angle">0</property>
-		</widget>
-		<packing>
-		  <property name="padding">0</property>
-		  <property name="expand">False</property>
-		  <property name="fill">False</property>
-		</packing>
-	      </child>
-
-	      <child>
-		<widget class="GtkEntry" id="ipv4Address">
-		  <property name="visible">True</property>
-		  <property name="editable">True</property>
-		  <property name="visibility">True</property>
-		  <property name="max_length">0</property>
-		  <property name="text" translatable="yes"></property>
-		  <property name="has_frame">True</property>
-		  <property name="invisible_char">â?¢</property>
-		  <property name="activates_default">False</property>
-		  <property name="width_chars">16</property>
-		</widget>
-		<packing>
-		  <property name="padding">0</property>
-		  <property name="expand">False</property>
-		  <property name="fill">True</property>
-		</packing>
-	      </child>
-
-	      <child>
-		<widget class="GtkLabel" id="label10">
-		  <property name="visible">True</property>
-		  <property name="label" translatable="yes" context="yes">/</property>
-		  <property name="use_underline">False</property>
-		  <property name="use_markup">False</property>
-		  <property name="justify">GTK_JUSTIFY_LEFT</property>
-		  <property name="wrap">False</property>
-		  <property name="selectable">False</property>
-		  <property name="xalign">0.5</property>
-		  <property name="yalign">0.5</property>
-		  <property name="xpad">0</property>
-		  <property name="ypad">0</property>
-		  <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
-		  <property name="width_chars">-1</property>
-		  <property name="single_line_mode">False</property>
-		  <property name="angle">0</property>
-		</widget>
-		<packing>
-		  <property name="padding">0</property>
-		  <property name="expand">False</property>
-		  <property name="fill">False</property>
-		</packing>
-	      </child>
-
-	      <child>
-		<widget class="GtkEntry" id="ipv4Netmask">
-		  <property name="visible">True</property>
-		  <property name="editable">True</property>
-		  <property name="visibility">True</property>
-		  <property name="max_length">0</property>
-		  <property name="text" translatable="yes"></property>
-		  <property name="has_frame">True</property>
-		  <property name="invisible_char">â?¢</property>
-		  <property name="activates_default">False</property>
-		  <property name="width_chars">16</property>
-		</widget>
-		<packing>
-		  <property name="padding">0</property>
-		  <property name="expand">False</property>
-		  <property name="fill">True</property>
-		</packing>
-	      </child>
-	    </widget>
-	    <packing>
-	      <property name="padding">0</property>
-	      <property name="expand">True</property>
-	      <property name="fill">True</property>
-	    </packing>
-	  </child>
-
-	  <child>
-	    <widget class="GtkHBox" id="ipv6Box">
-	      <property name="sensitive">False</property>
-	      <property name="homogeneous">False</property>
-	      <property name="spacing">6</property>
-
-	      <child>
-		<widget class="GtkLabel" id="ipv6Label">
-		  <property name="visible">True</property>
-		  <property name="label" translatable="yes" context="yes">&lt;b&gt;IPv6 Address:&lt;/b&gt;</property>
-		  <property name="use_underline">False</property>
-		  <property name="use_markup">True</property>
-		  <property name="justify">GTK_JUSTIFY_LEFT</property>
-		  <property name="wrap">False</property>
-		  <property name="selectable">False</property>
-		  <property name="xalign">0</property>
-		  <property name="yalign">0.5</property>
-		  <property name="xpad">0</property>
-		  <property name="ypad">0</property>
-		  <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
-		  <property name="width_chars">-1</property>
-		  <property name="single_line_mode">False</property>
-		  <property name="angle">0</property>
-		</widget>
-		<packing>
-		  <property name="padding">0</property>
-		  <property name="expand">False</property>
-		  <property name="fill">True</property>
-		</packing>
-	      </child>
-
-	      <child>
-		<widget class="GtkEntry" id="ipv6Address">
-		  <property name="visible">True</property>
-		  <property name="editable">True</property>
-		  <property name="visibility">True</property>
-		  <property name="max_length">0</property>
-		  <property name="text" translatable="yes"></property>
-		  <property name="has_frame">True</property>
-		  <property name="invisible_char">â?¢</property>
-		  <property name="activates_default">False</property>
-		  <property name="width_chars">41</property>
-		</widget>
-		<packing>
-		  <property name="padding">0</property>
-		  <property name="expand">False</property>
-		  <property name="fill">True</property>
-		</packing>
-	      </child>
-
-	      <child>
-		<widget class="GtkLabel" id="label11">
-		  <property name="visible">True</property>
-		  <property name="label" translatable="yes" context="yes">/</property>
-		  <property name="use_underline">False</property>
-		  <property name="use_markup">False</property>
-		  <property name="justify">GTK_JUSTIFY_LEFT</property>
-		  <property name="wrap">False</property>
-		  <property name="selectable">False</property>
-		  <property name="xalign">0.5</property>
-		  <property name="yalign">0.5</property>
-		  <property name="xpad">0</property>
-		  <property name="ypad">0</property>
-		  <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
-		  <property name="width_chars">-1</property>
-		  <property name="single_line_mode">False</property>
-		  <property name="angle">0</property>
-		</widget>
-		<packing>
-		  <property name="padding">0</property>
-		  <property name="expand">False</property>
-		  <property name="fill">False</property>
-		</packing>
-	      </child>
-
-	      <child>
-		<widget class="GtkEntry" id="ipv6Netmask">
-		  <property name="visible">True</property>
-		  <property name="editable">True</property>
-		  <property name="visibility">True</property>
-		  <property name="max_length">0</property>
-		  <property name="text" translatable="yes"></property>
-		  <property name="has_frame">True</property>
-		  <property name="invisible_char">â?¢</property>
-		  <property name="activates_default">False</property>
-		  <property name="width_chars">4</property>
-		</widget>
-		<packing>
-		  <property name="padding">0</property>
-		  <property name="expand">False</property>
-		  <property name="fill">True</property>
-		</packing>
-	      </child>
-	    </widget>
-	    <packing>
-	      <property name="padding">0</property>
-	      <property name="expand">True</property>
-	      <property name="fill">True</property>
-	    </packing>
-	  </child>
-
-	  <child>
-	    <widget class="GtkHBox" id="gatewayBox">
-	      <property name="visible">True</property>
-	      <property name="homogeneous">False</property>
-	      <property name="spacing">6</property>
-
-	      <child>
-		<widget class="GtkLabel" id="gatewayLabel">
-		  <property name="visible">True</property>
-		  <property name="label" translatable="yes" context="yes">&lt;b&gt;Gateway:&lt;/b&gt;</property>
-		  <property name="use_underline">False</property>
-		  <property name="use_markup">True</property>
-		  <property name="justify">GTK_JUSTIFY_LEFT</property>
-		  <property name="wrap">False</property>
-		  <property name="selectable">False</property>
-		  <property name="xalign">0</property>
-		  <property name="yalign">0.5</property>
-		  <property name="xpad">0</property>
-		  <property name="ypad">0</property>
-		  <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
-		  <property name="width_chars">-1</property>
-		  <property name="single_line_mode">False</property>
-		  <property name="angle">0</property>
-		</widget>
-		<packing>
-		  <property name="padding">0</property>
-		  <property name="expand">False</property>
-		  <property name="fill">True</property>
-		</packing>
-	      </child>
-
-	      <child>
-		<widget class="GtkEntry" id="gatewayEntry">
-		  <property name="visible">True</property>
-		  <property name="editable">True</property>
-		  <property name="visibility">True</property>
-		  <property name="max_length">0</property>
-		  <property name="text" translatable="yes"></property>
-		  <property name="has_frame">True</property>
-		  <property name="invisible_char">â?¢</property>
-		  <property name="activates_default">False</property>
-		  <property name="width_chars">41</property>
-		</widget>
-		<packing>
-		  <property name="padding">0</property>
-		  <property name="expand">False</property>
-		  <property name="fill">True</property>
-		</packing>
-	      </child>
-	    </widget>
-	    <packing>
-	      <property name="padding">0</property>
-	      <property name="expand">True</property>
-	      <property name="fill">True</property>
-	    </packing>
-	  </child>
-
-	  <child>
-	    <widget class="GtkHBox" id="nameserverBox">
-	      <property name="visible">True</property>
-	      <property name="homogeneous">False</property>
-	      <property name="spacing">6</property>
-
-	      <child>
-		<widget class="GtkLabel" id="nameserverLabel">
-		  <property name="visible">True</property>
-		  <property name="label" translatable="yes" context="yes">&lt;b&gt;Nameserver:&lt;/b&gt;</property>
-		  <property name="use_underline">False</property>
-		  <property name="use_markup">True</property>
-		  <property name="justify">GTK_JUSTIFY_LEFT</property>
-		  <property name="wrap">False</property>
-		  <property name="selectable">False</property>
-		  <property name="xalign">0</property>
-		  <property name="yalign">0.5</property>
-		  <property name="xpad">0</property>
-		  <property name="ypad">0</property>
-		  <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
-		  <property name="width_chars">-1</property>
-		  <property name="single_line_mode">False</property>
-		  <property name="angle">0</property>
-		</widget>
-		<packing>
-		  <property name="padding">0</property>
-		  <property name="expand">False</property>
-		  <property name="fill">True</property>
-		</packing>
-	      </child>
-
-	      <child>
-		<widget class="GtkEntry" id="nameserverEntry">
-		  <property name="visible">True</property>
-		  <property name="editable">True</property>
-		  <property name="visibility">True</property>
-		  <property name="max_length">0</property>
-		  <property name="text" translatable="yes"></property>
-		  <property name="has_frame">True</property>
-		  <property name="invisible_char">â?¢</property>
-		  <property name="activates_default">False</property>
-		  <property name="width_chars">41</property>
-		</widget>
-		<packing>
-		  <property name="padding">0</property>
-		  <property name="expand">False</property>
-		  <property name="fill">True</property>
-		</packing>
-	      </child>
-	    </widget>
-	    <packing>
-	      <property name="padding">0</property>
-	      <property name="expand">True</property>
-	      <property name="fill">True</property>
-	    </packing>
-	  </child>
-
-	  <child>
-	    <placeholder/>
-	  </child>
-	</widget>
-	<packing>
-	  <property name="padding">0</property>
-	  <property name="expand">True</property>
-	  <property name="fill">True</property>
-	</packing>
-      </child>
-    </widget>
-  </child>
-</widget>
-
-</glade-interface>
diff --git a/ui/network.glade b/ui/network.glade
deleted file mode 100644
index 1f17e2f..0000000
--- a/ui/network.glade
+++ /dev/null
@@ -1,259 +0,0 @@
-<?xml version="1.0" standalone="no"?> <!--*- mode: xml -*-->
-<!DOCTYPE glade-interface SYSTEM "http://glade.gnome.org/glade-2.0.dtd";>
-
-<glade-interface>
-
-<widget class="GtkWindow" id="network_window">
-  <property name="border_width">18</property>
-  <property name="title" translatable="yes" context="yes"></property>
-  <property name="type">GTK_WINDOW_TOPLEVEL</property>
-  <property name="window_position">GTK_WIN_POS_NONE</property>
-  <property name="modal">False</property>
-  <property name="resizable">True</property>
-  <property name="destroy_with_parent">False</property>
-  <property name="decorated">True</property>
-  <property name="skip_taskbar_hint">False</property>
-  <property name="skip_pager_hint">False</property>
-  <property name="type_hint">GDK_WINDOW_TYPE_HINT_NORMAL</property>
-  <property name="gravity">GDK_GRAVITY_NORTH_WEST</property>
-  <property name="focus_on_map">True</property>
-  <property name="urgency_hint">False</property>
-
-  <child>
-    <widget class="GtkAlignment" id="network_align">
-      <property name="width_request">400</property>
-      <property name="visible">True</property>
-      <property name="xalign">0</property>
-      <property name="yalign">0</property>
-      <property name="xscale">1</property>
-      <property name="yscale">1</property>
-      <property name="top_padding">0</property>
-      <property name="bottom_padding">0</property>
-      <property name="left_padding">0</property>
-      <property name="right_padding">0</property>
-
-      <child>
-	<widget class="GtkVBox" id="account_box">
-	  <property name="border_width">5</property>
-	  <property name="visible">True</property>
-	  <property name="homogeneous">False</property>
-	  <property name="spacing">10</property>
-
-	  <child>
-	    <widget class="GtkAlignment" id="alignment2">
-	      <property name="visible">True</property>
-	      <property name="xalign">0</property>
-	      <property name="yalign">0</property>
-	      <property name="xscale">1</property>
-	      <property name="yscale">1</property>
-	      <property name="top_padding">0</property>
-	      <property name="bottom_padding">0</property>
-	      <property name="left_padding">0</property>
-	      <property name="right_padding">0</property>
-
-	      <child>
-		<widget class="GtkHBox" id="desc_box">
-		  <property name="visible">True</property>
-		  <property name="homogeneous">False</property>
-		  <property name="spacing">0</property>
-
-		  <child>
-		    <widget class="GtkImage" id="icon">
-		      <property name="visible">True</property>
-		      <property name="xalign">0.5</property>
-		      <property name="yalign">0.5</property>
-		      <property name="xpad">10</property>
-		      <property name="ypad">0</property>
-		    </widget>
-		    <packing>
-		      <property name="padding">0</property>
-		      <property name="expand">False</property>
-		      <property name="fill">False</property>
-		    </packing>
-		  </child>
-
-		  <child>
-		    <widget class="GtkLabel" id="desc">
-		      <property name="visible">True</property>
-		      <property name="label" translatable="yes">Please name this computer.  The hostname identifies the computer on a network.</property>
-		      <property name="use_underline">False</property>
-		      <property name="use_markup">False</property>
-		      <property name="justify">GTK_JUSTIFY_LEFT</property>
-		      <property name="wrap">True</property>
-		      <property name="selectable">False</property>
-		      <property name="xalign">0</property>
-		      <property name="yalign">0.5</property>
-		      <property name="xpad">0</property>
-		      <property name="ypad">0</property>
-		      <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
-		      <property name="width_chars">-1</property>
-		      <property name="single_line_mode">False</property>
-		      <property name="angle">0</property>
-		    </widget>
-		    <packing>
-		      <property name="padding">0</property>
-		      <property name="expand">False</property>
-		      <property name="fill">False</property>
-		    </packing>
-		  </child>
-		</widget>
-	      </child>
-	    </widget>
-	    <packing>
-	      <property name="padding">0</property>
-	      <property name="expand">False</property>
-	      <property name="fill">False</property>
-	    </packing>
-	  </child>
-
-	  <child>
-	    <widget class="GtkAlignment" id="alignment4">
-	      <property name="visible">True</property>
-	      <property name="xalign">0.5</property>
-	      <property name="yalign">0.5</property>
-	      <property name="xscale">1</property>
-	      <property name="yscale">1</property>
-	      <property name="top_padding">0</property>
-	      <property name="bottom_padding">0</property>
-	      <property name="left_padding">0</property>
-	      <property name="right_padding">0</property>
-
-	      <child>
-		<widget class="GtkTable" id="table1">
-		  <property name="width_request">365</property>
-		  <property name="visible">True</property>
-		  <property name="n_rows">1</property>
-		  <property name="n_columns">2</property>
-		  <property name="homogeneous">False</property>
-		  <property name="row_spacing">5</property>
-		  <property name="column_spacing">5</property>
-
-		  <child>
-		    <widget class="GtkLabel" id="hostnameLabel">
-		      <property name="visible">True</property>
-		      <property name="label" translatable="yes">Hostname:</property>
-		      <property name="use_underline">False</property>
-		      <property name="use_markup">True</property>
-		      <property name="justify">GTK_JUSTIFY_LEFT</property>
-		      <property name="wrap">False</property>
-		      <property name="selectable">False</property>
-		      <property name="xalign">0</property>
-		      <property name="yalign">0.5</property>
-		      <property name="xpad">0</property>
-		      <property name="ypad">0</property>
-		      <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
-		      <property name="width_chars">-1</property>
-		      <property name="single_line_mode">False</property>
-		      <property name="angle">0</property>
-		    </widget>
-		    <packing>
-		      <property name="left_attach">0</property>
-		      <property name="right_attach">1</property>
-		      <property name="top_attach">0</property>
-		      <property name="bottom_attach">1</property>
-		      <property name="x_options">fill</property>
-		      <property name="y_options"></property>
-		    </packing>
-		  </child>
-
-		  <child>
-		    <widget class="GtkEntry" id="hostnameEntry">
-		      <property name="width_request">256</property>
-		      <property name="visible">True</property>
-		      <property name="can_focus">True</property>
-		      <property name="has_focus">True</property>
-		      <property name="editable">True</property>
-		      <property name="visibility">True</property>
-		      <property name="max_length">255</property>
-		      <property name="text" translatable="yes"></property>
-		      <property name="has_frame">True</property>
-		      <property name="invisible_char">â?¢</property>
-		      <property name="activates_default">True</property>
-		    </widget>
-		    <packing>
-		      <property name="left_attach">1</property>
-		      <property name="right_attach">2</property>
-		      <property name="top_attach">0</property>
-		      <property name="bottom_attach">1</property>
-		      <property name="x_options">fill</property>
-		      <property name="y_options"></property>
-		    </packing>
-		  </child>
-		</widget>
-	      </child>
-	    </widget>
-	    <packing>
-	      <property name="padding">0</property>
-	      <property name="expand">False</property>
-	      <property name="fill">False</property>
-	    </packing>
-	  </child>
-
-	  <child>
-	    <widget class="GtkAlignment" id="alignment5">
-	      <property name="visible">True</property>
-	      <property name="xalign">0.5</property>
-	      <property name="yalign">0.5</property>
-	      <property name="xscale">1</property>
-	      <property name="yscale">1</property>
-	      <property name="top_padding">0</property>
-	      <property name="bottom_padding">0</property>
-	      <property name="left_padding">0</property>
-	      <property name="right_padding">209</property>
-
-	      <child>
-		<placeholder/>
-	      </child>
-	    </widget>
-	    <packing>
-	      <property name="padding">0</property>
-	      <property name="expand">True</property>
-	      <property name="fill">True</property>
-	    </packing>
-	  </child>
-
-	  <child>
-	    <widget class="GtkAlignment" id="alignment6">
-	      <property name="visible">True</property>
-	      <property name="xalign">0.5</property>
-	      <property name="yalign">0.5</property>
-	      <property name="xscale">1</property>
-	      <property name="yscale">1</property>
-	      <property name="top_padding">0</property>
-	      <property name="bottom_padding">0</property>
-	      <property name="left_padding">0</property>
-	      <property name="right_padding">0</property>
-
-	      <child>
-		<widget class="GtkHButtonBox" id="hbuttonbox2">
-		  <property name="visible">True</property>
-		  <property name="layout_style">GTK_BUTTONBOX_START</property>
-		  <property name="spacing">0</property>
-
-		  <child>
-		    <widget class="GtkButton" id="netconfButton">
-		      <property name="visible">True</property>
-		      <property name="can_default">True</property>
-		      <property name="can_focus">True</property>
-		      <property name="label" translatable="yes">Configure Network</property>
-		      <property name="use_underline">True</property>
-		      <property name="relief">GTK_RELIEF_NORMAL</property>
-		      <property name="focus_on_click">True</property>
-		    </widget>
-		  </child>
-		</widget>
-	      </child>
-	    </widget>
-	    <packing>
-	      <property name="padding">0</property>
-	      <property name="expand">False</property>
-	      <property name="fill">False</property>
-	    </packing>
-	  </child>
-	</widget>
-      </child>
-    </widget>
-  </child>
-</widget>
-
-</glade-interface>
diff --git a/ui/tasksel.glade b/ui/tasksel.glade
deleted file mode 100644
index 3c280aa..0000000
--- a/ui/tasksel.glade
+++ /dev/null
@@ -1,335 +0,0 @@
-<?xml version="1.0" standalone="no"?> <!--*- mode: xml -*-->
-<!DOCTYPE glade-interface SYSTEM "http://glade.gnome.org/glade-2.0.dtd";>
-
-<glade-interface>
-
-<widget class="GtkWindow" id="window1">
-  <property name="visible">True</property>
-  <property name="title" translatable="yes" context="yes"></property>
-  <property name="type">GTK_WINDOW_TOPLEVEL</property>
-  <property name="window_position">GTK_WIN_POS_NONE</property>
-  <property name="modal">False</property>
-  <property name="default_width">440</property>
-  <property name="default_height">250</property>
-  <property name="resizable">True</property>
-  <property name="destroy_with_parent">False</property>
-  <property name="decorated">True</property>
-  <property name="skip_taskbar_hint">False</property>
-  <property name="skip_pager_hint">False</property>
-  <property name="type_hint">GDK_WINDOW_TYPE_HINT_NORMAL</property>
-  <property name="gravity">GDK_GRAVITY_NORTH_WEST</property>
-  <property name="focus_on_map">True</property>
-  <property name="urgency_hint">False</property>
-
-  <child>
-    <widget class="GtkVBox" id="taskBox">
-      <property name="border_width">12</property>
-      <property name="visible">True</property>
-      <property name="homogeneous">False</property>
-      <property name="spacing">18</property>
-
-      <child>
-	<widget class="GtkLabel" id="mainLabel">
-	  <property name="width_request">600</property>
-	  <property name="visible">True</property>
-	  <property name="label" translatable="yes" context="yes">The default installation of %s includes a set of software applicable for general internet usage.  What additional tasks would you like your system to support?</property>
-	  <property name="use_underline">False</property>
-	  <property name="use_markup">False</property>
-	  <property name="justify">GTK_JUSTIFY_LEFT</property>
-	  <property name="wrap">True</property>
-	  <property name="selectable">False</property>
-	  <property name="xalign">0</property>
-	  <property name="yalign">0</property>
-	  <property name="xpad">0</property>
-	  <property name="ypad">0</property>
-	  <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
-	  <property name="width_chars">-1</property>
-	  <property name="single_line_mode">False</property>
-	  <property name="angle">0</property>
-	</widget>
-	<packing>
-	  <property name="padding">0</property>
-	  <property name="expand">False</property>
-	  <property name="fill">False</property>
-	</packing>
-      </child>
-
-      <child>
-	<widget class="GtkVBox" id="cbVBox">
-	  <property name="visible">True</property>
-	  <property name="homogeneous">False</property>
-	  <property name="spacing">6</property>
-
-	  <child>
-	    <widget class="GtkScrolledWindow" id="taskSW">
-	      <property name="visible">True</property>
-	      <property name="can_focus">True</property>
-	      <property name="hscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
-	      <property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
-	      <property name="shadow_type">GTK_SHADOW_IN</property>
-	      <property name="window_placement">GTK_CORNER_TOP_LEFT</property>
-
-	      <child>
-		<widget class="GtkTreeView" id="taskList">
-		  <property name="visible">True</property>
-		  <property name="can_focus">True</property>
-		  <property name="headers_visible">False</property>
-		  <property name="rules_hint">False</property>
-		  <property name="reorderable">False</property>
-		  <property name="enable_search">False</property>
-		  <property name="fixed_height_mode">False</property>
-		  <property name="hover_selection">False</property>
-		  <property name="hover_expand">False</property>
-		</widget>
-	      </child>
-	    </widget>
-	    <packing>
-	      <property name="padding">0</property>
-	      <property name="expand">True</property>
-	      <property name="fill">True</property>
-	    </packing>
-	  </child>
-	</widget>
-	<packing>
-	  <property name="padding">0</property>
-	  <property name="expand">True</property>
-	  <property name="fill">True</property>
-	</packing>
-      </child>
-
-      <child>
-	<widget class="GtkVBox" id="customizeBox">
-	  <property name="visible">True</property>
-	  <property name="homogeneous">False</property>
-	  <property name="spacing">6</property>
-
-	  <child>
-	    <widget class="GtkLabel" id="label2">
-	      <property name="width_request">600</property>
-	      <property name="visible">True</property>
-	      <property name="label" translatable="yes" context="yes">You can further customize the software selection now, or after install via the software management application.</property>
-	      <property name="use_underline">False</property>
-	      <property name="use_markup">False</property>
-	      <property name="justify">GTK_JUSTIFY_LEFT</property>
-	      <property name="wrap">True</property>
-	      <property name="selectable">False</property>
-	      <property name="xalign">0</property>
-	      <property name="yalign">0.5</property>
-	      <property name="xpad">0</property>
-	      <property name="ypad">0</property>
-	      <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
-	      <property name="width_chars">-1</property>
-	      <property name="single_line_mode">False</property>
-	      <property name="angle">0</property>
-	    </widget>
-	    <packing>
-	      <property name="padding">0</property>
-	      <property name="expand">True</property>
-	      <property name="fill">True</property>
-	    </packing>
-	  </child>
-
-	  <child>
-	    <widget class="GtkHBox" id="hbox1">
-	      <property name="visible">True</property>
-	      <property name="homogeneous">False</property>
-	      <property name="spacing">24</property>
-
-	      <child>
-		<widget class="GtkRadioButton" id="laterRadio">
-		  <property name="visible">True</property>
-		  <property name="label" translatable="yes" context="yes">Customize _later</property>
-		  <property name="use_underline">True</property>
-		  <property name="relief">GTK_RELIEF_NORMAL</property>
-		  <property name="focus_on_click">True</property>
-		  <property name="active">False</property>
-		  <property name="inconsistent">False</property>
-		  <property name="draw_indicator">True</property>
-		</widget>
-		<packing>
-		  <property name="padding">0</property>
-		  <property name="expand">False</property>
-		  <property name="fill">False</property>
-		</packing>
-	      </child>
-
-	      <child>
-		<widget class="GtkRadioButton" id="customRadio">
-		  <property name="visible">True</property>
-		  <property name="label" translatable="yes" context="yes">_Customize now</property>
-		  <property name="use_underline">True</property>
-		  <property name="relief">GTK_RELIEF_NORMAL</property>
-		  <property name="focus_on_click">True</property>
-		  <property name="active">False</property>
-		  <property name="inconsistent">False</property>
-		  <property name="draw_indicator">True</property>
-		  <property name="group">laterRadio</property>
-		</widget>
-		<packing>
-		  <property name="padding">0</property>
-		  <property name="expand">False</property>
-		  <property name="fill">False</property>
-		</packing>
-	      </child>
-	    </widget>
-	    <packing>
-	      <property name="padding">0</property>
-	      <property name="expand">True</property>
-	      <property name="fill">True</property>
-	    </packing>
-	  </child>
-	</widget>
-	<packing>
-	  <property name="padding">0</property>
-	  <property name="expand">False</property>
-	  <property name="fill">False</property>
-	  <property name="pack_type">GTK_PACK_END</property>
-	</packing>
-      </child>
-
-      <child>
-	<widget class="GtkVBox" id="addRepoBox">
-	  <property name="visible">True</property>
-	  <property name="homogeneous">False</property>
-	  <property name="spacing">6</property>
-
-	  <child>
-	    <widget class="GtkLabel" id="label4">
-	      <property name="width_request">600</property>
-	      <property name="visible">True</property>
-	      <property name="label" translatable="yes">Please select any additional repositories that you want to use for software installation.</property>
-	      <property name="use_underline">False</property>
-	      <property name="use_markup">False</property>
-	      <property name="justify">GTK_JUSTIFY_LEFT</property>
-	      <property name="wrap">True</property>
-	      <property name="selectable">False</property>
-	      <property name="xalign">0</property>
-	      <property name="yalign">0.5</property>
-	      <property name="xpad">0</property>
-	      <property name="ypad">0</property>
-	      <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
-	      <property name="width_chars">-1</property>
-	      <property name="single_line_mode">False</property>
-	      <property name="angle">0</property>
-	    </widget>
-	    <packing>
-	      <property name="padding">0</property>
-	      <property name="expand">True</property>
-	      <property name="fill">True</property>
-	    </packing>
-	  </child>
-
-	  <child>
-	    <widget class="GtkScrolledWindow" id="repoSW">
-	      <property name="visible">True</property>
-	      <property name="can_focus">True</property>
-	      <property name="hscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
-	      <property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
-	      <property name="shadow_type">GTK_SHADOW_IN</property>
-	      <property name="window_placement">GTK_CORNER_TOP_LEFT</property>
-
-	      <child>
-		<widget class="GtkTreeView" id="repoList">
-		  <property name="visible">True</property>
-		  <property name="can_focus">True</property>
-		  <property name="headers_visible">False</property>
-		  <property name="rules_hint">False</property>
-		  <property name="reorderable">False</property>
-		  <property name="enable_search">False</property>
-		  <property name="fixed_height_mode">False</property>
-		  <property name="hover_selection">False</property>
-		  <property name="hover_expand">False</property>
-		</widget>
-	      </child>
-	    </widget>
-	    <packing>
-	      <property name="padding">0</property>
-	      <property name="expand">False</property>
-	      <property name="fill">False</property>
-	    </packing>
-	  </child>
-
-	  <child>
-	    <widget class="GtkHButtonBox" id="hbuttonbox1">
-	      <property name="visible">True</property>
-	      <property name="layout_style">GTK_BUTTONBOX_START</property>
-	      <property name="spacing">5</property>
-
-	      <child>
-		<widget class="GtkButton" id="addRepoButton">
-		  <property name="visible">True</property>
-		  <property name="can_default">True</property>
-		  <property name="can_focus">True</property>
-		  <property name="relief">GTK_RELIEF_NORMAL</property>
-		  <property name="focus_on_click">True</property>
-
-		  <child>
-		    <widget class="GtkLabel" id="label5">
-		      <property name="visible">True</property>
-		      <property name="label" translatable="yes">_Add additional software repositories</property>
-		      <property name="use_underline">True</property>
-		      <property name="use_markup">False</property>
-		      <property name="justify">GTK_JUSTIFY_LEFT</property>
-		      <property name="wrap">False</property>
-		      <property name="selectable">False</property>
-		      <property name="xalign">0.5</property>
-		      <property name="yalign">0.5</property>
-		      <property name="xpad">0</property>
-		      <property name="ypad">0</property>
-		      <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
-		      <property name="width_chars">-1</property>
-		      <property name="single_line_mode">False</property>
-		      <property name="angle">0</property>
-		    </widget>
-		  </child>
-		</widget>
-	      </child>
-
-	      <child>
-		<widget class="GtkButton" id="editRepoButton">
-		  <property name="visible">True</property>
-		  <property name="can_default">True</property>
-		  <property name="can_focus">True</property>
-		  <property name="relief">GTK_RELIEF_NORMAL</property>
-		  <property name="focus_on_click">True</property>
-
-		  <child>
-		    <widget class="GtkLabel" id="label6">
-		      <property name="visible">True</property>
-		      <property name="label" translatable="yes">_Modify repository</property>
-		      <property name="use_underline">True</property>
-		      <property name="use_markup">False</property>
-		      <property name="justify">GTK_JUSTIFY_LEFT</property>
-		      <property name="wrap">False</property>
-		      <property name="selectable">False</property>
-		      <property name="xalign">0.5</property>
-		      <property name="yalign">0.5</property>
-		      <property name="xpad">0</property>
-		      <property name="ypad">0</property>
-		      <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
-		      <property name="width_chars">-1</property>
-		      <property name="single_line_mode">False</property>
-		      <property name="angle">0</property>
-		    </widget>
-		  </child>
-		</widget>
-	      </child>
-	    </widget>
-	    <packing>
-	      <property name="padding">0</property>
-	      <property name="expand">False</property>
-	      <property name="fill">False</property>
-	    </packing>
-	  </child>
-	</widget>
-	<packing>
-	  <property name="padding">0</property>
-	  <property name="expand">False</property>
-	  <property name="fill">False</property>
-	</packing>
-      </child>
-    </widget>
-  </child>
-</widget>
-
-</glade-interface>
diff --git a/ui/zfcp-config.glade b/ui/zfcp-config.glade
deleted file mode 100644
index 8a09673..0000000
--- a/ui/zfcp-config.glade
+++ /dev/null
@@ -1,276 +0,0 @@
-<?xml version="1.0" standalone="no"?> <!--*- mode: xml -*-->
-<!DOCTYPE glade-interface SYSTEM "http://glade.gnome.org/glade-2.0.dtd";>
-
-<glade-interface>
-
-<widget class="GtkDialog" id="zfcpDialog">
-  <property name="title" translatable="yes">Add FCP device</property>
-  <property name="type">GTK_WINDOW_TOPLEVEL</property>
-  <property name="window_position">GTK_WIN_POS_CENTER</property>
-  <property name="modal">False</property>
-  <property name="resizable">True</property>
-  <property name="destroy_with_parent">False</property>
-  <property name="decorated">True</property>
-  <property name="skip_taskbar_hint">False</property>
-  <property name="skip_pager_hint">False</property>
-  <property name="type_hint">GDK_WINDOW_TYPE_HINT_DIALOG</property>
-  <property name="gravity">GDK_GRAVITY_NORTH_WEST</property>
-  <property name="focus_on_map">True</property>
-  <property name="urgency_hint">False</property>
-  <property name="has_separator">True</property>
-
-  <child internal-child="vbox">
-    <widget class="GtkVBox" id="dialog-vbox1">
-      <property name="visible">True</property>
-      <property name="homogeneous">False</property>
-      <property name="spacing">0</property>
-
-      <child internal-child="action_area">
-	<widget class="GtkHButtonBox" id="dialog-action_area1">
-	  <property name="visible">True</property>
-	  <property name="layout_style">GTK_BUTTONBOX_END</property>
-
-	  <child>
-	    <widget class="GtkButton" id="button1">
-	      <property name="visible">True</property>
-	      <property name="can_default">True</property>
-	      <property name="can_focus">True</property>
-	      <property name="label">gtk-cancel</property>
-	      <property name="use_stock">True</property>
-	      <property name="relief">GTK_RELIEF_NORMAL</property>
-	      <property name="focus_on_click">True</property>
-	      <property name="response_id">-6</property>
-	    </widget>
-	  </child>
-
-	  <child>
-	    <widget class="GtkButton" id="button2">
-	      <property name="visible">True</property>
-	      <property name="can_default">True</property>
-	      <property name="can_focus">True</property>
-	      <property name="label">gtk-add</property>
-	      <property name="use_stock">True</property>
-	      <property name="relief">GTK_RELIEF_NORMAL</property>
-	      <property name="focus_on_click">True</property>
-	      <property name="response_id">-10</property>
-	    </widget>
-	  </child>
-	</widget>
-	<packing>
-	  <property name="padding">0</property>
-	  <property name="expand">False</property>
-	  <property name="fill">True</property>
-	  <property name="pack_type">GTK_PACK_END</property>
-	</packing>
-      </child>
-
-      <child>
-	<widget class="GtkVBox" id="vbox1">
-	  <property name="border_width">12</property>
-	  <property name="visible">True</property>
-	  <property name="homogeneous">False</property>
-	  <property name="spacing">12</property>
-
-	  <child>
-	    <widget class="GtkLabel" id="label8">
-	      <property name="visible">True</property>
-	      <property name="label" translatable="yes">zSeries machines can access industry-standard SCSI devices via Fibre Channel (FCP). You need to provide a 16 bit device number, a 64 bit World Wide Port Name (WWPN), and a 64 bit FCP LUN for each device.</property>
-	      <property name="use_underline">False</property>
-	      <property name="use_markup">False</property>
-	      <property name="justify">GTK_JUSTIFY_LEFT</property>
-	      <property name="wrap">True</property>
-	      <property name="selectable">False</property>
-	      <property name="xalign">0.5</property>
-	      <property name="yalign">0.5</property>
-	      <property name="xpad">0</property>
-	      <property name="ypad">0</property>
-	      <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
-	      <property name="width_chars">-1</property>
-	      <property name="single_line_mode">False</property>
-	      <property name="angle">0</property>
-	    </widget>
-	    <packing>
-	      <property name="padding">0</property>
-	      <property name="expand">False</property>
-	      <property name="fill">False</property>
-	    </packing>
-	  </child>
-
-	  <child>
-	    <widget class="GtkTable" id="zfcpTable">
-	      <property name="border_width">12</property>
-	      <property name="visible">True</property>
-	      <property name="n_rows">3</property>
-	      <property name="n_columns">2</property>
-	      <property name="homogeneous">False</property>
-	      <property name="row_spacing">6</property>
-	      <property name="column_spacing">6</property>
-
-	      <child>
-		<widget class="GtkLabel" id="devnumLabel">
-		  <property name="visible">True</property>
-		  <property name="label" translatable="yes">&lt;b&gt;Device number:&lt;/b&gt;</property>
-		  <property name="use_underline">True</property>
-		  <property name="use_markup">True</property>
-		  <property name="justify">GTK_JUSTIFY_LEFT</property>
-		  <property name="wrap">False</property>
-		  <property name="selectable">False</property>
-		  <property name="xalign">0</property>
-		  <property name="yalign">0.5</property>
-		  <property name="xpad">0</property>
-		  <property name="ypad">0</property>
-		  <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
-		  <property name="width_chars">-1</property>
-		  <property name="single_line_mode">False</property>
-		  <property name="angle">0</property>
-		</widget>
-		<packing>
-		  <property name="left_attach">0</property>
-		  <property name="right_attach">1</property>
-		  <property name="top_attach">0</property>
-		  <property name="bottom_attach">1</property>
-		  <property name="x_options">fill</property>
-		  <property name="y_options"></property>
-		</packing>
-	      </child>
-
-	      <child>
-		<widget class="GtkEntry" id="devnumEntry">
-		  <property name="visible">True</property>
-		  <property name="can_focus">True</property>
-		  <property name="editable">True</property>
-		  <property name="visibility">True</property>
-		  <property name="max_length">0</property>
-		  <property name="text" translatable="yes"></property>
-		  <property name="has_frame">True</property>
-		  <property name="invisible_char">â?¢</property>
-		  <property name="activates_default">False</property>
-		</widget>
-		<packing>
-		  <property name="left_attach">1</property>
-		  <property name="right_attach">2</property>
-		  <property name="top_attach">0</property>
-		  <property name="bottom_attach">1</property>
-		  <property name="x_options"></property>
-		  <property name="y_options"></property>
-		</packing>
-	      </child>
-
-	      <child>
-		<widget class="GtkLabel" id="wwwpnLabel">
-		  <property name="visible">True</property>
-		  <property name="label" translatable="yes">&lt;b&gt;WWPN:&lt;/b&gt;</property>
-		  <property name="use_underline">True</property>
-		  <property name="use_markup">True</property>
-		  <property name="justify">GTK_JUSTIFY_LEFT</property>
-		  <property name="wrap">False</property>
-		  <property name="selectable">False</property>
-		  <property name="xalign">0</property>
-		  <property name="yalign">0.5</property>
-		  <property name="xpad">0</property>
-		  <property name="ypad">0</property>
-		  <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
-		  <property name="width_chars">-1</property>
-		  <property name="single_line_mode">False</property>
-		  <property name="angle">0</property>
-		</widget>
-		<packing>
-		  <property name="left_attach">0</property>
-		  <property name="right_attach">1</property>
-		  <property name="top_attach">1</property>
-		  <property name="bottom_attach">2</property>
-		  <property name="x_options">fill</property>
-		  <property name="y_options"></property>
-		</packing>
-	      </child>
-
-	      <child>
-		<widget class="GtkEntry" id="wwpnEntry">
-		  <property name="visible">True</property>
-		  <property name="can_focus">True</property>
-		  <property name="editable">True</property>
-		  <property name="visibility">True</property>
-		  <property name="max_length">0</property>
-		  <property name="text" translatable="yes"></property>
-		  <property name="has_frame">True</property>
-		  <property name="invisible_char">*</property>
-		  <property name="activates_default">False</property>
-		</widget>
-		<packing>
-		  <property name="left_attach">1</property>
-		  <property name="right_attach">2</property>
-		  <property name="top_attach">1</property>
-		  <property name="bottom_attach">2</property>
-		  <property name="x_options"></property>
-		  <property name="y_options"></property>
-		</packing>
-	      </child>
-
-	      <child>
-		<widget class="GtkLabel" id="fcplunLabel">
-		  <property name="visible">True</property>
-		  <property name="label" translatable="yes">&lt;b&gt;FCP LUN:&lt;/b&gt;</property>
-		  <property name="use_underline">True</property>
-		  <property name="use_markup">True</property>
-		  <property name="justify">GTK_JUSTIFY_LEFT</property>
-		  <property name="wrap">False</property>
-		  <property name="selectable">False</property>
-		  <property name="xalign">0</property>
-		  <property name="yalign">0.5</property>
-		  <property name="xpad">0</property>
-		  <property name="ypad">0</property>
-		  <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
-		  <property name="width_chars">-1</property>
-		  <property name="single_line_mode">False</property>
-		  <property name="angle">0</property>
-		</widget>
-		<packing>
-		  <property name="left_attach">0</property>
-		  <property name="right_attach">1</property>
-		  <property name="top_attach">2</property>
-		  <property name="bottom_attach">3</property>
-		  <property name="x_options">fill</property>
-		  <property name="y_options"></property>
-		</packing>
-	      </child>
-
-	      <child>
-		<widget class="GtkEntry" id="fcplunEntry">
-		  <property name="visible">True</property>
-		  <property name="can_focus">True</property>
-		  <property name="editable">True</property>
-		  <property name="visibility">True</property>
-		  <property name="max_length">0</property>
-		  <property name="text" translatable="yes"></property>
-		  <property name="has_frame">True</property>
-		  <property name="invisible_char">*</property>
-		  <property name="activates_default">False</property>
-		</widget>
-		<packing>
-		  <property name="left_attach">1</property>
-		  <property name="right_attach">2</property>
-		  <property name="top_attach">2</property>
-		  <property name="bottom_attach">3</property>
-		  <property name="x_options"></property>
-		  <property name="y_options"></property>
-		</packing>
-	      </child>
-	    </widget>
-	    <packing>
-	      <property name="padding">0</property>
-	      <property name="expand">True</property>
-	      <property name="fill">True</property>
-	    </packing>
-	  </child>
-	</widget>
-	<packing>
-	  <property name="padding">0</property>
-	  <property name="expand">True</property>
-	  <property name="fill">True</property>
-	</packing>
-      </child>
-    </widget>
-  </child>
-</widget>
-
-</glade-interface>
diff --git a/upgrade.py b/upgrade.py
deleted file mode 100644
index 91e8911..0000000
--- a/upgrade.py
+++ /dev/null
@@ -1,344 +0,0 @@
-#
-# upgrade.py - Existing install probe and upgrade procedure
-#
-# Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007  Red Hat, Inc.
-# 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 as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# 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, see <http://www.gnu.org/licenses/>.
-#
-# Author(s): Matt Wilson <msw@xxxxxxxxxx>
-#
-
-import isys
-import os
-import iutil
-import time
-import sys
-import os.path
-import shutil
-import string
-import selinux
-from flags import flags
-from constants import *
-from product import productName
-from storage import findExistingRootDevices, getReleaseString
-from storage import mountExistingSystem
-from storage.formats import getFormat
-
-import gettext
-_ = lambda x: gettext.ldgettext("anaconda", x)
-
-import rpm
-
-import logging
-log = logging.getLogger("anaconda")
-
-def queryUpgradeContinue(anaconda):
-    if anaconda.dir == DISPATCH_FORWARD:
-        return
-
-    rc = anaconda.intf.messageWindow(_("Proceed with upgrade?"),
-                       _("The file systems of the Linux installation "
-                         "you have chosen to upgrade have already been "
-                         "mounted. You cannot go back past this point. "
-                         "\n\n") + 
-                       _("Would you like to continue with the upgrade?"),
-                         type="custom", custom_icon=["error","error"],
-                         custom_buttons=[_("_Exit installer"), _("_Continue")])
-    if rc == 0:
-        sys.exit(0)
-    return DISPATCH_FORWARD
-
-def setUpgradeRoot(anaconda):
-    anaconda.upgradeRoot = []
-    root_device = None
-    # kickstart can pass device as device name or uuid. No quotes allowed.
-    if anaconda.ksdata and anaconda.ksdata.upgrade.root_device is not None:
-        root_device = anaconda.ksdata.upgrade.root_device
-    for (dev, label) in anaconda.rootParts:
-        if ((root_device is not None) and
-            (root_device == dev.name or root_device == "UUID=%s" % dev.format.uuid)):
-            anaconda.upgradeRoot.insert(0, (dev,label))
-        else:
-            anaconda.upgradeRoot.append((dev,label))
-
-def findRootParts(anaconda):
-    if anaconda.dir == DISPATCH_BACK:
-        return
-    if anaconda.rootParts is None:
-        anaconda.rootParts = findExistingRoots(anaconda,
-                                               flags.cmdline.has_key("upgradeany"))
-
-    setUpgradeRoot(anaconda)
-
-    if anaconda.rootParts is not None and len(anaconda.rootParts) > 0:
-        anaconda.dispatch.skipStep("findinstall", skip = 0)
-        if productName.find("Red Hat Enterprise Linux") == -1:
-            anaconda.dispatch.skipStep("installtype", skip = 1)
-    else:
-        anaconda.dispatch.skipStep("findinstall", skip = 1)
-        anaconda.dispatch.skipStep("installtype", skip = 0)
-
-def findExistingRoots(anaconda, upgradeany=False):
-    rootparts = findExistingRootDevices(anaconda, upgradeany=upgradeany)
-    return rootparts
-
-def bindMountDevDirectory(instPath):
-    getFormat("bind",
-              device="/dev",
-              mountpoint="/dev",
-              exists=True).mount(chroot=instPath)
-
-# returns None if no filesystem exist to migrate
-def upgradeMigrateFind(anaconda):
-    migents = anaconda.storage.migratableDevices
-    if not migents or len(migents) < 1:
-        anaconda.dispatch.skipStep("upgrademigratefs")
-    else:
-        anaconda.dispatch.skipStep("upgrademigratefs", skip = 0)
-
-def copyFromSysimage(rootPath, filename):
-    """Mirrors filename from the sysimage on the ramdisk."""
-    sysfile = os.path.normpath("%s/%s" % (rootPath, filename))
-    if os.access(sysfile, os.R_OK):
-        try:
-            # remove our copy if we have one (think liveinstall)
-            os.remove(filename)
-        except OSError:
-            pass
-        try:
-            shutil.copyfile(sysfile, filename)
-        except OSError as e:
-            log.error("Error copying %s to sysimage: %s" %(sysfile, e.strerror))
-            return False
-    else:
-        log.error("Error copying %s to sysimage, file not accessible." % sysfile)
-        return False
-    return True
-
-def restoreTime(anaconda):
-    """Load time setup for upgrade install.
-    
-    We need to find out the timezone and the UTC parameter of the old system and
-    set the system time accordingly, so timestamps are set correctly for the
-    files the upgrade procedure will create.
-
-    This is pretty much what packages.setupTimezone() does in reverse.
-    """
-    if anaconda.dir == DISPATCH_BACK:
-        return
-    if os.environ.has_key("TZ"):
-        del os.environ["TZ"]
-    copyFromSysimage(anaconda.rootPath, '/etc/localtime')
-    copyFromSysimage(anaconda.rootPath, '/etc/adjtime')
-    if iutil.isS390():
-        return
-    args = [ "--hctosys" ]
-    try:
-        iutil.execWithRedirect("/usr/sbin/hwclock", args,stdout = "/dev/tty5",
-                               stderr = "/dev/tty5")
-    except RuntimeError:
-        log.error("Failed to set the clock.")
-
-# returns None if no more swap is needed
-def upgradeSwapSuggestion(anaconda):
-    # mem is in kb -- round it up to the nearest 4Mb
-    mem = iutil.memInstalled()
-    rem = mem % 16384
-    if rem:
-	mem = mem + (16384 - rem)
-    mem = mem / 1024
-
-    anaconda.dispatch.skipStep("addswap", 0)
-    
-    # don't do this if we have more then 250 MB
-    if mem > 250:
-        anaconda.dispatch.skipStep("addswap", 1)
-        return
-    
-    swap = iutil.swapAmount() / 1024
-
-    # if we have twice as much swap as ram and at least 192 megs
-    # total, we're safe 
-    if (swap >= (mem * 1.5)) and (swap + mem >= 192):
-        anaconda.dispatch.skipStep("addswap", 1)
-	return
-
-    # if our total is 512 megs or more, we should be safe
-    if (swap + mem >= 512):
-        anaconda.dispatch.skipStep("addswap", 1)
-	return
-
-    fsList = []
-
-    for device in anaconda.storage.fsset.devices:
-        if not device.format:
-            continue
-        if device.format.mountable and device.format.linuxNative:
-            if not device.format.status:
-                continue
-            space = isys.pathSpaceAvailable(anaconda.rootPath + device.format.mountpoint)
-            if space > 16:
-                info = (device, space)
-                fsList.append(info)
-
-    suggestion = mem * 2 - swap
-    if (swap + mem + suggestion) < 192:
-        suggestion = 192 - (swap + mem)
-    if suggestion < 32:
-        suggestion = 32
-    suggSize = 0
-    suggMnt = None
-    for (device, size) in fsList:
-	if (size > suggSize) and (size > (suggestion + 100)):
-	    suggDev = device
-
-    anaconda.upgradeSwapInfo = (fsList, suggestion, suggDev)
-
-# XXX handle going backwards
-def upgradeMountFilesystems(anaconda):
-    # mount everything and turn on swap
-
-    try:
-        mountExistingSystem(anaconda, anaconda.upgradeRoot[0], allowDirty = 0)
-    except ValueError as e:
-        log.error("Error mounting filesystem: %s" % e)
-        anaconda.intf.messageWindow(_("Mount failed"),
-            _("The following error occurred when mounting the file "
-              "systems listed in /etc/fstab.  Please fix this problem "
-              "and try to upgrade again.\n%s" % e))
-        sys.exit(0)
-    except IndexError as e:
-        # The upgrade root is search earlier but we give the message here.
-        log.debug("No upgrade root was found.")
-        if anaconda.ksdata and anaconda.ksdata.upgrade.upgrade:
-            anaconda.intf.messageWindow(_("Upgrade root not found"),
-                _("The root for the previously installed system was not "
-                  "found."), type="custom",
-                custom_icon="info",
-                custom_buttons=[_("Exit installer")])
-            sys.exit(0)
-        else:
-            rc = anaconda.intf.messageWindow(_("Upgrade root not found"),
-                    _("The root for the previously installed system was not "
-                      "found.  You can exit installer or backtrack to choose "
-                      "installation instead of upgrade."),
-                type="custom",
-                custom_buttons = [ _("_Back"),
-                                   _("_Exit installer") ],
-                custom_icon="question")
-            if rc == 0:
-                return DISPATCH_BACK
-            elif rc == 1:
-                sys.exit(0)
-
-    checkLinks = ( '/etc', '/var', '/var/lib', '/var/lib/rpm',
-                   '/boot', '/tmp', '/var/tmp', '/root',
-                   '/bin/sh', '/usr/tmp')
-    badLinks = []
-    for n in checkLinks:
-        if not os.path.islink(anaconda.rootPath + n): continue
-        l = os.readlink(anaconda.rootPath + n)
-        if l[0] == '/':
-            badLinks.append(n)
-
-    if badLinks:
-        message = _("The following files are absolute symbolic " 
-                    "links, which we do not support during an " 
-                    "upgrade. Please change them to relative "
-                    "symbolic links and restart the upgrade.\n\n")
-        for n in badLinks:
-            message = message + '\t' + n + '\n'
-        anaconda.intf.messageWindow(_("Absolute Symlinks"), message)
-        sys.exit(0)
-
-    # fix for 80446
-    badLinks = []
-    mustBeLinks = ( '/usr/tmp', )
-    for n in mustBeLinks:
-        if not os.path.islink(anaconda.rootPath + n):
-            badLinks.append(n)
-
-    if badLinks: 
-        message = _("The following are directories which should instead "
-                    "be symbolic links, which will cause problems with the "
-                    "upgrade.  Please return them to their original state "
-                    "as symbolic links and restart the upgrade.\n\n")
-        for n in badLinks:
-            message = message + '\t' + n + '\n'
-        anaconda.intf.messageWindow(_("Invalid Directories"), message)
-        sys.exit(0)
-
-    anaconda.storage.turnOnSwap(upgrading=True)
-    anaconda.storage.mkDevRoot()
-
-    # Move /etc/rpm/platform out of the way.
-    if os.path.exists(anaconda.rootPath + "/etc/rpm/platform"):
-        shutil.move(anaconda.rootPath + "/etc/rpm/platform",
-                    anaconda.rootPath + "/etc/rpm/platform.rpmsave")
-
-    # if they've been booting with selinux disabled, then we should
-    # disable it during the install as well (#242510)
-    try:
-        if os.path.exists(anaconda.rootPath + "/.autorelabel"):
-            ctx = selinux.getfilecon(anaconda.rootPath + "/.autorelabel")[1]
-            if not ctx or ctx == "unlabeled":
-                flags.selinux = False
-                log.info("Disabled SELinux for upgrade based on /.autorelabel")
-    except Exception, e:
-        log.warning("error checking selinux state: %s" %(e,))
-
-def setSteps(anaconda):
-    dispatch = anaconda.dispatch
-    dispatch.setStepList(
-                "language",
-                "keyboard",
-                "welcome",
-                "filtertype",
-                "filter",
-                "cleardiskssel",
-                "installtype",
-                "storageinit",
-                "findrootparts",
-                "findinstall",
-                "upgrademount",
-                "restoretime",
-                "upgrademigfind",
-                "upgrademigratefs",
-                "enablefilesystems",
-                "upgradecontinue",
-                "reposetup",
-                "upgbootloader",
-                "checkdeps",
-                "dependencies",
-                "confirmupgrade",
-                "postselection",
-                "reipl",
-                "install",
-                "preinstallconfig",
-                "installpackages",
-                "postinstallconfig",
-                "instbootloader",
-                "dopostaction",
-                "methodcomplete",
-                "postscripts",
-                "copylogs",
-                "complete"
-            )
-
-    if not iutil.isX86():
-        dispatch.skipStep("bootloader")
-
-    if not iutil.isX86():
-        dispatch.skipStep("upgbootloader")            
diff --git a/users.py b/users.py
deleted file mode 100644
index 67d15b2..0000000
--- a/users.py
+++ /dev/null
@@ -1,307 +0,0 @@
-#
-# users.py:  Code for creating user accounts and setting the root password
-#
-# Copyright (C) 2006, 2007, 2008 Red Hat, Inc.  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 as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# 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, see <http://www.gnu.org/licenses/>.
-#
-# Author(s): Chris Lumens <clumens@xxxxxxxxxx>
-#
-
-import libuser
-import string
-import crypt
-import random
-import tempfile
-import os
-import os.path
-
-import logging
-log = logging.getLogger("anaconda")
-
-def createLuserConf(instPath, algoname='sha512'):
-    """Writes a libuser.conf for instPath."""
-    createTmp = False
-    try:
-        fn = os.environ["LIBUSER_CONF"]
-        if os.access(fn, os.F_OK):
-            log.info("removing libuser.conf at %s" % (os.getenv("LIBUSER_CONF")))
-            os.unlink(fn)
-        log.info("created new libuser.conf at %s with instPath=\"%s\"" % \
-                (fn,instPath))
-        fd = open(fn, 'w')
-    except:
-        createTmp = True
-
-    if createTmp:
-        (fp, fn) = tempfile.mkstemp(prefix="libuser.")
-        log.info("created new libuser.conf at %s with instPath=\"%s\"" % \
-                (fn,instPath))
-        fd = os.fdopen(fp, 'w')
-
-    buf = """
-[defaults]
-skeleton = %(instPath)s/etc/skel
-mailspooldir = %(instPath)s/var/mail
-crypt_style = %(algo)s
-modules = files shadow
-create_modules = files shadow
-[files]
-directory = %(instPath)s/etc
-[shadow]
-directory = %(instPath)s/etc
-""" % {"instPath": instPath, "algo": algoname}
-
-    fd.write(buf)
-    fd.close()
-    os.environ["LIBUSER_CONF"] = fn
-
-    return fn
-
-# These are explained in crypt/crypt-entry.c in glibc's code.  The prefixes
-# we use for the different crypt salts:
-#     $1$    MD5
-#     $5$    SHA256
-#     $6$    SHA512
-def cryptPassword(password, algo=None):
-    salts = {'md5': '$1$', 'sha256': '$5$', 'sha512': '$6$'}
-    saltlen = 2
-
-    if algo is None:
-        algo = 'sha512'
-
-    if algo == 'md5' or algo == 'sha256' or algo == 'sha512':
-        saltlen = 16
-
-    saltstr = salts[algo]
-
-    for i in range(saltlen):
-        saltstr = saltstr + random.choice (string.letters +
-                                           string.digits + './')
-
-    return crypt.crypt (password, saltstr)
-
-class Users:
-    def __init__ (self, anaconda):
-        self.anaconda = anaconda
-        self.admin = libuser.admin()
-        self.rootPassword = { "isCrypted": False, "password": "", "lock": False }
-
-    def createGroup (self, name=None, gid=None, root="/mnt/sysimage"):
-        childpid = os.fork()
-
-        if not childpid:
-            if not root in ["","/"]:
-                os.chroot(root)
-                del(os.environ["LIBUSER_CONF"])
-
-            self.admin = libuser.admin()
-
-            try:
-                if self.admin.lookupGroupByName(name):
-                    os._exit(1)
-
-                groupEnt = self.admin.initGroup(name)
-
-                if gid >= 0:
-                    groupEnt.set(libuser.GIDNUMBER, gid)
-
-                self.admin.addGroup(groupEnt)
-                os._exit(0)
-            except Exception, e:
-                log.critical("Error when creating new group: %s" % str(e))
-                os._exit(1)
-
-        try:
-            (pid, status) = os.waitpid(childpid, 0)
-        except OSError as e:
-            log.critical("exception from waitpid while creating a group: %s %s" % (e.errno, e.strerror))
-            return False
-
-        if os.WIFEXITED(status) and (os.WEXITSTATUS(status) == 0):
-            return True
-        else:
-            return False
-
-    def createUser (self, name=None, password=None, isCrypted=False, groups=[],
-                    homedir=None, shell=None, uid=None, algo=None, lock=False,
-                    root="/mnt/sysimage", gecos=None):
-        childpid = os.fork()
-
-        if not childpid:
-            if not root in ["","/"]:
-                os.chroot(root)
-                del(os.environ["LIBUSER_CONF"])
-
-            self.admin = libuser.admin()
-
-            try:
-                if self.admin.lookupUserByName(name):
-                    os._exit(1)
-
-                userEnt = self.admin.initUser(name)
-                groupEnt = self.admin.initGroup(name)
-
-                grpLst = filter(lambda grp: grp,
-                                map(lambda name: self.admin.lookupGroupByName(name), groups))
-                userEnt.set(libuser.GIDNUMBER, [groupEnt.get(libuser.GIDNUMBER)[0]] +
-                            map(lambda grp: grp.get(libuser.GIDNUMBER)[0], grpLst))
-
-                if not homedir:
-                    homedir = "/home/" + name
-
-                userEnt.set(libuser.HOMEDIRECTORY, homedir)
-
-                if shell:
-                    userEnt.set(libuser.LOGINSHELL, shell)
-
-                if uid >= 0:
-                    userEnt.set(libuser.UIDNUMBER, uid)
-
-                if gecos:
-                    userEnt.set(libuser.GECOS, gecos)
-
-                self.admin.addUser(userEnt)
-                self.admin.addGroup(groupEnt)
-
-                if password:
-                    if isCrypted:
-                        self.admin.setpassUser(userEnt, password, True)
-                    else:
-                        self.admin.setpassUser(userEnt,
-                                            cryptPassword(password, algo=algo),
-                                            True)
-
-                if lock:
-                    self.admin.lockUser(userEnt)
-
-                # Add the user to all the groups they should be part of.
-                grpLst.append(self.admin.lookupGroupByName(name))
-                for grp in grpLst:
-                    grp.add(libuser.MEMBERNAME, name)
-                    self.admin.modifyGroup(grp)
-
-                os._exit(0)
-            except Exception, e:
-                log.critical("Error when creating new user: %s" % str(e))
-                os._exit(1)
-
-        try:
-            (pid, status) = os.waitpid(childpid, 0)
-        except OSError as e:
-            log.critical("exception from waitpid while creating a user: %s %s" % (e.errno, e.strerror))
-            return False
-
-        if os.WIFEXITED(status) and (os.WEXITSTATUS(status) == 0):
-            return True
-        else:
-            return False
-
-    def checkUserExists(self, username, root="/mnt/sysimage"):
-        childpid = os.fork()
-
-        if not childpid:
-            if not root in ["","/"]:
-                os.chroot(root)
-                del(os.environ["LIBUSER_CONF"])
-
-            self.admin = libuser.admin()
-
-            try:
-                if self.admin.lookupUserByName(username):
-                    os._exit(0)
-            except Exception, e:
-                log.critical("Error when searching for user: %s" % str(e))
-            os._exit(1)
-
-        try:
-            (pid, status) = os.waitpid(childpid, 0)
-        except OSError as e:
-            log.critical("exception from waitpid while creating a user: %s %s" % (e.errno, e.strerror))
-            return False
-
-        if os.WIFEXITED(status) and (os.WEXITSTATUS(status) == 0):
-            return True
-        else:
-            return False
-
-    # Reads the auth string and returns a string indicating our desired
-    # password encoding algorithm.
-    def getPassAlgo(self):
-        if self.anaconda.security.auth.find("--enablemd5") != -1 or \
-           self.anaconda.security.auth.find("--passalgo=md5") != -1:
-            return 'md5'
-        elif self.anaconda.security.auth.find("--passalgo=sha256") != -1:
-            return 'sha256'
-        elif self.anaconda.security.auth.find("--passalgo=sha512") != -1:
-            return 'sha512'
-        else:
-            return None
-
-    def setUserPassword(self, username, password, isCrypted, lock, algo=None):
-        user = self.admin.lookupUserByName(username)
-
-        if isCrypted:
-            self.admin.setpassUser(user, password, True)
-        else:
-            self.admin.setpassUser(user, cryptPassword(password, algo=algo), True)
-
-        if lock:
-            self.admin.lockUser(user)
-
-        self.admin.modifyUser(user)
-
-    def setRootPassword(self, algo=None):
-        return self.setUserPassword("root", self.rootPassword["password"],
-                                    self.rootPassword["isCrypted"],
-                                    self.rootPassword["lock"], algo)
-
-    def write(self, instPath):
-        # make sure crypt_style in libuser.conf matches the salt we're using
-        createLuserConf(instPath, algoname=self.getPassAlgo())
-
-        # User should already exist, just without a password.
-        self.setRootPassword(algo=self.getPassAlgo())
-
-        if self.anaconda.ksdata:
-            for gd in self.anaconda.ksdata.group.groupList:
-                if not self.createGroup(name=gd.name,
-                                        gid=gd.gid,
-                                        root=instPath):
-                    log.error("Group %s already exists, not creating." % gd.name)
-
-            for ud in self.anaconda.ksdata.user.userList:
-                if not self.createUser(name=ud.name,
-                                       password=ud.password,
-                                       isCrypted=ud.isCrypted,
-                                       groups=ud.groups,
-                                       homedir=ud.homedir,
-                                       shell=ud.shell,
-                                       uid=ud.uid,
-                                       algo=self.getPassAlgo(),
-                                       lock=ud.lock,
-                                       root=instPath,
-                                       gecos=ud.gecos):
-                    log.error("User %s already exists, not creating." % ud.name)
-
-    def writeKS(self, f):
-        if self.rootPassword["isCrypted"]:
-            args = " --iscrypted %s" % self.rootPassword["password"]
-        else:
-            args = " --iscrypted %s" % cryptPassword(self.rootPassword["password"], algo=self.getPassAlgo())
-
-        if self.rootPassword["lock"]:
-            args += " --lock"
-
-        f.write("rootpw %s\n" % args)
diff --git a/vnc.py b/vnc.py
deleted file mode 100644
index 0a6a049..0000000
--- a/vnc.py
+++ /dev/null
@@ -1,437 +0,0 @@
-#
-# vnc.py: VNC related installer functionality
-#
-# Copyright (C) 2004, 2007  Red Hat, Inc.  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 as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# 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, see <http://www.gnu.org/licenses/>.
-#
-# Author(s): Jeremy Katz <katzj@xxxxxxxxxx>
-#
-
-import os, sys, string
-import time
-from snack import *
-from constants import *
-from constants_text import *
-import network
-import isys
-import product
-import socket
-import subprocess
-
-import gettext
-_ = lambda x: gettext.ldgettext("anaconda", x)
-P_ = lambda x, y, z: gettext.ldngettext("anaconda", x, y, z)
-
-import logging
-log = logging.getLogger("anaconda")
-stdoutLog = logging.getLogger("anaconda.stdout")
-
-class VncServer:
-
-    def __init__(self, display="1", root="/", ip=None, name=None,
-                desktop="Desktop", password="", vncconnecthost="",
-                vncconnectport="", log_file="/tmp/vncserver.log",
-                pw_file="/tmp/vncpassword", pw_init_file="/tmp/vncpassword.dat"):
-        self.display = display
-        self.root = root
-        self.ip = ip
-        self.name = name
-        self.desktop = desktop
-        self.password = password
-        self.vncconnecthost = vncconnecthost
-        self.vncconnectport = vncconnectport
-        self.log_file = log_file
-        self.pw_file = pw_file
-        self.pw_init_file = pw_init_file
-        self.connxinfo = None
-        self.anaconda = None
-        self.log = logging.getLogger("anaconda.stdout")
-
-    def recoverVNCPassword(self):
-        """Rescue the vncpassword from where loader left it 
-
-        We are not to check for validity yet, if there is a file
-        pass it to the variable, if there is not, set the var 
-        to ''. We will check valididty later.
-        """
-        # see if there is a vnc password file
-        try:
-            pfile = open(self.pw_init_file, "r")
-            self.password=pfile.readline().strip()
-            pfile.close()
-            os.unlink(self.pw_init_file)
-        except:
-            self.password=""
-
-    def setVNCPassword(self):
-        """Change the vnc server password. Output to file. """
-
-        if len(self.password) == 0:
-            self.setVNCParam("SecurityTypes", "None")
-            self.setVNCParam("rfbauth","0")
-            return
-
-        # If there is a password the SecurityTypes = VncAuth for all connections.
-        self.setVNCParam("SecurityTypes", "VncAuth")
-        self.setVNCParam("rfbauth",self.pw_file)
-
-        # password input combination.
-        pwinput = "%s\n%s\n" % (self.password, self.password)
-        vnccommand = [self.root+"/usr/bin/vncpasswd", self.pw_file]
-        vncpswdo = subprocess.Popen(vnccommand, stdin=subprocess.PIPE, stdout=subprocess.PIPE)# We pipe the output
-                                                                                              # so the user does not see it.
-        (out, err) = vncpswdo.communicate(input=pwinput)
-        return vncpswdo.returncode
-
-    def initialize(self):
-        """Here is were all the relative vars get initialized. """
-
-        # see if we can sniff out network info
-        netinfo = network.Network()
-
-        devices = netinfo.netdevices
-        active_devs = network.getActiveNetDevs()
-
-        if active_devs != []:
-            dev = devices[active_devs[0]]
-
-            try:
-                self.ip = isys.getIPAddress(dev.get("DEVICE"))
-                log.info("ip of %s is %s" % (dev.get("DEVICE"), self.ip))
-
-                if self.ip == "127.0.0.1" or self.ip == "::1":
-                    self.ip = None
-            except Exception, e:
-                log.warning("Got an exception trying to get the self.ip addr "
-                            "of %s: %s" % (dev.get("DEVICE"), e))
-        else:
-            self.ip = None
-
-        self.name = network.getDefaultHostname(self.anaconda)
-        ipstr = self.ip
-
-        if self.ip.find(':') != -1:
-            ipstr = "[%s]" % (self.ip,)
-
-        if (self.name is not None) and (not self.name.startswith('localhost')) and (ipstr is not None):
-            self.connxinfo = "%s:%s (%s)" % (socket.getfqdn(name=self.name), self.display, ipstr,)
-        elif ipstr is not None:
-            self.connxinfo = "%s:%s" % (ipstr, self.display,)
-        else:
-            self.connxinfo = None
-
-        # figure out product info
-        if self.name is not None:
-            self.desktop = _("%(productName)s %(productVersion)s installation "
-                             "on host %(name)s") \
-                           % {'productName': product.productName,
-                              'productVersion': product.productVersion,
-                              'name': self.name}
-        else:
-            self.desktop = _("%(productName)s %(productVersion)s installation")\
-                           % {'productName': product.productName,
-                              'productVersion': product.productVersion}
-
-    def setVNCParam(self, param, value):
-        """Set a parameter in the Xvnc server. 
-
-        Possible values for param and value. param=(values)
-        SecurityTypes=(VncAuth,None)
-        """
-        vncconfigcommand = [self.root+"/usr/bin/vncconfig", "-display", ":%s"%self.display , "-set" , "%s=%s" %(param, value)]
-        vncconfo = subprocess.Popen(vncconfigcommand)# we dont want output
-        return vncconfo.returncode
-
-    def openlogfile(self):
-        try:
-            err = os.open(self.log_file, os.O_RDWR | os.O_CREAT)
-            if err < 0:
-                sys.stderr.write("error opening %s\n", log)
-                return None
-            else:
-                return err
-        except:
-                return None
-
-    def connectToView(self):
-        """Attempt to connect to self.vncconnecthost"""
-
-        maxTries = 10
-        self.log.info(_("Attempting to connect to vnc client on host %s...") % (self.vncconnecthost,))
-
-        if self.vncconnectport != "":
-            hostarg = self.vncconnecthost + ":" + self.vncconnectport
-        else:
-            hostarg = self.vncconnecthost
-
-        vncconfigcommand = [self.root+"/usr/bin/vncconfig", "-display", ":%s"%self.display, "-connect", hostarg]
-
-        for i in range(maxTries):
-            vncconfp = subprocess.Popen(vncconfigcommand, stdout=subprocess.PIPE, stderr=subprocess.PIPE) # vncconfig process
-            (out, err) = vncconfp.communicate()
-
-            if err == '':
-                self.log.info(_("Connected!"))
-                return True
-            elif err.startswith("connecting") and err.endswith("failed\n"):
-                self.log.info(_("Will try to connect again in 15 seconds..."))
-                time.sleep(15)
-                continue
-            else:
-                log.critical(err)
-                sys.exit(1)
-        self.log.error(P_("Giving up attempting to connect after %d try!\n",
-                          "Giving up attempting to connect after %d tries!\n",
-                          maxTries) % (maxTries,))
-        return False
-
-    def VNCListen(self):
-        """Put the server in listening mode.
-
-        We dont really have to do anything for the server to listen :)
-        """
-        if self.connxinfo != None:
-            self.log.info(_("Please manually connect your vnc client to %s to begin the install.") % (self.connxinfo,))
-        else:
-            self.log.info(_("Please manually connect your vnc client to begin the install."))
-
-    def startServer(self):
-        self.log.info(_("Starting VNC..."))
-
-        # Lets call it from here for now.
-        self.initialize()
-
-        # Lets start the xvnc regardless of vncconnecthost and password.
-        # We can change the configuration on the fly later.
-        xvnccommand =  [ self.root + "/usr/bin/Xvnc", ":%s" % self.display, "-nevershared",
-                        "-depth", "16", "-geometry", "800x600", "-br",
-                        "IdleTimeout=0", "-auth", "/dev/null", "-once",
-                        "DisconnectClients=false", "desktop=%s" % (self.desktop,),
-                        "SecurityTypes=None"]
-        try:
-            xvncp = subprocess.Popen(xvnccommand, stdout=self.openlogfile(), stderr=subprocess.STDOUT)
-        except:
-            stdoutLog.critical("Could not start the VNC server.  Aborting.")
-            sys.exit(1)
-
-        # Lets give the xvnc time to initialize
-        time.sleep(1)
-
-        # Make sure it hasn't blown up
-        if xvncp.poll() != None:
-            sys.exit(1)
-        else:
-            self.log.info(_("The VNC server is now running."))
-
-        # Lets look at the password stuff
-        if self.password == "":
-            pass
-        elif len(self.password) < 6:
-            self.changeVNCPasswdWindow()
-
-        # Create the password file.
-        self.setVNCPassword()
-
-        # Lets tell the user what we are going to do.
-        if self.vncconnecthost != "":
-            self.log.warning(_("\n\nYou chose to connect to a listening vncviewer. \n"
-                                "This does not require a password to be set.  If you \n"
-                                "set a password, it will be used in case the connection \n"
-                                "to the vncviewer is unsuccessful\n\n"))
-        elif self.password == "":
-             self.log.warning(_("\n\nWARNING!!! VNC server running with NO PASSWORD!\n"
-                                "You can use the vncpassword=<password> boot option\n"
-                                "if you would like to secure the server.\n\n"))
-        elif self.password != "":
-             self.log.warning(_("\n\nYou chose to execute vnc with a password. \n\n"))
-        else:
-             self.log.warning(_("\n\nUnknown Error.  Aborting. \n\n"))
-             sys.exit(1)
-
-        # Lets try to configure the vnc server to whatever the user specified
-        if self.vncconnecthost != "":
-            connected = self.connectToView()
-            if not connected:
-                self.VNCListen()
-        else:
-            self.VNCListen()
-
-        os.environ["DISPLAY"]=":%s" % self.display
-
-    def changeVNCPasswdWindow(self):
-        """ Change the password to a sane parameter.
-
-        We ask user to input a password that len(password) > 6
-        or password == ''. Have to find a way to put askVncWindow
-        and this method together.
-        """
-
-        screen = SnackScreen()
-        grid = GridFormHelp(screen, _("VNC Configuration"),"vnc", 1, 10)
-
-        bb = ButtonBar(screen, (TEXT_OK_BUTTON,
-                                (_("No password"), "nopass")))
-
-        text = _("A password will prevent unauthorized listeners "
-                 "connecting and monitoring your installation progress.  "
-                 "Please enter a password to be used for the installation")
-        grid.add(TextboxReflowed(40, text), 0, 0, (0, 0, 0, 1))
-
-        entry1 = Entry (16, password = 1)
-        entry2 = Entry (16, password = 1)
-        passgrid = Grid (2, 2)
-        passgrid.setField (Label (_("Password:")), 0, 0, (0, 0, 1, 0), anchorLeft = 1)
-        passgrid.setField (Label (_("Password (confirm):")), 0, 1, (0, 0, 1, 0), anchorLeft = 1)
-        passgrid.setField (entry1, 1, 0)
-        passgrid.setField (entry2, 1, 1)
-        grid.add (passgrid, 0, 1, (0, 0, 0, 1))
-
-        grid.add(bb, 0, 8, (0, 1, 1, 0), growx = 1)
-
-        while 1:
-            res = grid.run()
-            rc = bb.buttonPressed(res)
-
-            if rc == "nopass":
-                screen.finish()
-                return ""
-            else:
-                pw = entry1.value()
-                cf = entry2.value()
-                if pw != cf:
-                    ButtonChoiceWindow(screen, _("Password Mismatch"),
-                                       _("The passwords you entered were "
-                                         "different. Please try again."),
-                                       buttons = [ TEXT_OK_BUTTON ],
-                                       width = 50)
-                elif len(pw) < 6:
-                    ButtonChoiceWindow(screen, _("Password Length"),
-                                       _("The password must be at least "
-                                         "six characters long."),
-                                       buttons = [ TEXT_OK_BUTTON ],
-                                       width = 50)
-                else:
-                    screen.finish()
-                    self.password = pw
-                    return 
-
-                entry1.set("")
-                entry2.set("")
-                continue
-            continue
-
-def askVncWindow(title = None, message = None):
-    if not os.access('/usr/bin/Xvnc', os.X_OK):
-        return -1
-
-    if not network.hasActiveNetDev():
-        return -1
-
-    if not title:
-        title = _("Unable to Start X")
-    if not message:
-        message = _("X was unable to start on your "
-                    "machine.  Would you like to "
-                    "start VNC to connect to "
-                    "this computer from another "
-                    "computer and perform a "
-                    "graphical install or continue "
-                    "with a text mode install?")
-
-    screen = SnackScreen()
-    vncpass = None
-    vncconnect = 0
-
-    STEP_MESSAGE = 0
-    STEP_PASS = 1
-    STEP_DONE = 3
-    step = 0
-    while step < STEP_DONE:
-        if step == STEP_MESSAGE:
-            button = ButtonChoiceWindow(screen, title, message,
-                                        buttons = [ _("Start VNC"),
-                                                    _("Use text mode") ])
-
-	    if button == string.lower (_("Use text mode")):
-                screen.finish()
-                return -1
-            else:
-                step = STEP_PASS
-                continue
-
-        if step == STEP_PASS:
-            grid = GridFormHelp(screen, _("VNC Configuration"),
-                                "vnc", 1, 10)
-
-            bb = ButtonBar(screen, (TEXT_OK_BUTTON,
-                                    (_("No password"), "nopass"),
-                                    TEXT_BACK_BUTTON))
-
-            text = _("A password will prevent unauthorized listeners "
-                     "connecting and monitoring your installation progress.  "
-                     "Please enter a password to be used for the installation")
-            grid.add(TextboxReflowed(40, text), 0, 0, (0, 0, 0, 1))
-
-            entry1 = Entry (16, password = 1)
-            entry2 = Entry (16, password = 1)
-            passgrid = Grid (2, 2)
-            passgrid.setField (Label (_("Password:")), 0, 0, (0, 0, 1, 0), anchorLeft = 1)
-            passgrid.setField (Label (_("Password (confirm):")), 0, 1, (0, 0, 1, 0), anchorLeft = 1)
-            passgrid.setField (entry1, 1, 0)
-            passgrid.setField (entry2, 1, 1)
-            grid.add (passgrid, 0, 1, (0, 0, 0, 1))
-
-            grid.add(bb, 0, 8, (0, 1, 1, 0), growx = 1)
-
-            while 1:
-                res = grid.run()
-                rc = bb.buttonPressed(res)
-
-                if rc == TEXT_BACK_CHECK:
-                    screen.popWindow()
-                    step = STEP_MESSAGE
-                    break
-                elif rc == "nopass":
-                    screen.finish()
-                    return None
-                else:
-                    pw = entry1.value()
-                    cf = entry2.value()
-                    if pw != cf:
-                        ButtonChoiceWindow(screen, _("Password Mismatch"),
-                                           _("The passwords you entered were "
-                                             "different. Please try again."),
-                                           buttons = [ TEXT_OK_BUTTON ],
-                                           width = 50)
-                    elif len(pw) < 6:
-                        ButtonChoiceWindow(screen, _("Password Length"),
-                                           _("The password must be at least "
-                                             "six characters long."),
-                                           buttons = [ TEXT_OK_BUTTON ],
-                                           width = 50)
-                    else:
-                        screen.finish()
-                        return pw
-
-                    entry1.set("")
-                    entry2.set("")
-                    continue
-                continue
-
-    screen.finish()
-    return -1
-
-if __name__ == "__main__":
-    askVncWindow()
diff --git a/xutils.c b/xutils.c
deleted file mode 100644
index 372ffca..0000000
--- a/xutils.c
+++ /dev/null
@@ -1,268 +0,0 @@
-/*
- * xutils.c - a Python wrapper for common Xlib ops
- *
- * Copyright (C) 2002  Red Hat, Inc.  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 as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * 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, see <http://www.gnu.org/licenses/>.
- *
- * Author(s): Michael Fulbright <msf@xxxxxxxxxx>
- */
-
-#include <Python.h>
-#include <X11/Xlib.h>
-#include <X11/Xatom.h>
-#include <gdk/gdkx.h>
-
-static PyObject * setRootResource(PyObject * s, PyObject * args);
-static PyObject * getXatom(PyObject *s, PyObject *args);
-
-
-static PyMethodDef xutilsMethods[] = {
-    { "setRootResource", setRootResource, 1, NULL },
-    { "getXatom", getXatom, 1, NULL },
-    { NULL, NULL, 0, NULL }
-};
-
-typedef struct _Resource {
-    char *key, *val;
-} Resource;
-
-static int
-openDisplay(Display **dpy, Window *root) 
-{
-    int     scrn;
-
-    *dpy=XOpenDisplay("");
-    if (!*dpy)
-	return -1;
-
-    scrn=DefaultScreen(*dpy);
-    *root = RootWindow(*dpy, scrn);
-    return 0;
-}
-
-static void
-closeDisplay(Display *dpy)
-{
-   XCloseDisplay(dpy);
-}    
-
-static Resource **
-getCurrentResources(Display *dpy)
-{
-    char *resource_string, *p;
-    Resource **rc;
-    int  nrec;
-
-    /* read through current resources, split on newlines */
-    resource_string = XResourceManagerString(dpy);
-
-    if (!resource_string)
-	return NULL;
-
-    rc = (Resource **)malloc(sizeof(Resource *));
-    p = resource_string;
-    nrec = 0;
-    while (1) {
-	char *eol;
-	char *sep;
-	int nleft;
-
-	/* find next newline, defines end of current record */
-	eol = strchr(p, '\n');
-
-	if (!eol)
-	    break;
-
-	/* find colon separating key and value */
-	/* if no colon skip this record        */
-	sep = strchr(p, ':');
-	if (sep) {
-	    int  len;
-	    Resource *newrec;
-
-	    newrec = (Resource *) malloc(sizeof(Resource));
-
-	    len = sep - p + 1;
-	    newrec->key = (char *) malloc(len*sizeof(char));
-	    memcpy(newrec->key, p, len);
-	    newrec->key[len-1] = '\0';
-
-	    len = eol - sep;
-	    newrec->val = (char *) malloc(len*sizeof(char));
-	    memcpy(newrec->val, sep+1, len);
-	    newrec->val[len-1] = '\0';
-
-	    rc = (Resource **) realloc(rc, (nrec+1) * sizeof(Resource *));
-	    rc[nrec] = newrec;
-	    nrec = nrec + 1;
-	}
-
-	nleft = strlen(resource_string) - (eol-resource_string);
-	if (nleft <= 0)
-	    break;
-
-	p = eol + 1;
-    }
-
-    if (nrec > 0) {
-	rc = (Resource **) realloc(rc, (nrec+1) * sizeof(Resource *));
-	rc[nrec] = NULL;
-    } else {
-	rc = NULL;
-    }
-
-    return rc;
-}
-
-static void
-freeResources(Resource **rc)
-{
-    int idx;
-
-    if (!rc)
-	return;
-
-    idx = 0;
-    while (rc[idx]) {
-	free(rc[idx]->key);
-	free(rc[idx]->val);
-	free(rc[idx]);
-
-	idx++;
-    }
-
-    free(rc);
-}
-
-static PyObject *
-setRootResource(PyObject *s, PyObject *args)
-{
-    Display *dpy;
-    Window  root;
-    Resource **resources, **p;
-    char *key, *val, *rstring;
-    int fnd, nrec;
-
-    if (!PyArg_ParseTuple(args, "ss", &key, &val)) {
-	return NULL;
-    }
-
-    if (openDisplay(&dpy, &root) < 0) {
-	PyErr_SetString(PyExc_SystemError, "Could not open display.");
-	return NULL;
-    }
-
-    resources = getCurrentResources(dpy);
-    fnd = 0;
-    nrec = 0;
-    if (resources) {
-	p = resources;
-	while (*p) {
-	    if (!strcmp(key, (*p)->key)) {
-		free((*p)->val);
-		(*p)->val = strdup(val);
-		fnd = 1;
-		break;
-	    }
-
-	    p++;
-	}
-
-	p = resources;
-	while (*p) {
-	    nrec++;
-	    p++;
-	}
-    }
-
-    if (!fnd) {
-	Resource *newrec;
-
-	newrec = (Resource *) malloc(sizeof(Resource));
-	newrec->key = strdup(key);
-	newrec->val = strdup(val);
-
-	if (nrec > 0)
-	    resources = (Resource **) realloc(resources, (nrec+2) * sizeof(Resource *));
-	else
-	    resources = (Resource **) malloc(2*sizeof(Resource *));
-
-	resources[nrec] = newrec;
-	resources[nrec+1] = NULL;
-    }
-
-    rstring = NULL;
-    p = resources;
-    while (*p) {
-	int len;
-	char *tmpstr;
-
-	len = strlen((*p)->key) + strlen((*p)->val) + 3;
-	tmpstr = (char *) malloc(len*sizeof(char));
-	strcpy(tmpstr, (*p)->key);
-	strcat(tmpstr, ":");
-	strcat(tmpstr, (*p)->val);
-	strcat(tmpstr, "\n");
-
-	if (rstring) {
-	    rstring = (char *)realloc(rstring, (strlen(rstring)+len+1)*sizeof(char));
-	    strcat(rstring, tmpstr);
-	} else {
-	    rstring = tmpstr;
-	}
-
-	p++;
-    }
-
-    XChangeProperty(dpy, root, XA_RESOURCE_MANAGER, XA_STRING, 
-		    8, PropModeReplace, (unsigned char *)rstring,
-		    strlen(rstring));
-
-    free(rstring);
-    freeResources(resources);
-
-    closeDisplay(dpy);
-
-    Py_INCREF(Py_None);
-    return Py_None;
-}
-
-/* this assumes you've already imported gtk and thus have a display */
-static PyObject * 
-getXatom(PyObject *s, PyObject *args)
-{
-    char *atomname;
-    Atom theatom;
-
-    if (!PyArg_ParseTuple(args, "s", &atomname)) {
-	return NULL;
-    }
-
-    theatom = gdk_x11_get_xatom_by_name(atomname);
-    if (XGetSelectionOwner (GDK_DISPLAY(), theatom) != None) {
-        Py_INCREF(Py_True);
-        return Py_True;
-    }
-    Py_INCREF(Py_False);
-    return Py_False;
-}
-
-void 
-initxutils ()
-{
-    PyObject * d;
-
-    d = Py_InitModule ("xutils", xutilsMethods);
-}
diff --git a/yuminstall.py b/yuminstall.py
deleted file mode 100644
index 3e0b1e2..0000000
--- a/yuminstall.py
+++ /dev/null
@@ -1,2024 +0,0 @@
-#
-# yuminstall.py
-#
-# Copyright (C) 2005, 2006, 2007  Red Hat, Inc.  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 as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# 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, see <http://www.gnu.org/licenses/>.
-#
-
-from flags import flags
-from errors import *
-
-import sys
-import os
-import os.path
-import shutil
-import time
-import warnings
-import types
-import locale
-import glob
-import tempfile
-import itertools
-import re
-
-
-import anaconda_log
-import rpm
-import rpmUtils
-import urlgrabber.progress
-import urlgrabber.grabber
-from urlgrabber.grabber import URLGrabber, URLGrabError
-import yum
-import iniparse
-from yum.constants import *
-from yum.Errors import *
-from yum.misc import to_unicode
-from yum.yumRepo import YumRepository
-from backend import AnacondaBackend
-from product import *
-from sortedtransaction import SplitMediaTransactionData
-from constants import *
-from image import *
-from compssort import *
-import packages
-
-import gettext
-_ = lambda x: gettext.ldgettext("anaconda", x)
-P_ = lambda x, y, z: gettext.ldngettext("anaconda", x, y, z)
-
-import network
-
-# specspo stuff
-rpm.addMacro("_i18ndomains", "redhat-dist")
-
-import logging
-log = logging.getLogger("anaconda")
-
-import urlparse
-urlparse.uses_fragment.append('media')
-
-urlgrabber.grabber.default_grabber.opts.user_agent = "%s (anaconda)/%s" %(productName, productVersion)
-
-import iutil
-import isys
-
-def size_string (size):
-    def number_format(s):
-        return locale.format("%s", s, 1)
-
-    retval = None
-
-    if size > 1024 * 1024:
-        size = size / (1024*1024)
-        retval = _("%s MB") %(number_format(size),)
-    elif size > 1024:
-        size = size / 1024
-        retval = _("%s KB") %(number_format(size),)
-    else:
-        retval = P_("%s Byte", "%s Bytes", size) % (number_format(size),)
-
-    return to_unicode(retval)
-
-class AnacondaCallback:
-
-    def __init__(self, ayum, anaconda, instLog, modeText):
-        self.repos = ayum.repos
-        self.ts = ayum.ts
-        self.ayum = ayum
-
-        self.messageWindow = anaconda.intf.messageWindow
-        self.pulseWindow = anaconda.intf.progressWindow
-        self.progress = anaconda.intf.instProgress
-        self.progressWindowClass = anaconda.intf.progressWindow
-        self.rootPath = anaconda.rootPath
-
-        self.initWindow = None
-
-        self.progressWindow = None
-        self.lastprogress = 0
-        self.incr = 20
-
-        self.instLog = instLog
-        self.modeText = modeText
-
-        self.openfile = None
-        self.inProgressPo = None
-
-    def setSizes(self, numpkgs, totalSize, totalFiles):
-        self.numpkgs = numpkgs
-        self.totalSize = totalSize
-        self.totalFiles = totalFiles
-
-        self.donepkgs = 0
-        self.doneSize = 0
-        self.doneFiles = 0
-        
-
-    def callback(self, what, amount, total, h, user):
-        if what == rpm.RPMCALLBACK_TRANS_START:
-            # step 6 is the bulk of the ts processing time
-            if amount == 6:
-                self.progressWindow = \
-                    self.progressWindowClass (_("Preparing to install"),
-                                              _("Preparing transaction from installation source"),
-                                              total)
-                self.incr = total / 10
-
-        if what == rpm.RPMCALLBACK_TRANS_PROGRESS:
-            if self.progressWindow and amount > self.lastprogress + self.incr:
-                self.progressWindow.set(amount)
-                self.lastprogress = amount
-
-        if what == rpm.RPMCALLBACK_TRANS_STOP and self.progressWindow:
-            self.progressWindow.pop()
-
-        if what == rpm.RPMCALLBACK_INST_OPEN_FILE:
-            (hdr, rpmloc) = h
-            # hate hate hate at epochs...
-            epoch = hdr['epoch']
-            if epoch is not None:
-                epoch = str(epoch)
-            txmbrs = self.ayum.tsInfo.matchNaevr(hdr['name'], hdr['arch'],
-                                                 epoch, hdr['version'],
-                                                 hdr['release'])
-            if len(txmbrs) == 0:
-                raise RuntimeError, "Unable to find package %s-%s-%s.%s" %(hdr['name'], hdr['version'], hdr['release'], hdr['arch'])
-            po = txmbrs[0].po
-
-            repo = self.repos.getRepo(po.repoid)
-
-            pkgStr = "%s-%s-%s.%s" % (po.name, po.version, po.release, po.arch)
-            s = to_unicode(_("<b>Installing %(pkgStr)s</b> (%(size)s)\n")) \
-                    % {'pkgStr': pkgStr, 'size': size_string(hdr['size'])}
-            summary = to_unicode(gettext.ldgettext("redhat-dist", hdr['summary'] or ""))
-            s += summary.strip()
-            self.progress.set_label(s)
-
-            self.instLog.write(self.modeText % str(pkgStr))
-
-            self.instLog.flush()
-            self.openfile = None
-
-            while self.openfile is None:
-                try:
-                    fn = repo.getPackage(po)
-
-                    f = open(fn, 'r')
-                    self.openfile = f
-                except yum.Errors.NoMoreMirrorsRepoError:
-                    self.ayum._handleFailure(po)
-                except IOError:
-                    self.ayum._handleFailure(po)
-                except yum.Errors.RepoError, e:
-                    continue
-            self.inProgressPo = po
-
-            return self.openfile.fileno()
-
-        elif what == rpm.RPMCALLBACK_INST_CLOSE_FILE:
-            if self.initWindow:
-                self.initWindow.pop()
-                self.initWindow = None
-
-            (hdr, rpmloc) = h
-
-            fn = self.openfile.name
-            self.openfile.close()
-            self.openfile = None
-
-            if os.path.dirname(fn).startswith("%s/var/cache/yum/" % self.rootPath):
-                try:
-                    os.unlink(fn)
-                except OSError as e:
-                    log.debug("unable to remove file %s" %(e.strerror,))
-
-            self.donepkgs += 1
-            self.doneSize += self.inProgressPo.returnSimple("installedsize") / 1024.0
-            self.doneFiles += len(hdr[rpm.RPMTAG_BASENAMES])
-
-            if self.donepkgs <= self.numpkgs:
-                self.progress.set_text(P_("Packages completed: "
-                                          "%(donepkgs)d of %(numpkgs)d",
-                                          "Packages completed: "
-                                          "%(donepkgs)d of %(numpkgs)d",
-                                          self.numpkgs)
-                                       % {'donepkgs': self.donepkgs,
-                                          'numpkgs': self.numpkgs})
-            self.progress.set_fraction(float(self.doneSize / self.totalSize))
-            self.progress.processEvents()
-
-            self.inProgressPo = None
-
-        elif what in (rpm.RPMCALLBACK_UNINST_START,
-                      rpm.RPMCALLBACK_UNINST_STOP):
-            if self.initWindow is None:
-                self.initWindow = self.pulseWindow(_("Finishing upgrade"),
-                                                   _("Finishing upgrade process.  This may take a little while."),
-                                                   0, pulse=True)
-            else:
-                self.initWindow.pulse()
-
-        elif what in (rpm.RPMCALLBACK_CPIO_ERROR,
-                      rpm.RPMCALLBACK_UNPACK_ERROR,
-                      rpm.RPMCALLBACK_SCRIPT_ERROR):
-            if not isinstance(h, types.TupleType):
-                h = (h, None)
-
-            (hdr, rpmloc) = h
-
-            # If this is a cleanup/remove, then hdr is a string not a header.
-            if isinstance(hdr, rpm.hdr):
-                name = hdr['name']
-            else:
-                name = hdr
-
-            # Script errors store whether or not they're fatal in "total".  So,
-            # we should only error out for fatal script errors or the cpio and
-            # unpack problems.
-            if what != rpm.RPMCALLBACK_SCRIPT_ERROR or total:
-                self.messageWindow(_("Error Installing Package"),
-                    _("A fatal error occurred when installing the %s "
-                      "package.  This could indicate errors when reading "
-                      "the installation media.  Installation cannot "
-                      "continue.") % name,
-                    type="custom", custom_icon="error",
-                    custom_buttons=[_("_Exit installer")])
-                sys.exit(1)
-
-        if self.initWindow is None:
-            self.progress.processEvents()
-
-class AnacondaYumRepo(YumRepository):
-    def __init__(self, *args, **kwargs):
-        YumRepository.__init__(self, *args, **kwargs)
-        self.enablegroups = True
-        self._anacondaBaseURLs = []
-
-    def needsNetwork(self):
-        def _isURL(s):
-            return s.startswith("http") or s.startswith("ftp")
-
-        if len(self.baseurl) > 0:
-            return len(filter(lambda s: _isURL(s), self.baseurl)) > 0
-        elif self.mirrorlist:
-            return _isURL(self.mirrorlist)
-        else:
-            return False
-
-    def dirCleanup(self):
-        cachedir = self.getAttribute('cachedir')
-
-        if os.path.isdir(cachedir):
-            if not self.needsNetwork() or self.name == "Installation Repo":
-                shutil.rmtree(cachedir)
-            else:
-                if os.path.exists("%s/headers" % cachedir):
-                    shutil.rmtree("%s/headers" % cachedir)
-                if os.path.exists("%s/packages" % cachedir):
-                    shutil.rmtree("%s/packages" % cachedir)
-
-    # needed to store nfs: repo url that yum doesn't know
-    def _getAnacondaBaseURLs(self):
-        return self._anacondaBaseURLs or self.baseurl or [self.mirrorlist]
-
-    def _setAnacondaBaseURLs(self, value):
-        self._anacondaBaseURLs = value
-
-    anacondaBaseURLs = property(_getAnacondaBaseURLs, _setAnacondaBaseURLs,
-                                doc="Extends AnacondaYum.baseurl to store non-yum urls:")
-
-class YumSorter(yum.YumBase):
-    def _transactionDataFactory(self):
-        return SplitMediaTransactionData()
-
-class AnacondaYum(YumSorter):
-    def __init__(self, anaconda):
-        YumSorter.__init__(self)
-        self.anaconda = anaconda
-        self._timestamp = None
-
-        self.repoIDcounter = itertools.count()
-
-        # Only needed for hard drive and nfsiso installs.
-        self._discImages = {}
-        self.isodir = None
-
-        # Only needed for media installs.
-        self.currentMedia = None
-        self.mediagrabber = None
-
-        # Where is the source media mounted?  This is the directory
-        # where Packages/ is located.
-        self.tree = "/mnt/source"
-
-        self.macros = {}
-
-        if flags.selinux:
-            for directory in ("/tmp/updates",
-                        "/etc/selinux/targeted/contexts/files",
-                        "/etc/security/selinux/src/policy/file_contexts",
-                        "/etc/security/selinux"):
-                fn = "%s/file_contexts" %(directory,)
-                if os.access(fn, os.R_OK):
-                    break
-            self.macros["__file_context_path"] = fn
-        else:
-            self.macros["__file_context_path"]  = "%{nil}"
-
-        self.updates = []
-        self.localPackages = []
-
-    def setup(self):
-        # yum doesn't understand all our method URLs, so use this for all
-        # except FTP and HTTP installs.
-        self._baseRepoURL = "file://%s" % self.tree
-
-        while True:
-            try:
-                self.configBaseURL()
-                break
-            except SystemError, e:
-                self.anaconda.intf.messageWindow(_("Error Setting Up Repository"),
-                    _("The following error occurred while setting up the "
-                      "installation repository:\n\n%(e)s\n\nPlease provide the "
-                      "correct information for installing %(productName)s.")
-                    % {'e': e, 'productName': productName})
-
-                self.anaconda.methodstr = self.anaconda.intf.methodstrRepoWindow(self.anaconda.methodstr or "cdrom:")
-
-        self.doConfigSetup(root=self.anaconda.rootPath)
-        self.conf.installonlypkgs = []
-
-    def _switchCD(self, discnum):
-        if os.access("%s/.discinfo" % self.tree, os.R_OK):
-            f = open("%s/.discinfo" % self.tree)
-            self._timestamp = f.readline().strip()
-            f.close()
-
-        dev = self.anaconda.storage.devicetree.getDeviceByName(self.anaconda.mediaDevice)
-        dev.format.mountpoint = self.tree
-
-        # If self.currentMedia is None, then there shouldn't be anything
-        # mounted.  Before going further, see if the correct disc is already
-        # in the drive.  This saves a useless eject and insert if the user
-        # has for some reason already put the disc in the drive.
-        if self.currentMedia is None:
-            try:
-                dev.format.mount()
-
-                if verifyMedia(self.tree, discnum, None):
-                    self.currentMedia = discnum
-                    return
-
-                dev.format.unmount()
-            except:
-                pass
-        else:
-            unmountCD(dev, self.anaconda.intf.messageWindow)
-            self.currentMedia = None
-
-        dev.eject()
-
-        while True:
-            if self.anaconda.intf:
-                self.anaconda.intf.beep()
-
-            self.anaconda.intf.messageWindow(_("Change Disc"),
-                _("Please insert %(productName)s disc %(discnum)d to continue.")
-                % {'productName': productName, 'discnum': discnum})
-
-            try:
-                dev.format.mount()
-
-                if verifyMedia(self.tree, discnum, self._timestamp):
-                    self.currentMedia = discnum
-                    break
-
-                self.anaconda.intf.messageWindow(_("Wrong Disc"),
-                        _("That's not the correct %s disc.")
-                          % (productName,))
-
-                dev.format.unmount()
-                dev.eject()
-            except:
-                self.anaconda.intf.messageWindow(_("Error"),
-                        _("Unable to access the disc."))
-
-    def _switchImage(self, discnum):
-        umountImage(self.tree, self.currentMedia)
-        self.currentMedia = None
-
-        # mountDirectory checks before doing anything, so it's safe to
-        # call this repeatedly.
-        mountDirectory(self.anaconda.methodstr,
-                       self.anaconda.intf.messageWindow)
-
-        self._discImages = mountImage(self.isodir, self.tree, discnum,
-                                      self.anaconda.intf.messageWindow,
-                                      discImages=self._discImages)
-        self.currentMedia = discnum
-
-    def configBaseURL(self):
-        # We only have a methodstr if method= or repo= was passed to
-        # anaconda.  No source for this base repo (the CD media, NFS,
-        # whatever) is mounted yet since loader only mounts the source
-        # for the stage2 image.  We need to set up the source mount
-        # now.
-        if flags.cmdline.has_key("preupgrade"):
-            path = "/var/cache/yum/preupgrade"
-            self.anaconda.methodstr = "hd::%s" % path 
-            self._baseRepoURL = "file:///mnt/sysimage/%s" % path
-        elif self.anaconda.methodstr:
-            m = self.anaconda.methodstr
-
-            if m.startswith("hd:"):
-                if m.count(":") == 2:
-                    (device, path) = m[3:].split(":")
-                else:
-                    (device, fstype, path) = m[3:].split(":")
-
-                self.isodir = "/mnt/isodir/%s" % path
-
-                # This takes care of mounting /mnt/isodir first.
-                self._switchImage(1)
-                self.mediagrabber = self.mediaHandler
-            elif m.startswith("nfsiso:"):
-                self.isodir = "/mnt/isodir"
-
-                # Calling _switchImage takes care of mounting /mnt/isodir first.
-                if not network.hasActiveNetDev():
-                    if not self.anaconda.intf.enableNetwork():
-                        self._baseRepoURL = None
-                        return
-
-                    urlgrabber.grabber.reset_curl_obj()
-
-                self._switchImage(1)
-                self.mediagrabber = self.mediaHandler
-            elif m.startswith("http") or m.startswith("ftp:"):
-                self._baseRepoURL = m
-            elif m.startswith("nfs:"):
-                if not network.hasActiveNetDev():
-                    if not self.anaconda.intf.enableNetwork():
-                        self._baseRepoURL = None
-
-                    urlgrabber.grabber.reset_curl_obj()
-
-                (opts, server, path) = iutil.parseNfsUrl(m)
-                isys.mount(server+":"+path, self.tree, "nfs", options=opts)
-
-                # This really should be fixed in loader instead but for now see
-                # if there's images and if so go with this being an NFSISO
-                # install instead.
-                images = findIsoImages(self.tree, self.anaconda.intf.messageWindow)
-                if images != {}:
-                    isys.umount(self.tree, removeDir=False)
-                    self.anaconda.methodstr = "nfsiso:%s" % m[4:]
-                    self.configBaseURL()
-                    return
-            elif m.startswith("cdrom:"):
-                self._switchCD(1)
-                self.mediagrabber = self.mediaHandler
-                self._baseRepoURL = "file://%s" % self.tree
-        else:
-            # No methodstr was given.  In order to find an installation source,
-            # we should first check to see if there's a CD/DVD with packages
-            # on it, and then default to the mirrorlist URL.  The user can
-            # always change the repo with the repo editor later.
-            cdr = scanForMedia(self.tree, self.anaconda.storage)
-            if cdr:
-                self.mediagrabber = self.mediaHandler
-                self.anaconda.mediaDevice = cdr
-                self.currentMedia = 1
-                log.info("found installation media on %s" % cdr)
-            else:
-                # No CD with media on it and no repo=/method= parameter, so
-                # default to using whatever's enabled in /etc/yum.repos.d/
-                self._baseRepoURL = None
-
-    def configBaseRepo(self, root='/'):
-        # Create the "base" repo object, assuming there is one.  Otherwise we
-        # just skip all this and use the defaults from /etc/yum.repos.d.
-        if not self._baseRepoURL:
-            return
-
-        # add default repos
-        anacondabaseurl = (self.anaconda.methodstr or
-                           "cdrom:%s" % (self.anaconda.mediaDevice))
-        anacondabasepaths = self.anaconda.instClass.getPackagePaths(anacondabaseurl)
-        for (name, uri) in self.anaconda.instClass.getPackagePaths(self._baseRepoURL).items():
-            rid = name.replace(" ", "")
-
-            repo = AnacondaYumRepo("anaconda-%s-%s" % (rid, productStamp))
-            repo.baseurl = uri
-            repo.anacondaBaseURLs = anacondabasepaths[name]
-
-            repo.name = name
-            repo.cost = 100
-
-            if self.anaconda.mediaDevice or self.isodir:
-                repo.mediaid = getMediaId(self.tree)
-                log.info("set mediaid of repo %s to: %s" % (rid, repo.mediaid))
-
-            repo.enable()
-            self.repos.add(repo)
-
-    def mediaHandler(self, *args, **kwargs):
-        mediaid = kwargs["mediaid"]
-        discnum = kwargs["discnum"]
-        relative = kwargs["relative"]
-
-        # The package exists on media other than what's mounted right now.
-        if discnum != self.currentMedia:
-            log.info("switching from media #%s to #%s for %s" %
-                     (self.currentMedia, discnum, relative))
-
-            # Unmount any currently mounted ISO images and mount the one
-            # containing the requested packages.
-            if self.isodir:
-                self._switchImage(discnum)
-            else:
-                self._switchCD(discnum)
-
-        ug = URLGrabber(checkfunc=kwargs["checkfunc"])
-        ug.urlgrab("%s/%s" % (self.tree, kwargs["relative"]), kwargs["local"],
-                   text=kwargs["text"], range=kwargs["range"], copy_local=1)
-        return kwargs["local"]
-
-    # XXX: This is straight out of yum, but we need to override it here in
-    # order to use our own repo class.
-    def readRepoConfig(self, parser, section):
-        '''Parse an INI file section for a repository.
-
-        @param parser: ConfParser or similar to read INI file values from.
-        @param section: INI file section to read.
-        @return: YumRepository instance.
-        '''
-        repo = AnacondaYumRepo(section)
-        repo.populate(parser, section, self.conf)
-
-        # Ensure that the repo name is set
-        if not repo.name:
-            repo.name = section
-            self.logger.error(_('Repository %r is missing name in configuration, '
-                    'using id') % section)
-
-        # Set attributes not from the config file
-        repo.yumvar.update(self.conf.yumvar)
-        repo.cfg = parser
-
-        if "-source" in repo.id or "-debuginfo" in repo.id:
-            name = repo.name
-            del(repo)
-            raise RepoError, "Repo %s contains -source or -debuginfo, excluding" % name
-
-        # this is a little hard-coded, but it's effective
-        if not BETANAG and ("rawhide" in repo.id or "development" in repo.id):
-            name = repo.name
-            del(repo)
-            raise RepoError, "Excluding devel repo %s for non-devel anaconda" % name
-
-        if BETANAG and not repo.enabled:
-            name = repo.name
-            del(repo)
-            raise RepoError, "Excluding disabled repo %s for prerelease" % name
-
-        # If repo=/method= was passed in, we want to default these extra
-        # repos to off.
-        if self._baseRepoURL:
-            repo.enabled = False
-
-        return repo
-
-    # We need to make sure $releasever gets set up before .repo files are
-    # read.  Since there's no redhat-release package in /mnt/sysimage (and
-    # won't be for quite a while), we need to do our own substutition.
-    def _getReleasever(self):
-        from ConfigParser import ConfigParser
-        c = ConfigParser()
-
-        try:
-            if os.access("%s/.treeinfo" % self.anaconda.methodstr, os.R_OK):
-                ConfigParser.read(c, "%s/.treeinfo" % self.anaconda.methodstr)
-            else:
-                ug = URLGrabber()
-                ug.urlgrab("%s/.treeinfo" % self.anaconda.methodstr,
-                           "/tmp/.treeinfo", copy_local=1)
-                ConfigParser.read(c, "/tmp/.treeinfo")
-
-            return c.get("general", "version")
-        except:
-            return productVersion
-
-    # Override this method so yum doesn't nuke our existing logging config.
-    def doLoggingSetup(self, *args, **kwargs):
-
-        import yum.logginglevels
-
-        file_handler = logging.FileHandler("/tmp/yum.log")
-        file_formatter = logging.Formatter("[%(asctime)s] %(levelname)-8s: %(message)s")
-        file_handler.setFormatter(file_formatter)
-
-        tty3_handler = logging.FileHandler("/dev/tty3")
-        tty3_formatter = logging.Formatter(anaconda_log.TTY_FORMAT,
-                                           anaconda_log.DATE_FORMAT)
-        tty3_handler.setFormatter(tty3_formatter)
-
-        verbose = logging.getLogger("yum.verbose")
-        verbose.setLevel(logging.DEBUG)
-        verbose.propagate = False
-        verbose.addHandler(file_handler)
-
-        logger = logging.getLogger("yum")
-        logger.propagate = False
-        logger.setLevel(yum.logginglevels.INFO_2)
-        logger.addHandler(file_handler)
-        anaconda_log.autoSetLevel(tty3_handler, True)
-        tty3_handler.setLevel(anaconda_log.logger.tty_loglevel)
-        logger.addHandler(tty3_handler)
-
-        # XXX filelogger is set in setFileLog - do we or user want it?
-        filelogger = logging.getLogger("yum.filelogging")
-        filelogger.setLevel(logging.INFO)
-        filelogger.propagate = False
-
-
-    def doConfigSetup(self, fn='/tmp/anaconda-yum.conf', root='/'):
-        if hasattr(self, "preconf"):
-            self.preconf.fn = fn
-            self.preconf.root = root
-            self.preconf.releasever = self._getReleasever()
-            self.preconf.enabled_plugins = ["whiteout", "blacklist"]
-            YumSorter._getConfig(self)
-        else:
-            YumSorter._getConfig(self, fn=fn, root=root,
-                                 enabled_plugins=["whiteout", "blacklist"])
-        self.configBaseRepo(root=root)
-
-        extraRepos = []
-
-        ddArch = os.uname()[4]
-
-        #Add the Driver disc repos to Yum
-        for d in glob.glob(DD_RPMS):
-            dirname = os.path.basename(d)
-            rid = "anaconda-%s" % dirname
-
-            repo = AnacondaYumRepo(rid)
-            repo.baseurl = [ "file:///%s" % d ]
-            repo.name = "Driver Disk %s" % dirname.split("-")[1]
-            repo.enable()
-            extraRepos.append(repo)
-
-        if self.anaconda.ksdata:
-            # This is the same pattern as from loader/urls.c:splitProxyParam.
-            pattern = re.compile("([[:alpha:]]+://)?(([[:alnum:]]+)(:[^:@]+)?@)?([^:]+)(:[[:digit:]]+)?(/.*)?")
-
-            for ksrepo in self.anaconda.ksdata.repo.repoList:
-                anacondaBaseURLs = [ksrepo.baseurl]
-
-                # yum doesn't understand nfs:// and doesn't want to.  We need
-                # to first do the mount, then translate it into a file:// that
-                # yum does understand.
-                # "nfs:" and "nfs://" prefixes are accepted in ks repo --baseurl
-                if ksrepo.baseurl and ksrepo.baseurl.startswith("nfs:"):
-                    if not network.hasActiveNetDev() and not self.anaconda.intf.enableNetwork():
-                        self.anaconda.intf.messageWindow(_("No Network Available"),
-                            _("Some of your software repositories require "
-                              "networking, but there was an error enabling the "
-                              "network on your system."),
-                            type="custom", custom_icon="error",
-                            custom_buttons=[_("_Exit installer")])
-                        sys.exit(1)
-
-                    urlgrabber.grabber.reset_curl_obj()
-
-                    dest = tempfile.mkdtemp("", ksrepo.name.replace(" ", ""), "/mnt")
-
-                    # handle "nfs://" prefix
-                    if ksrepo.baseurl[4:6] == '//':
-                        ksrepo.baseurl = ksrepo.baseurl.replace('//', '', 1)
-                        anacondaBaseURLs = [ksrepo.baseurl]
-                    try:
-                        isys.mount(ksrepo.baseurl[4:], dest, "nfs")
-                    except Exception as e:
-                        log.error("error mounting NFS repo: %s" % e)
-
-                    ksrepo.baseurl = "file://%s" % dest
-
-                repo = AnacondaYumRepo(ksrepo.name)
-                repo.mirrorlist = ksrepo.mirrorlist
-                repo.name = ksrepo.name
-
-                if not ksrepo.baseurl:
-                    repo.baseurl = []
-                else:
-                    repo.baseurl = [ ksrepo.baseurl ]
-                repo.anacondaBaseURLs = anacondaBaseURLs
-
-                if ksrepo.cost:
-                    repo.cost = ksrepo.cost
-
-                if ksrepo.excludepkgs:
-                    repo.exclude = ksrepo.excludepkgs
-
-                if ksrepo.includepkgs:
-                    repo.include = ksrepo.includepkgs
-
-                if ksrepo.proxy:
-                    m = pattern.match(ksrepo.proxy)
-
-                    if m and m.group(5):
-                        # If both a host and port was found, just paste them
-                        # together using the colon at the beginning of the port
-                        # match as a separator.  Otherwise, just use the host.
-                        if m.group(6):
-                            repo.proxy = m.group(5) + m.group(6)
-                        else:
-                            repo.proxy = m.group(5)
-
-                        # yum also requires a protocol.  If none was given,
-                        # default to http.
-                        if m.group(1):
-                            repo.proxy = m.group(1) + repo.proxy
-                        else:
-                            repo.proxy = "http://"; + repo.proxy
-
-                    if m and m.group(3):
-                        repo.proxy_username = m.group(3)
-
-                    if m and m.group(4):
-                        # Skip the leading colon.
-                        repo.proxy_password = m.group(4)[1:]
-
-                repo.enable()
-                extraRepos.append(repo)
-
-        for repo in extraRepos:
-            try:
-                self.repos.add(repo)
-                log.info("added repository %s with URL %s" % (repo.name, repo.mirrorlist or repo.baseurl))
-            except:
-                log.warning("ignoring duplicate repository %s with URL %s" % (repo.name, repo.mirrorlist or repo.baseurl))
-
-        self.repos.setCacheDir(self.conf.cachedir)
-
-        if os.path.exists("%s/boot/upgrade/install.img" % self.anaconda.rootPath):
-            log.info("REMOVING stage2 image from %s /boot/upgrade" % self.anaconda.rootPath )
-            try:
-                os.unlink("%s/boot/upgrade/install.img" % self.anaconda.rootPath)
-            except:
-                log.warning("failed to clean /boot/upgrade")
-
-    def downloadHeader(self, po):
-        while True:
-            # retrying version of download header
-            try:
-                YumSorter.downloadHeader(self, po)
-                break
-            except yum.Errors.NoMoreMirrorsRepoError:
-                self._handleFailure(po)
-            except IOError:
-                self._handleFailure(po)
-            except yum.Errors.RepoError, e:
-                continue
-
-    def _handleFailure(self, package):
-        if not self.isodir and self.currentMedia:
-            buttons = [_("Re_boot"), _("_Eject")]
-        else:
-            buttons = [_("Re_boot"), _("_Retry")]
-
-        pkgFile = to_unicode(os.path.basename(package.remote_path))
-        rc = self.anaconda.intf.messageWindow(_("Error"),
-                   _("The file %s cannot be opened.  This is due to a missing "
-                     "file, a corrupt package or corrupt media.  Please "
-                     "verify your installation source.\n\n"
-                     "If you exit, your system will be left in an inconsistent "
-                     "state that will likely require reinstallation.\n\n") %
-                                              (pkgFile,),
-                                    type="custom", custom_icon="error",
-                                    custom_buttons=buttons)
-
-        if rc == 0:
-            sys.exit(0)
-        else:
-            if os.path.exists(package.localPkg()):
-                os.unlink(package.localPkg())
-
-            if not self.isodir and self.currentMedia:
-                self._switchCD(self.currentMedia)
-            else:
-                return
-
-    def mirrorFailureCB (self, obj, *args, **kwargs):
-        # This gets called when a mirror fails, but it cannot know whether
-        # or not there are other mirrors left to try, since it cannot know
-        # which mirror we were on when we started this particular download. 
-        # Whenever we have run out of mirrors the grabber's get/open/retrieve
-        # method will raise a URLGrabError exception with errno 256.
-        grab = self.repos.getRepo(kwargs["repo"]).grab
-        log.warning("Failed to get %s from mirror %d/%d, "
-                    "or downloaded file is corrupt" % (obj.url, grab._next + 1,
-                                                       len(grab.mirrors)))
-
-        if self.currentMedia:
-            dev = self.anaconda.storage.devicetree.getDeviceByName(self.anaconda.mediaDevice)
-            dev.format.mountpoint = self.tree
-            unmountCD(dev, self.anaconda.intf.messageWindow)
-            self.currentMedia = None
-
-    def urlgrabberFailureCB (self, obj, *args, **kwargs):
-        if hasattr(obj, "exception"):
-            log.warning("Try %s/%s for %s failed: %s" % (obj.tries, obj.retry, obj.url, obj.exception))
-        else:
-            log.warning("Try %s/%s for %s failed" % (obj.tries, obj.retry, obj.url))
-
-        if obj.tries == obj.retry:
-            return
-
-        delay = 0.25*(2**(obj.tries-1))
-        if delay > 1:
-            w = self.anaconda.intf.waitWindow(_("Retrying"), _("Retrying download."))
-            time.sleep(delay)
-            w.pop()
-        else:
-            time.sleep(delay)
-
-    def getDownloadPkgs(self):
-        downloadpkgs = []
-        totalSize = 0
-        totalFiles = 0
-        for txmbr in self.tsInfo.getMembersWithState(output_states=TS_INSTALL_STATES):
-            if txmbr.po:
-                totalSize += int(txmbr.po.returnSimple("installedsize")) / 1024
-                for filetype in txmbr.po.returnFileTypes():
-                    totalFiles += len(txmbr.po.returnFileEntries(ftype=filetype))
-                downloadpkgs.append(txmbr.po)
-
-        return (downloadpkgs, totalSize, totalFiles)
-
-    def setColor(self):
-        if rpmUtils.arch.isMultiLibArch():
-            self.ts.ts.setColor(3)
-
-    def run(self, instLog, cb, intf, id):
-        def mediasort(a, b):
-            # sort so that first CD comes first, etc.  -99 is a magic number
-            # to tell us that the cd should be last
-            if a == -99:
-                return 1
-            elif b == -99:
-                return -1
-            if a < b:
-                return -1
-            elif a > b:
-                return 1
-            return 0
-
-        self.initActionTs()
-        if self.anaconda.upgrade:
-            self.ts.ts.setProbFilter(~rpm.RPMPROB_FILTER_DISKSPACE)
-        self.setColor()
-
-        # If we don't have any required media assume single disc
-        if self.tsInfo.reqmedia == {}:
-            self.tsInfo.reqmedia[0] = None
-        mkeys = self.tsInfo.reqmedia.keys()
-        mkeys.sort(mediasort)
-
-        stage2img = "%s/images/install.img" % self.tree
-        if os.path.exists(stage2img):
-            if self.anaconda.backend.mountInstallImage(self.anaconda, stage2img):
-                self.anaconda.storage.umountFilesystems()
-                return DISPATCH_BACK
-
-        for i in mkeys:
-            self.tsInfo.curmedia = i
-            if i > 0:
-                pkgtup = self.tsInfo.reqmedia[i][0]
-
-            try:
-                self.dsCallback = DownloadHeaderProgress(intf, self)
-                self.populateTs(keepold=0)
-                self.dsCallback.pop()
-                self.dsCallback = None
-            except RepoError, e:
-                msg = _("There was an error running your transaction for "
-                        "the following reason: %s\n") % str(e)
-
-                if self.anaconda.upgrade:
-                    rc = intf.messageWindow(_("Error"), msg, type="custom",
-                                            custom_icon="error",
-                                            custom_buttons=[_("_Exit installer")])
-                    sys.exit(1)
-                else:
-                    rc = intf.messageWindow(_("Error"), msg,
-                            type="custom", custom_icon="error",
-                            custom_buttons=[_("_Back"), _("_Exit installer")])
-
-                if rc == 1:
-                    sys.exit(1)
-                else:
-                    self.tsInfo.curmedia = None
-                    return DISPATCH_BACK
-
-            self.ts.check()
-            self.ts.order()
-
-            if self._run(instLog, cb, intf) == DISPATCH_BACK:
-                self.tsInfo.curmedia = None
-                return DISPATCH_BACK
-
-            self.ts.close()
-
-    def _run(self, instLog, cb, intf):
-        # set log fd.  FIXME: this is ugly.  see changelog entry from 2005-09-13
-        self.ts.ts.scriptFd = instLog.fileno()
-        rpm.setLogFile(instLog)
-
-        uniqueProbs = {}
-        spaceneeded = {}
-        spaceprob = ""
-        fileConflicts = []
-        fileprob = ""
-
-        try:
-            self.runTransaction(cb=cb)
-        except YumBaseError, probs:
-            # FIXME: we need to actually look at these problems...
-            probTypes = { rpm.RPMPROB_NEW_FILE_CONFLICT : _('file conflicts'),
-                          rpm.RPMPROB_FILE_CONFLICT : _('file conflicts'),
-                          rpm.RPMPROB_OLDPACKAGE: _('older package(s)'),
-                          rpm.RPMPROB_DISKSPACE: _('insufficient disk space'),
-                          rpm.RPMPROB_DISKNODES: _('insufficient disk inodes'),
-                          rpm.RPMPROB_CONFLICT: _('package conflicts'),
-                          rpm.RPMPROB_PKG_INSTALLED: _('package already installed'),
-                          rpm.RPMPROB_REQUIRES: _('required package'),
-                          rpm.RPMPROB_BADARCH: _('package for incorrect arch'),
-                          rpm.RPMPROB_BADOS: _('package for incorrect os'),
-            }
-
-            for (descr, (ty, mount, need)) in probs.value: # FIXME: probs.value???
-                log.error("%s: %s" %(probTypes[ty], descr))
-                if not uniqueProbs.has_key(ty) and probTypes.has_key(ty):
-                    uniqueProbs[ty] = probTypes[ty]
-
-                if ty == rpm.RPMPROB_DISKSPACE:
-                    spaceneeded[mount] = need
-                elif ty in [rpm.RPMPROB_NEW_FILE_CONFLICT, rpm.RPMPROB_FILE_CONFLICT]:
-                    fileConflicts.append(descr)
-
-            if spaceneeded:
-                spaceprob = _("You need more space on the following "
-                              "file systems:\n")
-
-                for (mount, need) in spaceneeded.items():
-                    log.info("(%s, %s)" %(mount, need))
-
-                    if mount.startswith("/mnt/sysimage/"):
-                        mount.replace("/mnt/sysimage", "")
-                    elif mount.startswith("/mnt/sysimage"):
-                        mount = "/" + mount.replace("/mnt/sysimage", "")
-
-                    spaceprob += "%d M on %s\n" % (need / (1024*1024), mount)
-            elif fileConflicts:
-                fileprob = _("There were file conflicts when checking the "
-                             "packages to be installed:\n%s\n") % ("\n".join(fileConflicts),)
-
-            msg = _("There was an error running your transaction for "
-                    "the following reason(s): %s.\n") % ', '.join(uniqueProbs.values())
-
-            spaceprob = to_unicode(spaceprob)
-            fileprob = to_unicode(fileprob)
-
-            if len(self.anaconda.backend.getRequiredMedia()) > 1 or self.anaconda.upgrade:
-                intf.detailedMessageWindow(_("Error Running Transaction"),
-                   msg, spaceprob + "\n" + fileprob, type="custom",
-                   custom_icon="error", custom_buttons=[_("_Exit installer")])
-                sys.exit(1)
-            else:
-                rc = intf.detailedMessageWindow(_("Error Running Transaction"),
-                        msg, spaceprob + "\n" + fileprob, type="custom",
-                        custom_icon="error",
-                        custom_buttons=[_("_Back"), _("_Exit installer")])
-
-            if rc == 1:
-                sys.exit(1)
-            else:
-                self._undoDepInstalls()
-                return DISPATCH_BACK
-
-    def doMacros(self):
-        for (key, val) in self.macros.items():
-            rpm.addMacro(key, val)
-
-    def simpleDBInstalled(self, name, arch=None):
-        # FIXME: doing this directly instead of using self.rpmdb.installed()
-        # speeds things up by 400%
-        mi = self.ts.ts.dbMatch('name', name)
-        if mi.count() == 0:
-            return False
-        if arch is None:
-            return True
-        if arch in map(lambda h: h['arch'], mi):
-            return True
-        return False
-
-    def isPackageInstalled(self, name = None, epoch = None, version = None,
-                           release = None, arch = None, po = None):
-        # FIXME: this sucks.  we should probably suck it into yum proper
-        # but it'll need a bit of cleanup first.
-        if po is not None:
-            (name, epoch, version, release, arch) = po.returnNevraTuple()
-
-        installed = False
-        if name and not (epoch or version or release or arch):
-            installed = self.simpleDBInstalled(name)
-        elif self.rpmdb.installed(name = name, epoch = epoch, ver = version,
-                                rel = release, arch = arch):
-            installed = True
-
-        lst = self.tsInfo.matchNaevr(name = name, epoch = epoch,
-                                     ver = version, rel = release,
-                                     arch = arch)
-        for txmbr in lst:
-            if txmbr.output_state in TS_INSTALL_STATES:
-                return True
-        if installed and len(lst) > 0:
-            # if we get here, then it was installed, but it's in the tsInfo
-            # for an erase or obsoleted --> not going to be installed at end
-            return False
-        return installed
-
-    def isGroupInstalled(self, grp):
-        if grp.selected:
-            return True
-        elif grp.installed and not grp.toremove:
-            return True
-        return False
-
-    def _pkgExists(self, pkg):
-        """Whether or not a given package exists in our universe."""
-        try:
-            pkgs = self.pkgSack.returnNewestByName(pkg)
-            return True
-        except yum.Errors.PackageSackError:
-            pass
-        try:
-            pkgs = self.rpmdb.returnNewestByName(pkg)
-            return True
-        except (IndexError, yum.Errors.PackageSackError):
-            pass
-        return False
-
-    def _groupHasPackages(self, grp):
-        # this checks to see if the given group has any packages available
-        # (ie, already installed or in the sack of available packages)
-        # so that we don't show empty groups.  also, if there are mandatory
-        # packages and we have none of them, don't show
-        for pkg in grp.mandatory_packages.keys():
-            if self._pkgExists(pkg):
-                return True
-        if len(grp.mandatory_packages) > 0:
-            return False
-        for pkg in grp.default_packages.keys() + grp.optional_packages.keys() + \
-                   grp.conditional_packages.keys():
-            if self._pkgExists(pkg):
-                return True
-        return False
-
-class YumBackend(AnacondaBackend):
-    def __init__ (self, anaconda):
-        AnacondaBackend.__init__(self, anaconda)
-        self.supportsPackageSelection = True
-
-        buf = """
-[main]
-installroot=%s
-cachedir=/var/cache/yum/$basearch/$releasever
-keepcache=0
-logfile=/tmp/yum.log
-metadata_expire=0
-obsoletes=True
-pluginpath=/usr/lib/yum-plugins,/tmp/updates/yum-plugins
-pluginconfpath=/etc/yum/pluginconf.d,/tmp/updates/pluginconf.d
-plugins=1
-reposdir=/etc/anaconda.repos.d,/tmp/updates/anaconda.repos.d,/tmp/product/anaconda.repos.d
-""" % (anaconda.rootPath)
-
-        if anaconda.proxy:
-            buf += "proxy=%s\n" % anaconda.proxy
-
-            if anaconda.proxyUsername:
-                buf += "proxy_username=%s\n" % anaconda.proxyUsername
-
-            if anaconda.proxyPassword:
-                buf += "proxy_password=%s\n" % anaconda.proxyPassword
-
-        fd = open("/tmp/anaconda-yum.conf", "w")
-        fd.write(buf)
-        fd.close()
-
-    def complete(self, anaconda):
-        if not anaconda.mediaDevice and os.path.ismount(self.ayum.tree):
-            isys.umount(self.ayum.tree)
-
-        anaconda.backend.removeInstallImage()
-
-        # clean up rpmdb locks so that kickstart %post scripts aren't
-        # unhappy (#496961)
-        iutil.resetRpmDb(anaconda.rootPath)
-
-    def doBackendSetup(self, anaconda):
-        if anaconda.dir == DISPATCH_BACK:
-            return DISPATCH_BACK
-
-        if anaconda.upgrade:
-           # FIXME: make sure that the rpmdb doesn't have stale locks :/
-           iutil.resetRpmDb(anaconda.rootPath)
-
-        iutil.writeRpmPlatform()
-        anaconda.backend.freetmp(anaconda)
-        self.ayum = AnacondaYum(anaconda)
-        self.ayum.setup()
-
-        self.ayum.doMacros()
-
-        # If any enabled repositories require networking, go ahead and bring
-        # it up now.  No need to have people wait for the timeout when we
-        # know this in advance.
-        for repo in self.ayum.repos.listEnabled():
-            if repo.needsNetwork() and not network.hasActiveNetDev():
-                if not anaconda.intf.enableNetwork():
-                    anaconda.intf.messageWindow(_("No Network Available"),
-                        _("Some of your software repositories require "
-                          "networking, but there was an error enabling the "
-                          "network on your system."),
-                        type="custom", custom_icon="error",
-                        custom_buttons=[_("_Exit installer")])
-                    sys.exit(1)
-
-                urlgrabber.grabber.reset_curl_obj()
-                break
-
-        self.doRepoSetup(anaconda)
-        self.doSackSetup(anaconda)
-        self.doGroupSetup(anaconda)
-
-        self.ayum.doMacros()
-
-    def doGroupSetup(self, anaconda):
-        while True:
-            try:
-                self.ayum.doGroupSetup()
-            except (GroupsError, NoSuchGroup, RepoError), e:
-                buttons = [_("_Exit installer"), _("_Retry")]
-            else:
-                break # success
-
-            rc = anaconda.intf.messageWindow(_("Error"),
-                                        _("Unable to read group information "
-                                          "from repositories.  This is "
-                                          "a problem with the generation "
-                                          "of your install tree."),
-                                        type="custom", custom_icon="error",
-                                        custom_buttons = buttons)
-            if rc == 0:
-                sys.exit(0)
-            else:
-                self.ayum._setGroups(None)
-                continue
-
-    def doRepoSetup(self, anaconda, thisrepo = None, fatalerrors = True):
-        self.__withFuncDo(anaconda, lambda r: self.ayum.doRepoSetup(thisrepo=r.id),
-                          thisrepo=thisrepo, fatalerrors=fatalerrors)
-
-    def doSackSetup(self, anaconda, thisrepo = None, fatalerrors = True):
-        self.__withFuncDo(anaconda, lambda r: self.ayum.doSackSetup(thisrepo=r.id),
-                          thisrepo=thisrepo, fatalerrors=fatalerrors)
-
-    def __withFuncDo(self, anaconda, fn, thisrepo=None, fatalerrors=True):
-        # Don't do this if we're being called as a dispatcher step (instead
-        # of being called when a repo is added via the UI) and we're going
-        # back.
-        if thisrepo is None and anaconda.dir == DISPATCH_BACK:
-            return
-
-        # We want to call the function one repo at a time so we have some
-        # concept of which repo didn't set up correctly.
-        if thisrepo is not None:
-            repos = [self.ayum.repos.getRepo(thisrepo)]
-        else:
-            repos = self.ayum.repos.listEnabled()
-
-        for repo in repos:
-            if repo.name is None:
-                txt = _("Retrieving installation information.")
-            else:
-                txt = _("Retrieving installation information for %s.")%(repo.name)
-
-            waitwin = anaconda.intf.waitWindow(_("Installation Progress"), txt)
-
-            while True:
-                try:
-                    fn(repo)
-                    waitwin.pop()
-                except RepoError, e:
-                    waitwin.pop()
-                    buttons = [_("_Exit installer"), _("Edit"), _("_Retry")]
-                else:
-                    break # success
-
-                if anaconda.ksdata:
-                    buttons.append(_("_Continue"))
-
-                if not fatalerrors:
-                    raise RepoError, e
-
-                rc = anaconda.intf.messageWindow(_("Error"),
-                                   _("Unable to read package metadata. This may be "
-                                     "due to a missing repodata directory.  Please "
-                                     "ensure that your install tree has been "
-                                     "correctly generated.\n\n%s" % e),
-                                     type="custom", custom_icon="error",
-                                     custom_buttons=buttons)
-                if rc == 0:
-                    # abort
-                    sys.exit(0)
-                elif rc == 1:
-                    # edit
-                    anaconda.intf.editRepoWindow(repo)
-                    break
-                elif rc == 2:
-                    # retry, but only if button is present
-                    continue
-                else:
-                    # continue, but only if button is present
-                    self.ayum.repos.delete(repo.id)
-                    break
-
-            # if we're in kickstart the repo may have been deleted just above
-            try:
-                self.ayum.repos.getRepo(repo.id)
-            except RepoError:
-                log.debug("repo %s has been removed" % (repo.id,))
-                continue
-
-            repo.setFailureObj(self.ayum.urlgrabberFailureCB)
-            repo.setMirrorFailureObj((self.ayum.mirrorFailureCB, (),
-                                     {"repo": repo.id}))
-
-        self.ayum.repos.callback = None
-
-    def getDefaultGroups(self, anaconda):
-        langs = anaconda.instLanguage.getCurrentLangSearchList()
-        rc = map(lambda x: x.groupid,
-                 filter(lambda x: x.default, self.ayum.comps.groups))
-        for g in self.ayum.comps.groups:
-            if g.langonly in langs:
-                rc.append(g.groupid)
-        return rc
-
-    def resetPackageSelections(self):
-        """Reset the package selection to an empty state."""
-        for txmbr in self.ayum.tsInfo:
-            self.ayum.tsInfo.remove(txmbr.pkgtup)
-        self.ayum.tsInfo.conditionals.clear()
-        for grp in self.ayum.comps.groups:
-            grp.selected = False
-
-    def selectModulePackages(self, anaconda, kernelPkgName):
-        (base, sep, ext) = kernelPkgName.partition("-")
-
-        moduleProvides = []
-
-        for (path, name) in anaconda.extraModules:
-            if ext != "":
-                moduleProvides.append("dud-%s-%s" % (name, ext))
-            else:
-                moduleProvides.append("dud-%s" % name)
-
-        #We need to install the packages which contain modules from DriverDiscs
-        for modPath in isys.modulesWithPaths():
-            if modPath.startswith(DD_EXTRACTED):
-                moduleProvides.append(modPath[len(DD_EXTRACTED):])
-            else:
-                continue
-
-        for module in moduleProvides:
-            pkgs = self.ayum.returnPackagesByDep(module)
-
-            if not pkgs:
-                log.warning("Didn't find any package providing %s" % module)
-
-            for pkg in pkgs:
-                log.info("selecting package %s for %s" % (pkg.name, module))
-                self.ayum.install(po=pkg)
-
-    def selectBestKernel(self, anaconda):
-        """Find the best kernel package which is available and select it."""
-
-        def getBestKernelByArch(pkgname, ayum):
-            """Convenience func to find the best arch of a kernel by name"""
-            try:
-                pkgs = ayum.pkgSack.returnNewestByName(pkgname)
-            except yum.Errors.PackageSackError:
-                return None
-
-            pkgs = self.ayum.bestPackagesFromList(pkgs)
-            if len(pkgs) == 0:
-                return None
-            return pkgs[0]
-
-        def selectKernel(pkgname):
-            try:
-                pkg = getBestKernelByArch(pkgname, self.ayum)
-            except PackageSackError:
-                log.debug("no %s package" % pkgname)
-                return False
-
-            if not pkg:
-                return False
-
-            log.info("selected %s package for kernel" % pkg.name)
-            self.ayum.install(po=pkg)
-            self.selectModulePackages(anaconda, pkg.name)
-
-            if len(self.ayum.tsInfo.matchNaevr(name="gcc")) > 0:
-                log.debug("selecting %s-devel" % pkg.name)
-                self.selectPackage("%s-devel.%s" % (pkg.name, pkg.arch))
-
-            return True
-
-        foundkernel = False
-
-        if not foundkernel and isys.isPaeAvailable():
-            if selectKernel("kernel-PAE"):
-                foundkernel = True
-
-        if not foundkernel:
-            selectKernel("kernel")
-
-    def selectFSPackages(self, storage):
-        for device in storage.fsset.devices:
-            # this takes care of device and filesystem packages
-            map(self.selectPackage, device.packages)
-
-    # anaconda requires several programs on the installed system to complete
-    # installation, but we have no guarantees that some of these will be
-    # installed (they could have been removed in kickstart).  So we'll force
-    # it.
-    def selectAnacondaNeeds(self):
-        for pkg in ['authconfig', 'chkconfig', 'system-config-firewall-base']:
-            self.selectPackage(pkg)
-
-    def doPostSelection(self, anaconda):
-        # Only solve dependencies on the way through the installer, not the way back.
-        if anaconda.dir == DISPATCH_BACK:
-            return
-
-        dscb = YumDepSolveProgress(anaconda.intf, self.ayum)
-        self.ayum.dsCallback = dscb
-
-        # do some sanity checks for kernel and bootloader
-        if not anaconda.upgrade:
-            # New installs only - upgrades will already have all this stuff.
-            self.selectBestKernel(anaconda)
-            map(self.selectPackage, anaconda.platform.packages)
-            self.selectFSPackages(anaconda.storage)
-            self.selectAnacondaNeeds()
-        else:
-            self.ayum.update()
-
-        while True:
-            try:
-                (code, msgs) = self.ayum.buildTransaction()
-
-                # If %packages --ignoremissing was given, don't bother
-                # prompting for missing dependencies.
-                if anaconda.ksdata and anaconda.ksdata.packages.handleMissing == KS_MISSING_IGNORE:
-                    break
-
-                if code == 1 and not anaconda.upgrade:
-                    # resolveDeps returns 0 if empty transaction, 1 if error,
-                    # 2 if success
-                    depprob = "\n".join(msgs)
-
-                    rc = anaconda.intf.detailedMessageWindow(_("Warning"),
-                            _("Some of the packages you have selected for "
-                              "install are missing dependencies.  You can "
-                              "exit the installation, go back and change "
-                              "your package selections, or continue "
-                              "installing these packages without their "
-                              "dependencies.  If you continue, these packages "
-                              "may not work correctly due to missing components."),
-                            depprob + "\n", type="custom", custom_icon="error",
-                            custom_buttons=[_("_Exit installer"), _("_Back"),
-                                            _("_Continue")])
-                    dscb.pop()
-
-                    if rc == 0:
-                        sys.exit(1)
-                    elif rc == 1:
-                        self.ayum._undoDepInstalls()
-                        return DISPATCH_BACK
-
-                break
-            except RepoError, e:
-                # FIXME: would be nice to be able to recover here
-                rc = anaconda.intf.messageWindow(_("Error"),
-                               _("Unable to read package metadata. This may be "
-                                 "due to a missing repodata directory.  Please "
-                                 "ensure that your install tree has been "
-                                 "correctly generated.\n\n%s" % e),
-                                 type="custom", custom_icon="error",
-                                 custom_buttons=[_("_Exit installer"), _("_Retry")])
-                dscb.pop()
-
-                if rc == 0:
-                    sys.exit(0)
-                else:
-                    continue
-            else:
-                break
-
-        (self.dlpkgs, self.totalSize, self.totalFiles)  = self.ayum.getDownloadPkgs()
-
-        if not anaconda.upgrade:
-            largePart = anaconda.storage.mountpoints.get("/usr", anaconda.storage.rootDevice)
-
-            if largePart and largePart.size < self.totalSize / 1024:
-                rc = anaconda.intf.messageWindow(_("Error"),
-                                        _("Your selected packages require %d MB "
-                                          "of free space for installation, but "
-                                          "you do not have enough available.  "
-                                          "You can change your selections or "
-                                          "exit the installer." % (self.totalSize / 1024)),
-                                        type="custom", custom_icon="error",
-                                        custom_buttons=[_("_Back"), _("_Exit installer")])
-
-                dscb.pop()
-
-                if rc == 1:
-                    sys.exit(1)
-                else:
-                    self.ayum._undoDepInstalls()
-                    return DISPATCH_BACK
-
-        dscb.pop()
-
-        if anaconda.mediaDevice and not anaconda.ksdata:
-           rc = presentRequiredMediaMessage(anaconda)
-           if rc == 0:
-               rc2 = anaconda.intf.messageWindow(_("Reboot?"),
-                                       _("The system will be rebooted now."),
-                                       type="custom", custom_icon="warning",
-                                       custom_buttons=[_("_Back"), _("_Reboot")])
-               if rc2 == 1:
-                   sys.exit(0)
-               else:
-                   return DISPATCH_BACK
-           elif rc == 1: # they asked to go back
-               return DISPATCH_BACK
-
-        self.ayum.dsCallback = None
-
-    def doPreInstall(self, anaconda):
-        if anaconda.dir == DISPATCH_BACK:
-            for d in ("/selinux", "/dev", "/proc/bus/usb"):
-                try:
-                    isys.umount(anaconda.rootPath + d, removeDir = False)
-                except Exception, e:
-                    log.error("unable to unmount %s: %s" %(d, e))
-            return
-
-        if anaconda.upgrade:
-            # An old mtab can cause confusion (esp if loop devices are
-            # in it).  Be extra special careful and delete any mtab first,
-            # in case the user has done something funny like make it into
-            # a symlink.
-            if os.access(anaconda.rootPath + "/etc/mtab", os.F_OK):
-                os.remove(anaconda.rootPath + "/etc/mtab")
-
-            f = open(anaconda.rootPath + "/etc/mtab", "w+")
-            f.close()
-
-            # we really started writing modprobe.conf out before things were
-            # all completely ready.  so now we need to nuke old modprobe.conf's
-            # if you're upgrading from a 2.4 dist so that we can get the
-            # transition right
-            if (os.path.exists(anaconda.rootPath + "/etc/modules.conf") and
-                os.path.exists(anaconda.rootPath + "/etc/modprobe.conf") and
-                not os.path.exists(anaconda.rootPath + "/etc/modprobe.conf.anacbak")):
-                log.info("renaming old modprobe.conf -> modprobe.conf.anacbak")
-                os.rename(anaconda.rootPath + "/etc/modprobe.conf",
-                          anaconda.rootPath + "/etc/modprobe.conf.anacbak")
-
-        dirList = ['/var', '/var/lib', '/var/lib/rpm', '/tmp', '/dev', '/etc',
-                   '/etc/sysconfig', '/etc/sysconfig/network-scripts',
-                   '/etc/X11', '/root', '/var/tmp', '/etc/rpm', '/var/cache',
-                   '/var/cache/yum', '/etc/modprobe.d']
-
-        # If there are any protected partitions we want to mount, create their
-        # mount points now.
-        for protected in anaconda.storage.protectedDevices:
-            if getattr(protected.format, "mountpoint", None):
-                dirList.append(protected.format.mountpoint)
-
-        for i in dirList:
-            try:
-                os.mkdir(anaconda.rootPath + i)
-            except os.error, (errno, msg):
-                pass
-#            log.error("Error making directory %s: %s" % (i, msg))
-
-        self.initLog(anaconda.rootPath)
-
-        # setup /etc/rpm/ for the post-install environment
-        iutil.writeRpmPlatform(anaconda.rootPath)
-
-        try:
-            # FIXME: making the /var/lib/rpm symlink here is a hack to
-            # workaround db->close() errors from rpm
-            iutil.mkdirChain("/var/lib")
-            for path in ("/var/tmp", "/var/lib/rpm"):
-                if os.path.exists(path) and not os.path.islink(path):
-                    shutil.rmtree(path)
-                if not os.path.islink(path):
-                    os.symlink("%s/%s" %(anaconda.rootPath, path), "%s" %(path,))
-                else:
-                    log.warning("%s already exists as a symlink to %s" %(path, os.readlink(path),))
-        except Exception, e:
-            # how this could happen isn't entirely clear; log it in case
-            # it does and causes problems later
-            log.error("error creating symlink, continuing anyway: %s" %(e,))
-
-        # SELinux hackery (#121369)
-        if flags.selinux:
-            try:
-                os.mkdir(anaconda.rootPath + "/selinux")
-            except Exception, e:
-                pass
-            try:
-                isys.mount("/selinux", anaconda.rootPath + "/selinux", "selinuxfs")
-            except Exception, e:
-                log.error("error mounting selinuxfs: %s" %(e,))
-
-        # For usbfs
-        try:
-            isys.mount("/proc/bus/usb", anaconda.rootPath + "/proc/bus/usb", "usbfs")
-        except Exception, e:
-            log.error("error mounting usbfs: %s" %(e,))
-
-        # write out the fstab
-        if not anaconda.upgrade:
-            anaconda.storage.fsset.write(anaconda.rootPath)
-            if os.access("/etc/modprobe.d/anaconda.conf", os.R_OK):
-                shutil.copyfile("/etc/modprobe.d/anaconda.conf", 
-                                anaconda.rootPath + "/etc/modprobe.d/anaconda.conf")
-            anaconda.network.write(instPath=anaconda.rootPath, anaconda=anaconda)
-            anaconda.storage.write(anaconda.rootPath)
-            if not anaconda.isHeadless:
-                anaconda.keyboard.write(anaconda.rootPath)
-
-        # make a /etc/mtab so mkinitrd can handle certain hw (usb) correctly
-        f = open(anaconda.rootPath + "/etc/mtab", "w+")
-        f.write(anaconda.storage.mtab)
-        f.close()
-
-    def checkSupportedUpgrade(self, anaconda):
-        if anaconda.dir == DISPATCH_BACK:
-            return
-        self._checkUpgradeVersion(anaconda)
-        self._checkUpgradeArch(anaconda)
-
-    def _checkUpgradeVersion(self, anaconda):
-        # Figure out current version for upgrade nag and for determining weird
-        # upgrade cases
-        supportedUpgradeVersion = -1
-        for pkgtup in self.ayum.rpmdb.whatProvides('redhat-release', None, None):
-            n, a, e, v, r = pkgtup
-            if supportedUpgradeVersion <= 0:
-                val = rpmUtils.miscutils.compareEVR((None, '3', '1'),
-                                                    (e, v,r))
-                if val > 0:
-                    supportedUpgradeVersion = 0
-                else:
-                    supportedUpgradeVersion = 1
-                    break
-
-        if "Red Hat Enterprise Linux" not in productName:
-            supportedUpgradeVersion = 1
-
-        if supportedUpgradeVersion == 0:
-            rc = anaconda.intf.messageWindow(_("Warning"),
-                                    _("You appear to be upgrading from a system "
-                                      "which is too old to upgrade to this "
-                                      "version of %s.  Are you sure you wish to "
-                                      "continue the upgrade "
-                                      "process?") %(productName,),
-                                    type = "yesno")
-            if rc == 0:
-                iutil.resetRpmDb(anaconda.rootPath)
-                sys.exit(0)
-
-    def _checkUpgradeArch(self, anaconda):
-        def compareArch(a, b):
-            if re.match("i.86", a) and re.match("i.86", b):
-                return True
-            else:
-                return a == b
-
-        # get the arch of the initscripts package
-        try:
-            pkgs = self.ayum.pkgSack.returnNewestByName('initscripts')
-        except yum.Errors.PackageSackError:
-            log.info("no packages named initscripts")
-            return None
-
-        pkgs = self.ayum.bestPackagesFromList(pkgs)
-        if len(pkgs) == 0:
-            log.info("no best package")
-            return
-        myarch = pkgs[0].arch
-
-        log.info("initscripts is arch: %s" %(myarch,))
-        for po in self.ayum.rpmdb.getProvides('initscripts'):
-            log.info("po.arch is arch: %s" %(po.arch,))
-            if not compareArch(po.arch, myarch):
-                rc = anaconda.intf.messageWindow(_("Warning"),
-                         _("The arch of the release of %(productName)s you "
-                           "are upgrading to appears to be %(myarch)s which "
-                           "does not match your previously installed arch of "
-                           "%(arch)s.  This is likely to not succeed.  Are "
-                           "you sure you wish to continue the upgrade "
-                           "process?")
-                         % {'productName': productName,
-                            'myarch': myarch,
-                            'arch': po.arch},
-                         type="yesno")
-                if rc == 0:
-                    iutil.resetRpmDb(anaconda.rootPath)
-                    sys.exit(0)
-                else:
-                    log.warning("upgrade between possibly incompatible "
-                                "arches %s -> %s" %(po.arch, myarch))
-                    break
-
-    def doInstall(self, anaconda):
-        log.info("Preparing to install packages")
-
-        if not anaconda.upgrade:
-            rpm.addMacro("__dbi_htconfig",
-                         "hash nofsync %{__dbi_other} %{__dbi_perms}")
-
-        if anaconda.ksdata and anaconda.ksdata.packages.excludeDocs:
-            rpm.addMacro("_excludedocs", "1")
-
-        cb = AnacondaCallback(self.ayum, anaconda,
-                              self.instLog, self.modeText)
-        cb.setSizes(len(self.dlpkgs), self.totalSize, self.totalFiles)
-
-        rc = self.ayum.run(self.instLog, cb, anaconda.intf, anaconda.id)
-
-        if cb.initWindow is not None:
-            cb.initWindow.pop()
-
-        self.instLog.write("*** FINISHED INSTALLING PACKAGES ***")
-        self.instLog.close ()
-
-        anaconda.intf.setInstallProgressClass(None)
-
-        if rc == DISPATCH_BACK:
-            return DISPATCH_BACK
-
-    def doPostInstall(self, anaconda):
-        if anaconda.upgrade:
-            w = anaconda.intf.waitWindow(_("Post Upgrade"),
-                                    _("Performing post-upgrade configuration"))
-        else:
-            w = anaconda.intf.waitWindow(_("Post Installation"),
-                                    _("Performing post-installation configuration"))
-
-        packages.rpmSetupGraphicalSystem(anaconda)
-
-        for repo in self.ayum.repos.listEnabled():
-            repo.dirCleanup()
-
-        # expire yum caches on upgrade
-        if anaconda.upgrade and os.path.exists("%s/var/cache/yum" %(anaconda.rootPath,)):
-            log.info("Expiring yum caches")
-            try:
-                iutil.execWithRedirect("yum", ["clean", "all"],
-                                       stdout="/dev/tty5", stderr="/dev/tty5",
-                                       root = anaconda.rootPath)
-            except:
-                pass
-
-        # nuke preupgrade
-        if flags.cmdline.has_key("preupgrade") and os.path.exists("%s/var/cache/yum/anaconda-upgrade" %(anaconda.rootPath,)):
-            try:
-                shutil.rmtree("%s/var/cache/yum/anaconda-upgrade" %(anaconda.rootPath,))
-            except:
-                pass
-
-        # XXX: write proper lvm config
-
-        AnacondaBackend.doPostInstall(self, anaconda)
-        w.pop()
-
-    def kernelVersionList(self, rootPath="/"):
-        # FIXME: using rpm here is a little lame, but otherwise, we'd
-        # be pulling in filelists
-        return packages.rpmKernelVersionList(rootPath)
-
-    def __getGroupId(self, group):
-        """Get the groupid for the given name (english or translated)."""
-        for g in self.ayum.comps.groups:
-            if group == g.name:
-                return g.groupid
-            for trans in g.translated_name.values():
-                if group == trans:
-                    return g.groupid
-
-    def isGroupSelected(self, group):
-        try:
-            grp = self.ayum.comps.return_group(group)
-            if grp.selected: return True
-        except yum.Errors.GroupsError, e:
-            pass
-        return False
-
-    def selectGroup(self, group, *args):
-        if not self.ayum.comps.has_group(group):
-            log.debug("no such group %s" % group)
-            raise NoSuchGroup, group
-
-        types = ["mandatory"]
-
-        if args:
-            if args[0][0]:
-                types.append("default")
-            if args[0][1]:
-                types.append("optional")
-        else:
-            types.append("default")
-
-        try:
-            mbrs = self.ayum.selectGroup(group, group_package_types=types)
-            if len(mbrs) == 0 and self.isGroupSelected(group):
-                return
-        except yum.Errors.GroupsError, e:
-            # try to find out if it's the name or translated name
-            gid = self.__getGroupId(group)
-            if gid is not None:
-                mbrs = self.ayum.selectGroup(gid, group_package_types=types)
-                if len(mbrs) == 0 and self.isGroupSelected(gid):
-                    return
-            else:
-                log.debug("no such group %s" %(group,))
-                raise NoSuchGroup, group
-
-    def deselectGroup(self, group, *args):
-        try:
-            self.ayum.deselectGroup(group)
-        except yum.Errors.GroupsError, e:
-            # try to find out if it's the name or translated name
-            gid = self.__getGroupId(group)
-            if gid is not None:
-                self.ayum.deselectGroup(gid)
-            else:
-                log.debug("no such group %s" %(group,))
-
-    def selectPackage(self, pkg, *args):
-        if self.ayum.tsInfo.matchNaevr(name=pkg):
-            return 0
-
-        try:
-            mbrs = self.ayum.install(pattern=pkg)
-            return len(mbrs)
-        except yum.Errors.InstallError:
-            log.debug("no package matching %s" %(pkg,))
-            return 0
-
-    def deselectPackage(self, pkg, *args):
-        sp = pkg.rsplit(".", 2)
-        txmbrs = []
-        if len(sp) == 2:
-            txmbrs = self.ayum.tsInfo.matchNaevr(name=sp[0], arch=sp[1])
-
-        if len(txmbrs) == 0:
-            exact, match, unmatch = yum.packages.parsePackages(self.ayum.pkgSack.returnPackages(), [pkg], casematch=1)
-            for p in exact + match:
-                txmbrs.append(p)
-
-        if len(txmbrs) > 0:
-            for x in txmbrs:
-                self.ayum.tsInfo.remove(x.pkgtup)
-                # we also need to remove from the conditionals
-                # dict so that things don't get pulled back in as a result
-                # of them.  yes, this is ugly.  conditionals should die.
-                for req, pkgs in self.ayum.tsInfo.conditionals.iteritems():
-                    if x in pkgs:
-                        pkgs.remove(x)
-                        self.ayum.tsInfo.conditionals[req] = pkgs
-            return len(txmbrs)
-        else:
-            log.debug("no such package %s to remove" %(pkg,))
-            return 0
-
-    def groupListExists(self, grps):
-        """Returns bool of whether all of the given groups exist."""
-        for gid in grps:
-            g = self.ayum.comps.return_group(gid)
-            if not g:
-                log.debug("no such group %s" % (gid,))
-                return False
-        return True
-
-    def groupListDefault(self, grps):
-        """Returns bool of whether all of the given groups are default"""
-        rc = False
-        for gid in grps:
-            g = self.ayum.comps.return_group(gid)
-            if g and not g.default:
-                return False
-            elif g:
-                rc = True
-        return rc
-
-    def writeKS(self, f):
-        for repo in self.ayum.repos.listEnabled():
-            if repo.name == "Installation Repo":
-                continue
-
-            line = "repo --name=\"%s\" " % (repo.name or repo.repoid)
-
-            if repo.baseurl:
-                line += " --baseurl=%s\n" % repo.baseurl[0]
-            else:
-                line += " --mirrorlist=%s\n" % repo.mirrorlist
-
-            f.write(line)
-
-    def writePackagesKS(self, f, anaconda):
-        if anaconda.ksdata:
-            f.write(anaconda.ksdata.packages.__str__())
-            return
-
-        groups = []
-        installed = []
-        removed = []
-
-        # Faster to grab all the package names up front rather than call
-        # searchNevra in the loop below.
-        allPkgNames = map(lambda pkg: pkg.name, self.ayum.pkgSack.returnPackages())
-        allPkgNames.sort()
-
-        # On CD/DVD installs, we have one transaction per CD and will end up
-        # checking allPkgNames against a very short list of packages.  So we
-        # have to reset to media #0, which is an all packages transaction.
-        old = self.ayum.tsInfo.curmedia
-        self.ayum.tsInfo.curmedia = 0
-
-        self.ayum.tsInfo.makelists()
-        txmbrNames = map (lambda x: x.name, self.ayum.tsInfo.getMembers())
-
-        self.ayum.tsInfo.curmedia = old
-
-        if len(self.ayum.tsInfo.instgroups) == 0 and len(txmbrNames) == 0:
-            return
-
-        f.write("\n%packages\n")
-
-        for grp in filter(lambda x: x.selected, self.ayum.comps.groups):
-            groups.append(grp.groupid)
-
-            defaults = grp.default_packages.keys() + grp.mandatory_packages.keys()
-            optionals = grp.optional_packages.keys()
-
-            for pkg in filter(lambda x: x in defaults and (not x in txmbrNames and x in allPkgNames), grp.packages):
-                removed.append(pkg)
-
-            for pkg in filter(lambda x: x in txmbrNames, optionals):
-                installed.append(pkg)
-
-        for grp in groups:
-            f.write("@%s\n" % grp)
-
-        for pkg in installed:
-            f.write("%s\n" % pkg)
-
-        for pkg in removed:
-            f.write("-%s\n" % pkg)
-
-        f.write("%end")
-
-    def writeConfiguration(self):
-        return
-
-    def getRequiredMedia(self):
-        return self.ayum.tsInfo.reqmedia.keys()
-
-class DownloadHeaderProgress:
-    def __init__(self, intf, ayum=None):
-        window = intf.progressWindow(_("Installation Starting"),
-                                     _("Starting installation process"),
-                                     1.0, 0.01)
-        self.window = window
-        self.ayum = ayum
-        self.current = self.loopstart = 0
-        self.incr = 1
-
-        if self.ayum is not None and self.ayum.tsInfo is not None:
-            self.numpkgs = len(self.ayum.tsInfo.getMembers())
-            if self.numpkgs != 0:
-                self.incr = (1.0 / self.numpkgs) * (1.0 - self.loopstart)
-        else:
-            self.numpkgs = 0
-
-        self.refresh()
-
-        self.restartLoop = self.downloadHeader = self.transactionPopulation = self.refresh
-        self.procReq = self.procConflict = self.unresolved = self.noop
-
-    def noop(self, *args, **kwargs):
-        pass
-
-    def pkgAdded(self, *args):
-        if self.numpkgs:
-            self.set(self.current + self.incr)
-
-    def pop(self):
-        self.window.pop()
-
-    def refresh(self, *args):
-        self.window.refresh()
-
-    def set(self, value):
-        self.current = value
-        self.window.set(self.current)
-
-class YumDepSolveProgress:
-    def __init__(self, intf, ayum = None):
-        window = intf.progressWindow(_("Dependency Check"),
-                                     _("Checking dependencies in packages selected for installation"),
-                                     1.0, 0.01)
-        self.window = window
-
-        self.numpkgs = None
-        self.loopstart = None
-        self.incr = None
-        self.ayum = ayum
-        self.current = 0
-
-        self.restartLoop = self.downloadHeader = self.transactionPopulation = self.refresh
-        self.procReq = self.procConflict = self.unresolved = self.noop
-
-    def tscheck(self, num = None):
-        self.refresh()
-        if num is None and self.ayum is not None and self.ayum.tsInfo is not None:
-            num = len(self.ayum.tsInfo.getMembers())
-
-        if num:
-            self.numpkgs = num
-            self.loopstart = self.current
-            self.incr = (1.0 / num) * ((1.0 - self.loopstart) / 2)
-
-    def pkgAdded(self, *args):
-        if self.numpkgs:
-            self.set(self.current + self.incr)
-
-    def noop(self, *args, **kwargs):
-        pass
-
-    def refresh(self, *args):
-        self.window.refresh()
-
-    def set(self, value):
-        self.current = value
-        self.window.set(self.current)
-
-    def start(self):
-        self.set(0.0)
-        self.refresh()
-
-    def end(self):
-        self.window.set(1.0)
-        self.window.refresh()
-
-    def pop(self):
-        self.window.pop()
-- 
1.6.6.1

_______________________________________________
Anaconda-devel-list mailing list
Anaconda-devel-list@xxxxxxxxxx
https://www.redhat.com/mailman/listinfo/anaconda-devel-list

[Index of Archives]     [Kickstart]     [Fedora Users]     [Fedora Legacy List]     [Fedora Maintainers]     [Fedora Desktop]     [Fedora SELinux]     [Big List of Linux Books]     [Yosemite News]     [Yosemite Photos]     [KDE Users]     [Fedora Tools]
  Powered by Linux